Commit graph

382 commits

Author SHA1 Message Date
c65124c8f4 Pass actor parameter through cycle generation
Extract actor from changeset context in Member hooks and pass it
through all cycle generation functions to ensure proper authorization.
2026-01-09 05:26:01 +01:00
57bcef17ca Add current_actor/1 helper for consistent actor access
Provides a single function to access current_user from socket assigns
across all LiveViews, ensuring consistent access pattern.
2026-01-09 05:25:59 +01:00
23f00d2cba
Refactor test setup: use global setup and fix MembershipFees domain alias
All checks were successful
continuous-integration/drone/push Build is passing
- Remove redundant setup blocks from member_live tests
- Add build_unauthenticated_conn helper for AuthController tests
- Add global setup in conn_case.ex
2026-01-09 02:25:30 +01:00
c544cdc07c
Integrate Member policies in LiveViews
- Add on_mount hook to ensure user role is loaded in all Member LiveViews
- Pass actor parameter to all Ash operations (read, get, create, update, destroy, load)
2026-01-09 00:03:58 +01:00
a42fc8a6eb Fix: Update comment in auto_filter to reflect expr(false) usage
Update comment from 'id IN [] = never matches' to 'expr(false) = match none'
to match the actual implementation of deny_filter().
2026-01-08 23:34:04 +01:00
dd4b88f0b7
Improve: Make deny_filter robust and add regression test
All checks were successful
continuous-integration/drone/push Build is passing
- Change deny_filter from [id: {:in, []}] to expr(false)
- Add regression test to ensure deny-filter matches 0 records
2026-01-08 23:30:06 +01:00
05cbd833bc
Security: Fix critical deny-filter bug and improve authorization
All checks were successful
continuous-integration/drone/push Build is passing
CRITICAL FIX: Deny-filter was allowing all records instead of denying
Fix: User validation in Member now uses actor from changeset.context
2026-01-08 23:15:48 +01:00
236eb53a24
Refactor: NoActor to SimpleCheck with compile-time environment check
This prevents security issues where :create/:read without actor would
be allowed in production. Now all operations require an actor in production.
2026-01-08 22:55:45 +01:00
6cd18545bd
Fix: HasPermission auto_filter and strict_check implementation
Fixes security issue where auto_filter returned nil instead of proper
filter expressions, which could lead to incorrect authorization behavior.
2026-01-08 22:55:24 +01:00
9d58c9d1ef
feat: implement authorization policies for Member resource
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-08 21:22:45 +01:00
db0a187058
fix: correct relationship filter paths in HasPermission check
All checks were successful
continuous-integration/drone/push Build is passing
- Use user.id instead of user_id for Member linked scope
- Use member.user.id for CustomFieldValue linked scope
- Add lazy logger evaluation
- Improve action nil handling
- Add integration tests for filter expressions
2026-01-08 17:45:02 +01:00
288002f404 feat: implement HasPermission policy check
All checks were successful
continuous-integration/drone/push Build is passing
Implement custom Ash Policy Check that reads permissions from
PermissionSets module and applies scope filters to Ash queries.
2026-01-08 16:48:43 +01:00
68c09b761e
perf: optimize load_user_counts with DB-side aggregation
All checks were successful
continuous-integration/drone/push Build is passing
Replace Elixir-side counting with Ecto GROUP BY COUNT query for
better performance. This avoids loading all users into memory and
performs the aggregation directly in the database.
2026-01-08 16:20:27 +01:00
5ac9ab7ff9
refactor: add opts_with_actor helper and improve error formatting
Add opts_with_actor helper function to reduce duplication when building
Ash options with actor and domain. Improve format_error documentation
and ensure consistent error message formatting.
2026-01-08 16:20:27 +01:00
34afe798ec
fix: use verified routes in navbar and improve can_access_page?
Use ~p verified routes instead of string paths in navbar template.
Update can_access_page? to handle both string and verified route paths
for better type safety.
2026-01-08 16:20:27 +01:00
ad0a3cd458
fix: add ensure_user_role_loaded to router live_session globally 2026-01-08 16:20:27 +01:00
675ab14fce
fix: correct German translations for role management
Fix incorrect translations:
- 'Listing Roles' -> 'Rollen auflisten' (was 'Benutzer*innen auflisten')
- 'Custom' -> 'Benutzerdefiniert' (was 'Benutzerdefinierte Felder')
2026-01-08 16:20:27 +01:00
59d656a07c
fix: add authorization check for Roles link in navbar
Only show Roles link in Settings dropdown for users with admin
permissions, preventing unauthorized access attempts.
2026-01-08 16:20:26 +01:00
32296625fe
refactor: extract shared helpers for RoleLive modules
Extract format_error and permission_set_badge_class functions into
MvWeb.RoleLive.Helpers module to eliminate code duplication between
Index and Show LiveViews.
2026-01-08 16:20:26 +01:00
e3cd400899
fix: add actor parameter to Ash.load in LiveHelpers
Use self as actor when loading user role relationship to ensure
proper authorization and policy enforcement.
2026-01-08 16:20:26 +01:00
d9dd936ae3
fix: add actor and domain parameters to user count functions in Show
Add actor and domain parameters to recalculate_user_count and
load_user_count to ensure consistent authorization. Clarify that
load_user_count is for initial display while recalculate_user_count
is for fresh count before deletion.
2026-01-08 16:20:26 +01:00
548bad6703
fix: add actor and domain parameters to user count functions
Add actor parameter to load_user_counts and recalculate_user_count
in Index LiveView to ensure consistent authorization and policy
enforcement. Also add domain parameter for clarity.
2026-01-08 16:20:25 +01:00
37a2fc3e83
refactor: replace cond with if in handle_delete_role functions 2026-01-08 16:20:25 +01:00
75ab046be4
refactor: extract ensure_user_role_loaded into shared on_mount hook
Move duplicate ensure_user_role_loaded logic into MvWeb.LiveHelpers
on_mount hook to eliminate code duplication across RoleLive modules
and centralize security-related user role loading.
2026-01-08 16:20:25 +01:00
ac67b8073d
fix: eliminate duplicate user_count queries in delete handlers
Calculate user_count once and reuse the value instead of calling
recalculate_user_count twice, reducing unnecessary database queries.
2026-01-08 16:20:25 +01:00
83812193b6
fix: add actor parameter to Authorization.get_role in Index
Ensure consistent authorization by passing actor parameter to
get_role call, matching the pattern used in Show LiveView.
2026-01-08 16:20:24 +01:00
8d36c0b02c
fix: use reraise instead of raise in rescue blocks
Replace raise with reraise to preserve the original stacktrace when
re-raising exceptions in rescue blocks, improving error debugging.
2026-01-08 16:19:49 +01:00
54c825bac3
refactor: reduce nesting depth in RoleLive handle_event functions 2026-01-08 16:19:49 +01:00
b638a54bd6
feat: prevent deletion of roles with assigned users 2026-01-08 16:19:47 +01:00
954fc4261a
fix: improve contrast for 'No description' text to meet WCAG 2 AA
Change text-base-content/50 to text-base-content/70 for better
accessibility contrast ratio in role index and show pages
2026-01-08 16:19:02 +01:00
a24bbc2188
feat: convert Settings to dropdown menu with sub-items
- Convert Settings menu item to dropdown (similar to Contributions)
- Add Global Settings and Roles as sub-items
- Update German translations: 'Global Settings' and 'Roles'
2026-01-08 16:19:00 +01:00
9c8cdb5e17
feat: add user count display for each role
- Add Users column showing number of users assigned to each role
- Load user counts efficiently in single query to avoid N+1
- Similar implementation to membership fee types member count
2026-01-08 16:18:07 +01:00
7d4bc84ce0
refactor: reduce nesting depth in RoleLive.Index.mount
Extract role loading logic into separate private functions to fix Credo warning about nested function body.
2026-01-08 16:16:54 +01:00
2f03f7c00c
feat: assign admin role to admin user in seeds
- Create Admin role if it doesn't exist
- Assign Admin role to admin@mv.local user
- Remove separate create_admin_role script (integrated into seeds)
2026-01-08 16:16:54 +01:00
61c98d1b88
feat: add visible buttons with text for role CRUD operations
- Add text labels to Edit and Delete buttons in index page
- Change button size from btn-xs to btn-sm for better visibility
- Add Delete button to show page for non-system roles
- Implement handle_event for delete in show page
- Add format_error helper to show page
2026-01-08 16:16:54 +01:00
9a86e0ec01
feat: implement role management LiveViews
Add complete CRUD interface for role management under /admin/roles.

- Index page with table showing name, description, permission_set_name, is_system_role
- Show page for role details
- Form component for create/edit with permission_set_name dropdown
- System role badge and disabled delete button
- Flash messages for success/error
- Authorization checks using MvWeb.Authorization helpers
- Comprehensive test coverage (22 tests)

Routes added under /admin scope. All LiveViews load user role
for authorization checks. Form uses custom dropdown for permission sets.
2026-01-08 16:16:53 +01:00
ff9c8d2d64
feat: add UI-level authorization helpers
Implement MvWeb.Authorization module with can?/3 and can_access_page?/2
functions for conditional rendering in LiveView templates.

- can?/3 supports both resource atoms and record structs with scope checking
- can_access_page?/2 checks page access permissions
- All functions use PermissionSets module for consistency with backend
- Graceful handling of nil users and invalid permission sets
- Comprehensive test coverage with 17 test cases
2026-01-08 16:16:53 +01:00
ee3e1745e0 fix linting errors
Some checks failed
continuous-integration/drone/push Build is failing
2026-01-07 10:59:20 +01:00
0c8a255476 Merge branch 'main' into feature/273_member_fields
Some checks failed
continuous-integration/drone/push Build is failing
2026-01-07 10:22:18 +01:00
a5a1cb7fdd style: remove display name helper in member overview for UX
Some checks failed
continuous-integration/drone/push Build is failing
2026-01-07 09:55:06 +01:00
9f97515d74 chore: movs display name helper to won helper module 2026-01-07 09:54:37 +01:00
e1211fcf0f fix linting
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-07 09:05:51 +01:00
18ec4bfd16 fix: add missing /custom_field_values/:id page to read_only and normal_user
All checks were successful
continuous-integration/drone/push Build is passing
- Add /custom_field_values/:id to read_only pages (users can view list, should also view details)
- Add /custom_field_values/:id to normal_user pages
- Refactor tests to reduce duplication (use for-comprehension for structure tests)
- Add tests for invalid input types in valid_permission_set?/1
- Update @spec for valid_permission_set?/1 to accept any() type
2026-01-06 22:17:33 +01:00
7845117fad refactor: improve error handling and documentation in PermissionSets
All checks were successful
continuous-integration/drone/push Build is passing
- Add explicit ArgumentError for invalid permission set names with helpful message
- Soften performance claim in documentation (intended to be constant-time)
- Add tests for error handling
- Improve maintainability with guard clause for invalid inputs
2026-01-06 21:55:52 +01:00
9b0d022767 fix: add missing /profile page to read_only and normal_user permission sets
Both permission sets allow User:update :own, so users should be able
to access their profile page. This makes the implementation consistent
with the documentation and the logical permission model.
2026-01-06 21:55:13 +01:00
3a0fb4e84f
feat: implement PermissionSets module with all 4 permission sets
- Add types for scope, action, resource_permission, permission_set
- Implement get_permissions/1 for all 4 sets (own_data, read_only, normal_user, admin)
- Implement valid_permission_set?/1 for string and atom validation
- Implement permission_set_name_to_atom/1 with error handling
2026-01-06 21:33:39 +01:00
5f13901ca5 security: remove is_system_role from public API
Remove is_system_role from accept lists in create_role and update_role
actions. This field should only be set via seeds or internal actions to
prevent users from creating unkillable roles through the public API.
2026-01-06 19:04:03 +01:00
deacc43030 docs: document FK constraint behavior for role relationship
Add comment explaining on_delete: :restrict behavior for
users.role_id foreign key constraint.
2026-01-06 18:37:37 +01:00
f63405052f feat: add get_role action to Authorization domain
Add get_role action for retrieving single role by ID through
code interface.
2026-01-06 18:37:35 +01:00
557eb4d27d refactor: simplify system role deletion validation
Remove redundant action_type check since validation already
runs only on destroy actions. Add field to error for better
error handling.
2026-01-06 18:37:34 +01:00