mirror of
https://github.com/moodle/moodle.git
synced 2025-08-09 02:46:40 +02:00
MDL-79213 groups: Add visibility checks in groups_get_members_join()
Group visibility was not taken into account when generating SQL for getting enrolled users restricted to a list of groups. This may have allowed users to infer membership of groups they were not allowed to see members of.
This commit is contained in:
parent
f5f6ce375e
commit
b0bb97ee3b
5 changed files with 242 additions and 45 deletions
|
@ -123,23 +123,28 @@ class visibility {
|
|||
* @param string $groupsalias The SQL alias being used for the groups table.
|
||||
* @param string $groupsmembersalias The SQL alias being used for the groups_members table.
|
||||
* @param string $useralias The SQL alias being used for the user table.
|
||||
* @param string $paramprefix Prefix for the parameter names.
|
||||
* @return array [$where, $params]
|
||||
*/
|
||||
public static function sql_member_visibility_where(string $groupsalias = 'g',
|
||||
string $groupsmembersalias = 'gm', string $useralias = 'u'): array {
|
||||
public static function sql_member_visibility_where(
|
||||
string $groupsalias = 'g',
|
||||
string $groupsmembersalias = 'gm',
|
||||
string $useralias = 'u',
|
||||
string $paramprefix = '',
|
||||
): array {
|
||||
global $USER;
|
||||
|
||||
list($memberssql, $membersparams) = self::sql_members_visibility_condition($groupsalias, $groupsmembersalias);
|
||||
list($memberssql, $membersparams) = self::sql_members_visibility_condition($groupsalias, $groupsmembersalias, $paramprefix);
|
||||
|
||||
$where = " AND (
|
||||
{$groupsalias}.visibility = :all
|
||||
OR ($memberssql)
|
||||
OR ({$groupsalias}.visibility = :own AND {$useralias}.id = :currentuser2)
|
||||
)";
|
||||
$where = "(
|
||||
{$groupsalias}.visibility = :{$paramprefix}all
|
||||
OR ($memberssql)
|
||||
OR ({$groupsalias}.visibility = :{$paramprefix}own AND {$useralias}.id = :{$paramprefix}currentuser2)
|
||||
)";
|
||||
$params = [
|
||||
'all' => GROUPS_VISIBILITY_ALL,
|
||||
'own' => GROUPS_VISIBILITY_OWN,
|
||||
'currentuser2' => $USER->id,
|
||||
"{$paramprefix}all" => GROUPS_VISIBILITY_ALL,
|
||||
"{$paramprefix}own" => GROUPS_VISIBILITY_OWN,
|
||||
"{$paramprefix}currentuser2" => $USER->id,
|
||||
];
|
||||
$params = array_merge($params, $membersparams);
|
||||
return [$where, $params];
|
||||
|
@ -150,21 +155,25 @@ class visibility {
|
|||
*
|
||||
* @param string $groupsalias The SQL alias being used for the groups table.
|
||||
* @param string $groupsmembersalias The SQL alias being used for the groups_members table.
|
||||
* @param string $paramprefix Prefix for the parameter names.
|
||||
* @return array [$sql, $params]
|
||||
*/
|
||||
protected static function sql_members_visibility_condition(string $groupsalias = 'g',
|
||||
string $groupsmembersalias = 'gm'): array {
|
||||
protected static function sql_members_visibility_condition(
|
||||
string $groupsalias = 'g',
|
||||
string $groupsmembersalias = 'gm',
|
||||
string $paramprefix = '',
|
||||
): array {
|
||||
global $USER;
|
||||
$sql = "{$groupsalias}.visibility = :members
|
||||
$sql = "{$groupsalias}.visibility = :{$paramprefix}members
|
||||
AND (
|
||||
SELECT gm2.id
|
||||
FROM {groups_members} gm2
|
||||
WHERE gm2.groupid = {$groupsmembersalias}.groupid
|
||||
AND gm2.userid = :currentuser
|
||||
AND gm2.userid = :{$paramprefix}currentuser
|
||||
) IS NOT NULL";
|
||||
$params = [
|
||||
'members' => GROUPS_VISIBILITY_MEMBERS,
|
||||
'currentuser' => $USER->id
|
||||
"{$paramprefix}members" => GROUPS_VISIBILITY_MEMBERS,
|
||||
"{$paramprefix}currentuser" => $USER->id
|
||||
];
|
||||
|
||||
return [$sql, $params];
|
||||
|
|
|
@ -54,9 +54,7 @@ Feature: Private groups
|
|||
| student8 | N |
|
||||
|
||||
Scenario: Participants in "Visible to everyone" groups see their membership and other members:
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I follow "Participants"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student1"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
@ -69,9 +67,7 @@ Feature: Private groups
|
|||
| Student 8 | No groups |
|
||||
|
||||
Scenario: Participants in "Only visible to members" groups see their membership and other members, plus "Visible to everyone"
|
||||
Given I log in as "student2"
|
||||
And I am on "Course 1" course homepage
|
||||
When I follow "Participants"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student2"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
@ -84,9 +80,7 @@ Feature: Private groups
|
|||
| Student 8 | No groups |
|
||||
|
||||
Scenario: Participants in "Only see own membership" groups see their membership but not other members, plus "Visible to everyone"
|
||||
Given I log in as "student3"
|
||||
And I am on "Course 1" course homepage
|
||||
When I follow "Participants"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
@ -99,9 +93,7 @@ Feature: Private groups
|
|||
| Student 8 | No groups |
|
||||
|
||||
Scenario: Participants in "Not visible" groups do not see that group, do see "Visible to everyone"
|
||||
Given I log in as "student4"
|
||||
And I am on "Course 1" course homepage
|
||||
When I follow "Participants"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student4"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
@ -114,9 +106,7 @@ Feature: Private groups
|
|||
| Student 8 | No groups |
|
||||
|
||||
Scenario: View participants list as a teacher:
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I follow "Participants"
|
||||
Given I am on the "C1" "enrolled users" page logged in as "teacher1"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
@ -127,3 +117,60 @@ Feature: Private groups
|
|||
| Student 6 | Only visible to members/Non-Participation, Only visible to members/Participation |
|
||||
| Student 7 | Only see own membership |
|
||||
| Student 8 | Not visible |
|
||||
|
||||
@javascript
|
||||
Scenario: Filtering by "Only see own membership" groups should not show other members.
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
When I set the field "type" to "Groups"
|
||||
And I set the field "Type or select..." to "Only see own membership"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 3 | Only see own membership |
|
||||
And the following should not exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 7 | No groups |
|
||||
|
||||
@javascript
|
||||
Scenario: Filtering by "No group" should show all users whose memberships I cannot see
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
When I set the field "type" to "Groups"
|
||||
And I set the field "Type or select..." to "No group"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 2 | No groups |
|
||||
| Student 4 | No groups |
|
||||
| Student 6 | No groups |
|
||||
| Student 7 | No groups |
|
||||
| Student 8 | No groups |
|
||||
|
||||
@javascript
|
||||
Scenario: Filtering by not a member of "Only see own membership" groups I am a member of should show everyone except me
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
When I set the field "Match" in the "Filter 1" "fieldset" to "None"
|
||||
And I set the field "type" to "Groups"
|
||||
And I set the field "Type or select..." to "Only see own membership"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
| Student 2 | No groups |
|
||||
| Student 4 | No groups |
|
||||
| Student 5 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
| Student 6 | No groups |
|
||||
| Student 7 | No groups |
|
||||
| Student 8 | No groups |
|
||||
|
||||
@javascript
|
||||
Scenario: Filtering by not a member of "No group" should only show users whose memberships I can see
|
||||
Given I am on the "C1" "enrolled users" page logged in as "student3"
|
||||
When I set the field "Match" in the "Filter 1" "fieldset" to "None"
|
||||
And I set the field "type" to "Groups"
|
||||
And I set the field "Type or select..." to "No group"
|
||||
And I click on "Apply filters" "button"
|
||||
Then the following should exist in the "participants" table:
|
||||
| First name / Surname | Groups |
|
||||
| Student 1 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
| Student 3 | Only see own membership |
|
||||
| Student 5 | Visible to everyone/Non-Participation, Visible to everyone/Participation |
|
||||
|
|
|
@ -18,6 +18,9 @@ information provided here is intended especially for developers.
|
|||
'group.svg'
|
||||
);
|
||||
* Added group/grouping custom fields.
|
||||
* groups_get_members_join() now includes visibility checks for group memberships.
|
||||
* \core_group\visibility::sql_member_visibility_where() no longer prefixes the returned WHERE statement with AND, to
|
||||
give the calling code greater flexibility about how to use it.
|
||||
|
||||
=== 4.2 ===
|
||||
* `\core_group\visibility` class added to support new `visibility` field in group records. This holds the visibility constants
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue