From 8259f715ea03525be53856d31372871d77da2e3a Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 13 Apr 2021 08:14:59 -0400 Subject: [PATCH] APIv4 - Add test to ensure gatekeeper permissions are checked across joins --- .../api/v4/Query/PermissionCheckTest.php | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 tests/phpunit/api/v4/Query/PermissionCheckTest.php diff --git a/tests/phpunit/api/v4/Query/PermissionCheckTest.php b/tests/phpunit/api/v4/Query/PermissionCheckTest.php new file mode 100644 index 0000000000..790e08c6fb --- /dev/null +++ b/tests/phpunit/api/v4/Query/PermissionCheckTest.php @@ -0,0 +1,178 @@ +reset(); + $config = \CRM_Core_Config::singleton(); + unset($config->userPermissionClass->permissions); + parent::tearDown(); + } + + /** + */ + public function testGatekeeperPermissions() { + $config = \CRM_Core_Config::singleton(); + $config->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access CiviEvent', + 'view event info', + ]; + // Above permissions should be sufficient to perform Event::get + Event::get()->execute(); + + $config->userPermissionClass->permissions = []; + // Ensure error is thrown if permissions are not sufficient + try { + Event::get()->execute(); + } + catch (UnauthorizedException $e) { + $err = $e->getMessage(); + } + $this->assertContains('Authorization failed', $err); + } + + /** + * Tests that gatekeeper permissions are enforced for implicit joins + */ + public function testImplicitJoinPermissions() { + $config = \CRM_Core_Config::singleton(); + $config->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access CiviEvent', + 'view all contacts', + 'view event info', + 'view event participants', + ]; + $name = uniqid(__FUNCTION__); + $event = Event::create(FALSE) + ->addValue('title', 'ABC123 Event') + ->addValue('event_type_id', 1) + ->addValue('start_date', 'now') + ->execute()->first(); + $contact = Contact::create(FALSE) + ->addValue('first_name', $name) + ->addChain('participant', Participant::create() + ->addValue('contact_id', '$id') + ->addValue('event_id', $event['id']), + 0) + ->execute()->first(); + $participant = Participant::get() + ->addSelect('contact.first_name', 'event.title') + ->addWhere('event.id', '=', $event['id']) + ->execute() + ->first(); + + $this->assertEquals('ABC123 Event', $participant['event.title']); + $this->assertEquals($name, $participant['contact.first_name']); + + // Remove access to view events + $config->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access CiviEvent', + 'view all contacts', + 'view event participants', + ]; + $participant = Participant::get() + ->addSelect('contact.first_name') + ->addSelect('event.title') + ->addWhere('id', '=', $contact['participant']['id']) + ->execute() + ->first(); + + $this->assertTrue(empty($participant['event.title'])); + $this->assertEquals($name, $participant['contact.first_name']); + + } + + /** + * Tests that gatekeeper permissions are enforced for explicit joins + */ + public function testExplicitJoinPermissions() { + $config = \CRM_Core_Config::singleton(); + $config->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access CiviEvent', + 'view all contacts', + 'view event info', + 'view event participants', + ]; + $name = uniqid(__FUNCTION__); + $event = Event::create(FALSE) + ->addValue('title', 'ABC321 Event') + ->addValue('event_type_id', 1) + ->addValue('start_date', 'now') + ->execute()->first(); + $contact = Contact::create(FALSE) + ->addValue('first_name', $name) + ->addChain('participant', Participant::create() + ->addValue('contact_id', '$id') + ->addValue('event_id', $event['id']), + 0) + ->execute()->first(); + $participant = Participant::get() + ->addJoin('Contact AS contact1', 'INNER', ['contact1.id', '=', 'contact_id']) + ->addJoin('Event AS event1', 'INNER') + ->addSelect('contact1.first_name', 'event1.title') + ->addWhere('event1.id', '=', $event['id']) + ->execute() + ->first(); + + $this->assertEquals('ABC321 Event', $participant['event1.title']); + $this->assertEquals($name, $participant['contact1.first_name']); + + // Remove access to view events + $config->userPermissionClass->permissions = [ + 'access CiviCRM', + 'access CiviEvent', + 'view all contacts', + 'view event participants', + ]; + $participant = Participant::get() + ->addJoin('Contact AS contact1', 'INNER', ['contact1.id', '=', 'contact_id']) + ->addJoin('Event AS event1', 'INNER') + ->addSelect('contact1.first_name') + ->addSelect('event1.title') + ->addWhere('id', '=', $contact['participant']['id']) + ->execute() + ->first(); + + $this->assertTrue(empty($participant['event1.title'])); + $this->assertEquals($name, $participant['contact1.first_name']); + + } + +} -- 2.25.1