refactor(access): fold allowed_users into allowed_principals

Move the model-route access modal off the deprecated allowed_users
policy/field onto the unified allowed_principals + principals surface,
persisting everything through a single /access POST.

- "specific users" radio now uses allowed_principals; a returned legacy
  allowed_users value is normalized so existing routes still select it.
- derive the picker's selection and the full grant set from `principals`
  in GET /access (fall back to legacy `items` if a backend doesn't
  return principals yet).
- save as `principals`: the principal-based override sends its staged
  set; the user picker maps its selection to USER-kind grants and
  preserves any non-user grants from the snapshot (no longer sends
  `users`).
- guard saving before the GET seeds principals (would wipe grants);
  share the ALLOWED_PRINCIPALS_POLICY constant.
- AccessControlFormData: `users` optional, add `principals`.
This commit is contained in:
gitlawr
2026-05-29 17:11:12 +08:00
committed by jialin
parent f71bf1b074
commit a80b889760
4 changed files with 132 additions and 37 deletions
+17 -2
View File
@@ -379,9 +379,24 @@ export interface BackendOption {
export interface AccessControlFormData {
// See `RouteItem.access_policy` for why plugin-defined values are
// accepted alongside the built-ins.
// accepted alongside the built-ins. The OSS "specific users" entry
// now writes `allowed_principals` (with a user-only grant list);
// `allowed_users` remains accepted as the deprecated released value.
access_policy: 'public' | 'authed' | 'allowed_users' | (string & {});
users: { id: number }[];
// Omitted when the caller isn't managing the user list (the
// principal-based override, or authed/public) so the server leaves
// existing grants untouched; an explicit (possibly empty) list
// replaces the route's USER-kind grants.
users?: { id: number }[];
// Full grant set (any kind) submitted by the principal-based override
// on save — replaces the route's entire grant set. OSS leaves it unset
// (it manages users via `users`).
principals?: {
principal_type: string;
principal_id: number;
principal_name?: string;
principal_display_name?: string;
}[];
}
export interface BackendItem {