Commit 0cf441f3 authored by Robert Lyon's avatar Robert Lyon

Bug 1855383: Adding in autogroupadmin user role

behatnotneeded

Change-Id: I90b352ee72190783baf1b7aac90c606e83c00042
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent 2641c9be
......@@ -115,6 +115,8 @@ $groupadminsform = pieform(array(
'elements' => array(
'admins' => array(
'type' => 'userlist',
'group' => $group->id,
'allowuserrules' => true,
'hiddenlabel' => true,
'title' => get_string('groupadmins', 'group'),
'defaultvalue' => $admins,
......@@ -142,7 +144,7 @@ function groupadminsform_submit(Pieform $form, $values) {
UPDATE {group_member}
SET role = 'member'
WHERE role = 'admin' AND \"group\" = ?
AND member IN ($demoted)",
AND \"member\" IN ($demoted)",
array($group->id)
);
}
......
......@@ -110,7 +110,7 @@ if ($user->roles && isset($user->roles['_site'])) {
foreach ($user->roles['_site'] as $rk => $role) {
$roleelements['userroles_' . $role->id] = array(
'type' => 'switchbox',
'title' => get_string($rk),
'title' => get_string($rk, 'artefact.internal'),
'defaultvalue' => $role->active,
);
}
......
......@@ -76,8 +76,10 @@ $string['pinterest.input'] = 'Pinterest username';
$string['pinterest'] = 'Pinterest';
$string['occupation'] = 'Occupation';
$string['industry'] = 'Industry';
// Custom user roles
$string['userroles'] = 'User roles';
$string['nospecialroles'] = '<span class="text-midtone">No special roles</span>';
$string['autogroupadmin'] = 'Auto group admin';
// Field names for view user and search user display
$string['name'] = 'Name';
......
......@@ -96,6 +96,9 @@ $string['samlfieldforrolesitestaff'] = 'Role mapping for site staff';
$string['samlfieldforroleinstadmin'] = 'Role mapping for institution administrator';
$string['samlfieldforroleinststaff'] = 'Role mapping for institution staff';
$string['samlfieldfororganisationname'] = 'SSO field for Organisation';
$string['samlfieldforautogroups'] = 'Roles have auto group administration';
$string['samlfieldforautogroupsall'] = 'Auto group administration to all groups';
$string['samlfieldforautogroupsalldescription'] = 'If enabled then the user will be added as a group admin to all groups otherwise they are only added as a group admin to groups within their institution.';
$string['samlfieldauthloginmsg'] = 'Wrong login message';
$string['spentityid'] = "Service Provider entityId";
$string['title'] = 'SAML';
......
......@@ -100,6 +100,8 @@ class AuthSaml extends Auth {
$this->config['roleinstadmin'] = '';
$this->config['roleinststaff'] = '';
$this->config['organisationname'] = '';
$this->config['roleautogroups'] = '';
$this->config['roleautogroupsall'] = false;
$this->instanceid = $id;
if (!empty($id)) {
......@@ -164,6 +166,11 @@ class AuthSaml extends Auth {
$rolesitestaff = isset($this->config['rolesitestaff']) ? array_map('trim', explode(',', $this->config['rolesitestaff'])) : array();
$roleinstadmin = isset($this->config['roleinstadmin']) ? array_map('trim', explode(',', $this->config['roleinstadmin'])) : array();
$roleinststaff = isset($this->config['roleinststaff']) ? array_map('trim', explode(',', $this->config['roleinststaff'])) : array();
$roleautogroups = isset($this->config['roleautogroups']) ? array_map('trim', explode(',', $this->config['roleautogroups'])) : array();
$roleautogroupsall = isset($this->config['roleautogroupsall']) ? $this->config['roleautogroupsall'] : false;
if (is_isolated()) {
$roleautogroupsall = false;
}
$institutionname = $this->institution;
$create = false;
......@@ -259,6 +266,7 @@ class AuthSaml extends Auth {
/*******************************************/
$institutionrole = 'member'; // default role
$userroles = array();
$usr_is_siteadmin = 0;
$usr_is_sitestaff = 0;
if ($roles && is_array($roles)) {
......@@ -277,6 +285,12 @@ class AuthSaml extends Auth {
if (in_array($rv, $roleinststaff)) {
$institutionrole = 'staff';
}
if (in_array($rv, $roleautogroups)) {
$userroles[] = array('role' => 'autogroupadmin',
'institution' => ($roleautogroupsall ? '_site' : $institutionname),
'active' => 1,
'provisioner' => 'saml');
}
}
}
......@@ -404,6 +418,52 @@ class AuthSaml extends Auth {
$user->lastlastlogin = $user->lastlogin;
$user->lastlogin = time();
}
if (!empty($userroles)) {
if ($create) {
$user->set_roles($userroles);
}
else {
$user->get_roles();
// Turn off all the roles that are not associated with the SAML user roles anymore
foreach ($user->roles as $inst => $roles) {
if (in_array($inst, array_column($userroles, 'institution')) === false) {
// Not in institution anymore so remove institution specific roles
foreach ($roles as $role) {
$user->update_role($role->id, 0);
}
continue;
}
foreach ($roles as $k => $role) {
if (in_array($role->role, array_column($userroles, 'role')) === false) {
// User does not have role any more in IdP so remove role
$user->update_role($role->id, 0);
}
}
}
// Now check which roles need adding / updating
foreach ($userroles as $index => $userrole) {
if (isset($user->roles[$userrole['institution']]) &&
isset($user->roles[$userrole['institution']][$userrole['role']])) {
if ($user->roles[$userrole['institution']][$userrole['role']]->active == 0) {
// Need to activate role
$user->update_role($user->roles[$userrole['institution']][$userrole['role']]->id, 1);
}
}
else {
// Need to add role
$user->set_roles(array($userrole));
}
}
}
}
else if (empty($userroles) && !$create) {
// User exists but doesn't have any user roles so we need to turn of all existing ones
$existingroleids = get_column('usr_roles', 'id', 'usr', $user->get('id'), 'active', 1);
foreach ($existingroleids as $roleid) {
$user->update_role($roleid, 0);
}
}
$user->commit();
/**
......@@ -465,6 +525,8 @@ class PluginAuthSaml extends PluginAuth {
'roleinstadmin' => '',
'roleinststaff' => '',
'organisationname' => '',
'roleautogroups' => '',
'roleautogroupsall' => 0,
'emailfield' => '',
'studentidfield' => '',
'updateuserinfoonlogin' => 1,
......@@ -1427,8 +1489,20 @@ EOF;
'type' => 'text',
'title' => get_string('samlfieldforroleinststaff', 'auth.saml'),
'defaultvalue' => self::$default_config['roleinststaff'],
),
'roleautogroups' => array(
'type' => 'text',
'title' => get_string('samlfieldforautogroups', 'auth.saml'),
'defaultvalue' => self::$default_config['roleautogroups'],
'help' => false,
),
'roleautogroupsall' => array(
'type' => 'switchbox',
'title' => get_string('samlfieldforautogroupsall', 'auth.saml'),
'defaultvalue' => is_isolated() ? false : self::$default_config['roleautogroupsall'],
'description' => get_string('samlfieldforautogroupsalldescription', 'auth.saml'),
'disabled' => is_isolated(),
),
'authloginmsg' => array(
'type' => 'wysiwyg',
'rows' => 10,
......@@ -1605,6 +1679,8 @@ EOF;
'roleinstadmin' => $values['roleinstadmin'],
'roleinststaff' => $values['roleinststaff'],
'organisationname' => $values['organisationname'],
'roleautogroups' => $values['roleautogroups'],
'roleautogroupsall' => $values['roleautogroupsall'],
'updateuserinfoonlogin' => $values['updateuserinfoonlogin'],
'institutionattribute' => $values['institutionattribute'],
'institutionvalue' => $values['institutionvalue'],
......
......@@ -1050,7 +1050,11 @@ class User {
}
public function update_role($roleid, $state) {
set_field('usr_roles', 'active', $state, 'id', $roleid);
$role = ucfirst(get_field('usr_roles', 'role', 'id', $roleid));
$classname = 'UserRole' . $role;
$r = new $classname((object)array('id' => $roleid));
$r->set('active', $state);
$r->commit();
$this->reset_roles();
}
......@@ -2322,6 +2326,113 @@ abstract class UserRole {
}
}
class UserRoleAutogroupadmin extends UserRole {
public function __construct($data=null) {
parent::__construct('autogroupadmin', $data);
}
public function commit() {
parent::commit();
require_once(get_config('docroot') . 'lib/group.php');
$institution = $this->institution == '_site' || $this->institution === null ? 'all' : $this->institution;
if ($this->active) {
// Add the user to all the groups as a group admin
group_add_user_to_existing_groups($this->usr, 'admin', $institution);
}
else {
// Remove the user from all the groups where they are group admin
group_remove_user_from_existing_groups($this->usr, $institution);
}
}
private function _prepare_sql($data) {
$wheresql = 'role = ? ';
$where = array($this->role);
if (empty($data['institution']) || $data['institution'] == '_site') {
$wheresql .= 'AND institution IS NULL ';
}
else {
$wheresql .= 'AND (institution = ? OR institution IS NULL) ';
$where[] = $data['institution'];
}
if (isset($data['active'])) {
$wheresql .= 'AND active = ? ';
$where[] = (bool)$data['active'];
}
if (!empty($data['userid'])) {
$wheresql .= 'AND usr = ? ';
$where[] = $data['userid'];
}
if (!empty($data['provisioner'])) {
$wheresql .= 'AND provisioner = ? ';
$where[] = $data['provisioner'];
}
return array($wheresql, $where);
}
public function group_join($data) {
if (!empty($data['groupid'])) {
list($wheresql, $where) = self::_prepare_sql($data);
if ($results = get_column_sql("SELECT usr FROM {usr_roles} WHERE " . $wheresql . " AND active = 1", $where)) {
foreach ($results as $userid) {
insert_record('group_member', (object) array(
'group' => $data['groupid'],
'member' => $userid,
'role' => 'admin',
'ctime' => !empty($data['ctime']) ? $data['ctime'] : db_format_timestamp(time()),
));
}
return array('userids' => $results);
}
}
return false;
}
public function group_leave($data) {
if (!empty($data['groupid']) && !empty($data['userid'])) {
list($wheresql, $where) = self::_prepare_sql($data);
if ($results = get_column_sql("SELECT usr FROM {usr_roles} WHERE " . $wheresql, $where)) {
return array('can_leave' => false);
}
}
return array('can_leave' => true);
}
public function interaction_subscribe($data) {
if (!empty($data['userid'])) {
// subscribe one user to the forum
subscribe_user_to_forum($data['userid'], $data['id']);
}
else {
// Need to make sure all autogroupadmins are subscribed
list($wheresql, $where) = self::_prepare_sql($data);
if ($results = get_column_sql("SELECT usr FROM {usr_roles} WHERE " . $wheresql . " AND active = 1", $where)) {
foreach ($results as $userid) {
if (!get_record('interaction_forum_subscription_forum', 'user', $userid, 'forum', $data['id'])) {
subscribe_user_to_forum($data['userid'], $data['id']);
}
}
}
}
return array('can_subscribe' => true);
}
public function interaction_unsubscribe($data) {
if (!empty($data['userid'])) {
// Check to see if this user has the authgroupadmin role
list($wheresql, $where) = self::_prepare_sql($data);
if ($results = get_column_sql("SELECT usr FROM {usr_roles} WHERE " . $wheresql, $where)) {
// Not allowed to remove subscription
return array('can_unsubscribe' => false);
}
}
return array('can_unsubscribe' => true);
}
}
/**
* Indicates whether the site is closed for a user
* @param boolean $isuseradmin Whether the user we're checking for is an admin
......
......@@ -57,17 +57,18 @@ if ($forums) {
foreach ($forums as $forum) {
$forum->feedlink = get_config('wwwroot') . 'interaction/forum/atom.php?type=f&id=' . $forum->id;
$allowunsubscribe = get_config_plugin_instance('interaction_forum', $forum->id, 'allowunsubscribe');
if ($allowunsubscribe) {
if ($allowunsubscribe === null || $allowunsubscribe > 0) {
// Check if any UserRoles are in play
$checks = $USER->apply_userrole_method('interaction_unsubscribe', array('forum' => $forum->id, 'userid' => $USER->get('id')));
$checks = $USER->apply_userrole_method('interaction_unsubscribe', array('forum' => $forum->id, 'userid' => $USER->get('id'), 'institution' => $group->institution));
foreach ($checks as $check) {
if ($check['can_unsubscribe'] === false) {
// A UserRole is stopping us from unsubscribing
$allowunsubscribe = false;
$allowunsubscribe = 0;
break;
}
}
}
if ($membership) {
$forum->subscribe = pieform(array(
'name' => 'subscribe_forum' . ($i == 0 ? '' : $i),
......
......@@ -1703,7 +1703,7 @@ function subscribe_forum_submit(Pieform $form, $values) {
else {
$can_unsubscribe = true;
// Check if any UserRoles are in play
$checks = $USER->apply_userrole_method('interaction_unsubscribe', array('forum' => $values['forum'], 'userid' => $USER->get('id')));
$checks = $USER->apply_userrole_method('interaction_unsubscribe', array('forum' => $values['forum'], 'userid' => $USER->get('id'), 'institution' => get_field('group', 'institution', 'id', $values['group'])));
foreach ($checks as $check) {
if ($check['can_unsubscribe'] === false) {
// A UserRole is stopping us from unsubscribing
......
......@@ -36,9 +36,18 @@ function pieform_element_userlist(Pieform $form, $element) {
$members = get_records_select_assoc('usr','id IN (' . join(',',array_map('intval', $value)) . ')', null, $orderby, 'id,username,firstname,lastname,preferredname,staff');
foreach($members as &$member) {
$member = display_name($member);
$member->displayname = display_name($member);
if (!empty($element['allowuserrules']) && !empty($element['group'])) {
global $USER;
$institution = get_field('group', 'institution', 'id', $element['group']);
$checks = $USER->apply_userrole_method('group_leave', array('groupid' => $element['group'], 'userid' => $member->id, 'institution' => $institution));
foreach ($checks as $check) {
if ($check['can_leave'] === false) {
$member->disabled = true;
}
}
}
}
$smarty->assign('options',$members);
$smarty->assign('value', join(',',$value));
}
......
......@@ -494,7 +494,7 @@ function group_create($data) {
);
}
// Check if any UserRoles are in play
$USER->apply_userrole_method('group_join', array('groupid' => $id, 'ctime' => $data['ctime']));
$USER->apply_userrole_method('group_join', array('groupid' => $id, 'ctime' => $data['ctime'], 'institution' => $data['institution']));
// Copy views for the new group
$artefactcopies = array();
......@@ -1077,7 +1077,7 @@ function group_user_can_leave($group, $userid=null) {
}
// Check if any UserRoles are in play
$checks = $USER->apply_userrole_method('group_leave', array('groupid' => $group->id, 'userid' => $userid));
$checks = $USER->apply_userrole_method('group_leave', array('groupid' => $group->id, 'userid' => $userid, 'institution' => $group->institution));
foreach ($checks as $check) {
if ($check['can_leave'] === false) {
return ($result[$group->id][$userid] = false);
......@@ -1898,9 +1898,10 @@ function group_get_membersearch_data($results, $group, $query, $membershiptype,
$role = group_user_access($group);
$userid = $USER->get('id');
$institution = get_field('group', 'institution', 'id', $group);
foreach ($results['data'] as &$r) {
// Check if any UserRoles are in play
$checks = $USER->apply_userrole_method('group_leave', array('groupid' => $group, 'userid' => $r['id']));
$checks = $USER->apply_userrole_method('group_leave', array('groupid' => $group, 'userid' => $r['id'], 'institution' => $institution));
foreach ($checks as $check) {
if ($check['can_leave'] === false) {
continue 2;
......@@ -3268,7 +3269,7 @@ function get_group_access_roles() {
return $data;
}
function group_add_user_to_existing_groups($userid = null, $role = 'member') {
function group_add_user_to_existing_groups($userid = null, $role = 'member', $institution = 'all') {
global $USER;
if (empty($userid)) {
......@@ -3276,11 +3277,21 @@ function group_add_user_to_existing_groups($userid = null, $role = 'member') {
}
// Find all the non-deleted groups where the user is not present
// or is present but with a different group role
$where = array($userid, $role);
$wheresql = '';
if (is_array($institution)) {
$wheresql .= ' AND g.institution IN (' . join(',', array_map('db_quote', $institution)) . ')';
}
else if ($institution != 'all') {
$wheresql .= ' AND g.institution IN (?)';
$where[] = $institution;
}
if ($groups = get_records_sql_assoc("SELECT g.id, gm.* FROM {group} g
LEFT JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ?)
WHERE (gm.role IS NULL OR gm.role != ?)
AND g.deleted = 0
ORDER BY g.id", array($userid, $role))) {
" . $wheresql . "
ORDER BY g.id", $where)) {
foreach ($groups as $k => $group) {
if ($group->role) {
try {
......@@ -3306,17 +3317,27 @@ function group_add_user_to_existing_groups($userid = null, $role = 'member') {
$user->reset_grouproles();
}
function group_remove_user_from_existing_groups($userid = null) {
function group_remove_user_from_existing_groups($userid = null, $institution = 'all') {
global $USER;
if (empty($userid)) {
$userid = $USER->get('id');
}
// Find all the non-deleted groups where the user is present
$where = array($userid);
$wheresql = '';
if (is_array($institution)) {
$wheresql .= ' AND g.institution IN (' . join(',', array_map('db_quote', $institution)) . ')';
}
else if ($institution != 'all') {
$wheresql .= ' AND g.institution IN (?)';
$where[] = $institution;
}
if ($groups = get_records_sql_assoc("SELECT g.id, gm.* FROM {group} g
JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ?)
WHERE g.deleted = 0
ORDER BY g.id", array($userid))) {
" . $wheresql . "
ORDER BY g.id", $where)) {
foreach ($groups as $k => $group) {
try {
group_remove_user($k, $userid, true);
......
......@@ -166,7 +166,7 @@
{{if $righttitle}}<label class="h3" for="{{$name}}_members">{{$righttitle}}</label>{{/if}}
<select class="form-control" size="10" multiple="true" id="{{$name}}_members" style="width: 100%;"><option></option>
{{foreach from=$options key=id item=user}}
<option value="{{$id}}">{{$user}}</option>
<option {{if $user->disabled}}disabled="disabled"{{/if}} value="{{$id}}">{{$user->displayname}}</option>
{{/foreach}}
</select>
</td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment