diff options
Diffstat (limited to 'lib/permissions/permission-group-actions.ts')
| -rw-r--r-- | lib/permissions/permission-group-actions.ts | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/lib/permissions/permission-group-actions.ts b/lib/permissions/permission-group-actions.ts new file mode 100644 index 00000000..51e3c2c0 --- /dev/null +++ b/lib/permissions/permission-group-actions.ts @@ -0,0 +1,270 @@ +// app/actions/permission-group-actions.ts + +"use server"; + +import db from "@/db/db"; +import { eq, and, inArray, sql } from "drizzle-orm"; +import { + permissionGroups, + permissionGroupMembers, + permissions, + rolePermissions, + userPermissions, + roles, + users +} from "@/db/schema"; +import { checkUserPermission } from "./service"; +import { getServerSession } from "next-auth/next" +import { authOptions } from "@/app/api/auth/[...nextauth]/route" + +// 권한 그룹 목록 조회 +export async function getPermissionGroups() { + const groups = await db + .select({ + id: permissionGroups.id, + groupKey: permissionGroups.groupKey, + name: permissionGroups.name, + description: permissionGroups.description, + domain: permissionGroups.domain, + isActive: permissionGroups.isActive, + createdAt: permissionGroups.createdAt, + updatedAt: permissionGroups.updatedAt, + permissionCount: sql<number>`count(distinct ${permissionGroupMembers.permissionId})`.mapWith(Number), + }) + .from(permissionGroups) + .leftJoin(permissionGroupMembers, eq(permissionGroupMembers.groupId, permissionGroups.id)) + .groupBy(permissionGroups.id) + .orderBy(permissionGroups.name); + + // 각 그룹의 역할 및 사용자 수 계산 + const groupsWithCounts = await Promise.all( + groups.map(async (group) => { + const roleCount = await db + .selectDistinct({ roleId: rolePermissions.roleId }) + .from(rolePermissions) + .where(eq(rolePermissions.permissionGroupId, group.id)); + + const userCount = await db + .selectDistinct({ userId: userPermissions.userId }) + .from(userPermissions) + .where(eq(userPermissions.permissionGroupId, group.id)); + + return { + ...group, + roleCount: roleCount.length, + userCount: userCount.length, + }; + }) + ); + + return groupsWithCounts; +} + +// 권한 그룹 생성 +export async function createPermissionGroup(data: { + groupKey: string; + name: string; + description?: string; + domain?: string; + isActive: boolean; +}) { + const session = await getServerSession(authOptions) + if (!session?.user?.id) { + throw new Error("인증이 필요합니다.") + } + const currentUserId = Number(session.user.id) + + if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { + throw new Error("권한 관리 권한이 없습니다."); + } + + // 중복 체크 + const existing = await db.select() + .from(permissionGroups) + .where(eq(permissionGroups.groupKey, data.groupKey)) + .limit(1); + + if (existing.length > 0) { + throw new Error("이미 존재하는 그룹 키입니다."); + } + + const [created] = await db.insert(permissionGroups).values(data).returning(); + return created; +} + +// 권한 그룹 수정 +export async function updatePermissionGroup(id: number, data: any) { + const session = await getServerSession(authOptions) + if (!session?.user?.id) { + throw new Error("인증이 필요합니다.") + } + const currentUserId = Number(session.user.id) + + if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { + throw new Error("권한 관리 권한이 없습니다."); + } + + const [updated] = await db.update(permissionGroups) + .set({ + ...data, + updatedAt: new Date(), + }) + .where(eq(permissionGroups.id, id)) + .returning(); + + return updated; +} + +// 권한 그룹 삭제 +export async function deletePermissionGroup(id: number) { + const currentUser = await getCurrentUser(); + if (!currentUser) throw new Error("Unauthorized"); + + if (!await checkUserPermission(currentUser.id, "admin.permissions.manage")) { + throw new Error("권한 관리 권한이 없습니다."); + } + + await db.transaction(async (tx) => { + // 그룹 멤버 삭제 + await tx.delete(permissionGroupMembers) + .where(eq(permissionGroupMembers.groupId, id)); + + // 그룹 삭제 + await tx.delete(permissionGroups) + .where(eq(permissionGroups.id, id)); + }); +} + +// 그룹의 권한 조회 +export async function getGroupPermissions(groupId: number) { + const groupPermissions = await db + .select({ + id: permissions.id, + permissionKey: permissions.permissionKey, + name: permissions.name, + description: permissions.description, + resource: permissions.resource, + action: permissions.action, + permissionType: permissions.permissionType, + scope: permissions.scope, + }) + .from(permissionGroupMembers) + .innerJoin(permissions, eq(permissions.id, permissionGroupMembers.permissionId)) + .where(eq(permissionGroupMembers.groupId, groupId)); + + const allPermissions = await db.select().from(permissions) + .where(eq(permissions.isActive, true)); + + return { + permissions: groupPermissions, + availablePermissions: allPermissions, + }; +} + +// 그룹 권한 업데이트 +export async function updateGroupPermissions(groupId: number, permissionIds: number[]) { + const session = await getServerSession(authOptions) + if (!session?.user?.id) { + throw new Error("인증이 필요합니다.") + } + const currentUserId = Number(session.user.id) + + if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { + throw new Error("권한 관리 권한이 없습니다."); + } + + await db.transaction(async (tx) => { + // 기존 권한 삭제 + await tx.delete(permissionGroupMembers) + .where(eq(permissionGroupMembers.groupId, groupId)); + + // 새 권한 추가 + if (permissionIds.length > 0) { + await tx.insert(permissionGroupMembers).values( + permissionIds.map(permissionId => ({ + groupId, + permissionId, + })) + ); + } + }); +} + +// 권한 그룹 복제 +export async function clonePermissionGroup(groupId: number) { + const session = await getServerSession(authOptions) + if (!session?.user?.id) { + throw new Error("인증이 필요합니다.") + } + const currentUserId = Number(session.user.id) + + if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { + throw new Error("권한 관리 권한이 없습니다."); + } + + // 원본 그룹 조회 + const [originalGroup] = await db.select() + .from(permissionGroups) + .where(eq(permissionGroups.id, groupId)); + + if (!originalGroup) { + throw new Error("그룹을 찾을 수 없습니다."); + } + + // 원본 그룹의 권한 조회 + const originalPermissions = await db.select() + .from(permissionGroupMembers) + .where(eq(permissionGroupMembers.groupId, groupId)); + + // 새 그룹 생성 + const timestamp = Date.now(); + const [newGroup] = await db.insert(permissionGroups).values({ + groupKey: `${originalGroup.groupKey}_copy_${timestamp}`, + name: `${originalGroup.name} (복사본)`, + description: originalGroup.description, + domain: originalGroup.domain, + isActive: originalGroup.isActive, + }).returning(); + + // 권한 복사 + if (originalPermissions.length > 0) { + await db.insert(permissionGroupMembers).values( + originalPermissions.map(p => ({ + groupId: newGroup.id, + permissionId: p.permissionId, + })) + ); + } + + return newGroup; +} + +// 그룹 할당 정보 조회 +export async function getGroupAssignments(groupId: number) { + const assignedRoles = await db + .select({ + id: roles.id, + name: roles.name, + domain: roles.domain, + }) + .from(rolePermissions) + .innerJoin(roles, eq(roles.id, rolePermissions.roleId)) + .where(eq(rolePermissions.permissionGroupId, groupId)); + + const assignedUsers = await db + .select({ + id: users.id, + name: users.name, + email: users.email, + imageUrl: users.imageUrl, + domain: users.domain, + }) + .from(userPermissions) + .innerJoin(users, eq(users.id, userPermissions.userId)) + .where(eq(userPermissions.permissionGroupId, groupId)); + + return { + roles: assignedRoles, + users: assignedUsers, + }; +}
\ No newline at end of file |
