feat(group): 1st implementation of Groups
this implements first version (manageable only by admin right now)
routes:
GET /api/groups
List subject groups (paginated). Admin-only.
POST /api/groups
Create a new ReBAC subject group. Admin-only. The name must match the RFC 5321 local-part shape and be globally unique (case-insensitive).
GET /api/groups/search
Search non-virtual groups by name substring. Authenticated only (no admin role required) — backs the share-dialog recipient autocomplete.
GET /api/groups/{id}
Fetch a single group's details. Admin-only.
DELETE /api/groups/{id}
Delete a group. Cascades to `subject_group_members` (FK) and to `access_grants` rows referencing this group as a subject. Admin-only.
PATCH /api/groups/{id}
Update a group's metadata. Admin-only. v1 only persists name renames.
GET /api/groups/{id}/effective-members
List every user transitively reached through this group (members of members of members, etc.). Used by admin / audit tooling. Admin-only.
GET /api/groups/{id}/members
List the *direct* members of a group (one level only). Admin-only.
POST /api/groups/{id}/members
Add a member to a group. Exactly one of `user_id` / `group_id` must be provided. Adding a group-member runs a write-time cycle check and a nesting-depth check (max 8). Admin-only.
DELETE /api/groups/{id}/members/group/{gid}
Remove a nested group-member from a group. Admin-only.
DELETE /api/groups/{id}/members/user/{uid}
Remove a user-member from a group. Admin-only.
fix hurl
groups
round
groups
This commit is contained in:
@@ -563,6 +563,14 @@ pub fn create_api_routes(app_state: &Arc<AppState>) -> Router<Arc<AppState>> {
|
||||
let admin_router = admin_handler::admin_routes().with_state(app_state.clone());
|
||||
router = router.nest("/admin", admin_router);
|
||||
|
||||
// ReBAC subject-group management. All mutating routes are admin-gated;
|
||||
// /api/groups/search is authenticated-only so the share dialog can list
|
||||
// groups as recipients.
|
||||
let group_router =
|
||||
crate::interfaces::api::handlers::subject_group_handler::subject_group_routes()
|
||||
.with_state(app_state.clone());
|
||||
router = router.nest("/groups", group_router);
|
||||
|
||||
// Transparent compression (gzip + brotli) for all API responses.
|
||||
// tower-http negotiates via Accept-Encoding and skips already-compressed
|
||||
// content types automatically. No manual compression in handlers.
|
||||
|
||||
Reference in New Issue
Block a user