diff --git a/src/djangooidc/views.py b/src/djangooidc/views.py index c4d4cec81..815df4ecf 100644 --- a/src/djangooidc/views.py +++ b/src/djangooidc/views.py @@ -9,8 +9,6 @@ from django.http import HttpResponseRedirect from django.shortcuts import redirect from urllib.parse import parse_qs, urlencode -from waffle import flag_is_active - from djangooidc.oidc import Client from djangooidc import exceptions as o_e from registrar.models import User @@ -113,13 +111,6 @@ def login_callback(request): if not user.verification_type or is_fixture_user: user.set_user_verification_type() user.save() - - if not flag_is_active(request, "multiple_portfolios"): - user.set_default_last_selected_portfolio() - user.save() - else: - user.last_selected_portfolio = None - user.save() login(request, user) logger.info("Successfully logged in user %s" % user) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index fd555520d..a41035f71 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -717,17 +717,12 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin): "is_superuser", "groups", "user_permissions", - "last_selected_portfolio", ) }, ), ("Important dates", {"fields": ("last_login", "date_joined")}), ) - autocomplete_fields = [ - "last_selected_portfolio", - ] - readonly_fields = ("verification_type",) analyst_fieldsets = ( @@ -747,7 +742,6 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin): "fields": ( "is_active", "groups", - "last_selected_portfolio", ) }, ), @@ -802,7 +796,6 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin): "Important dates", "last_login", "date_joined", - "last_selected_portfolio", ] # TODO: delete after we merge organization feature diff --git a/src/registrar/context_processors.py b/src/registrar/context_processors.py index ca7c92892..7d28260ed 100644 --- a/src/registrar/context_processors.py +++ b/src/registrar/context_processors.py @@ -61,27 +61,34 @@ def add_has_profile_feature_flag_to_context(request): def portfolio_permissions(request): """Make portfolio permissions for the request user available in global context""" try: - if not request.user or not request.user.is_authenticated or not flag_is_active(request, "organization_feature"): + if request.session["portfolio"] is not None: return { - "has_base_portfolio_permission": False, - "has_domains_portfolio_permission": False, - "has_domain_requests_portfolio_permission": False, - "portfolio": None, - "has_organization_feature_flag": False, + "has_base_portfolio_permission": request.user.has_base_portfolio_permission(request.session["portfolio"]), + "has_domains_portfolio_permission": request.user.has_domains_portfolio_permission(request.session["portfolio"]), + "has_domain_requests_portfolio_permission": request.user.has_domain_requests_portfolio_permission(request.session["portfolio"]), + "has_view_suborganization": request.user.has_view_suborganization(request.session["portfolio"]), + "has_edit_suborganization": request.user.has_edit_suborganization(request.session["portfolio"]), + "portfolio": request.session["portfolio"], + "has_organization_feature_flag": True, } return { - "has_base_portfolio_permission": request.user.has_base_portfolio_permission(), - "has_domains_portfolio_permission": request.user.has_domains_portfolio_permission(), - "has_domain_requests_portfolio_permission": request.user.has_domain_requests_portfolio_permission(), - "portfolio": request.user.last_selected_portfolio, - "has_organization_feature_flag": True, + "has_base_portfolio_permission": False, + "has_domains_portfolio_permission": False, + "has_domain_requests_portfolio_permission": False, + "has_view_suborganization": False, + "has_edit_suborganization": False, + "portfolio": None, + "has_organization_feature_flag": False, } + except AttributeError: # Handles cases where request.user might not exist return { "has_base_portfolio_permission": False, "has_domains_portfolio_permission": False, "has_domain_requests_portfolio_permission": False, + "has_view_suborganization": False, + "has_edit_suborganization": False, "portfolio": None, "has_organization_feature_flag": False, } diff --git a/src/registrar/migrations/0119_remove_user_portfolio_and_more.py b/src/registrar/migrations/0119_remove_user_portfolio_and_more.py index 7c9d2defc..84ed45cd1 100644 --- a/src/registrar/migrations/0119_remove_user_portfolio_and_more.py +++ b/src/registrar/migrations/0119_remove_user_portfolio_and_more.py @@ -25,17 +25,6 @@ class Migration(migrations.Migration): model_name="user", name="portfolio_roles", ), - migrations.AddField( - model_name="user", - name="last_selected_portfolio", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="portfolio_selected_by_users", - to="registrar.portfolio", - ), - ), migrations.CreateModel( name="UserPortfolioPermission", fields=[ diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 34f2f8bcf..b151f3800 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -110,14 +110,6 @@ class User(AbstractUser): related_name="users", ) - last_selected_portfolio = models.ForeignKey( - "registrar.Portfolio", - null=True, - blank=True, - related_name="portfolio_selected_by_users", - on_delete=models.SET_NULL, - ) - phone = PhoneNumberField( null=True, blank=True, @@ -208,50 +200,48 @@ class User(AbstractUser): def has_contact_info(self): return bool(self.title or self.email or self.phone) - def _has_portfolio_permission(self, portfolio_permission): + def _has_portfolio_permission(self, portfolio, portfolio_permission): """The views should only call this function when testing for perms and not rely on roles.""" - if not self.last_selected_portfolio: - return False - - portfolio_perms = self.portfolio_permissions.filter(portfolio=self.last_selected_portfolio, user=self).first() + portfolio_perms = self.portfolio_permissions.filter(portfolio=portfolio, user=self).first() if not portfolio_perms: return False portfolio_permissions = portfolio_perms._get_portfolio_permissions() return portfolio_permission in portfolio_permissions - def has_base_portfolio_permission(self): - return self._has_portfolio_permission(UserPortfolioPermissionChoices.VIEW_PORTFOLIO) + def has_base_portfolio_permission(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_PORTFOLIO) - def has_edit_org_portfolio_permission(self): - return self._has_portfolio_permission(UserPortfolioPermissionChoices.EDIT_PORTFOLIO) + def has_edit_org_portfolio_permission(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.EDIT_PORTFOLIO) - def has_domains_portfolio_permission(self): - return self._has_portfolio_permission( + def has_domains_portfolio_permission(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS - ) or self._has_portfolio_permission(UserPortfolioPermissionChoices.VIEW_MANAGED_DOMAINS) + ) or self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_MANAGED_DOMAINS) - def has_domain_requests_portfolio_permission(self): - return self._has_portfolio_permission( + def has_domain_requests_portfolio_permission(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS - ) or self._has_portfolio_permission(UserPortfolioPermissionChoices.VIEW_CREATED_REQUESTS) + ) or self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_CREATED_REQUESTS) - def has_view_all_domains_permission(self): + def has_view_all_domains_permission(self, portfolio): """Determines if the current user can view all available domains in a given portfolio""" - return self._has_portfolio_permission(UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS) + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS) # Field specific permission checks - def has_view_suborganization(self): - return self._has_portfolio_permission(UserPortfolioPermissionChoices.VIEW_SUBORGANIZATION) + def has_view_suborganization(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.VIEW_SUBORGANIZATION) - def has_edit_suborganization(self): - return self._has_portfolio_permission(UserPortfolioPermissionChoices.EDIT_SUBORGANIZATION) + def has_edit_suborganization(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.EDIT_SUBORGANIZATION) - def set_default_last_selected_portfolio(self): + def get_first_portfolio(self): permission = self.portfolio_permissions.first() if permission: - self.last_selected_portfolio = permission.portfolio + return permission.portfolio + return None @classmethod def needs_identity_verification(cls, email, uuid): @@ -367,7 +357,7 @@ class User(AbstractUser): email__iexact=self.email, status=PortfolioInvitation.PortfolioInvitationStatus.INVITED ): only_single_portfolio = ( - not flag_is_active(None, "multiple_portfolios") and self.last_selected_portfolio is None + not flag_is_active(None, "multiple_portfolios") and self.get_first_portfolio() is None ) if only_single_portfolio or flag_is_active(None, "multiple_portfolios"): try: @@ -396,12 +386,12 @@ class User(AbstractUser): def is_org_user(self, request): has_organization_feature_flag = flag_is_active(request, "organization_feature") - return has_organization_feature_flag and self.has_base_portfolio_permission() + return has_organization_feature_flag and self.has_base_portfolio_permission(request.session["portfolio"]) def get_user_domain_ids(self, request): """Returns either the domains ids associated with this user on UserDomainRole or Portfolio""" - if self.is_org_user(request) and self.has_view_all_domains_permission(): - return DomainInformation.objects.filter(portfolio=self.last_selected_portfolio).values_list( + if self.is_org_user(request) and self.has_view_all_domains_permission(request.session["portfolio"]): + return DomainInformation.objects.filter(portfolio=request.session["portfolio"]).values_list( "domain_id", flat=True ) else: diff --git a/src/registrar/registrar_middleware.py b/src/registrar/registrar_middleware.py index 6e7d110fb..1da74a527 100644 --- a/src/registrar/registrar_middleware.py +++ b/src/registrar/registrar_middleware.py @@ -125,8 +125,9 @@ class CheckUserProfileMiddleware: class CheckPortfolioMiddleware: """ - Checks if the current user has a portfolio - If they do, redirect them to the portfolio homepage when they navigate to home. + this middleware should serve two purposes: + 1 - set the portfolio in session if appropriate # views will need the session portfolio + 2 - if path is home and session portfolio is set, redirect based on permissions of user """ def __init__(self, get_response): @@ -140,20 +141,28 @@ class CheckPortfolioMiddleware: def process_view(self, request, view_func, view_args, view_kwargs): current_path = request.path - if current_path == self.home and request.user.is_authenticated and request.user.is_org_user(request): + if not request.user.is_authenticated: + return None + + # set the portfolio in the session if it is not set + if not "portfolio" in request.session or request.session["portfolio"] is None: + # if user is a multiple portfolio + if flag_is_active(request, "multiple_portfolios"): + # NOTE: we will want to change later to have a workflow for selecting + # portfolio and another for switching portfolio; for now, select first + request.session["portfolio"] = request.user.get_first_portfolio() + elif flag_is_active(request, "organization_feature"): + request.session["portfolio"] = request.user.get_first_portfolio() + else: + request.session["portfolio"] = None - if request.user.has_base_portfolio_permission(): - portfolio = request.user.last_selected_portfolio - - # Add the portfolio to the request object - request.last_selected_portfolio = portfolio - - if request.user.has_domains_portfolio_permission(): + if request.session["portfolio"] is not None and current_path == self.home: + if request.user.has_base_portfolio_permission(request.session["portfolio"]): + if request.user.has_domains_portfolio_permission(request.session["portfolio"]): portfolio_redirect = reverse("domains") else: # View organization is the lowest access portfolio_redirect = reverse("organization") - return HttpResponseRedirect(portfolio_redirect) return None diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index 19f196e40..cf55f7070 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -72,7 +72,7 @@ {% include "includes/summary_item.html" with title='DNSSEC' value='Not Enabled' edit_link=url editable=is_editable %} {% endif %} - {% if portfolio and has_domains_portfolio_permission and request.user.has_view_suborganization %} + {% if portfolio and has_domains_portfolio_permission and has_view_suborganization %} {% url 'domain-suborganization' pk=domain.id as url %} {% include "includes/summary_item.html" with title='Suborganization' value=domain.domain_info.sub_organization edit_link=url editable=is_editable|and:request.user.has_edit_suborganization %} {% else %} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index f2e9f190c..24f92bf16 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -61,7 +61,7 @@ {% if portfolio %} {% comment %} Only show this menu option if the user has the perms to do so {% endcomment %} - {% if has_domains_portfolio_permission and request.user.has_view_suborganization %} + {% if has_domains_portfolio_permission and has_view_suborganization %} {% with url_name="domain-suborganization" %} {% include "includes/domain_sidenav_item.html" with item_text="Suborganization" %} {% endwith %} diff --git a/src/registrar/templates/includes/domains_table.html b/src/registrar/templates/includes/domains_table.html index 73331c3f0..f790da4d5 100644 --- a/src/registrar/templates/includes/domains_table.html +++ b/src/registrar/templates/includes/domains_table.html @@ -157,7 +157,7 @@ Domain name Expires Status - {% if has_domains_portfolio_permission and request.user.has_view_suborganization %} + {% if has_domains_portfolio_permission and has_view_suborganization %} Suborganization {% endif %}