[FEATURE]: Complete Permissions for Groups, Membership Fees, and User Role Assignment #404
Labels
No labels
bug
duplicate
enhancement
help wanted
high priority
invalid
L
low priority
M
medium priority
needs refinement
optional
question
S
UX research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: local-it/mitgliederverwaltung#404
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
The current roles-and-permissions implementation covers User, Member, CustomFieldValue, CustomField, and Role with resource policies and PermissionSets. Several resources and one UI flow are missing:
/settings,/membership_fee_settings) are not explicitly listed in PermissionSets (only covered by admin wildcard*).This issue implements resource policies and PermissionSets for Group, MemberGroup, MembershipFeeType, and MembershipFeeCycle, adds explicit settings page entries, implements the User role-assignment UI (admin-only), and enforces “at least one admin” when changing roles. Documentation (roles-and-permissions architecture and related docs) must be updated to reflect the new resources and behaviour.
Permission design (agreed):
/settingsand/membership_fee_settingsin PermissionSets.Tasks
PermissionSets
/settingsand/membership_fee_settingsto the admin permission set only (so they are documented and can be restricted later without relying on*).Group resource
policiesblock tolib/membership/group.exusingMv.Authorization.Checks.HasPermission. Rely on existing PermissionSets entries (read for own_data/read_only/normal_user, full CRUD for admin).MemberGroup resource
policiesblock tolib/membership/member_group.exusing HasPermission (and any bypass for read if needed for linked scope). Ensure create/destroy are allowed only for normal_user and admin per PermissionSets.MembershipFeeType resource
policiesblock tolib/membership_fees/membership_fee_type.exusing HasPermission. Read for all roles; create/update/destroy for admin only.MembershipFeeCycle resource
policiesblock tolib/membership_fees/membership_fee_cycle.exusing HasPermission. Read for all; update (and custom actions) for normal_user and admin; create/destroy for admin only. Align action names with PermissionSets (e.g. treat custom update actions as :update or add explicit permissions if needed).User resource and role assignment
role_id(or add a dedicated action for assigning role, admin-only). Add a validation: when changingrole_idaway from the Admin role, forbid if the user is the last user with the Admin role (query count of users with Admin role; if this user is one of them and count is 1, return validation error).User role assignment UI
lib/mv_web/live/user_live/form.ex, add a role dropdown (list roles fromMv.Authorization.Role). Show only when the current user is admin (e.g.can?(@current_user, :update, Mv.Authorization.Role)or equivalent). Includerole_idin the form params and pass it to the User update action when saving. Ensure the form is only used for the admin path (e.g. user index/edit) and not for profile edit if profile must not change role.Documentation
docs/roles-and-permissions-architecture.md: add Group to the resource list and permission matrix; add MemberGroup, MembershipFeeType, MembershipFeeCycle; document resource and page permissions; add “User role assignment” (admin-only, last-admin validation) and explicit settings pages.docs/roles-and-permissions-implementation-plan.md(or equivalent) with completed/added items for Group, MemberGroup, MembershipFee*, settings pages, and User role UI.docs/groups-architecture.mdauthorization section to state that Group (and MemberGroup) policies are implemented and reference the roles-and-permissions architecture.docs/membership-fee-architecture.mdto state that MembershipFeeType and MembershipFeeCycle are integrated with PermissionSets and policies, with a short summary of who may read/update.HasPermission / resource names
Mv.Authorization.Checks.HasPermission(and any UI helper) resolve resource names correctly forMemberGroup,MembershipFeeType,MembershipFeeCycle(e.g.Module.split() |> List.last()). Add or adjust mapping if needed (e.g. “MembershipFeeType” vs “MembershipFeeCycle” in PermissionSets).Acceptance Criteria
Ash.read/Ash.createetc. with an actor respect policies./settingsand/membership_fee_settingsfor admin; CheckPagePermission denies non-admin access even if wildcard behaviour is changed later.role_idis persisted. Non-admins do not see the role dropdown. When changing a user’s role from Admin to a non-admin role, the operation is rejected with a clear error if that user is the last user with the Admin role.Test Strategy
PermissionSets
get_permissions(:normal_user)(and others) include MemberGroup, MembershipFeeType, MembershipFeeCycle with expected actions/scopes; admin pages list includes/settingsand/membership_fee_settings.Group
MemberGroup
MembershipFeeType
MembershipFeeCycle
Page permission
/settingsor/membership_fee_settings(redirect or 403); admin can.User role assignment
role_idis updated. As non-admin, open user form (if possible); role dropdown is not present or not submittable.Documentation