Parent PRD
#195
What to build
Wire user_email through the authorization flow so that role matching checks both group membership AND direct email assignment. This is the core authorization change that makes assigned_users actually grant permissions.
Key decisions from the PRD
get_user_effective_permissions() gains optional user_email param
- Role matching loop: match if groups intersect OR email in
assigned_users (case-insensitive)
PermissionChecker.__call__() passes user_email=user_details.email
ApprovalChecker.__call__() checks email against role.assigned_users
- No-groups guard relaxed: user with no groups but direct email assignment is allowed through
- User routes (
get_current_user_permissions, get_actual_user_permissions) pass email through
is_user_admin refactoring is explicitly out of scope (PRD "Out of Scope" section)
Tests
- Authorization manager:
get_user_effective_permissions() returns correct permissions for user matched by email only, by group only, and by both
- PermissionChecker: user with no groups but direct email assignment is not denied
Acceptance criteria
Blocked by
User stories addressed
- User story 7 (same permissions regardless of assignment method)
- User story 8 (no group memberships but directly assigned — still works)
Parent PRD
#195
What to build
Wire
user_emailthrough the authorization flow so that role matching checks both group membership AND direct email assignment. This is the core authorization change that makesassigned_usersactually grant permissions.Key decisions from the PRD
get_user_effective_permissions()gains optionaluser_emailparamassigned_users(case-insensitive)PermissionChecker.__call__()passesuser_email=user_details.emailApprovalChecker.__call__()checks email againstrole.assigned_usersget_current_user_permissions,get_actual_user_permissions) pass email throughis_user_adminrefactoring is explicitly out of scope (PRD "Out of Scope" section)Tests
get_user_effective_permissions()returns correct permissions for user matched by email only, by group only, and by bothAcceptance criteria
AuthorizationManager.get_user_effective_permissions()accepts optionaluser_emailparameterassigned_users(case-insensitive) in addition toassigned_groupsPermissionCheckerpassesuser_email=user_details.emailto the authorization managerApprovalCheckerchecks user email againstrole.assigned_usersPermissionCheckerrelaxed: users with no groups but a direct email assignment are not 403'duser_emailto auth manager callsBlocked by
User stories addressed