fix: permission-analyze에서 user_roles 테이블 조회 추가

- checkRolePermission(): user_roles 테이블 쿼리 추가
- traceUsersWithPermission(): user_roles 기반 역할 사용자 조회 추가
- getUserRoles(): model_has_roles + user_roles 통합 조회로 변경
- 중복 제거 및 결과 병합 처리
This commit is contained in:
2025-12-09 20:30:33 +09:00
parent 8c348f2e02
commit fd3d3b5448

View File

@@ -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();