Skip to content

Commit

Permalink
Merge branch 'wip-MDL-50917-29' of git://github.com/abgreeve/moodle i…
Browse files Browse the repository at this point in the history
…nto MOODLE_29_STABLE
  • Loading branch information
danpoltawski committed Sep 22, 2015
2 parents 8422607 + 1283e4c commit 4addd78
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 10 deletions.
6 changes: 3 additions & 3 deletions lib/myprofilelib.php
Expand Up @@ -35,7 +35,7 @@
* @return bool
*/
function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
global $CFG, $USER, $DB;
global $CFG, $USER, $DB, $PAGE;

$usercontext = context_user::instance($user->id, MUST_EXIST);
$systemcontext = context_system::instance();
Expand Down Expand Up @@ -101,8 +101,8 @@ function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user,
}
}

// Preference page. Only visible by administrators.
if (!$iscurrentuser && is_siteadmin()) {
// Preference page.
if (!$iscurrentuser && $PAGE->settingsnav->can_view_user_preferences($user->id)) {
$url = new moodle_url('/user/preferences.php', array('userid' => $user->id));
$title = get_string('preferences', 'moodle');
$node = new core_user\output\myprofile\node('administration', 'preferences', $title, null, $url);
Expand Down
27 changes: 27 additions & 0 deletions lib/navigationlib.php
Expand Up @@ -4761,6 +4761,33 @@ protected function load_local_plugin_settings() {
public function clear_cache() {
$this->cache->volatile();
}

/**
* Checks to see if there are child nodes available in the specific user's preference node.
* If so, then they have the appropriate permissions view this user's preferences.
*
* @since Moodle 2.9
* @param int $userid The user's ID.
* @return bool True if child nodes exist to view, otherwise false.
*/
public function can_view_user_preferences($userid) {
if (is_siteadmin()) {
return true;
}
// See if any nodes are present in the preferences section for this user.
$preferencenode = $this->find('userviewingsettings' . $userid, null);
if ($preferencenode && $preferencenode->has_children()) {
// Run through each child node.
foreach ($preferencenode->children as $childnode) {
// If the child node has children then this user has access to a link in the preferences page.
if ($childnode->has_children()) {
return true;
}
}
}
// No links found for the user to access on the preferences page.
return false;
}
}

/**
Expand Down
39 changes: 39 additions & 0 deletions lib/tests/navigationlib_test.php
Expand Up @@ -450,6 +450,45 @@ public function test_setting__initialise($node) {
return $node;
}

/**
* Test that users with the correct permissions can view the preferences page.
*/
public function test_can_view_user_preferences() {
global $PAGE, $DB, $SITE;
$this->resetAfterTest();

$persontoview = $this->getDataGenerator()->create_user();
$persondoingtheviewing = $this->getDataGenerator()->create_user();

$PAGE->set_url('/');
$PAGE->set_course($SITE);

// Check that a standard user can not view the preferences page.
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->getDataGenerator()->role_assign($studentrole->id, $persondoingtheviewing->id);
$this->setUser($persondoingtheviewing);
$settingsnav = new exposed_settings_navigation();
$settingsnav->initialise();
$settingsnav->extend_for_user($persontoview->id);
$this->assertFalse($settingsnav->can_view_user_preferences($persontoview->id));

// Set persondoingtheviewing as a manager.
$managerrole = $DB->get_record('role', array('shortname' => 'manager'));
$this->getDataGenerator()->role_assign($managerrole->id, $persondoingtheviewing->id);
$settingsnav = new exposed_settings_navigation();
$settingsnav->initialise();
$settingsnav->extend_for_user($persontoview->id);
$this->assertTrue($settingsnav->can_view_user_preferences($persontoview->id));

// Check that the admin can view the preferences page.
$this->setAdminUser();
$settingsnav = new exposed_settings_navigation();
$settingsnav->initialise();
$settingsnav->extend_for_user($persontoview->id);
$preferencenode = $settingsnav->find('userviewingsettings' . $persontoview->id, null);
$this->assertTrue($settingsnav->can_view_user_preferences($persontoview->id));
}

/**
* @depends test_setting__initialise
* @param mixed $node
Expand Down
15 changes: 8 additions & 7 deletions user/preferences.php
Expand Up @@ -33,11 +33,6 @@
$userid = optional_param('userid', $USER->id, PARAM_INT);
$currentuser = $userid == $USER->id;

// Only administrators can access another user's preferences.
if (!$currentuser && !is_siteadmin($USER)) {
throw new moodle_exception('cannotedituserpreferences', 'error');
}

// Check that the user is a valid user.
$user = core_user::get_user($userid);
if (!$user || !core_user::is_real_user($userid)) {
Expand All @@ -53,10 +48,16 @@

if (!$currentuser) {
$PAGE->navigation->extend_for_user($user);
$settings = $PAGE->settingsnav->find('userviewingsettings' . $user->id, null);
$settings->make_active();
// Need to check that settings exist.
if ($settings = $PAGE->settingsnav->find('userviewingsettings' . $user->id, null)) {
$settings->make_active();
}
$url = new moodle_url('/user/preferences.php', array('userid' => $userid));
$navbar = $PAGE->navbar->add(get_string('preferences', 'moodle'), $url);
// Show an error if there are no preferences that this user has access to.
if (!$PAGE->settingsnav->can_view_user_preferences($userid)) {
throw new moodle_exception('cannotedituserpreferences', 'error');
}
} else {
// Shutdown the users node in the navigation menu.
$usernode = $PAGE->navigation->find('users', null);
Expand Down
85 changes: 85 additions & 0 deletions user/tests/behat/view_preferences_page.feature
@@ -0,0 +1,85 @@
@core @core_user
Feature: Access to preferences page
In order to view the preferences page
As a user
I need global permissions to view the page.

Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| manager1 | Manager | 1 | manager1@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
| parent | Parent | 1 | parent1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
| Course 2 | C2 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "system role assigns" exist:
| user | course | role |
| manager1 | Acceptance test site | manager |

Scenario: A student and teacher with normal permissions can not view another user's permissions page.
Given I log in as "student1"
And I follow "Course 1"
And I navigate to "Participants" node in "Current course > C1"
And I follow "Student 2"
And I should not see "Preferences" in the "#region-main" "css_element"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
When I navigate to "Participants" node in "Current course > C1"
And I follow "Student 2"
Then I should not see "Preferences" in the "#region-main" "css_element"

Scenario: Administrators and Managers can view another user's permissions page.
Given I log in as "admin"
And I am on site homepage
And I follow "Course 1"
And I navigate to "Participants" node in "Current course > C1"
And I follow "Student 2"
And I should see "Preferences" in the "#region-main" "css_element"
And I log out
And I log in as "manager1"
And I am on site homepage
And I follow "Course 1"
When I navigate to "Participants" node in "Current course > C1"
And I follow "Student 2"
Then I should see "Preferences" in the "#region-main" "css_element"

@javascript
Scenario: A user with the appropriate permissions can view another user's permissions page.
Given I log in as "admin"
And I am on site homepage
And I follow "Turn editing on"
And I add the "Mentees" block
And I navigate to "Define roles" node in "Site administration > Users > Permissions"
And I click on "Add a new role" "button"
And I click on "Continue" "button"
And I set the following fields to these values:
| Short name | Parent |
| Custom full name | Parent |
| contextlevel30 | 1 |
| moodle/user:editprofile | 1 |
| moodle/user:viewalldetails | 1 |
| moodle/user:viewuseractivitiesreport | 1 |
| moodle/user:viewdetails | 1 |
And I click on "Create this role" "button"
And I navigate to "Browse list of users" node in "Site administration > Users > Accounts"
And I follow "Student 1"
And I click on "Preferences" "link" in the ".profile_tree" "css_element"
And I follow "Assign roles relative to this user"
And I follow "Parent"
And I click on "//select[@id='addselect']/descendant::option[contains(., 'Parent 1 (parent1@example.com)')]" "xpath_element"
And I click on "Add" "button"
And I log out
And I log in as "parent"
And I am on site homepage
When I follow "Student 1"
Then I should see "Preferences" in the "#region-main" "css_element"

0 comments on commit 4addd78

Please sign in to comment.