FIX Members can access their own profiles in CMS

This commit is contained in:
Daniel Hensby 2015-08-26 15:46:52 +01:00
parent a40e70f874
commit 2d4b743090
7 changed files with 133 additions and 95 deletions

View File

@ -50,20 +50,20 @@ class CMSProfileController extends LeftAndMain {
} }
public function canView($member = null) { public function canView($member = null) {
if(!$member && $member !== FALSE) $member = Member::currentUser(); if(!$member && $member !== false) $member = Member::currentUser();
// cms menus only for logged-in members // cms menus only for logged-in members
if(!$member) return false; if(!$member) return false;
// Only check for generic CMS permissions // Check they can access the CMS and that they are trying to edit themselves
if( if(
!Permission::checkMember($member, "CMS_ACCESS_LeftAndMain") Permission::checkMember($member, "CMS_ACCESS")
&& !Permission::checkMember($member, "CMS_ACCESS_CMSMain") && $member->ID === Member::currentUserID()
) { ) {
return false; return true;
} }
return true; return false;
} }
public function save($data, $form) { public function save($data, $form) {

View File

@ -412,7 +412,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* Will collate all IDs form all fixtures if multiple fixtures are provided. * Will collate all IDs form all fixtures if multiple fixtures are provided.
* *
* @param string $className * @param string $className
* @return A map of fixture-identifier => object-id * @return array A map of fixture-identifier => object-id
*/ */
protected function allFixtureIDs($className) { protected function allFixtureIDs($className) {
return $this->getFixtureFactory()->getIds($className); return $this->getFixtureFactory()->getIds($className);

View File

@ -167,12 +167,21 @@ class Permission extends DataObject implements TemplateGlobalProvider {
if(!is_array($code)) $code = array($code); if(!is_array($code)) $code = array($code);
if($arg == 'any') { if($arg == 'any') {
$adminImpliesAll = (bool)Config::inst()->get('Permission', 'admin_implies_all');
// Cache the permissions in memory // Cache the permissions in memory
if(!isset(self::$cache_permissions[$memberID])) { if(!isset(self::$cache_permissions[$memberID])) {
self::$cache_permissions[$memberID] = self::permissions_for_member($memberID); self::$cache_permissions[$memberID] = self::permissions_for_member($memberID);
} }
foreach ($code as $permCode) { foreach ($code as $permCode) {
if (substr($permCode, 0, 11) == 'CMS_ACCESS_') { if ($permCode === 'CMS_ACCESS') {
foreach (self::$cache_permissions[$memberID] as $perm) {
//if they have admin rights OR they have an explicit access to the CMS then give permission
if (($adminImpliesAll && $perm == 'ADMIN') || substr($perm, 0, 11) === 'CMS_ACCESS_') {
return true;
}
}
}
elseif (substr($permCode, 0, 11) === 'CMS_ACCESS_') {
//cms_access_leftandmain means access to all CMS areas //cms_access_leftandmain means access to all CMS areas
$code[] = 'CMS_ACCESS_LeftAndMain'; $code[] = 'CMS_ACCESS_LeftAndMain';
break; break;
@ -180,7 +189,9 @@ class Permission extends DataObject implements TemplateGlobalProvider {
} }
// if ADMIN has all privileges, then we need to push that code in // if ADMIN has all privileges, then we need to push that code in
if(Config::inst()->get('Permission', 'admin_implies_all')) $code[] = "ADMIN"; if($adminImpliesAll) {
$code[] = "ADMIN";
}
// Multiple $code values - return true if at least one matches, ie, intersection exists // Multiple $code values - return true if at least one matches, ie, intersection exists
return (bool)array_intersect($code, self::$cache_permissions[$memberID]); return (bool)array_intersect($code, self::$cache_permissions[$memberID]);

View File

@ -32,7 +32,7 @@ class CMSProfileControllerTest extends FunctionalTest {
} }
public function testMemberEditsOwnProfile() { public function testMemberEditsOwnProfile() {
$member = $this->objFromFixture('Member', 'user1'); $member = $this->objFromFixture('Member', 'user3');
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
$response = $this->post('admin/myprofile/EditForm', array( $response = $this->post('admin/myprofile/EditForm', array(
@ -46,9 +46,9 @@ class CMSProfileControllerTest extends FunctionalTest {
'Password[_ConfirmPassword]' => 'password', 'Password[_ConfirmPassword]' => 'password',
)); ));
$member = $this->objFromFixture('Member', 'user1'); $member = $this->objFromFixture('Member', 'user3');
$this->assertEquals($member->FirstName, 'JoeEdited', 'FirstName field was changed'); $this->assertEquals('JoeEdited', $member->FirstName, 'FirstName field was changed');
} }
public function testExtendedPermissionsStopEditingOwnProfile() { public function testExtendedPermissionsStopEditingOwnProfile() {

View File

@ -1,27 +1,38 @@
Permission: Permission:
admin: admin:
Code: ADMIN Code: ADMIN
cmsmain: cmsmain:
Code: CMS_ACCESS_LeftAndMain Code: CMS_ACCESS_LeftAndMain
leftandmain: leftandmain:
Code: CMS_ACCESS_CMSMain Code: CMS_ACCESS_CMSMain
test:
Code: CMS_ACCESS_TestController
Group: Group:
admins: admins:
Title: Administrators Title: Administrators
Permissions: =>Permission.admin Permissions: =>Permission.admin
cmsusers: cmsusers:
Title: CMS Users Title: CMS Users
Permissions: =>Permission.cmsmain, =>Permission.leftandmain Permissions: =>Permission.cmsmain, =>Permission.leftandmain
test:
Title: Test group
Permissions: =>Permission.test
Member: Member:
admin: admin:
FirstName: Admin FirstName: Admin
Email: admin@user.com Email: admin@user.com
Groups: =>Group.admins Groups: =>Group.admins
user1: user1:
FirstName: Joe FirstName: Joe
Email: user1@user.com Email: user1@user.com
Groups: =>Group.cmsusers Groups: =>Group.cmsusers
user2: user2:
FirstName: Steve FirstName: Steve
Email: user2@user.com Email: user2@user.com
Groups: =>Group.cmsusers Groups: =>Group.cmsusers
user3:
FirstName: Files
Email: user3@example.com
Groups: =>Group.test

View File

@ -14,7 +14,7 @@ class PermissionTest extends SapphireTest {
} }
public function testGetCodesUngrouped() { public function testGetCodesUngrouped() {
$codes = Permission::get_codes(null, false); $codes = Permission::get_codes(false);
$this->assertArrayHasKey('SITETREE_VIEW_ALL', $codes); $this->assertArrayHasKey('SITETREE_VIEW_ALL', $codes);
} }
@ -23,20 +23,25 @@ class PermissionTest extends SapphireTest {
$this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL")); $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL"));
} }
public function testLeftAndMainAccessAll() { public function testCMSAccess() {
//add user and group $members = Member::get()->byIDs($this->allFixtureIDs('Member'));
$member = Member::create()->update(array( foreach ($members as $member) {
'FirstName' => 'Left', $this->assertTrue(Permission::checkMember($member, 'CMS_ACCESS'));
'Surname' => 'Main', }
'Email' => 'leftandmain@example.com',
$member = new Member();
$member->update(array(
'FirstName' => 'No CMS',
'Surname' => 'Access',
'Email' => 'no-access@example.com',
)); ));
$member->write(); $member->write();
$group = Group::create()->update(array( $this->assertFalse(Permission::checkMember($member, 'CMS_ACCESS'));
'Title' => 'LeftAndMain', }
));
$group->write(); public function testLeftAndMainAccessAll() {
Permission::grant($group->ID, 'CMS_ACCESS_LeftAndMain'); //add user and group
$group->DirectMembers()->add($member); $member = $this->objFromFixture('Member', 'leftandmain');
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));

View File

@ -1,52 +1,63 @@
PermissionRole: PermissionRole:
author: author:
Title: Author Title: Author
access: access:
Title: Access Administrator Title: Access Administrator
PermissionRoleCode: PermissionRoleCode:
author1: author1:
Role: =>PermissionRole.author Role: =>PermissionRole.author
Code: CMS_ACCESS_MyAdmin Code: CMS_ACCESS_MyAdmin
author2: author2:
Role: =>PermissionRole.author Role: =>PermissionRole.author
Code: CMS_ACCESS_AssetAdmin Code: CMS_ACCESS_AssetAdmin
access1: access1:
Role: =>PermissionRole.access Role: =>PermissionRole.access
Code: CMS_ACCESS_SecurityAdmin Code: CMS_ACCESS_SecurityAdmin
access2: access2:
Role: =>PermissionRole.access Role: =>PermissionRole.access
Code: EDIT_PERMISSIONS Code: EDIT_PERMISSIONS
Member: Member:
author: author:
FirstName: Test FirstName: Test
Surname: Author Surname: Author
access: access:
FirstName: Test FirstName: Test
Surname: Access Administrator Surname: Access Administrator
globalauthor: globalauthor:
FirstName: Test FirstName: Test
Surname: Global Author Surname: Global Author
leftandmain:
FirstName: Left
Surname: AndMain
Email: leftandmain@example.com
Group: Group:
author: author:
Title: Authors Title: Authors
Members: =>Member.author Members: =>Member.author
Roles: =>PermissionRole.author Roles: =>PermissionRole.author
access: access:
Title: Access Administrators + Authors Title: Access Administrators + Authors
Members: =>Member.access Members: =>Member.access
Roles: =>PermissionRole.access,=>PermissionRole.author Roles: =>PermissionRole.access,=>PermissionRole.author
globalauthor: globalauthor:
Parent: =>Group.author Parent: =>Group.author
Title: Global Authors Title: Global Authors
Members: =>Member.globalauthor Members: =>Member.globalauthor
leftandmain:
Title: LeftAndMain
Members: =>Member.leftandmain
Permission: Permission:
extra1: extra1:
Code: SITETREE_VIEW_ALL Code: SITETREE_VIEW_ALL
Group: =>Group.author Group: =>Group.author
globalauthor: globalauthor:
Code: SITETREE_EDIT_ALL Code: SITETREE_EDIT_ALL
Group: =>Group.globalauthor Group: =>Group.globalauthor
leftandmain:
Code: CMS_ACCESS_LeftAndMain
Group: =>Group.leftandmain