mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-13 21:19:42 +02:00
Cleanup
Pushing old commit content to save work already done
This commit is contained in:
parent
04ced13eb6
commit
bb42732c80
9 changed files with 211 additions and 235 deletions
|
@ -104,8 +104,8 @@ urlpatterns = [
|
||||||
# We embed the current user ID here, but we have a permission check
|
# We embed the current user ID here, but we have a permission check
|
||||||
# that ensures the user is who they say they are.
|
# that ensures the user is who they say they are.
|
||||||
"finish-user-setup/<int:pk>",
|
"finish-user-setup/<int:pk>",
|
||||||
views.ContactProfileSetupView.as_view(),
|
views.FinishUserSetupView.as_view(),
|
||||||
name="finish-contact-profile-setup",
|
name="finish-user-profile-setup",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"domain-request/<id>/edit/",
|
"domain-request/<id>/edit/",
|
||||||
|
|
|
@ -203,7 +203,6 @@ NameserverFormset = formset_factory(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO - refactor, wait until daves PR
|
|
||||||
class ContactForm(forms.ModelForm):
|
class ContactForm(forms.ModelForm):
|
||||||
"""Form for updating contacts."""
|
"""Form for updating contacts."""
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ from django import forms
|
||||||
from phonenumber_field.formfields import PhoneNumberField # type: ignore
|
from phonenumber_field.formfields import PhoneNumberField # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class ContactForm(forms.Form):
|
class FinishUserSetupForm(forms.Form):
|
||||||
"""Form for adding or editing a contact"""
|
"""Form for adding or editing user information"""
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
|
@ -22,7 +22,6 @@ class RegistrarForm(forms.Form):
|
||||||
kwargs.setdefault("label_suffix", "")
|
kwargs.setdefault("label_suffix", "")
|
||||||
# save a reference to a domain request object
|
# save a reference to a domain request object
|
||||||
self.domain_request = kwargs.pop("domain_request", None)
|
self.domain_request = kwargs.pop("domain_request", None)
|
||||||
|
|
||||||
super(RegistrarForm, self).__init__(*args, **kwargs)
|
super(RegistrarForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_database(self, obj: DomainRequest | Contact):
|
def to_database(self, obj: DomainRequest | Contact):
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
from urllib.parse import urlparse, urlunparse, urlencode
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -286,3 +287,27 @@ def from_database(form_class, obj):
|
||||||
if obj is None:
|
if obj is None:
|
||||||
return {}
|
return {}
|
||||||
return {name: getattr(obj, name) for name in form_class.declared_fields.keys()} # type: ignore
|
return {name: getattr(obj, name) for name in form_class.declared_fields.keys()} # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
def replace_url_queryparams(url_to_modify: str, query_params: dict[Any, list]):
|
||||||
|
"""
|
||||||
|
Replaces the query parameters of a given URL.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url_to_modify (str): The URL whose query parameters need to be modified.
|
||||||
|
query_params (dict): Dictionary of query parameters to use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The modified URL with the updated query parameters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Split the URL into parts
|
||||||
|
url_parts = list(urlparse(url_to_modify))
|
||||||
|
|
||||||
|
# Modify the query param bit
|
||||||
|
url_parts[4] = urlencode(query_params)
|
||||||
|
|
||||||
|
# Reassemble the URL
|
||||||
|
new_url = urlunparse(url_parts)
|
||||||
|
|
||||||
|
return new_url
|
|
@ -7,6 +7,8 @@ from django.urls import reverse
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from waffle.decorators import flag_is_active
|
from waffle.decorators import flag_is_active
|
||||||
|
|
||||||
|
from registrar.models.utility.generic_helper import replace_url_queryparams
|
||||||
|
|
||||||
|
|
||||||
class CheckUserProfileMiddleware:
|
class CheckUserProfileMiddleware:
|
||||||
"""
|
"""
|
||||||
|
@ -28,26 +30,29 @@ class CheckUserProfileMiddleware:
|
||||||
# Check that the user is "opted-in" to the profile feature flag
|
# Check that the user is "opted-in" to the profile feature flag
|
||||||
has_profile_feature_flag = flag_is_active(request, "profile_feature")
|
has_profile_feature_flag = flag_is_active(request, "profile_feature")
|
||||||
|
|
||||||
# If they aren't, skip this entirely
|
# If they aren't, skip this check entirely
|
||||||
if not has_profile_feature_flag:
|
if not has_profile_feature_flag:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Check if setup is not finished
|
# Check if setup is not finished
|
||||||
finished_setup = hasattr(request.user, "finished_setup") and request.user.finished_setup
|
finished_setup = hasattr(request.user, "finished_setup") and request.user.finished_setup
|
||||||
if request.user.is_authenticated and not finished_setup:
|
if request.user.is_authenticated and not finished_setup:
|
||||||
setup_page = reverse("finish-contact-profile-setup", kwargs={"pk": request.user.contact.pk})
|
return self._handle_setup_not_finished(request)
|
||||||
|
|
||||||
|
# Continue processing the view
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _handle_setup_not_finished(self, request):
|
||||||
|
setup_page = reverse("finish-user-profile-setup", kwargs={"pk": request.user.contact.pk})
|
||||||
logout_page = reverse("logout")
|
logout_page = reverse("logout")
|
||||||
excluded_pages = [
|
excluded_pages = [
|
||||||
setup_page,
|
setup_page,
|
||||||
logout_page,
|
logout_page,
|
||||||
]
|
]
|
||||||
custom_redirect = None
|
|
||||||
|
|
||||||
# In some cases, we don't want to redirect to home.
|
# In some cases, we don't want to redirect to home. This handles that.
|
||||||
# This handles that.
|
# Can easily be generalized if need be, but for now lets keep this easy to read.
|
||||||
if request.path == "/request/":
|
custom_redirect = "domain-request:" if request.path == "/request/" else None
|
||||||
# This can be generalized if need be, but for now lets keep this easy to read.
|
|
||||||
custom_redirect = "domain-request:"
|
|
||||||
|
|
||||||
# Don't redirect on excluded pages (such as the setup page itself)
|
# Don't redirect on excluded pages (such as the setup page itself)
|
||||||
if not any(request.path.startswith(page) for page in excluded_pages):
|
if not any(request.path.startswith(page) for page in excluded_pages):
|
||||||
|
@ -59,17 +64,12 @@ class CheckUserProfileMiddleware:
|
||||||
query_params["redirect"] = custom_redirect
|
query_params["redirect"] = custom_redirect
|
||||||
|
|
||||||
if query_params:
|
if query_params:
|
||||||
# Split the URL into parts
|
setup_page = replace_url_queryparams(setup_page, query_params)
|
||||||
setup_page_parts = list(urlparse(setup_page))
|
|
||||||
# Modify the query param bit
|
|
||||||
setup_page_parts[4] = urlencode(query_params)
|
|
||||||
# Reassemble the URL
|
|
||||||
setup_page = urlunparse(setup_page_parts)
|
|
||||||
|
|
||||||
# Redirect to the setup page
|
# Redirect to the setup page
|
||||||
return HttpResponseRedirect(setup_page)
|
return HttpResponseRedirect(setup_page)
|
||||||
|
else:
|
||||||
# Continue processing the view
|
# Process the view as normal
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ from .domain import (
|
||||||
DomainInvitationDeleteView,
|
DomainInvitationDeleteView,
|
||||||
DomainDeleteUserView,
|
DomainDeleteUserView,
|
||||||
)
|
)
|
||||||
from .contact import (
|
from .finish_user_setup import (
|
||||||
ContactProfileSetupView,
|
FinishUserSetupView,
|
||||||
)
|
)
|
||||||
from .health import *
|
from .health import *
|
||||||
from .index import *
|
from .index import *
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
from enum import Enum
|
||||||
from waffle.decorators import waffle_flag
|
from waffle.decorators import waffle_flag
|
||||||
from urllib.parse import urlencode, urlunparse, urlparse, quote
|
from urllib.parse import quote
|
||||||
from django.urls import NoReverseMatch, reverse
|
from django.urls import NoReverseMatch, reverse
|
||||||
from registrar.forms.contact import ContactForm
|
from registrar.forms.finish_user_setup import FinishUserSetupForm
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from registrar.models.contact import Contact
|
from registrar.models.contact import Contact
|
||||||
from registrar.templatetags.url_helpers import public_site_url
|
from registrar.templatetags.url_helpers import public_site_url
|
||||||
from registrar.views.utility.permission_views import ContactPermissionView
|
from registrar.views.utility.permission_views import ContactPermissionView
|
||||||
from django.views.generic.edit import FormMixin
|
from django.views.generic.edit import FormMixin
|
||||||
from registrar.models.utility.generic_helper import to_database, from_database
|
from registrar.models.utility.generic_helper import replace_url_queryparams, to_database, from_database
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
|
@ -19,27 +20,17 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BaseContactView(SuccessMessageMixin, ContactPermissionView):
|
class BaseContactView(SuccessMessageMixin, ContactPermissionView):
|
||||||
"""Provides a base view for the contact object. On get, the contact
|
|
||||||
is saved in the session and on self.object."""
|
|
||||||
|
|
||||||
def get_success_message(self, cleaned_data):
|
def get_success_message(self, cleaned_data):
|
||||||
"""Content of the returned success message"""
|
"""Content of the returned success message"""
|
||||||
return "Contact updated successfully."
|
return "Contact updated successfully."
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
"""Sets the current contact in cache, defines the current object as self.object
|
self._update_object_and_session(request)
|
||||||
then returns render_to_response"""
|
|
||||||
self._set_contact(request)
|
|
||||||
context = self.get_context_data(object=self.object)
|
context = self.get_context_data(object=self.object)
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
def _set_contact(self, request):
|
def _update_object_and_session(self, request):
|
||||||
"""
|
|
||||||
get contact from session cache or from db and set
|
|
||||||
to self.object
|
|
||||||
set session to self for downstream functions to
|
|
||||||
update session cache
|
|
||||||
"""
|
|
||||||
self.session = request.session
|
self.session = request.session
|
||||||
|
|
||||||
contact_pk = "contact:" + str(self.kwargs.get("pk"))
|
contact_pk = "contact:" + str(self.kwargs.get("pk"))
|
||||||
|
@ -50,9 +41,9 @@ class BaseContactView(SuccessMessageMixin, ContactPermissionView):
|
||||||
else:
|
else:
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
|
|
||||||
self._update_session_with_contact()
|
self._refresh_session()
|
||||||
|
|
||||||
def _update_session_with_contact(self):
|
def _refresh_session(self):
|
||||||
"""
|
"""
|
||||||
Set contact pk in the session cache
|
Set contact pk in the session cache
|
||||||
"""
|
"""
|
||||||
|
@ -63,46 +54,30 @@ class BaseContactView(SuccessMessageMixin, ContactPermissionView):
|
||||||
class ContactFormBaseView(BaseContactView, FormMixin):
|
class ContactFormBaseView(BaseContactView, FormMixin):
|
||||||
"""Adds a FormMixin to BaseContactView, and handles post"""
|
"""Adds a FormMixin to BaseContactView, and handles post"""
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
"""Form submission posts to this view.
|
|
||||||
|
|
||||||
This post method harmonizes using BaseContactView and FormMixin
|
|
||||||
"""
|
|
||||||
# Set the current contact object in cache
|
|
||||||
self._set_contact(request)
|
|
||||||
|
|
||||||
form = self.get_form()
|
|
||||||
|
|
||||||
# Get the current form and validate it
|
|
||||||
return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
|
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
# updates session cache with contact
|
# updates session cache with contact
|
||||||
self._update_session_with_contact()
|
self._refresh_session()
|
||||||
|
|
||||||
# superclass has the redirect
|
# superclass has the redirect
|
||||||
return super().form_invalid(form)
|
return super().form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
class ContactProfileSetupView(ContactFormBaseView):
|
class FinishUserSetupView(ContactFormBaseView):
|
||||||
"""This view forces the user into providing additional details that
|
"""This view forces the user into providing additional details that
|
||||||
we may have missed from Login.gov"""
|
we may have missed from Login.gov"""
|
||||||
|
|
||||||
template_name = "finish_contact_setup.html"
|
template_name = "finish_contact_setup.html"
|
||||||
form_class = ContactForm
|
form_class = FinishUserSetupForm
|
||||||
model = Contact
|
model = Contact
|
||||||
|
|
||||||
redirect_type = None
|
redirect_type = None
|
||||||
|
|
||||||
# TODO - make this an enum
|
class RedirectType(Enum):
|
||||||
class RedirectType:
|
|
||||||
"""
|
"""
|
||||||
Contains constants for each type of redirection.
|
Enums for each type of redirection. Enforces behaviour on `get_redirect_url()`.
|
||||||
Not an enum as we just need to track string values,
|
|
||||||
but we don't care about enforcing it.
|
|
||||||
|
|
||||||
- HOME: We want to redirect to reverse("home")
|
- HOME: We want to redirect to reverse("home")
|
||||||
- BACK_TO_SELF: We want to redirect back to reverse("finish-contact-profile-setup")
|
- BACK_TO_SELF: We want to redirect back to reverse("finish-user-profile-setup")
|
||||||
- TO_SPECIFIC_PAGE: We want to redirect to the page specified in the queryparam "redirect"
|
- 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
|
- 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
|
redirect after the next POST should be either HOME or TO_SPECIFIC_PAGE
|
||||||
|
@ -113,146 +88,6 @@ class ContactProfileSetupView(ContactFormBaseView):
|
||||||
COMPLETE_SETUP = "complete_setup"
|
COMPLETE_SETUP = "complete_setup"
|
||||||
TO_SPECIFIC_PAGE = "domain_request"
|
TO_SPECIFIC_PAGE = "domain_request"
|
||||||
|
|
||||||
def get_success_message(self, cleaned_data):
|
|
||||||
"""Content of the returned success message"""
|
|
||||||
return "Your profile has been successfully updated."
|
|
||||||
|
|
||||||
# TODO - refactor
|
|
||||||
@waffle_flag("profile_feature")
|
|
||||||
@method_decorator(csrf_protect)
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag.
|
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
# Default redirect type
|
|
||||||
default_redirect = self.RedirectType.BACK_TO_SELF
|
|
||||||
|
|
||||||
# Update redirect type based on the query parameter if present
|
|
||||||
redirect_type = request.GET.get("redirect", None)
|
|
||||||
|
|
||||||
is_default = False
|
|
||||||
# We set this here rather than in .get so we don't override
|
|
||||||
# existing data if no queryparam is present.
|
|
||||||
if redirect_type is None:
|
|
||||||
is_default = True
|
|
||||||
redirect_type = default_redirect
|
|
||||||
|
|
||||||
# Set the default if nothing exists already
|
|
||||||
if self.redirect_type is None:
|
|
||||||
self.redirect_type = redirect_type
|
|
||||||
|
|
||||||
if not is_default:
|
|
||||||
default_redirects = [
|
|
||||||
self.RedirectType.HOME,
|
|
||||||
self.RedirectType.COMPLETE_SETUP,
|
|
||||||
self.RedirectType.BACK_TO_SELF,
|
|
||||||
self.RedirectType.TO_SPECIFIC_PAGE,
|
|
||||||
]
|
|
||||||
if redirect_type not in default_redirects:
|
|
||||||
self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE
|
|
||||||
request.session["profile_setup_redirect_viewname"] = redirect_type
|
|
||||||
else:
|
|
||||||
self.redirect_type = redirect_type
|
|
||||||
|
|
||||||
return super().dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_redirect_url(self):
|
|
||||||
"""
|
|
||||||
Returns a URL string based on the current value of self.redirect_type.
|
|
||||||
|
|
||||||
Depending on self.redirect_type, constructs a base URL and appends a
|
|
||||||
'redirect' query parameter. Handles different redirection types such as
|
|
||||||
HOME, BACK_TO_SELF, COMPLETE_SETUP, and TO_SPECIFIC_PAGE.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The full URL with the appropriate query parameters.
|
|
||||||
"""
|
|
||||||
base_url = ""
|
|
||||||
query_params = {}
|
|
||||||
match self.redirect_type:
|
|
||||||
case self.RedirectType.HOME:
|
|
||||||
base_url = reverse("home")
|
|
||||||
case self.RedirectType.BACK_TO_SELF | self.RedirectType.COMPLETE_SETUP:
|
|
||||||
base_url = reverse("finish-contact-profile-setup", kwargs={"pk": self.object.pk})
|
|
||||||
case self.RedirectType.TO_SPECIFIC_PAGE:
|
|
||||||
|
|
||||||
# We only allow this session value to use viewnames,
|
|
||||||
# because otherwise this allows anyone to enter any value in here.
|
|
||||||
# This restricts what can be redirected to.
|
|
||||||
try:
|
|
||||||
desired_view = self.session["profile_setup_redirect_viewname"]
|
|
||||||
base_url = reverse(desired_view)
|
|
||||||
except NoReverseMatch as err:
|
|
||||||
logger.error(err)
|
|
||||||
logger.error("ContactProfileSetupView -> get_redirect_url -> Could not find specified page.")
|
|
||||||
base_url = reverse("home")
|
|
||||||
case _:
|
|
||||||
base_url = reverse("home")
|
|
||||||
|
|
||||||
# Quote cleans up the value so that it can be used in a url
|
|
||||||
query_params["redirect"] = quote(self.redirect_type)
|
|
||||||
|
|
||||||
# Parse the base URL
|
|
||||||
url_parts = list(urlparse(base_url))
|
|
||||||
|
|
||||||
# Update the query part of the URL
|
|
||||||
url_parts[4] = urlencode(query_params)
|
|
||||||
|
|
||||||
# Construct the full URL with query parameters
|
|
||||||
full_url = urlunparse(url_parts)
|
|
||||||
return full_url
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
"""Redirect to the nameservers page for the domain."""
|
|
||||||
redirect_url = self.get_redirect_url()
|
|
||||||
return redirect_url
|
|
||||||
|
|
||||||
# TODO - delete session information
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
"""Form submission posts to this view.
|
|
||||||
|
|
||||||
This post method harmonizes using BaseContactView and FormMixin
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Set the current contact object in cache
|
|
||||||
self._set_contact(request)
|
|
||||||
|
|
||||||
form = self.get_form()
|
|
||||||
|
|
||||||
# Get the current form and validate it
|
|
||||||
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
|
|
||||||
elif "contact_setup_submit_button" in request.POST:
|
|
||||||
if "profile_setup_redirect_viewname" in self.session:
|
|
||||||
self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE
|
|
||||||
else:
|
|
||||||
self.redirect_type = self.RedirectType.HOME
|
|
||||||
|
|
||||||
return self.form_valid(form)
|
|
||||||
else:
|
|
||||||
return self.form_invalid(form)
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
|
|
||||||
completed_states = [self.RedirectType.TO_SPECIFIC_PAGE, self.RedirectType.HOME]
|
|
||||||
if self.redirect_type in completed_states:
|
|
||||||
self.request.user.finished_setup = True
|
|
||||||
self.request.user.save()
|
|
||||||
|
|
||||||
to_database(form=form, obj=self.object)
|
|
||||||
self._update_session_with_contact()
|
|
||||||
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
"""The initial value for the form (which is a formset here)."""
|
"""The initial value for the form (which is a formset here)."""
|
||||||
db_object = from_database(form_class=self.form_class, obj=self.object)
|
db_object = from_database(form_class=self.form_class, obj=self.object)
|
||||||
|
@ -276,3 +111,133 @@ class ContactProfileSetupView(ContactFormBaseView):
|
||||||
"If the wrong email is displayed below, you’ll need to update your Login.gov account "
|
"If the wrong email is displayed below, you’ll need to update your Login.gov account "
|
||||||
f'and log back in. <a class="usa-link" href={help_url}>Get help with your Login.gov account.</a>'
|
f'and log back in. <a class="usa-link" href={help_url}>Get help with your Login.gov account.</a>'
|
||||||
) # nosec
|
) # nosec
|
||||||
|
|
||||||
|
|
||||||
|
def get_success_message(self, cleaned_data):
|
||||||
|
"""Content of the returned success message"""
|
||||||
|
return "Your profile has been successfully updated."
|
||||||
|
|
||||||
|
@waffle_flag("profile_feature")
|
||||||
|
@method_decorator(csrf_protect)
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag.
|
||||||
|
|
||||||
|
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
|
||||||
|
redirect_type = request.GET.get("redirect", None)
|
||||||
|
|
||||||
|
# We set this here rather than in .get so we don't override
|
||||||
|
# existing data if no queryparam is present.
|
||||||
|
is_default = redirect_type is None
|
||||||
|
if is_default:
|
||||||
|
# Set to the default
|
||||||
|
redirect_type = self.RedirectType.BACK_TO_SELF
|
||||||
|
self.redirect_type = redirect_type
|
||||||
|
else:
|
||||||
|
all_redirect_types = [r.value for r in self.RedirectType]
|
||||||
|
if redirect_type in all_redirect_types:
|
||||||
|
self.redirect_type = self.RedirectType(redirect_type)
|
||||||
|
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_type)
|
||||||
|
|
||||||
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
"""Form submission posts to this view.
|
||||||
|
|
||||||
|
This post method harmonizes using BaseContactView and FormMixin
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Set the current object in cache
|
||||||
|
self._update_object_and_session(request)
|
||||||
|
|
||||||
|
form = self.get_form()
|
||||||
|
|
||||||
|
# Get the current form and validate it
|
||||||
|
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
|
||||||
|
elif "contact_setup_submit_button" in request.POST:
|
||||||
|
if "redirect_viewname" in self.session:
|
||||||
|
self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE
|
||||||
|
else:
|
||||||
|
self.redirect_type = self.RedirectType.HOME
|
||||||
|
|
||||||
|
return self.form_valid(form)
|
||||||
|
else:
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
"""Saves the current contact to the database, and if the user is complete
|
||||||
|
with their setup, then we mark user.finished_setup to True."""
|
||||||
|
completed_states = [self.RedirectType.TO_SPECIFIC_PAGE, self.RedirectType.HOME]
|
||||||
|
if self.redirect_type in completed_states:
|
||||||
|
self.request.user.finished_setup = True
|
||||||
|
self.request.user.save()
|
||||||
|
|
||||||
|
to_database(form=form, obj=self.object)
|
||||||
|
self._refresh_session()
|
||||||
|
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
"""Redirect to the nameservers page for the domain."""
|
||||||
|
redirect_url = self.get_redirect_url()
|
||||||
|
return redirect_url
|
||||||
|
|
||||||
|
def get_redirect_url(self):
|
||||||
|
"""
|
||||||
|
Returns a URL string based on the current value of self.redirect_type.
|
||||||
|
|
||||||
|
Depending on self.redirect_type, constructs a base URL and appends a
|
||||||
|
'redirect' query parameter. Handles different redirection types such as
|
||||||
|
HOME, BACK_TO_SELF, COMPLETE_SETUP, and TO_SPECIFIC_PAGE.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The full URL with the appropriate query parameters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# These redirect types redirect to the same page
|
||||||
|
self_redirect = [
|
||||||
|
self.RedirectType.BACK_TO_SELF,
|
||||||
|
self.RedirectType.COMPLETE_SETUP
|
||||||
|
]
|
||||||
|
|
||||||
|
# Maps the redirect type to a URL
|
||||||
|
base_url = ""
|
||||||
|
try:
|
||||||
|
if self.redirect_type in self_redirect:
|
||||||
|
base_url = reverse("finish-user-profile-setup", kwargs={"pk": self.object.pk})
|
||||||
|
elif self.redirect_type == self.RedirectType.TO_SPECIFIC_PAGE:
|
||||||
|
# We only allow this session value to use viewnames,
|
||||||
|
# because this restricts what can be redirected to.
|
||||||
|
desired_view = self.session["redirect_viewname"]
|
||||||
|
base_url = reverse(desired_view)
|
||||||
|
else:
|
||||||
|
base_url = reverse("home")
|
||||||
|
except NoReverseMatch as err:
|
||||||
|
logger.error(f"get_redirect_url -> Could not find the specified page. Err: {err}")
|
||||||
|
|
||||||
|
query_params = {}
|
||||||
|
|
||||||
|
# Quote cleans up the value so that it can be used in a url
|
||||||
|
query_params["redirect"] = quote(self.redirect_type.value)
|
||||||
|
|
||||||
|
# Generate the full url from the given query params
|
||||||
|
full_url = replace_url_queryparams(base_url, query_params)
|
||||||
|
return full_url
|
||||||
|
|
|
@ -358,18 +358,6 @@ class ContactPermission(PermissionsLoginMixin):
|
||||||
if not requested_user_exists or not requested_contact_exists:
|
if not requested_user_exists or not requested_contact_exists:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Check if the user has an associated contact
|
|
||||||
associated_contacts = Contact.objects.filter(user=current_user)
|
|
||||||
associated_contacts_length = len(associated_contacts)
|
|
||||||
|
|
||||||
if associated_contacts_length == 0:
|
|
||||||
# This means that the user trying to access this page
|
|
||||||
# is a different user than the contact holder.
|
|
||||||
return False
|
|
||||||
elif associated_contacts_length > 1:
|
|
||||||
# TODO - change this
|
|
||||||
raise ValueError("User has multiple connected contacts")
|
|
||||||
else:
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue