From b9693a72db5a57f5529c374a9b83bdead6ce3589 Mon Sep 17 00:00:00 2001 From: Rostyslav Proskuriakov Date: Wed, 12 Apr 2023 17:34:21 +0200 Subject: [PATCH] Add caveat support for bundle --- composer.json | 2 +- src/Security/AuthzedSubject.php | 20 ++++++++++++++---- src/Security/AuthzedVoter.php | 3 ++- tests/BundleTest.php | 36 +++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 8aeeb06..d510def 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ ], "require": { "php": ">=7.4", - "linkorb/spicedb-php": "^1.0", + "linkorb/spicedb-php": "^1.1", "symfony/dependency-injection": "^4.4|^5.4|^6.0", "symfony/config": "^4.4|^5.4|^6.0", "symfony/http-kernel": "^4.4|^5.4|^6.0", diff --git a/src/Security/AuthzedSubject.php b/src/Security/AuthzedSubject.php index b8a8051..df45d46 100644 --- a/src/Security/AuthzedSubject.php +++ b/src/Security/AuthzedSubject.php @@ -11,12 +11,19 @@ class AuthzedSubject private SubjectReference $subject; private ObjectReference $object; private ?Consistency $consistency; + private ?array $caveatContext; - public function __construct(SubjectReference $subject, ObjectReference $object, Consistency $consistency = null) + public function __construct( + SubjectReference $subject, + ObjectReference $object, + Consistency $consistency = null, + array $caveatContext = null + ) { - $this->subject = $subject; - $this->object = $object; - $this->consistency = $consistency; + $this->subject = $subject; + $this->object = $object; + $this->consistency = $consistency; + $this->caveatContext = $caveatContext; } public function getSubject(): SubjectReference @@ -33,4 +40,9 @@ public function getConsistency(): ?Consistency { return $this->consistency; } + + public function getCaveatContext(): ?array + { + return $this->caveatContext; + } } diff --git a/src/Security/AuthzedVoter.php b/src/Security/AuthzedVoter.php index 7aed92c..260ad71 100644 --- a/src/Security/AuthzedVoter.php +++ b/src/Security/AuthzedVoter.php @@ -49,7 +49,8 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ $subject->getConsistency(), $subject->getObject(), $attribute, - $subject->getSubject() + $subject->getSubject(), + $subject->getCaveatContext() ) ); } catch (SpiceDBServerException $e) { diff --git a/tests/BundleTest.php b/tests/BundleTest.php index e21b685..6a1ea9f 100644 --- a/tests/BundleTest.php +++ b/tests/BundleTest.php @@ -4,6 +4,7 @@ use LinkORB\Authzed\ConnectorInterface; use LinkORB\Authzed\Dto\ObjectReference; +use LinkORB\Authzed\Dto\Request\PermissionCheck as PermissionCheckRequest; use LinkORB\Authzed\Dto\Response\PermissionCheck; use LinkORB\Authzed\Dto\SubjectReference; use LinkORB\Authzed\SpiceDB; @@ -107,4 +108,39 @@ public function testVoterException() ['view'] ); } + + public function testVoterCaveat() + { + static::bootKernel(); + + $container = static::getContainer(); + + $subject = new AuthzedSubject( + new SubjectReference(new ObjectReference('user_data', '456')), + new ObjectReference('user', '123'), + null, + ['second_parameter' => 'hello world'] + ); + + $client = $this->createMock(ConnectorInterface::class); + $client->expects($this->once()) + ->method('checkPermission') + ->with(new PermissionCheckRequest( + $subject->getConsistency(), + $subject->getObject(), + 'view', + $subject->getSubject(), + $subject->getCaveatContext() + )) + ->willReturn(new PermissionCheck(null, PermissionCheck::PERMISSIONSHIP_NO_PERMISSION)); + $container->set(SpiceDB::class, $client); + + $voter = $container->get(AuthzedVoter::class); + $this->assertInstanceOf(AuthzedVoter::class, $voter); + + $this->assertEquals( + VoterInterface::ACCESS_DENIED, + $voter->vote(new NullToken(), $subject, ['view']) + ); + } }