Complete Permissions for Groups, Membership Fees, and User Role Assignment closes #404 #405
3 changed files with 13 additions and 12 deletions
|
|
@ -420,9 +420,9 @@ lib/
|
||||||
|
|
||||||
**Actions:**
|
**Actions:**
|
||||||
- `read` - View groups (all permission sets)
|
- `read` - View groups (all permission sets)
|
||||||
- `create` - Create groups (admin only)
|
- `create` - Create groups (normal_user and admin)
|
||||||
- `update` - Edit groups (admin only)
|
- `update` - Edit groups (normal_user and admin)
|
||||||
- `destroy` - Delete groups (admin only)
|
- `destroy` - Delete groups (normal_user and admin)
|
||||||
|
|
||||||
**Scopes:**
|
**Scopes:**
|
||||||
- `:all` - All groups (for all permission sets that have read access)
|
- `:all` - All groups (for all permission sets that have read access)
|
||||||
|
|
@ -444,7 +444,7 @@ lib/
|
||||||
**Own Data Permission Set:**
|
**Own Data Permission Set:**
|
||||||
- `read` action on `Group` resource with `:all` scope - granted
|
- `read` action on `Group` resource with `:all` scope - granted
|
||||||
|
|
||||||
**Note:** All permission sets use `:all` scope for groups. Groups are considered public information that all users with member read permission can view. Only admins can manage (create/update/destroy) groups.
|
**Note:** All permission sets use `:all` scope for groups. Groups are considered public information that all users with member read permission can view. normal_user and admin can manage (create/update/destroy) groups.
|
||||||
|
|
||||||
### Member-Group Association Permissions
|
### Member-Group Association Permissions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,10 @@ Control CRUD operations on:
|
||||||
- CustomFieldValue (custom field values)
|
- CustomFieldValue (custom field values)
|
||||||
- CustomField (custom field definitions)
|
- CustomField (custom field definitions)
|
||||||
- Role (role management)
|
- Role (role management)
|
||||||
- Group (group definitions; read all, create/update/destroy admin only)
|
- Group (group definitions; read all, create/update/destroy normal_user and admin)
|
||||||
- MemberGroup (member–group associations; own_data read :linked, read_only read :all, normal_user/admin create/destroy)
|
- MemberGroup (member–group associations; own_data read :linked, read_only read :all, normal_user/admin create/destroy)
|
||||||
- MembershipFeeType (fee type definitions; all read, admin-only create/update/destroy)
|
- MembershipFeeType (fee type definitions; all read, admin-only create/update/destroy)
|
||||||
- MembershipFeeCycle (fee cycles; all read, normal_user/admin read+create+update+destroy; manual "Regenerate Cycles" for normal_user and admin)
|
- MembershipFeeCycle (fee cycles; own_data read :linked, read_only read :all, normal_user/admin read+create+update+destroy; manual "Regenerate Cycles" for normal_user and admin)
|
||||||
|
|
||||||
**4. Page-Level Permissions**
|
**4. Page-Level Permissions**
|
||||||
|
|
||||||
|
|
@ -691,11 +691,12 @@ Quick reference table showing what each permission set allows:
|
||||||
| **CustomFieldValue** (all) | - | R | R, C, U, D | R, C, U, D |
|
| **CustomFieldValue** (all) | - | R | R, C, U, D | R, C, U, D |
|
||||||
| **CustomField** (all) | R | R | R | R, C, U, D |
|
| **CustomField** (all) | R | R | R | R, C, U, D |
|
||||||
| **Role** (all) | - | - | - | R, C, U, D |
|
| **Role** (all) | - | - | - | R, C, U, D |
|
||||||
| **Group** (all) | R | R | R | R, C, U, D |
|
| **Group** (all) | R | R | R, C, U, D | R, C, U, D |
|
||||||
| **MemberGroup** (linked) | R | - | - | - |
|
| **MemberGroup** (linked) | R | - | - | - |
|
||||||
| **MemberGroup** (all) | - | R | R, C, D | R, C, D |
|
| **MemberGroup** (all) | - | R | R, C, D | R, C, D |
|
||||||
| **MembershipFeeType** (all) | R | R | R | R, C, U, D |
|
| **MembershipFeeType** (all) | R | R | R | R, C, U, D |
|
||||||
| **MembershipFeeCycle** (all) | R | R | R, C, U, D | R, C, U, D |
|
| **MembershipFeeCycle** (linked) | R | - | - | - |
|
||||||
|
| **MembershipFeeCycle** (all) | - | R | R, C, U, D | R, C, U, D |
|
||||||
|
|
||||||
**Legend:** R=Read, C=Create, U=Update, D=Destroy
|
**Legend:** R=Read, C=Create, U=Update, D=Destroy
|
||||||
|
|
||||||
|
|
@ -1217,13 +1218,13 @@ Only admins can change a user's role. The `update_user` action accepts `role_id`
|
||||||
|
|
||||||
**Location:** `lib/membership/group.ex`
|
**Location:** `lib/membership/group.ex`
|
||||||
|
|
||||||
Policies use `HasPermission` for read/create/update/destroy. All permission sets can read; only admin can create, update, destroy. No bypass (scope :all only in PermissionSets).
|
Policies use `HasPermission` for read/create/update/destroy. All permission sets can read; normal_user and admin can create, update, destroy. No bypass (scope :all only in PermissionSets).
|
||||||
|
|
||||||
### MemberGroup Resource Policies
|
### MemberGroup Resource Policies
|
||||||
|
|
||||||
**Location:** `lib/membership/member_group.ex`
|
**Location:** `lib/membership/member_group.ex`
|
||||||
|
|
||||||
Bypass for read with `expr(member_id == ^actor(:member_id))` (own_data list); HasPermission for read (read_only/normal_user/admin :all) and create/destroy (normal_user + admin only). HasPermission applies `:linked` scope for MemberGroup (see HasPermission apply_scope).
|
Bypass for read restricted to own_data (MemberGroupReadLinkedForOwnData check: own_data only, filter `member_id == actor.member_id`); HasPermission for read (read_only/normal_user/admin :all) and create/destroy (normal_user + admin only). Admin with member_id set still gets :all from HasPermission (bypass does not apply).
|
||||||
|
|
||||||
### MembershipFeeType Resource Policies
|
### MembershipFeeType Resource Policies
|
||||||
|
|
||||||
|
|
@ -1235,7 +1236,7 @@ Policies use `HasPermission` for read/create/update/destroy. All permission sets
|
||||||
|
|
||||||
**Location:** `lib/membership_fees/membership_fee_cycle.ex`
|
**Location:** `lib/membership_fees/membership_fee_cycle.ex`
|
||||||
|
|
||||||
Policies use `HasPermission` for read/create/update/destroy. All can read; read_only cannot update/create/destroy; normal_user and admin can read, create, update, and destroy (including mark_as_paid and manual "Regenerate Cycles" in the member detail view; UI button is shown when `can_create_cycle`).
|
Bypass for read restricted to own_data (MembershipFeeCycleReadLinkedForOwnData: own_data only, filter `member_id == actor.member_id`); HasPermission for read (read_only/normal_user/admin :all) and create/update/destroy. own_data can only read cycles of the linked member; read_only can read all; normal_user and admin can read, create, update, and destroy (including mark_as_paid and manual "Regenerate Cycles"; UI button when `can_create_cycle`). Regenerate-cycles handler enforces `can?(:create, MembershipFeeCycle)` server-side.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ defmodule Mv.Membership.GroupPoliciesTest do
|
||||||
Tests for Group resource authorization policies.
|
Tests for Group resource authorization policies.
|
||||||
|
|
||||||
Verifies that own_data, read_only, normal_user can read groups;
|
Verifies that own_data, read_only, normal_user can read groups;
|
||||||
only admin can create, update, and destroy groups.
|
normal_user and admin can create, update, and destroy groups.
|
||||||
"""
|
"""
|
||||||
use Mv.DataCase, async: false
|
use Mv.DataCase, async: false
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue