UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

310 lines (280 loc) 7.4 kB
export enum MediaPermission { VIEW = "view", UPLOAD = "upload", EDIT = "edit", DELETE = "delete", MANAGE_PERMISSIONS = "manage_permissions", DOWNLOAD = "download", SHARE = "share", } export enum MediaRole { ADMIN = "admin", EDITOR = "editor", AUTHOR = "author", CONTRIBUTOR = "contributor", SUBSCRIBER = "subscriber", GUEST = "guest", } export interface MediaUser { id: string; role: MediaRole; permissions?: MediaPermission[]; folders?: string[]; // 접근 가능한 폴더 ID 목록 } export interface MediaFolder { id: string; name: string; parentId?: string; ownerId: string; permissions: MediaFolderPermission[]; inheritParentPermissions: boolean; isPublic: boolean; createdAt: Date; updatedAt: Date; } export interface MediaFolderPermission { id: string; folderId: string; userId?: string; roleId?: MediaRole; permissions: MediaPermission[]; allowInheritance: boolean; createdAt: Date; } export interface MediaCollection { id: string; name: string; description?: string; ownerId: string; permissions: MediaCollectionPermission[]; isPublic: boolean; tags: string[]; createdAt: Date; updatedAt: Date; } export interface MediaCollectionPermission { id: string; collectionId: string; userId?: string; roleId?: MediaRole; permissions: MediaPermission[]; createdAt: Date; } // 기본 역할별 권한 매핑 export const DEFAULT_ROLE_PERMISSIONS: Record<MediaRole, MediaPermission[]> = { [MediaRole.ADMIN]: [ MediaPermission.VIEW, MediaPermission.UPLOAD, MediaPermission.EDIT, MediaPermission.DELETE, MediaPermission.MANAGE_PERMISSIONS, MediaPermission.DOWNLOAD, MediaPermission.SHARE, ], [MediaRole.EDITOR]: [ MediaPermission.VIEW, MediaPermission.UPLOAD, MediaPermission.EDIT, MediaPermission.DELETE, MediaPermission.DOWNLOAD, MediaPermission.SHARE, ], [MediaRole.AUTHOR]: [ MediaPermission.VIEW, MediaPermission.UPLOAD, MediaPermission.EDIT, MediaPermission.DOWNLOAD, MediaPermission.SHARE, ], [MediaRole.CONTRIBUTOR]: [ MediaPermission.VIEW, MediaPermission.UPLOAD, MediaPermission.DOWNLOAD, ], [MediaRole.SUBSCRIBER]: [MediaPermission.VIEW, MediaPermission.DOWNLOAD], [MediaRole.GUEST]: [MediaPermission.VIEW], }; export class MediaPermissionService { /** * 사용자가 특정 작업을 수행할 권한이 있는지 확인 */ hasPermission( user: MediaUser, permission: MediaPermission, context?: { folderId?: string; collectionId?: string; fileId?: string; ownerId?: string; } ): boolean { // 관리자는 모든 권한 보유 if (user.role === MediaRole.ADMIN) { return true; } // 소유자는 MANAGE_PERMISSIONS를 제외한 모든 권한 보유 if ( context?.ownerId === user.id && permission !== MediaPermission.MANAGE_PERMISSIONS ) { return true; } // 사용자별 직접 권한 확인 if (user.permissions?.includes(permission)) { return true; } // 역할 기반 기본 권한 확인 const rolePermissions = DEFAULT_ROLE_PERMISSIONS[user.role]; if (rolePermissions.includes(permission)) { return true; } // 폴더별 권한 확인 if (context?.folderId) { return this.hasFolderPermission(user, permission, context.folderId); } // 컬렉션별 권한 확인 if (context?.collectionId) { return this.hasCollectionPermission( user, permission, context.collectionId ); } return false; } /** * 폴더별 권한 확인 (상속 포함) */ private hasFolderPermission( _user: MediaUser, _permission: MediaPermission, _folderId: string ): boolean { // 실제 구현에서는 데이터베이스에서 폴더 권한 조회 // 여기서는 Mock 구현 return true; } /** * 컬렉션별 권한 확인 */ private hasCollectionPermission( _user: MediaUser, _permission: MediaPermission, _collectionId: string ): boolean { // 실제 구현에서는 데이터베이스에서 컬렉션 권한 조회 // 여기서는 Mock 구현 return true; } /** * 사용자가 접근 가능한 폴더 목록 반환 */ async getAccessibleFolders(_user: MediaUser): Promise<MediaFolder[]> { // 실제 구현에서는 데이터베이스에서 조회 return []; } /** * 사용자가 접근 가능한 컬렉션 목록 반환 */ async getAccessibleCollections(_user: MediaUser): Promise<MediaCollection[]> { // 실제 구현에서는 데이터베이스에서 조회 return []; } /** * 폴더에 사용자 권한 추가 */ async addFolderPermission( folderId: string, userId: string, permissions: MediaPermission[], grantedBy: string ): Promise<MediaFolderPermission> { // 실제 구현에서는 데이터베이스에 저장 const permission: MediaFolderPermission = { id: `perm_${Date.now()}`, folderId, userId, permissions, allowInheritance: true, createdAt: new Date(), }; // 감사 로그 기록 await this.logPermissionChange({ action: "add_folder_permission", resourceType: "folder", resourceId: folderId, targetUserId: userId, permissions, grantedBy, }); return permission; } /** * 컬렉션에 사용자 권한 추가 */ async addCollectionPermission( collectionId: string, userId: string, permissions: MediaPermission[], grantedBy: string ): Promise<MediaCollectionPermission> { // 실제 구현에서는 데이터베이스에 저장 const permission: MediaCollectionPermission = { id: `perm_${Date.now()}`, collectionId, userId, permissions, createdAt: new Date(), }; // 감사 로그 기록 await this.logPermissionChange({ action: "add_collection_permission", resourceType: "collection", resourceId: collectionId, targetUserId: userId, permissions, grantedBy, }); return permission; } /** * 권한 변경 사항 로깅 */ private async logPermissionChange(data: { action: string; resourceType: string; resourceId: string; targetUserId: string; permissions: MediaPermission[]; grantedBy: string; }): Promise<void> { // 감사 로그 서비스에 기록 console.log("Permission change logged:", data); } /** * 폴더 권한 상속 처리 */ async inheritFolderPermissions( _parentFolderId: string, _childFolderId: string ): Promise<void> { // 부모 폴더의 권한을 자식 폴더에 상속 // 실제 구현에서는 데이터베이스 작업 } /** * 사용자 권한 검증 미들웨어 */ createPermissionMiddleware(requiredPermission: MediaPermission) { return (user: MediaUser, context?: Record<string, unknown>) => { return this.hasPermission(user, requiredPermission, context); }; } } // 싱글톤 인스턴스 let permissionServiceInstance: MediaPermissionService | null = null; export function getMediaPermissionService(): MediaPermissionService { if (!permissionServiceInstance) { permissionServiceInstance = new MediaPermissionService(); } return permissionServiceInstance; }