Skip to content

Commit

Permalink
Merge pull request #146 from creative-commoners/pulls/5/onlytheseusers
Browse files Browse the repository at this point in the history
ENH Add "only these users" option to siteconfig access settings
  • Loading branch information
sabina-talipova authored Oct 24, 2023
2 parents 8281e9c + c0c65b0 commit 0176111
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 12 deletions.
104 changes: 93 additions & 11 deletions code/SiteConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use SilverStripe\Security\Security;
use SilverStripe\View\TemplateGlobalProvider;
use SilverStripe\CMS\Controllers\CMSMain;
use SilverStripe\Security\InheritedPermissions;

/**
* SiteConfig
Expand All @@ -40,15 +41,18 @@ class SiteConfig extends DataObject implements PermissionProvider, TemplateGloba
private static $db = [
"Title" => "Varchar(255)",
"Tagline" => "Varchar(255)",
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
"CanCreateTopLevelType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers, OnlyTheseMembers', 'Anyone')",
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers, OnlyTheseMembers', 'LoggedInUsers')",
"CanCreateTopLevelType" => "Enum('LoggedInUsers, OnlyTheseUsers, OnlyTheseMembers', 'LoggedInUsers')",
];

private static $many_many = [
"ViewerGroups" => Group::class,
"EditorGroups" => Group::class,
"CreateTopLevelGroups" => Group::class,
"ViewerMembers" => Member::class,
"EditorMembers" => Member::class,
"CreateTopLevelMembers" => Member::class,
];

private static $defaults = [
Expand Down Expand Up @@ -100,6 +104,7 @@ public function getCMSFields()
$groupsMap = $mapFn(Group::get());
$viewAllGroupsMap = $mapFn(Permission::get_groups_by_permission(['SITETREE_VIEW_ALL', 'ADMIN']));
$editAllGroupsMap = $mapFn(Permission::get_groups_by_permission(['SITETREE_EDIT_ALL', 'ADMIN']));
$membersMap = Member::get()->map('ID', 'Name');

$fields = FieldList::create(
TabSet::create(
Expand Down Expand Up @@ -127,6 +132,11 @@ public function getCMSFields()
'data-placeholder',
_t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
),
$viewerMembersField = ListboxField::create(
"ViewerMembers",
_t(self::class . '.VIEWERMEMBERS', "Viewer Users"),
$membersMap,
),
$editorsOptionsField = OptionsetField::create(
"CanEditType",
_t(self::class . '.EDITHEADER', "Who can edit pages on this site?")
Expand All @@ -140,19 +150,29 @@ public function getCMSFields()
'data-placeholder',
_t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
),
$editorMembersField = ListboxField::create(
"EditorMembers",
_t(self::class . '.EDITORMEMBERS', "Editor Users"),
$membersMap,
),
$topLevelCreatorsOptionsField = OptionsetField::create(
"CanCreateTopLevelType",
_t(self::class . '.TOPLEVELCREATE', "Who can create pages in the root of the site?")
),
$topLevelCreatorsGroupsField = ListboxField::create(
"CreateTopLevelGroups",
_t(self::class . '.TOPLEVELCREATORGROUPS', "Top level creators")
_t(self::class . '.TOPLEVELCREATORGROUPS2', "Top level creator groups")
)
->setSource($groupsMap)
->setAttribute(
'data-placeholder',
_t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
)
),
$topLevelCreatorsMembersField = ListboxField::create(
"CreateTopLevelMembers",
_t(self::class . '.TOPLEVELCREATORUSERS', "Top level creator users"),
$membersMap,
)
)
),
HiddenField::create('ID')
Expand All @@ -168,6 +188,10 @@ public function getCMSFields()
'SilverStripe\\CMS\\Model\\SiteTree.ACCESSONLYTHESE',
"Only these groups (choose from list)"
);
$viewersOptionsSource[InheritedPermissions::ONLY_THESE_MEMBERS] = _t(
self::class . '.ACCESSONLYTHESEMEMBERS',
"Only these users (choose from list)"
);
$viewersOptionsField->setSource($viewersOptionsSource);

if ($viewAllGroupsMap) {
Expand Down Expand Up @@ -195,19 +219,53 @@ public function getCMSFields()
'SilverStripe\\CMS\\Model\\SiteTree.EDITONLYTHESE',
"Only these groups (choose from list)"
);
$editorsOptionsSource[InheritedPermissions::ONLY_THESE_MEMBERS] = _t(
self::class . '.EDITONLYTHESEMEMBERS',
"Only these users (choose from list)"
);
$editorsOptionsField->setSource($editorsOptionsSource);

$topLevelCreatorsOptionsField->setSource($editorsOptionsSource);

if (!Permission::check('EDIT_SITECONFIG')) {
$fields->makeFieldReadonly($taglineField);
$fields->makeFieldReadonly($titleField);
// Hide and remove appropriate viewer fields
$fields->makeFieldReadonly($viewersOptionsField);
$fields->makeFieldReadonly($viewerGroupsField);
if ($this->CanViewType === InheritedPermissions::ONLY_THESE_USERS) {
$fields->makeFieldReadonly($viewerGroupsField);
$fields->removeByName('ViewerMembers');
} elseif ($this->CanViewType === InheritedPermissions::ONLY_THESE_MEMBERS) {
$fields->makeFieldReadonly($viewerMembersField);
$fields->removeByName('ViewerGroups');
} else {
$fields->removeByName('ViewerGroups');
$fields->removeByName('ViewerMembers');
}
// Hide and remove appropriate editor fields
$fields->makeFieldReadonly($editorsOptionsField);
$fields->makeFieldReadonly($editorGroupsField);
if ($this->CanEditType === InheritedPermissions::ONLY_THESE_USERS) {
$fields->makeFieldReadonly($editorGroupsField);
$fields->removeByName('EditorMembers');
} elseif ($this->CanEditType === InheritedPermissions::ONLY_THESE_MEMBERS) {
$fields->makeFieldReadonly($editorMembersField);
$fields->removeByName('EditorGroups');
} else {
$fields->removeByName('EditorGroups');
$fields->removeByName('EditorMembers');
}
// Hide and remove appropriate top-level creator fields
$fields->makeFieldReadonly($topLevelCreatorsOptionsField);
$fields->makeFieldReadonly($topLevelCreatorsGroupsField);
$fields->makeFieldReadonly($taglineField);
$fields->makeFieldReadonly($titleField);
if ($this->CanCreateTopLevelType === InheritedPermissions::ONLY_THESE_USERS) {
$fields->makeFieldReadonly($topLevelCreatorsGroupsField);
$fields->removeByName('CreateTopLevelMembers');
} elseif ($this->CanCreateTopLevelType === InheritedPermissions::ONLY_THESE_MEMBERS) {
$fields->makeFieldReadonly($topLevelCreatorsMembersField);
$fields->removeByName('CreateTopLevelGroups');
} else {
$fields->removeByName('CreateTopLevelGroups');
$fields->removeByName('CreateTopLevelMembers');
}
}

if (file_exists(BASE_PATH . '/install.php')) {
Expand Down Expand Up @@ -370,6 +428,14 @@ public function canViewPages($member = null)
return true;
}

// check for specific users
if ($this->CanViewType === InheritedPermissions::ONLY_THESE_MEMBERS
&& $member
&& $this->ViewerMembers()->filter('ID', $member->ID)->count() > 0
) {
return true;
}

return false;
}

Expand Down Expand Up @@ -403,11 +469,19 @@ public function canEditPages($member = null)
return true;
}

// check for specific groups
// check for specific groups
if ($this->CanEditType === 'OnlyTheseUsers' && $member && $member->inGroups($this->EditorGroups())) {
return true;
}

// check for specific users
if ($this->CanEditType === InheritedPermissions::ONLY_THESE_MEMBERS
&& $member
&& $this->EditorMembers()->filter('ID', $member->ID)->count() > 0
) {
return true;
}

return false;
}

Expand Down Expand Up @@ -482,6 +556,14 @@ public function canCreateTopLevel($member = null)
return true;
}

// check for specific users
if ($this->CanCreateTopLevelType === InheritedPermissions::ONLY_THESE_MEMBERS
&& $member
&& $this->CreateTopLevelMembers()->filter('ID', $member->ID)->count() > 0
) {
return true;
}

return false;
}

Expand Down
111 changes: 110 additions & 1 deletion tests/behat/features/manage-page-permissions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Feature: Manage global page permissions
Given a "page" "Home" with "Content"="<p>Welcome</p>"
And a "group" "AUTHOR" has permissions "Access to 'Pages' section"
And a "group" "SECURITY" has permissions "Access to 'Security' section"
# Have to supply an email address like this for "I am logged in as a member of <name> group" to find this user
And a "member" "AUTHOR" belonging to "AUTHOR" with "Email"="[email protected]"
And a "member" "SECURITY" belonging to "SECURITY" with "Email"="[email protected]"
And I am logged in with "ADMIN" permissions
And I go to "admin/settings"
And I click the "Access" CMS tab
Expand Down Expand Up @@ -43,6 +46,28 @@ Feature: Manage global page permissions
And I go to the homepage
Then I should see "Welcome"

Scenario: I can limit global view permissions to certain members
Given I select "Only these users (choose from list)" from "Who can view pages on this site?" input group
And I select "AUTHOR" from "Viewer Users" with javascript
And I press the "Save" button
When I am not logged in
And I go to the homepage
Then I should see a log-in form
When I am logged in as a member of "SECURITY" group
And I go to the homepage
Then I will see a "warning" log-in message
When I am not logged in
And I am logged in as a member of "AUTHOR" group
And I go to the homepage
Then I should see "Welcome"

Scenario: I can open global edit permissions to everyone
Given I select "Anyone who can log-in to the CMS" from "Who can edit pages on this site?" input group
And I press the "Save" button
Then pages should be editable by "AUTHOR"
# "anyone" doesn't override actual permissions
And pages should not be editable by "SECURITY"

Scenario: I can limit global edit permissions to logged-in users
Given I am not logged in
And I am logged in as a member of "AUTHOR" group
Expand All @@ -55,11 +80,95 @@ Feature: Manage global page permissions
And I press the "Save" button
Then pages should be editable by "AUTHOR"
And pages should be editable by "ADMIN"
And pages should not be editable by "SECURITY"

Scenario: I can limit global edit permissions to certain groups
Given I select "Only these groups (choose from list)" from "Who can edit pages on this site?" input group
When I select "Only these groups (choose from list)" from "Who can edit pages on this site?" input group
And I select "ADMIN group" from "Editor Groups" with javascript
And I press the "Save" button
Then pages should not be editable by "AUTHOR"
And pages should not be editable by "SECURITY"
But pages should be editable by "ADMIN"

Scenario: I can limit global edit permissions to certain members
Given I select "Only these users (choose from list)" from "Who can edit pages on this site?" input group
And I select "ADMIN" from "Editor Users" with javascript
And I press the "Save" button
Then pages should not be editable by "AUTHOR"
And pages should not be editable by "SECURITY"
But pages should be editable by "ADMIN"

Scenario: I should only see member/group fields when I am limiting access to members/groups (View)
Given I select "Anyone" from "Who can view pages on this site?" input group
# Need to wait a beat after each selection so the animation has time to finish
And I wait for 1 second
Then I should not see "Viewer Groups"
And I should not see "Viewer Users"
When I select "Logged-in users" from "Who can view pages on this site?" input group
And I wait for 1 second
Then I should not see "Viewer Groups"
And I should not see "Viewer Users"
When I select "Only these groups (choose from list)" from "Who can view pages on this site?" input group
And I wait for 1 second
Then I should see "Viewer Groups"
And I should not see "Viewer Users"
When I select "Only these users (choose from list)" from "Who can view pages on this site?" input group
And I wait for 1 second
Then I should not see "Viewer Groups"
And I should see "Viewer Users"
When I select "Logged-in users" from "Who can view pages on this site?" input group
And I wait for 1 second
Then I should not see "Viewer Groups"
And I should not see "Viewer Users"
# Avoids having a toast which crashes the test
When I press the "Save" button

Scenario: I should only see member/group fields when I am limiting access to members/groups (Edit)
Given I select "Anyone who can log-in to the CMS" from "Who can edit pages on this site?" input group
# Need to wait a beat after each selection so the animation has time to finish
And I wait for 1 second
Then I should not see "Editor Groups"
And I should not see "Editor Users"
When I select "Logged-in users" from "Who can edit pages on this site?" input group
And I wait for 1 second
Then I should not see "Editor Groups"
And I should not see "Editor Users"
When I select "Only these groups (choose from list)" from "Who can edit pages on this site?" input group
And I wait for 1 second
Then I should see "Editor Groups"
And I should not see "Editor Users"
When I select "Only these users (choose from list)" from "Who can edit pages on this site?" input group
And I wait for 1 second
Then I should not see "Editor Groups"
And I should see "Editor Users"
When I select "Anyone who can log-in to the CMS" from "Who can edit pages on this site?" input group
And I wait for 1 second
Then I should not see "Editor Groups"
And I should not see "Editor Users"
# Avoids having a toast which crashes the test
When I press the "Save" button

Scenario: I should only see member/group fields when I am limiting access to members/groups (Create)
Given I select "Anyone who can log-in to the CMS" from "Who can create pages in the root of the site?" input group
# Need to wait a beat after each selection so the animation has time to finish
And I wait for 1 second
Then I should not see "Top level creator groups"
And I should not see "Top level creator users"
When I select "Logged-in users" from "Who can create pages in the root of the site?" input group
And I wait for 1 second
Then I should not see "Top level creator groups"
And I should not see "Top level creator users"
When I select "Only these groups (choose from list)" from "Who can create pages in the root of the site?" input group
And I wait for 1 second
Then I should see "Top level creator groups"
And I should not see "Top level creator users"
When I select "Only these users (choose from list)" from "Who can create pages in the root of the site?" input group
And I wait for 1 second
Then I should not see "Top level creator groups"
And I should see "Top level creator users"
When I select "Anyone who can log-in to the CMS" from "Who can create pages in the root of the site?" input group
And I wait for 1 second
Then I should not see "Top level creator groups"
And I should not see "Top level creator users"
# Avoids having a toast which crashes the test
When I press the "Save" button

0 comments on commit 0176111

Please sign in to comment.