BUGFIX: make sure non-admins can access the main site via group role

This commit is contained in:
Mateusz Uzdowski 2011-10-05 15:02:57 +13:00
parent fb998aec87
commit 5f337db553
4 changed files with 62 additions and 15 deletions

View File

@ -127,7 +127,8 @@ class LeftAndMainSubsites extends Extension {
$member = Member::currentUser(); $member = Member::currentUser();
if ($member && $member->isAdmin()) return true; //admin can access all subsites if ($member && $member->isAdmin()) return true; //admin can access all subsites
$sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}")->toDropdownMap(); $sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}", true)->toDropdownMap();
if($sites && !isset($sites[Subsite::currentSubsiteID()])) { if($sites && !isset($sites[Subsite::currentSubsiteID()])) {
$siteIDs = array_keys($sites); $siteIDs = array_keys($sites);
Subsite::changeSubsite($siteIDs[0]); Subsite::changeSubsite($siteIDs[0]);
@ -139,7 +140,7 @@ class LeftAndMainSubsites extends Extension {
foreach($menu as $candidate) { foreach($menu as $candidate) {
if($candidate->controller != $this->owner->class) { if($candidate->controller != $this->owner->class) {
$sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}")->toDropdownMap(); $sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}", true)->toDropdownMap();
if($sites && !isset($sites[Subsite::currentSubsiteID()])) { if($sites && !isset($sites[Subsite::currentSubsiteID()])) {
$siteIDs = array_keys($sites); $siteIDs = array_keys($sites);
Subsite::changeSubsite($siteIDs[0]); Subsite::changeSubsite($siteIDs[0]);

View File

@ -347,6 +347,7 @@ JS;
$SQL_perms = join("','", $SQLa_perm); $SQL_perms = join("','", $SQLa_perm);
$memberID = (int)$member->ID; $memberID = (int)$member->ID;
// Count this user's groups which can access the main site
$groupCount = DB::query(" $groupCount = DB::query("
SELECT COUNT(\"Permission\".\"ID\") SELECT COUNT(\"Permission\".\"ID\")
FROM \"Permission\" FROM \"Permission\"
@ -356,8 +357,21 @@ JS;
AND \"MemberID\" = {$memberID} AND \"MemberID\" = {$memberID}
")->value(); ")->value();
return ($groupCount > 0); // Count this user's groups which have a role that can access the main site
$roleCount = DB::query("
SELECT COUNT(\"PermissionRoleCode\".\"ID\")
FROM \"Group\"
INNER JOIN \"Group_Members\" ON \"Group_Members\".\"GroupID\" = \"Group\".\"ID\"
INNER JOIN \"Group_Roles\" ON \"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"
INNER JOIN \"PermissionRole\" ON \"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"
INNER JOIN \"PermissionRoleCode\" ON \"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\"
WHERE \"PermissionRoleCode\".\"Code\" IN ('$SQL_perms')
AND \"Group\".\"AccessAllSubsites\" = 1
AND \"MemberID\" = {$memberID}
")->value();
// There has to be at least one that allows access.
return ($groupCount + $roleCount > 0);
} }
/** /**
@ -419,6 +433,7 @@ JS;
$templateClassList = "'" . implode("', '", ClassInfo::subclassesFor("Subsite_Template")) . "'"; $templateClassList = "'" . implode("', '", ClassInfo::subclassesFor("Subsite_Template")) . "'";
// Get all subsites accessible via a group
$subsites = DataObject::get( $subsites = DataObject::get(
'Subsite', 'Subsite',
"\"Subsite\".\"Title\" != ''", "\"Subsite\".\"Title\" != ''",
@ -434,7 +449,9 @@ JS;
ON \"Group\".\"ID\"=\"Permission\".\"GroupID\" ON \"Group\".\"ID\"=\"Permission\".\"GroupID\"
AND \"Permission\".\"Code\" IN ($SQL_codes, 'ADMIN')" AND \"Permission\".\"Code\" IN ($SQL_codes, 'ADMIN')"
); );
if (!$subsites) $subsites = new DataObjectSet();
// Get all subsites accessible via a role
$rolesSubsites = DataObject::get( $rolesSubsites = DataObject::get(
'Subsite', 'Subsite',
"\"Subsite\".\"Title\" != ''", "\"Subsite\".\"Title\" != ''",
@ -455,16 +472,16 @@ JS;
AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'ADMIN')" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'ADMIN')"
); );
if(!$subsites && $rolesSubsites) return $rolesSubsites; // Merge subsites
if($rolesSubsites) {
if($rolesSubsites) foreach($rolesSubsites as $subsite) { if($rolesSubsites) foreach($rolesSubsites as $subsite) {
if(!$subsites->containsIDs(array($subsite->ID))) { if(!$subsites->containsIDs(array($subsite->ID))) {
$subsites->push($subsite); $subsites->push($subsite);
} }
} }
}
// Include the main site // Include the main site, if requested
if(!$subsites) $subsites = new DataObjectSet();
if($includeMainSite) { if($includeMainSite) {
if(!is_array($permCode)) $permCode = array($permCode); if(!is_array($permCode)) $permCode = array($permCode);
if(self::hasMainSitePermission($member, $permCode)) { if(self::hasMainSitePermission($member, $permCode)) {

View File

@ -109,7 +109,7 @@ class SubsiteTest extends SapphireTest {
$this->objFromFixture('Member', 'subsite1member')); $this->objFromFixture('Member', 'subsite1member'));
$member1SiteTitles = $member1Sites->column("Title"); $member1SiteTitles = $member1Sites->column("Title");
sort($member1SiteTitles); sort($member1SiteTitles);
$this->assertEquals(array('Subsite1 Template'), $member1SiteTitles); $this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
$adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null, $adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
$this->objFromFixture('Member', 'admin')); $this->objFromFixture('Member', 'admin'));
@ -123,6 +123,20 @@ class SubsiteTest extends SapphireTest {
'Test 2', 'Test 2',
'Test 3', 'Test 3',
), $adminSiteTitles); ), $adminSiteTitles);
$member2Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
$this->objFromFixture('Member', 'subsite1member2'));
$member2SiteTitles = $member2Sites->column("Title");
sort($member2SiteTitles);
$this->assertEquals('Subsite1 Template', $member2SiteTitles[0], 'Member can get to subsite via a group role');
}
function testHasMainSitePermission() {
$canAccess = Subsite::hasMainSitePermission($this->objFromFixture('Member', 'subsite1member'), array("CMS_ACCESS_CMSMain"));
$this->assertTrue($canAccess, 'Member has access to Main site via a group');
$canAccess = Subsite::hasMainSitePermission($this->objFromFixture('Member', 'subsite1member2'), array("CMS_ACCESS_CMSMain"));
$this->assertTrue($canAccess, 'Member has access to Main site via a group role');
} }
function testDuplicateSubsite() { function testDuplicateSubsite() {

View File

@ -75,6 +75,13 @@ SiteTree:
Title: Contact Us (Subsite 2) Title: Contact Us (Subsite 2)
SubsiteID: =>Subsite_Template.subsite2 SubsiteID: =>Subsite_Template.subsite2
PermissionRoleCode:
roleCode1:
Code: CMS_ACCESS_CMSMain
PermissionRole:
role1:
Title: role1
Codes: =>PermissionRoleCode.roleCode1
Group: Group:
admin: admin:
Title: Admin Title: Admin
@ -87,13 +94,18 @@ Group:
subsite1_group: subsite1_group:
Title: subsite1_group Title: subsite1_group
Code: subsite1_group Code: subsite1_group
AccessAllSubsites: 0 AccessAllSubsites: 1
Subsites: =>Subsite_Template.subsite1 Subsites: =>Subsite_Template.subsite1
subsite2_group: subsite2_group:
Title: subsite2_group Title: subsite2_group
Code: subsite2_group Code: subsite2_group
AccessAllSubsites: 0 AccessAllSubsites: 0
Subsites: =>Subsite_Template.subsite2 Subsites: =>Subsite_Template.subsite2
subsite1_group_via_role:
Title: subsite1_group_via_role
Code: subsite1_group_via_role
AccessAllSubsites: 1
Roles: =>PermissionRole.role1
Permission: Permission:
admin: admin:
Code: ADMIN Code: ADMIN
@ -139,3 +151,6 @@ Member:
subsite2member: subsite2member:
Email: subsite2member@test.com Email: subsite2member@test.com
Groups: =>Group.subsite2_group Groups: =>Group.subsite2_group
subsite1member2:
Email: subsite1member2@test.com
Groups: =>Group.subsite1_group_via_role