mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
24ff3622fd
* wip * restore lock * remove debug * add tests + extract util * Update packages/features/pbac/services/permission.service.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix parse permission string * use correct permission strings in tests * use eventType instead of event * fix import --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
120 lines
4.0 KiB
TypeScript
120 lines
4.0 KiB
TypeScript
import { PermissionMapper } from "../domain/mappers/PermissionMapper";
|
|
import type { Permission, PermissionPattern, PermissionValidationResult } from "../domain/models/Permission";
|
|
import type {
|
|
PermissionString,
|
|
Resource,
|
|
CrudAction,
|
|
CustomAction,
|
|
PermissionDetails,
|
|
} from "../domain/types/permission-registry";
|
|
import { PERMISSION_REGISTRY, filterResourceConfig } from "../domain/types/permission-registry";
|
|
|
|
// Helper function to check if an object is PermissionDetails
|
|
const isPermissionDetails = (obj: any): obj is PermissionDetails => {
|
|
return obj && "description" in obj && "category" in obj && "i18nKey" in obj && "descriptionI18nKey" in obj;
|
|
};
|
|
|
|
export class PermissionService {
|
|
validatePermission(permission: PermissionString): PermissionValidationResult {
|
|
try {
|
|
const permissionObj = PermissionMapper.fromPermissionString(permission);
|
|
const registryEntry = PERMISSION_REGISTRY[permissionObj.resource];
|
|
const actionEntry = registryEntry?.[permissionObj.action];
|
|
const isValid = !!actionEntry;
|
|
|
|
return {
|
|
isValid,
|
|
error: isValid ? null : `Invalid permission: ${permission}`,
|
|
};
|
|
} catch (error) {
|
|
console.debug(`[DEBUG] Error validating permission ${permission}:`, error);
|
|
if (error instanceof Error) {
|
|
return {
|
|
isValid: false,
|
|
error: error.message,
|
|
};
|
|
}
|
|
return {
|
|
isValid: false,
|
|
error: `Invalid permission format: ${permission}`,
|
|
};
|
|
}
|
|
}
|
|
|
|
validatePermissions(permissions: PermissionString[]): PermissionValidationResult {
|
|
for (const permission of permissions) {
|
|
const result = this.validatePermission(permission);
|
|
if (!result.isValid) {
|
|
return result;
|
|
}
|
|
}
|
|
return { isValid: true, error: null };
|
|
}
|
|
|
|
permissionMatches(pattern: PermissionPattern, permission: Permission): boolean {
|
|
// Handle full wildcard
|
|
if (pattern.resource === "*" && pattern.action === "*") return true;
|
|
|
|
// Check if resource matches (either exact match or wildcard)
|
|
const resourceMatches = pattern.resource === "*" || pattern.resource === permission.resource;
|
|
|
|
// Check if action matches (either exact match or wildcard)
|
|
const actionMatches = pattern.action === "*" || pattern.action === permission.action;
|
|
|
|
return resourceMatches && actionMatches;
|
|
}
|
|
|
|
getAllPermissions(): Permission[] {
|
|
const permissions: Permission[] = [];
|
|
|
|
Object.entries(PERMISSION_REGISTRY).forEach(([resource, actions]) => {
|
|
const filteredActions = filterResourceConfig(actions);
|
|
Object.entries(filteredActions).forEach(([action, details]) => {
|
|
if (details && isPermissionDetails(details)) {
|
|
permissions.push({
|
|
resource: resource as Resource,
|
|
action: action as CrudAction | CustomAction,
|
|
description: details?.description,
|
|
category: details?.category,
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
return permissions;
|
|
}
|
|
|
|
getPermissionsByResource(resource: Resource): Permission[] {
|
|
const resourcePermissions = PERMISSION_REGISTRY[resource];
|
|
if (!resourcePermissions) return [];
|
|
|
|
const filteredPermissions = filterResourceConfig(resourcePermissions);
|
|
return Object.entries(filteredPermissions)
|
|
.filter(([_, details]) => details !== undefined && isPermissionDetails(details))
|
|
.map(([action, details]) => ({
|
|
resource,
|
|
action: action as CrudAction | CustomAction,
|
|
description: details?.description,
|
|
category: details?.category,
|
|
}));
|
|
}
|
|
|
|
getPermissionsByCategory(category: string) {
|
|
return this.getAllPermissions().filter((p) => p.category === category);
|
|
}
|
|
|
|
getPermissionCategories(): string[] {
|
|
return Array.from(
|
|
new Set(
|
|
this.getAllPermissions()
|
|
.map((p) => p.category)
|
|
.filter((category): category is string => category !== undefined)
|
|
)
|
|
);
|
|
}
|
|
|
|
getPermissionsByAction(action: CrudAction | CustomAction): Permission[] {
|
|
return this.getAllPermissions().filter((p) => p.action === action);
|
|
}
|
|
}
|