diff --git a/app/Services/PermissionAnalyzeService.php b/app/Services/PermissionAnalyzeService.php index 150d5229..d84e56ab 100644 --- a/app/Services/PermissionAnalyzeService.php +++ b/app/Services/PermissionAnalyzeService.php @@ -151,7 +151,7 @@ public function analyzeUserPermission(int $userId, int $menuId, string $permissi $now = now(); // 1. 역할 권한 확인 - $hasRolePermission = $this->checkRolePermission($userId, $permissionName, $guardName); + $hasRolePermission = $this->checkRolePermission($userId, $permissionName, $guardName, $tenantId); // 2. 부서 권한 확인 $hasDeptPermission = $this->checkDepartmentPermission($userId, $permissionName, $tenantId, $guardName); @@ -196,11 +196,12 @@ public function analyzeUserPermission(int $userId, int $menuId, string $permissi } /** - * 역할 권한 확인 + * 역할 권한 확인 (model_has_roles + user_roles) */ - private function checkRolePermission(int $userId, string $permissionName, string $guardName): bool + private function checkRolePermission(int $userId, string $permissionName, string $guardName, ?int $tenantId = null): bool { - return DB::table('model_has_roles as mhr') + // 1. Spatie model_has_roles 테이블에서 확인 + $hasSpatiePermission = DB::table('model_has_roles as mhr') ->join('role_has_permissions as rhp', 'rhp.role_id', '=', 'mhr.role_id') ->join('permissions as p', 'p.id', '=', 'rhp.permission_id') ->where('mhr.model_type', User::class) @@ -208,6 +209,25 @@ private function checkRolePermission(int $userId, string $permissionName, string ->where('p.guard_name', $guardName) ->where('p.name', $permissionName) ->exists(); + + if ($hasSpatiePermission) { + return true; + } + + // 2. user_roles 테이블에서 확인 + $userRolesQuery = DB::table('user_roles as ur') + ->join('role_has_permissions as rhp', 'rhp.role_id', '=', 'ur.role_id') + ->join('permissions as p', 'p.id', '=', 'rhp.permission_id') + ->where('ur.user_id', $userId) + ->whereNull('ur.deleted_at') + ->where('p.guard_name', $guardName) + ->where('p.name', $permissionName); + + if ($tenantId) { + $userRolesQuery->where('ur.tenant_id', $tenantId); + } + + return $userRolesQuery->exists(); } /** @@ -328,27 +348,44 @@ private function getUserDepartments(int $userId, ?int $tenantId): array } /** - * 사용자의 역할 목록 조회 (Spatie model_has_roles 테이블 사용) + * 사용자의 역할 목록 조회 (model_has_roles + user_roles) */ private function getUserRoles(int $userId, ?int $tenantId): array { - $query = DB::table('model_has_roles as mhr') + // 1. Spatie model_has_roles 테이블에서 조회 + $spatieQuery = DB::table('model_has_roles as mhr') ->join('roles as r', 'r.id', '=', 'mhr.role_id') ->select('r.id', 'r.name', 'r.description') ->where('mhr.model_type', User::class) ->where('mhr.model_id', $userId); if ($tenantId) { - $query->where('mhr.tenant_id', $tenantId); + $spatieQuery->where('mhr.tenant_id', $tenantId); } - return $query->get()->map(function ($role) { + $spatieRoles = $spatieQuery->get(); + + // 2. user_roles 테이블에서 조회 + $userRolesQuery = DB::table('user_roles as ur') + ->join('roles as r', 'r.id', '=', 'ur.role_id') + ->select('r.id', 'r.name', 'r.description') + ->where('ur.user_id', $userId) + ->whereNull('ur.deleted_at'); + + if ($tenantId) { + $userRolesQuery->where('ur.tenant_id', $tenantId); + } + + $userRoles = $userRolesQuery->get(); + + // 3. 두 결과 합치기 (중복 제거) + return $spatieRoles->merge($userRoles)->unique('id')->map(function ($role) { return [ 'id' => $role->id, 'name' => $role->name, 'display_name' => $role->description, ]; - })->toArray(); + })->values()->toArray(); } /** @@ -365,8 +402,8 @@ public function traceUsersWithPermission(int $menuId, string $permissionType = ' $permissionName = "menu:{$menuId}.{$permissionType}"; $excludeSuperAdmin = ! auth()->user()?->is_super_admin; - // 역할로 권한이 있는 사용자 - $usersFromRoleQuery = DB::table('model_has_roles as mhr') + // 역할로 권한이 있는 사용자 (model_has_roles) + $usersFromSpatieRoleQuery = DB::table('model_has_roles as mhr') ->join('role_has_permissions as rhp', 'rhp.role_id', '=', 'mhr.role_id') ->join('permissions as p', 'p.id', '=', 'rhp.permission_id') ->join('users as u', 'u.id', '=', 'mhr.model_id') @@ -377,12 +414,32 @@ public function traceUsersWithPermission(int $menuId, string $permissionType = ' ->where('p.name', $permissionName) ->where('u.is_active', true); - // 일반 관리자는 슈퍼관리자를 볼 수 없음 if ($excludeSuperAdmin) { - $usersFromRoleQuery->where('u.is_super_admin', false); + $usersFromSpatieRoleQuery->where('u.is_super_admin', false); } - $usersFromRole = $usersFromRoleQuery->get(); + // 역할로 권한이 있는 사용자 (user_roles) + $usersFromUserRolesQuery = DB::table('user_roles as ur') + ->join('role_has_permissions as rhp', 'rhp.role_id', '=', 'ur.role_id') + ->join('permissions as p', 'p.id', '=', 'rhp.permission_id') + ->join('users as u', 'u.id', '=', 'ur.user_id') + ->join('roles as r', 'r.id', '=', 'ur.role_id') + ->select('u.id as user_id', 'u.name as user_name', 'u.email', 'r.id as role_id', 'r.name as role_name', 'r.description as role_display_name') + ->whereNull('ur.deleted_at') + ->where('p.guard_name', $guardName) + ->where('p.name', $permissionName) + ->where('u.is_active', true); + + if ($excludeSuperAdmin) { + $usersFromUserRolesQuery->where('u.is_super_admin', false); + } + + if ($tenantId) { + $usersFromUserRolesQuery->where('ur.tenant_id', $tenantId); + } + + // 두 쿼리 결과 합치기 + $usersFromRole = $usersFromSpatieRoleQuery->get()->merge($usersFromUserRolesQuery->get())->unique('user_id'); // 부서로 권한이 있는 사용자 $now = now();