Docs: Correct :linked scope documentation
This commit is contained in:
parent
4fffeeaaa0
commit
b3eb6c9223
2 changed files with 16 additions and 12 deletions
|
|
@ -110,8 +110,8 @@ Control access to LiveView pages:
|
|||
Three scope levels for permissions:
|
||||
- **:own** - Only records where `record.id == user.id` (for User resource)
|
||||
- **:linked** - Only records linked to user via relationships
|
||||
- Member: `member.user_id == user.id`
|
||||
- CustomFieldValue: `custom_field_value.member.user_id == user.id`
|
||||
- Member: `id == user.member_id` (User.member_id → Member.id, inverse relationship)
|
||||
- CustomFieldValue: `member_id == user.member_id` (traverses Member → User relationship)
|
||||
- **:all** - All records, no filtering
|
||||
|
||||
**6. Special Cases**
|
||||
|
|
@ -714,8 +714,8 @@ defmodule Mv.Authorization.Checks.HasPermission do
|
|||
- **:all** - Authorizes without filtering (returns all records)
|
||||
- **:own** - Filters to records where record.id == actor.id
|
||||
- **:linked** - Filters based on resource type:
|
||||
- Member: member.user_id == actor.id
|
||||
- CustomFieldValue: custom_field_value.member.user_id == actor.id (traverses relationship!)
|
||||
- Member: `id == actor.member_id` (User.member_id → Member.id, inverse relationship)
|
||||
- CustomFieldValue: `member_id == actor.member_id` (CustomFieldValue.member_id → Member.id → User.member_id)
|
||||
|
||||
## Error Handling
|
||||
|
||||
|
|
@ -799,12 +799,14 @@ defmodule Mv.Authorization.Checks.HasPermission do
|
|||
defp apply_scope(:linked, actor, resource_name) do
|
||||
case resource_name do
|
||||
"Member" ->
|
||||
# Member.user_id == actor.id (direct relationship)
|
||||
{:filter, expr(user_id == ^actor.id)}
|
||||
# User.member_id → Member.id (inverse relationship)
|
||||
# Filter: member.id == actor.member_id
|
||||
{:filter, expr(id == ^actor.member_id)}
|
||||
|
||||
"CustomFieldValue" ->
|
||||
# CustomFieldValue.member.user_id == actor.id (traverse through member!)
|
||||
{:filter, expr(member.user_id == ^actor.id)}
|
||||
# CustomFieldValue.member_id → Member.id → User.member_id
|
||||
# Filter: custom_field_value.member_id == actor.member_id
|
||||
{:filter, expr(member_id == ^actor.member_id)}
|
||||
|
||||
_ ->
|
||||
# Fallback for other resources: try direct user_id
|
||||
|
|
@ -918,7 +920,7 @@ end
|
|||
|
||||
**Location:** `lib/mv/membership/member.ex`
|
||||
|
||||
**Special Case:** Users can always access their linked member (where `member.user_id == user.id`).
|
||||
**Special Case:** Users can always READ their linked member (where `id == user.member_id`).
|
||||
|
||||
```elixir
|
||||
defmodule Mv.Membership.Member do
|
||||
|
|
@ -978,10 +980,10 @@ defmodule Mv.Membership.CustomFieldValue do
|
|||
|
||||
policies do
|
||||
# SPECIAL CASE: Users can access custom field values of their linked member
|
||||
# Note: This traverses the member relationship!
|
||||
# Note: This uses member_id relationship (CustomFieldValue.member_id → Member.id → User.member_id)
|
||||
policy action_type([:read, :update]) do
|
||||
description "Users can access custom field values of their linked member"
|
||||
authorize_if expr(member.user_id == ^actor(:id))
|
||||
authorize_if expr(member_id == ^actor(:member_id))
|
||||
end
|
||||
|
||||
# GENERAL: Check permissions from role
|
||||
|
|
|
|||
|
|
@ -294,7 +294,9 @@ Each Permission Set contains:
|
|||
**:own** - Only records where id == actor.id
|
||||
- Example: User can read their own User record
|
||||
|
||||
**:linked** - Only records where user_id == actor.id
|
||||
**:linked** - Only records linked to actor via relationships
|
||||
- Member: `id == actor.member_id` (User.member_id → Member.id, inverse relationship)
|
||||
- CustomFieldValue: `member_id == actor.member_id` (traverses Member → User relationship)
|
||||
- Example: User can read Member linked to their account
|
||||
|
||||
**:all** - All records without restriction
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue