diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 380cdb803..158f8e812 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -211,6 +211,7 @@ urlpatterns = [ # Rather than dealing with that, we keep everything centralized in one location. # This way, we can share a view for djangooidc, and other pages as we see fit. handler500 = "registrar.views.utility.error_views.custom_500_error_view" +handler403 = "registrar.views.utility.error_views.custom_403_error_view" # we normally would guard these with `if settings.DEBUG` but tests run with # DEBUG = False even when these apps have been loaded because settings.DEBUG diff --git a/src/registrar/forms/user_profile.py b/src/registrar/forms/user_profile.py index c04baa9e5..c825c6352 100644 --- a/src/registrar/forms/user_profile.py +++ b/src/registrar/forms/user_profile.py @@ -51,6 +51,7 @@ class UserProfileForm(forms.ModelForm): self.fields["email"].error_messages = { "required": "Enter your email address in the required format, like name@example.com." } + # self.fields["email"].widget.attrs["readonly"] = "readonly" self.fields["phone"].error_messages["required"] = "Enter your phone number." self.domainInfo = None diff --git a/src/registrar/templates/base.html b/src/registrar/templates/base.html index 03b7c0f2a..d3a7e3e48 100644 --- a/src/registrar/templates/base.html +++ b/src/registrar/templates/base.html @@ -156,6 +156,7 @@ {% if user.is_authenticated %} {{ user.email }} + {% if has_profile_feature_flag %}
  • | {% url 'user-profile' as user_profile_url %} @@ -163,6 +164,7 @@ Your profile
  • + {% endif %}
  • | Sign out diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index 2b2d45695..67837196f 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -59,8 +59,10 @@ {% url 'domain-authorizing-official' pk=domain.id as url %} {% include "includes/summary_item.html" with title='Authorizing official' value=domain.domain_info.authorizing_official contact='true' edit_link=url editable=domain.is_editable %} + {% if not has_profile_feature_flag %} {% url 'domain-your-contact-information' pk=domain.id as url %} {% include "includes/summary_item.html" with title='Your contact information' value=request.user.contact contact='true' edit_link=url editable=domain.is_editable %} + {% endif %} {% url 'domain-security-email' pk=domain.id as url %} {% if security_email is not None and security_email not in hidden_security_emails%} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 9e00fafa9..7453909a8 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -73,6 +73,7 @@
  • + {% if not has_profile_feature_flag %}
  • {% url 'domain-your-contact-information' pk=domain.id as url %}
  • + {% endif %}
  • {% url 'domain-security-email' pk=domain.id as url %} diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 9134080a1..2dc096083 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -59,7 +59,7 @@ from epplibwrapper import ( from ..utility.email import send_templated_email, EmailSendingError from .utility import DomainPermissionView, DomainInvitationPermissionDeleteView - +from waffle.decorators import flag_is_active logger = logging.getLogger(__name__) @@ -102,6 +102,13 @@ class DomainBaseView(DomainPermissionView): domain_pk = "domain:" + str(self.kwargs.get("pk")) self.session[domain_pk] = self.object + def get_context_data(self, **kwargs): + """Adjust context from FormMixin for formsets.""" + context = super().get_context_data(**kwargs) + # This is a django waffle flag which toggles features based off of the "flag" table + context["has_profile_feature_flag"] = flag_is_active(self.request, "profile_feature") + return context + class DomainFormBaseView(DomainBaseView, FormMixin): """ @@ -588,6 +595,17 @@ class DomainYourContactInformationView(DomainFormBaseView): # superclass has the redirect return super().form_valid(form) + + def has_permission(self): + """Check if this user has access to this domain. + + The user is in self.request.user and the domain needs to be looked + up from the domain's primary key in self.kwargs["pk"] + """ + if flag_is_active(self.request, "profile_feature"): + return False + + return super().has_permission() class DomainSecurityEmailView(DomainFormBaseView): diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index f93976138..5d1e234a6 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -22,6 +22,8 @@ from .utility import ( DomainRequestWizardPermissionView, ) +from waffle.decorators import flag_is_active + logger = logging.getLogger(__name__) @@ -225,14 +227,14 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): # will NOT be redirected. The purpose of this is to allow code to # send users "to the domain request wizard" without needing to # know which view is first in the list of steps. + context = self.get_context_data() if self.__class__ == DomainRequestWizard: if request.path_info == self.NEW_URL_NAME: - return render(request, "domain_request_intro.html") + return render(request, "domain_request_intro.html", context) else: return self.goto(self.steps.first) self.steps.current = current_url - context = self.get_context_data() context["forms"] = self.get_forms() # if pending requests exist and user does not have approved domains, @@ -392,6 +394,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): "is_federal": self.domain_request.is_federal(), "modal_button": modal_button, "modal_heading": modal_heading, + "has_profile_feature_flag": flag_is_active(self.request, "profile_feature") } def get_step_list(self) -> list: @@ -695,6 +698,13 @@ class Finished(DomainRequestWizard): class DomainRequestStatus(DomainRequestPermissionView): template_name = "domain_request_status.html" + def get_context_data(self, **kwargs): + """Adjust context from FormMixin for formsets.""" + context = super().get_context_data(**kwargs) + # This is a django waffle flag which toggles features based off of the "flag" table + context["has_profile_feature_flag"] = flag_is_active(self.request, "profile_feature") + return context + class DomainRequestWithdrawConfirmation(DomainRequestPermissionWithdrawView): """This page will ask user to confirm if they want to withdraw @@ -705,6 +715,13 @@ class DomainRequestWithdrawConfirmation(DomainRequestPermissionWithdrawView): template_name = "domain_request_withdraw_confirmation.html" + def get_context_data(self, **kwargs): + """Adjust context from FormMixin for formsets.""" + context = super().get_context_data(**kwargs) + # This is a django waffle flag which toggles features based off of the "flag" table + context["has_profile_feature_flag"] = flag_is_active(self.request, "profile_feature") + return context + class DomainRequestWithdrawn(DomainRequestPermissionWithdrawView): # this view renders no template diff --git a/src/registrar/views/user_profile.py b/src/registrar/views/user_profile.py index ea1f1ffdf..cddb51e48 100644 --- a/src/registrar/views/user_profile.py +++ b/src/registrar/views/user_profile.py @@ -13,7 +13,7 @@ from registrar.models import ( Contact, ) from registrar.views.utility.permission_views import UserProfilePermissionView - +from waffle.decorators import flag_is_active logger = logging.getLogger(__name__) @@ -29,10 +29,6 @@ class UserProfileView(UserProfilePermissionView, FormMixin): template_name = "profile.html" form_class = UserProfileForm - # def get(self, request, *args, **kwargs): - # logger.info("in get") - # return super().get(request, *args, **kwargs) - def get(self, request, *args, **kwargs): logger.info("in get()") self.object = self.get_object() @@ -41,26 +37,21 @@ class UserProfileView(UserProfilePermissionView, FormMixin): logger.info(context) return self.render_to_response(context) + def get_context_data(self, **kwargs): + """Adjust context from FormMixin for formsets.""" + context = super().get_context_data(**kwargs) + # This is a django waffle flag which toggles features based off of the "flag" table + context["has_profile_feature_flag"] = flag_is_active(self.request, "profile_feature") + return context + def get_success_url(self): """Redirect to the overview page for the domain.""" return reverse("user-profile") - # def post(self, request, *args, **kwargs): - # # Handle POST request logic here - # form = self.get_form() - # if form.is_valid(): - # # Save form data or perform other actions - # return HttpResponseRedirect(reverse('profile_success')) # Redirect to a success page - # else: - # # Form is not valid, re-render the page with errors - # return self.render_to_response(self.get_context_data(form=form)) - def post(self, request, *args, **kwargs): self.object = self.get_object() - form = self.get_form() - form.instance.id = self.object.id - form.instance.created_at = self.object.created_at - form.instance.user = self.request.user + form = self.form_class(request.POST, instance=self.object) + if form.is_valid(): return self.form_valid(form) else: diff --git a/src/registrar/views/utility/error_views.py b/src/registrar/views/utility/error_views.py index 48ae628a4..2374277d5 100644 --- a/src/registrar/views/utility/error_views.py +++ b/src/registrar/views/utility/error_views.py @@ -14,19 +14,28 @@ Rather than dealing with that, we keep everything centralized in one location. """ from django.shortcuts import render +from waffle.decorators import flag_is_active def custom_500_error_view(request, context=None): """Used to redirect 500 errors to a custom view""" if context is None: - return render(request, "500.html", status=500) - else: - return render(request, "500.html", context=context, status=500) + context = {} + context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature") + return render(request, "500.html", context=context, status=500) def custom_401_error_view(request, context=None): """Used to redirect 401 errors to a custom view""" if context is None: - return render(request, "401.html", status=401) - else: - return render(request, "401.html", context=context, status=401) + context = {} + context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature") + return render(request, "401.html", context=context, status=401) + + +def custom_403_error_view(request, exception=None, context=None): + """Used to redirect 403 errors to a custom view""" + if context is None: + context = {} + context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature") + return render(request, "403.html", context=context, status=403)