Coverage for benefits / core / admin / users.py: 100%
50 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-13 19:35 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-13 19:35 +0000
1import logging
3import requests
4from django.conf import settings
5from django.contrib import admin
6from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin, UserAdmin as BaseUserAdmin
7from django.contrib.auth.models import Group, User
9from benefits.core.admin.mixins import StaffPermissionMixin
11logger = logging.getLogger(__name__)
14GOOGLE_USER_INFO_URL = "https://www.googleapis.com/oauth2/v3/userinfo"
17# We unregister and re-register both User and Group admins to hide
18# the database-level "permissions" fields, making our ModelAdmin
19# mixins the single source of truth.
20#
21# For GroupAdmin, we can just use `exclude` because its default form
22# is simple and doesn't use `fieldsets`.
23#
24# For UserAdmin, we must override `get_fieldsets()` because:
25# 1. The default UserAdmin uses `fieldsets`.
26# 2. `fieldsets` takes precedence over `exclude`.
27admin.site.unregister(Group)
28admin.site.unregister(User)
31@admin.register(Group)
32class GroupAdmin(StaffPermissionMixin, BaseGroupAdmin):
33 # This will remove the "Permissions" multi-select box
34 # from the Group change page.
35 exclude = ("permissions",)
38@admin.register(User)
39class UserAdmin(StaffPermissionMixin, BaseUserAdmin):
40 def get_fieldsets(self, request, obj=None):
41 # get the default fieldsets
42 # ensures we get any new fields from future Django versions
43 fieldsets = super().get_fieldsets(request, obj)
44 # Build a set of fields to remove from the "Permissions" section
45 fields_to_remove = set()
46 fields_to_remove.add("user_permissions")
47 if not request.user.is_superuser:
48 fields_to_remove.add("is_superuser")
49 # create a new list of fieldsets to return
50 new_fieldsets = []
51 for name, options in fieldsets:
52 # find the 'Permissions' fieldset
53 if name == "Permissions":
54 # copy the fields, but filter out 'user_permissions'
55 new_fields = tuple(f for f in options.get("fields", ()) if f not in fields_to_remove)
56 options["fields"] = new_fields
57 # append the (potentially modified) options for this fieldset
58 new_fieldsets.append((name, options))
60 return new_fieldsets
63def add_google_sso_userinfo(user, request):
64 token = request.session.get("google_sso_access_token")
65 if token:
66 headers = {
67 "Authorization": f"Bearer {token}",
68 }
70 # Request Google user info to get name and email
71 response = requests.get(GOOGLE_USER_INFO_URL, headers=headers, timeout=settings.REQUESTS_TIMEOUT)
72 user_data = response.json()
73 logger.debug(f"Updating user data from Google for user with email: {user_data['email']}")
75 user.first_name = user_data["given_name"]
76 user.last_name = user_data["family_name"]
77 user.username = user_data["email"]
78 user.email = user_data["email"]
79 user.save()
80 else:
81 logger.warning("google_sso_access_token not found in session.")
84def add_staff_user_to_group(user, request):
85 if user.email in settings.GOOGLE_SSO_STAFF_LIST:
86 staff_group = Group.objects.get(name=settings.STAFF_GROUP_NAME)
87 staff_group.user_set.add(user)
90def pre_login_user(user, request):
91 logger.debug(f"Running pre-login callback for user: {user.username}")
92 add_google_sso_userinfo(user, request)
93 add_staff_user_to_group(user, request)