minimally works, requires cleanup

This commit is contained in:
David Kennedy 2024-06-19 14:26:36 -04:00
parent c020007d51
commit a6c4710777
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
7 changed files with 130 additions and 97 deletions

View file

@ -9,6 +9,7 @@ from urllib.parse import parse_qs, unquote
from urllib.parse import quote
from django.contrib import messages
from django.http import QueryDict
from django.views.generic.edit import FormMixin
from registrar.forms.user_profile import UserProfileForm, FinishSetupProfileForm
from django.urls import NoReverseMatch, reverse
@ -31,16 +32,48 @@ class UserProfileView(UserProfilePermissionView, FormMixin):
Base View for the User Profile. Handles getting and setting the User Profile
"""
class RedirectType(Enum):
"""
Enums for each type of redirection. Enforces behaviour on `get_redirect_url()`.
- HOME: We want to redirect to reverse("home")
- BACK_TO_SELF: We want to redirect back to this page
- TO_SPECIFIC_PAGE: We want to redirect to the page specified in the queryparam "redirect"
- COMPLETE_SETUP: Indicates that we want to navigate BACK_TO_SELF, but the subsequent
redirect after the next POST should be either HOME or TO_SPECIFIC_PAGE
"""
HOME = "home"
TO_SPECIFIC_PAGE = "domain_request"
BACK_TO_SELF = "back_to_self"
COMPLETE_SETUP = "complete_setup"
@classmethod
def get_all_redirect_types(cls) -> list[str]:
"""Returns the value of every redirect type defined in this enum."""
return [r.value for r in cls]
model = Contact
template_name = "profile.html"
form_class = UserProfileForm
base_view_name = "user-profile"
all_redirect_types = RedirectType.get_all_redirect_types()
redirect_type: RedirectType
def get(self, request, *args, **kwargs):
"""Handle get requests by getting user's contact object and setting object
and form to context before rendering."""
self._refresh_session_and_object(request)
form = self.form_class(instance=self.object)
context = self.get_context_data(object=self.object, form=form)
#self._refresh_session_and_object(request)
self.object = self.get_object()
# Get the redirect parameter from the query string
redirect = request.GET.get('redirect', 'home')
logger.info(f"redirect value is {redirect}")
form = self.form_class(instance=self.object, initial={'redirect': redirect})
context = self.get_context_data(object=self.object, form=form, redirect=redirect)
if (
hasattr(self.user, "finished_setup")
@ -63,8 +96,8 @@ class UserProfileView(UserProfilePermissionView, FormMixin):
@waffle_flag("profile_feature") # type: ignore
def dispatch(self, request, *args, **kwargs): # type: ignore
# Store the original queryparams to persist them
query_params = request.META["QUERY_STRING"]
request.session["query_params"] = query_params
# query_params = request.META["QUERY_STRING"]
# request.session["query_params"] = query_params
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
@ -73,10 +106,14 @@ class UserProfileView(UserProfilePermissionView, FormMixin):
# 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")
# The text for the back button on this page
context["profile_back_button_text"] = "Go to manage your domains"
context["show_back_button"] = False
# Set the profile_back_button_text based on the redirect parameter
if kwargs.get('redirect') == 'domain-request:':
context["profile_back_button_text"] = "Go back to your request"
else:
context["profile_back_button_text"] = "Go to manage your domains"
# Show back button conditional on user having finished setup
context["show_back_button"] = False
if hasattr(self.user, "finished_setup") and self.user.finished_setup:
context["user_finished_setup"] = True
context["show_back_button"] = True
@ -84,21 +121,30 @@ class UserProfileView(UserProfilePermissionView, FormMixin):
return context
def get_success_url(self):
"""Redirect to the user's profile page."""
"""Redirect to the user's profile page with updated query parameters."""
query_params = {}
if "query_params" in self.session:
params = unquote(self.session["query_params"])
query_params = parse_qs(params)
# Get the redirect parameter from the form submission
redirect_param = self.request.POST.get('redirect', None)
# Preserve queryparams and add them back to the url
base_url = reverse("user-profile")
new_redirect = replace_url_queryparams(base_url, query_params, convert_list_to_csv=True)
return new_redirect
# Initialize QueryDict with existing query parameters from current request
query_params = QueryDict(mutable=True)
query_params.update(self.request.GET)
# Update query parameters with the 'redirect' value from form submission
if redirect_param and redirect_param != 'home':
query_params['redirect'] = redirect_param
# Generate the URL with updated query parameters
base_url = reverse(self.base_view_name)
# Generate the full url from the given query params
full_url = replace_url_queryparams(base_url, query_params)
return full_url
def post(self, request, *args, **kwargs):
"""Handle post requests (form submissions)"""
self._refresh_session_and_object(request)
#self._refresh_session_and_object(request)
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
if form.is_valid():
@ -133,80 +179,75 @@ class FinishProfileSetupView(UserProfileView):
"""This view forces the user into providing additional details that
we may have missed from Login.gov"""
class RedirectType(Enum):
"""
Enums for each type of redirection. Enforces behaviour on `get_redirect_url()`.
- HOME: We want to redirect to reverse("home")
- BACK_TO_SELF: We want to redirect back to this page
- TO_SPECIFIC_PAGE: We want to redirect to the page specified in the queryparam "redirect"
- COMPLETE_SETUP: Indicates that we want to navigate BACK_TO_SELF, but the subsequent
redirect after the next POST should be either HOME or TO_SPECIFIC_PAGE
"""
HOME = "home"
TO_SPECIFIC_PAGE = "domain_request"
BACK_TO_SELF = "back_to_self"
COMPLETE_SETUP = "complete_setup"
@classmethod
def get_all_redirect_types(cls) -> list[str]:
"""Returns the value of every redirect type defined in this enum."""
return [r.value for r in cls]
template_name = "finish_profile_setup.html"
form_class = FinishSetupProfileForm
model = Contact
all_redirect_types = RedirectType.get_all_redirect_types()
redirect_type: RedirectType
base_view_name = "finish-user-profile-setup"
def get_context_data(self, **kwargs):
"""Extend get_context_data to include has_profile_feature_flag"""
context = super().get_context_data(**kwargs)
# Hide the back button by default
# Show back button conditional on user having finished setup
context["show_back_button"] = False
if self.redirect_type == self.RedirectType.COMPLETE_SETUP:
if hasattr(self.user, "finished_setup") and self.user.finished_setup:
context["confirm_changes"] = True
if "redirect_viewname" not in self.session:
if kwargs.get('redirect') == 'home':
context["profile_back_button_text"] = "Go to manage your domains"
context["show_back_button"] = True
else:
context["going_to_specific_page"] = True
context["redirect_button_text"] = "Continue to your request"
return context
# def get_context_data(self, **kwargs):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
"""
Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag.
# context = super().get_context_data(**kwargs)
This method sets the redirect type based on the 'redirect' query parameter,
defaulting to BACK_TO_SELF if not provided.
It updates the session with the redirect view name if the redirect type is TO_SPECIFIC_PAGE.
# # Hide the back button by default
# context["show_back_button"] = False
Returns:
HttpResponse: The response generated by the parent class's dispatch method.
"""
# logger.info(f"self.redirect_type = {self.redirect_type}")
# if self.redirect_type == self.RedirectType.COMPLETE_SETUP:
# context["confirm_changes"] = True
# Update redirect type based on the query parameter if present
default_redirect_value = self.RedirectType.BACK_TO_SELF.value
redirect_value = request.GET.get("redirect", default_redirect_value)
# if "redirect_viewname" not in self.session:
# context["show_back_button"] = True
# else:
# context["going_to_specific_page"] = True
# context["redirect_button_text"] = "Continue to your request"
if redirect_value in self.all_redirect_types:
# If the redirect value is a preexisting value in our enum, set it to that.
self.redirect_type = self.RedirectType(redirect_value)
else:
# If the redirect type is undefined, then we assume that we are specifying a particular page to redirect to.
self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE
# return context
# Store the page that we want to redirect to for later use
request.session["redirect_viewname"] = str(redirect_value)
# @method_decorator(csrf_protect)
# def dispatch(self, request, *args, **kwargs):
# """
# Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag.
return super().dispatch(request, *args, **kwargs)
# This method sets the redirect type based on the 'redirect' query parameter,
# defaulting to BACK_TO_SELF if not provided.
# It updates the session with the redirect view name if the redirect type is TO_SPECIFIC_PAGE.
# Returns:
# HttpResponse: The response generated by the parent class's dispatch method.
# """
# # Update redirect type based on the query parameter if present
# default_redirect_value = self.RedirectType.BACK_TO_SELF.value
# redirect_value = request.GET.get("redirect", default_redirect_value)
# if redirect_value in self.all_redirect_types:
# # If the redirect value is a preexisting value in our enum, set it to that.
# self.redirect_type = self.RedirectType(redirect_value)
# else:
# # If the redirect type is undefined, then we assume that we are specifying a particular page to redirect to.
# self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE
# # Store the page that we want to redirect to for later use
# request.session["redirect_viewname"] = str(redirect_value)
# return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
"""Form submission posts to this view."""
@ -217,17 +258,23 @@ class FinishProfileSetupView(UserProfileView):
if form.is_valid():
if "contact_setup_save_button" in request.POST:
# Logic for when the 'Save' button is clicked
self.redirect_type = self.RedirectType.COMPLETE_SETUP
self.redirect_page = False
#self.redirect_type = self.RedirectType.COMPLETE_SETUP
elif "contact_setup_submit_button" in request.POST:
specific_redirect = "redirect_viewname" in self.session
self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE if specific_redirect else self.RedirectType.HOME
self.redirect_page = True
# specific_redirect = "redirect_viewname" in self.session
# self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE if specific_redirect else self.RedirectType.HOME
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
"""Redirect to the nameservers page for the domain."""
return self.get_redirect_url()
# Get the redirect parameter from the form submission
redirect_param = self.request.POST.get('redirect', None)
if self.redirect_page and redirect_param:
return reverse(redirect_param)
return super().get_success_url()
def get_redirect_url(self):
"""