fix: 개인 권한 관리 페이지 메뉴 리스트 표시 오류 수정
- getMenuTree()에 TenantScope 비활성화 추가 (HQ 관리자가 다른 테넌트 메뉴 조회 가능) - getRolePermissions()에 user_roles 테이블 쿼리 추가 (테넌트별 역할 권한 반영) - hasRolePermission(), getUserPermissionCounts()도 user_roles 포함하도록 수정 - 사용자 버튼의 data-context-menu를 아이디 뱃지로 이동 (클릭 이벤트 충돌 해결)
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Commons\Menu;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Scopes\TenantScope;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
@@ -28,8 +29,8 @@ public function getUserPermissionMatrix(int $userId, ?int $tenantId = null, stri
|
||||
{
|
||||
$now = now();
|
||||
|
||||
// 1. 역할 권한 조회 (Spatie)
|
||||
$rolePermissions = $this->getRolePermissions($userId, $guardName);
|
||||
// 1. 역할 권한 조회 (Spatie + user_roles)
|
||||
$rolePermissions = $this->getRolePermissions($userId, $guardName, $tenantId);
|
||||
|
||||
// 2. 부서 권한 조회 (permission_overrides with Department)
|
||||
$departmentPermissions = $this->getDepartmentPermissions($userId, $tenantId, $guardName);
|
||||
@@ -93,11 +94,12 @@ public function getUserPermissionMatrix(int $userId, ?int $tenantId = null, stri
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 권한 조회 (Spatie model_has_roles + role_has_permissions)
|
||||
* 역할 권한 조회 (Spatie model_has_roles + user_roles + role_has_permissions)
|
||||
*/
|
||||
private function getRolePermissions(int $userId, string $guardName): array
|
||||
private function getRolePermissions(int $userId, string $guardName, ?int $tenantId = null): array
|
||||
{
|
||||
$rolePermissions = DB::table('model_has_roles as mhr')
|
||||
// 1. Spatie model_has_roles 테이블에서 권한 조회
|
||||
$spatiePermissions = 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)
|
||||
@@ -107,6 +109,24 @@ private function getRolePermissions(int $userId, string $guardName): array
|
||||
->pluck('p.name')
|
||||
->toArray();
|
||||
|
||||
// 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', 'like', 'menu:%');
|
||||
|
||||
if ($tenantId) {
|
||||
$userRolesQuery->where('ur.tenant_id', $tenantId);
|
||||
}
|
||||
|
||||
$userRolesPermissions = $userRolesQuery->pluck('p.name')->toArray();
|
||||
|
||||
// 3. 권한 통합 (중복 제거)
|
||||
$rolePermissions = array_unique(array_merge($spatiePermissions, $userRolesPermissions));
|
||||
|
||||
$result = [];
|
||||
foreach ($rolePermissions as $permName) {
|
||||
if (preg_match('/^menu:(\d+)\.(\w+)$/', $permName, $matches)) {
|
||||
@@ -258,7 +278,7 @@ public function togglePermission(int $userId, int $menuId, string $permissionTyp
|
||||
->first();
|
||||
|
||||
// 역할/부서 권한 확인
|
||||
$hasRolePermission = $this->hasRolePermission($userId, $permissionName, $guardName);
|
||||
$hasRolePermission = $this->hasRolePermission($userId, $permissionName, $tenantId, $guardName);
|
||||
$hasDeptPermission = $this->hasDeptPermission($userId, $permissionName, $tenantId, $guardName);
|
||||
$hasInheritedPermission = $hasRolePermission || $hasDeptPermission;
|
||||
|
||||
@@ -303,11 +323,12 @@ public function togglePermission(int $userId, int $menuId, string $permissionTyp
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 권한 존재 여부 확인
|
||||
* 역할 권한 존재 여부 확인 (Spatie + user_roles)
|
||||
*/
|
||||
private function hasRolePermission(int $userId, string $permissionName, string $guardName): bool
|
||||
private function hasRolePermission(int $userId, string $permissionName, ?int $tenantId, string $guardName): 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)
|
||||
@@ -315,6 +336,25 @@ private function hasRolePermission(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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -616,7 +656,10 @@ public function resetToDefaultPermissions(int $userId, ?int $tenantId = null, st
|
||||
*/
|
||||
public function getMenuTree(?int $tenantId = null): \Illuminate\Support\Collection
|
||||
{
|
||||
$query = Menu::with('parent')
|
||||
// TenantScope를 비활성화하고 명시적으로 tenant_id 필터 적용
|
||||
// (HQ 관리자가 다른 테넌트의 메뉴를 조회할 수 있도록)
|
||||
$query = Menu::withoutGlobalScope(TenantScope::class)
|
||||
->with('parent')
|
||||
->where('is_active', 1);
|
||||
|
||||
if ($tenantId) {
|
||||
@@ -759,8 +802,8 @@ private function getUserPermissionCounts(int $userId, int $tenantId, $now): arra
|
||||
$result = ['web' => 0, 'api' => 0];
|
||||
|
||||
foreach (['web', 'api'] as $guardName) {
|
||||
// 1. 역할 권한
|
||||
$rolePermissions = DB::table('model_has_roles as mhr')
|
||||
// 1-1. Spatie 역할 권한 (model_has_roles)
|
||||
$spatieRolePermissions = 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)
|
||||
@@ -770,6 +813,21 @@ private function getUserPermissionCounts(int $userId, int $tenantId, $now): arra
|
||||
->pluck('p.name')
|
||||
->toArray();
|
||||
|
||||
// 1-2. 테넌트별 역할 권한 (user_roles)
|
||||
$userRolesPermissions = 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)
|
||||
->where('ur.tenant_id', $tenantId)
|
||||
->whereNull('ur.deleted_at')
|
||||
->where('p.guard_name', $guardName)
|
||||
->where('p.name', 'like', 'menu:%')
|
||||
->pluck('p.name')
|
||||
->toArray();
|
||||
|
||||
// 역할 권한 통합
|
||||
$rolePermissions = array_unique(array_merge($spatieRolePermissions, $userRolesPermissions));
|
||||
|
||||
// 2. 부서 권한
|
||||
$deptPermissions = DB::table('department_user as du')
|
||||
->join('permission_overrides as po', function ($j) use ($now, $tenantId) {
|
||||
|
||||
@@ -40,9 +40,6 @@ class="user-button px-4 py-2 text-sm font-medium rounded-lg border transition-co
|
||||
data-user-name="{{ $user->name }}"
|
||||
data-user-login="{{ $user->user_id }}"
|
||||
data-auto-select="{{ $user->id == $autoSelectId ? 'true' : 'false' }}"
|
||||
data-context-menu="user"
|
||||
data-entity-id="{{ $user->id }}"
|
||||
data-entity-name="{{ $user->name }}"
|
||||
hx-get="/api/admin/user-permissions/matrix"
|
||||
hx-target="#permission-matrix"
|
||||
hx-include="[name='guard_name']"
|
||||
@@ -50,7 +47,13 @@ class="user-button px-4 py-2 text-sm font-medium rounded-lg border transition-co
|
||||
onclick="selectUser(this)"
|
||||
>
|
||||
{{ $user->name }}
|
||||
<span class="user-id-badge px-1.5 py-0.5 text-xs bg-gray-200 text-gray-600 rounded"> {{ $user->user_id }} </span>
|
||||
<span
|
||||
class="user-id-badge px-1.5 py-0.5 text-xs bg-gray-200 text-gray-600 rounded cursor-pointer"
|
||||
data-context-menu="user"
|
||||
data-entity-id="{{ $user->id }}"
|
||||
data-entity-name="{{ $user->name }}"
|
||||
onclick="event.stopPropagation();"
|
||||
> {{ $user->user_id }} </span>
|
||||
@php
|
||||
$showWebCount = auth()->user()?->is_super_admin && $user->web_permission_count > 0;
|
||||
$showApiCount = $user->api_permission_count > 0;
|
||||
|
||||
Reference in New Issue
Block a user