summaryrefslogtreecommitdiff
path: root/lib/permissions/permission-group-actions.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/permissions/permission-group-actions.ts')
-rw-r--r--lib/permissions/permission-group-actions.ts270
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