hak akses konsisten: sidebar Master Data pakai permission per-menu (+directive canAnyPermission); FIX direktif canPermission pakai canPermission() model (sebelumnya hanya role kolom — multi-role & user tanpa kolom role tidak dapat menu) + test
This commit is contained in:
@@ -4,7 +4,6 @@ namespace App\Providers;
|
|||||||
|
|
||||||
use Illuminate\Pagination\Paginator;
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@@ -30,17 +29,22 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
if (! $user) {
|
if (! $user) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($user->role === 'admin') {
|
|
||||||
return true;
|
return $user->canPermission($permission);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Blade directive: @canAnyPermission('a', 'b', ...) — true jika user punya SALAH SATU permission
|
||||||
|
Blade::if('canAnyPermission', function (string ...$permissions) {
|
||||||
|
$user = auth()->user();
|
||||||
|
if (! $user) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
$rolePermissions = Cache::remember('role_permissions:' . $user->role, 3600, function () use ($user) {
|
foreach ($permissions as $permission) {
|
||||||
return \DB::table('role_permissions')
|
if ($user->canPermission($permission)) {
|
||||||
->join('permissions', 'role_permissions.permission_id', '=', 'permissions.id')
|
return true;
|
||||||
->where('role_permissions.role', $user->role)
|
}
|
||||||
->pluck('permissions.key')
|
}
|
||||||
->toArray();
|
return false;
|
||||||
});
|
|
||||||
return in_array($permission, $rolePermissions);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,17 +171,23 @@
|
|||||||
<x-nav-item href="{{ route('reports.violations') }}" icon="file-lines" :active="request()->routeIs('reports.violations*')">Laporan</x-nav-item>
|
<x-nav-item href="{{ route('reports.violations') }}" icon="file-lines" :active="request()->routeIs('reports.violations*')">Laporan</x-nav-item>
|
||||||
@endcanPermission
|
@endcanPermission
|
||||||
|
|
||||||
@canPermission('categories-manage')
|
@canAnyPermission('categories-manage', 'violation-types-manage', 'thresholds-manage', 'face-register')
|
||||||
<div class="pt-4 mt-4 border-t border-gray-200">
|
<div class="pt-4 mt-4 border-t border-gray-200">
|
||||||
<p class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider">Master Data</p>
|
<p class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider">Master Data</p>
|
||||||
</div>
|
</div>
|
||||||
|
@endcanAnyPermission
|
||||||
@canPermission('face-register')
|
@canPermission('face-register')
|
||||||
<x-nav-item href="{{ route('face.register') }}" icon="user-plus" :active="request()->routeIs('face.register')">Registrasi Wajah</x-nav-item>
|
<x-nav-item href="{{ route('face.register') }}" icon="user-plus" :active="request()->routeIs('face.register')">Registrasi Wajah</x-nav-item>
|
||||||
@endcanPermission
|
@endcanPermission
|
||||||
|
@canPermission('categories-manage')
|
||||||
<x-nav-item href="{{ route('settings.categories') }}" icon="tag" :active="request()->routeIs('settings.categories*')">Kategori Pelanggaran</x-nav-item>
|
<x-nav-item href="{{ route('settings.categories') }}" icon="tag" :active="request()->routeIs('settings.categories*')">Kategori Pelanggaran</x-nav-item>
|
||||||
|
@endcanPermission
|
||||||
|
@canPermission('violation-types-manage')
|
||||||
<x-nav-item href="{{ route('settings.violation-types') }}" icon="list" :active="request()->routeIs('settings.violation-types*')">Jenis Pelanggaran</x-nav-item>
|
<x-nav-item href="{{ route('settings.violation-types') }}" icon="list" :active="request()->routeIs('settings.violation-types*')">Jenis Pelanggaran</x-nav-item>
|
||||||
<x-nav-item href="{{ route('settings.handling-types') }}" icon="hand-holding-heart" :active="request()->routeIs('settings.handling-types*')">Jenis Penanganan</x-nav-item>
|
<x-nav-item href="{{ route('settings.handling-types') }}" icon="hand-holding-heart" :active="request()->routeIs('settings.handling-types*')">Jenis Penanganan</x-nav-item>
|
||||||
<x-nav-item href="{{ route('settings.homeroom') }}" icon="chalkboard-user" :active="request()->routeIs('settings.homeroom*')">Wali Kelas</x-nav-item>
|
<x-nav-item href="{{ route('settings.homeroom') }}" icon="chalkboard-user" :active="request()->routeIs('settings.homeroom*')">Wali Kelas</x-nav-item>
|
||||||
|
@endcanPermission
|
||||||
|
@canPermission('thresholds-manage')
|
||||||
<x-nav-item href="{{ route('settings.thresholds') }}" icon="chart-bar" :active="request()->routeIs('settings.thresholds*')">Ambang SP</x-nav-item>
|
<x-nav-item href="{{ route('settings.thresholds') }}" icon="chart-bar" :active="request()->routeIs('settings.thresholds*')">Ambang SP</x-nav-item>
|
||||||
@endcanPermission
|
@endcanPermission
|
||||||
|
|
||||||
|
|||||||
@@ -52,4 +52,26 @@ class PermissionManagementTest extends TestCase
|
|||||||
->assertSee('view-point-audit')
|
->assertSee('view-point-audit')
|
||||||
->assertSee('Khusus Admin');
|
->assertSee('Khusus Admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_menu_sidebar_mengikuti_permission_role(): void
|
||||||
|
{
|
||||||
|
// Role staff dengan akses dashboard + thresholds-manage SAJA
|
||||||
|
$staff = User::factory()->create(['roles' => ['staff']]);
|
||||||
|
$ids = DB::table('permissions')->whereIn('key', ['access-dashboard', 'thresholds-manage'])->pluck('id');
|
||||||
|
foreach ($ids as $pid) {
|
||||||
|
DB::table('role_permissions')->insert([
|
||||||
|
'role' => 'staff',
|
||||||
|
'permission_id' => $pid,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->actingAs($staff)
|
||||||
|
->get('/dashboard')
|
||||||
|
->assertOk()
|
||||||
|
->assertSee('Ambang SP')
|
||||||
|
->assertDontSee('Kategori Pelanggaran')
|
||||||
|
->assertDontSee('Sinkronisasi');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user