From dd8120aed797b86bb94b00518dc3ce0d86ed6185 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Thu, 15 Oct 2009 22:27:56 +0000 Subject: [PATCH] API CHANGE: Added PermissionRole and PermissionRoleCode, along with relevant tests for the permission system. (from r85173) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@89187 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- security/Group.php | 1 + security/Permission.php | 13 ++++++-- security/PermissionRole.php | 21 +++++++++++++ security/PermissionRoleCode.php | 14 +++++++++ tests/security/PermissionTest.php | 44 ++++++++++++++++++++++++++ tests/security/PermissionTest.yml | 52 +++++++++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 security/PermissionRole.php create mode 100644 security/PermissionRoleCode.php create mode 100644 tests/security/PermissionTest.php create mode 100644 tests/security/PermissionTest.yml diff --git a/security/Group.php b/security/Group.php index 0ba975783..845254e49 100644 --- a/security/Group.php +++ b/security/Group.php @@ -28,6 +28,7 @@ class Group extends DataObject { static $many_many = array( "Members" => "Member", + "Roles" => "PermissionRole", ); static $extensions = array( diff --git a/security/Permission.php b/security/Permission.php index c9a412246..79c421189 100755 --- a/security/Permission.php +++ b/security/Permission.php @@ -232,11 +232,20 @@ class Permission extends DataObject { $groupCSV = implode(", ", $groupList); // Raw SQL for efficiency - return DB::query(" + return array_unique(DB::query(" SELECT \"Code\" FROM \"Permission\" WHERE \"Type\" = " . self::GRANT_PERMISSION . " AND \"GroupID\" IN ($groupCSV) - ")->column(); + + UNION + + SELECT \"Code\" + FROM \"PermissionRoleCode\" AS PRC + INNER JOIN \"PermissionRole\" AS PR ON PRC.\"RoleID\" = PR.\"ID\" + INNER JOIN \"Group_Roles\" AS GR ON GR.\"PermissionRoleID\" = PR.\"ID\" + WHERE \"GroupID\" IN ($groupCSV) + ")->column()); + } else { return array(); } diff --git a/security/PermissionRole.php b/security/PermissionRole.php new file mode 100644 index 000000000..c6e41196c --- /dev/null +++ b/security/PermissionRole.php @@ -0,0 +1,21 @@ + "Varchar", + ); + + static $has_many = array( + "Codes" => "PermissionRoleCode", + ); + + static $belongs_many_many = array( + "Groups" => "Group", + ); +} \ No newline at end of file diff --git a/security/PermissionRoleCode.php b/security/PermissionRoleCode.php new file mode 100644 index 000000000..aa24ea88e --- /dev/null +++ b/security/PermissionRoleCode.php @@ -0,0 +1,14 @@ + "Varchar", + ); + + static $has_one = array( + "Role" => "PermissionRole", + ); +} \ No newline at end of file diff --git a/tests/security/PermissionTest.php b/tests/security/PermissionTest.php new file mode 100644 index 000000000..9bb176924 --- /dev/null +++ b/tests/security/PermissionTest.php @@ -0,0 +1,44 @@ +objFromFixture('Member', 'author'); + $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL")); + } + + function testPermissionAreInheritedFromOneRole() { + $member = $this->objFromFixture('Member', 'author'); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_CMSMain")); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); + $this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin")); + } + + function testPermissionAreInheritedFromMultipleRoles() { + $member = $this->objFromFixture('Member', 'access'); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_CMSMain")); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin")); + $this->assertTrue(Permission::checkMember($member, "EDIT_PERMISSIONS")); + $this->assertFalse(Permission::checkMember($member, "SITETREE_VIEW_ALL")); + } + + function testRolesAndPermissionsFromParentGroupsAreInherited() { + $member = $this->objFromFixture('Member', 'globalauthor'); + + // Check that permissions applied to the group are there + $this->assertTrue(Permission::checkMember($member, "SITETREE_EDIT_ALL")); + + // Check that roles from parent groups are there + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_CMSMain")); + $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); + + // Check that permissions from parent groups are there + $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL")); + + // Check that a random permission that shouldn't be there isn't + $this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin")); + } + +} \ No newline at end of file diff --git a/tests/security/PermissionTest.yml b/tests/security/PermissionTest.yml new file mode 100644 index 000000000..0bc0d832b --- /dev/null +++ b/tests/security/PermissionTest.yml @@ -0,0 +1,52 @@ +PermissionRole: + author: + Title: Author + access: + Title: Access Administrator + +PermissionRoleCode: + author1: + Role: =>PermissionRole.author + Code: CMS_ACCESS_CMSMain + author2: + Role: =>PermissionRole.author + Code: CMS_ACCESS_AssetAdmin + access1: + Role: =>PermissionRole.access + Code: CMS_ACCESS_SecurityAdmin + access2: + Role: =>PermissionRole.access + Code: EDIT_PERMISSIONS + +Member: + author: + FirstName: Test + Surname: Author + access: + FirstName: Test + Surname: Access Administrator + globalauthor: + FirstName: Test + Surname: Global Author + +Group: + author: + Title: Authors + Members: =>Member.author + Roles: =>PermissionRole.author + access: + Title: Access Administrators + Authors + Members: =>Member.access + Roles: =>PermissionRole.access,=>PermissionRole.author + globalauthor: + Parent: =>Group.author + Title: Global Authors + Members: =>Member.globalauthor + +Permission: + extra1: + Code: SITETREE_VIEW_ALL + Group: =>Group.author + globalauthor: + Code: SITETREE_EDIT_ALL + Group: =>Group.globalauthor