feat(auth): add user and role management
This commit is contained in:
59
packages/web/src/helpers/computePermissions.ee.ts
Normal file
59
packages/web/src/helpers/computePermissions.ee.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { IRole, IPermission } from '@automatisch/types';
|
||||
|
||||
type ComputeAction = {
|
||||
conditions: Record<string, boolean>;
|
||||
value: boolean;
|
||||
}
|
||||
type ComputedActions = Record<string, ComputeAction>;
|
||||
type ComputedPermissions = Record<string, ComputedActions>;
|
||||
export type RoleWithComputedPermissions = IRole & { computedPermissions: ComputedPermissions };
|
||||
|
||||
export function getRoleWithComputedPermissions(role: IRole): RoleWithComputedPermissions {
|
||||
const computedPermissions = role.permissions.reduce((computedPermissions, permission) => ({
|
||||
...computedPermissions,
|
||||
[permission.subject]: {
|
||||
...(computedPermissions[permission.subject] || {}),
|
||||
[permission.action]: {
|
||||
conditions: Object.fromEntries(permission
|
||||
.conditions
|
||||
.map(condition => [condition, true])),
|
||||
value: true,
|
||||
},
|
||||
}
|
||||
}), {} as ComputedPermissions);
|
||||
|
||||
return {
|
||||
...role,
|
||||
computedPermissions,
|
||||
};
|
||||
}
|
||||
|
||||
export function getPermissions(computedPermissions?: ComputedPermissions) {
|
||||
if (!computedPermissions) return [];
|
||||
|
||||
return Object
|
||||
.entries(computedPermissions)
|
||||
.reduce((permissions, computedPermissionEntry) => {
|
||||
const [subject, actionsWithConditions] = computedPermissionEntry;
|
||||
|
||||
for (const action in actionsWithConditions) {
|
||||
const {
|
||||
value: permitted,
|
||||
conditions = {},
|
||||
} = actionsWithConditions[action];
|
||||
|
||||
if (permitted) {
|
||||
permissions.push({
|
||||
action,
|
||||
subject,
|
||||
conditions: Object
|
||||
.entries(conditions)
|
||||
.filter(([, enabled]) => enabled)
|
||||
.map(([condition]) => condition),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}, [] as Partial<IPermission>[]);
|
||||
}
|
20
packages/web/src/helpers/userAbility.ts
Normal file
20
packages/web/src/helpers/userAbility.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { PureAbility, fieldPatternMatcher, mongoQueryMatcher } from '@casl/ability';
|
||||
import { IUser } from '@automatisch/types';
|
||||
|
||||
// Must be kept in sync with `packages/backend/src/helpers/user-ability.ts`!
|
||||
export default function userAbility(user: IUser) {
|
||||
const permissions = user?.permissions;
|
||||
const role = user?.role;
|
||||
|
||||
// We're not using mongo, but our fields, conditions match
|
||||
const options = {
|
||||
conditionsMatcher: mongoQueryMatcher,
|
||||
fieldMatcher: fieldPatternMatcher
|
||||
};
|
||||
|
||||
if (!role || !permissions) {
|
||||
return new PureAbility([], options);
|
||||
}
|
||||
|
||||
return new PureAbility<[string, string], string[]>(permissions, options);
|
||||
}
|
Reference in New Issue
Block a user