From 9983bc8fe3c0b02ba9db5d45d0c9bc27919fea89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EC=B0=BD=EC=9A=B1?= Date: Sun, 12 Jul 2026 00:19:47 +0900 Subject: [PATCH] feat(cloud): RBAC permission matrix --- cloud/src/Auth/Rbac.php | 15 +++++++++++++++ cloud/tests/RbacTest.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 cloud/src/Auth/Rbac.php create mode 100644 cloud/tests/RbacTest.php diff --git a/cloud/src/Auth/Rbac.php b/cloud/src/Auth/Rbac.php new file mode 100644 index 0000000..e524c66 --- /dev/null +++ b/cloud/src/Auth/Rbac.php @@ -0,0 +1,15 @@ + ['view_events','acknowledge','edit_zones','manage_thresholds','manage_compliance'], + 'operator' => ['view_events','acknowledge','edit_zones'], + 'viewer' => ['view_events'], + ]; + public static function can(string $role, string $permission): bool { + return in_array($permission, self::MATRIX[$role] ?? [], true); + } +} diff --git a/cloud/tests/RbacTest.php b/cloud/tests/RbacTest.php new file mode 100644 index 0000000..bd7b38f --- /dev/null +++ b/cloud/tests/RbacTest.php @@ -0,0 +1,28 @@ +assertTrue(Rbac::can('viewer', 'view_events')); + $this->assertFalse(Rbac::can('viewer', 'acknowledge')); + $this->assertFalse(Rbac::can('viewer', 'edit_zones')); + } + public function testOperator(): void { + $this->assertTrue(Rbac::can('operator', 'acknowledge')); + $this->assertTrue(Rbac::can('operator', 'edit_zones')); + $this->assertFalse(Rbac::can('operator', 'manage_thresholds')); + } + public function testAdminAll(): void { + foreach (['view_events','acknowledge','edit_zones','manage_thresholds','manage_compliance'] as $p) { + $this->assertTrue(Rbac::can('admin', $p)); + } + } + public function testUnknownDenied(): void { + $this->assertFalse(Rbac::can('ghost', 'view_events')); + $this->assertFalse(Rbac::can('admin', 'unknown_perm')); + } +}