Commit dbe457ba authored by Robert Lyon's avatar Robert Lyon Committed by Gerrit Code Review
Browse files

Separation of the functions (Bug #1393621)



Allowing each of the 'classname' classes listed in external_functions
to be it's own function file to make it easier for developers.

Change-Id: I9c4e3dfc198abdf2c274c8a7d569fce5bf431471
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent f28e81b4
<?php
/**
*
* @package mahara
* @subpackage auth-webservice
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
/**
* External user API
*
* @package auth
* @subpackage webservice
* @copyright 2009 Moodle Pty Ltd (http://moodle.com)
* @copyright Copyright (C) 2011 Catalyst IT Ltd (http://www.catalyst.net.nz)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Piers Harding
*/
require_once(get_config('docroot') . 'webservice/lib.php');
require_once(get_config('docroot') . 'webservice/rest/locallib.php');
require_once(get_config('docroot') . 'lib/user.php');
require_once(get_config('docroot') . 'lib/group.php');
require_once(get_config('docroot') . 'lib/institution.php');
require_once(get_config('docroot') . 'lib/searchlib.php');
global $WEBSERVICE_OAUTH_USER;
/**
* Class container for core Mahara group related API calls
*/
class mahara_group_external extends external_api {
// possible membership roles
private static $member_roles = array('admin', 'tutor', 'member');
/**
* parameter definition for input of create_groups method
*
* Returns description of method parameters
* @return external_function_parameters
*/
public static function create_groups_parameters() {
$group_types = group_get_grouptypes();
$group_edit_roles = array_keys(group_get_editroles_options());
return new external_function_parameters(
array(
'groups' => new external_multiple_structure(
new external_single_structure(
array(
'name' => new external_value(PARAM_RAW, 'Group name'),
'shortname' => new external_value(PARAM_RAW, 'Group shortname for API only controlled groups', VALUE_OPTIONAL),
'description' => new external_value(PARAM_NOTAGS, 'Group description'),
'institution' => new external_value(PARAM_TEXT, 'Mahara institution - required for API controlled groups', VALUE_OPTIONAL),
'grouptype' => new external_value(PARAM_ALPHANUMEXT, 'Group type: ' . implode(',', $group_types)),
'category' => new external_value(PARAM_TEXT, 'Group category - the title of an existing group category', VALUE_OPTIONAL),
'editroles' => new external_value(PARAM_ALPHANUMEXT, 'Edit roles allowed: ' . implode(',', $group_edit_roles), VALUE_OPTIONAL),
'open' => new external_value(PARAM_INTEGER, 'Boolean 1/0 open - Users can join the group without approval from group administrators', VALUE_DEFAULT, '0'),
'controlled' => new external_value(PARAM_INTEGER, 'Boolean 1/0 controlled - Group administrators can add users to the group without their consent, and members cannot choose to leave', VALUE_DEFAULT, '0'),
'request' => new external_value(PARAM_INTEGER, 'Boolean 1/0 request - Users can send membership requests to group administrators', VALUE_DEFAULT, '0'),
'submitpages' => new external_value(PARAM_INTEGER, 'Boolean 1/0 submitpages - Members can submit pages to the group', VALUE_DEFAULT),
'public' => new external_value(PARAM_INTEGER, 'Boolean 1/0 public group', VALUE_DEFAULT),
'viewnotify' => new external_value(PARAM_INTEGER, 'Boolean 1/0 for Shared page notifications', VALUE_DEFAULT),
'usersautoadded' => new external_value(PARAM_INTEGER, 'Boolean 1/0 for auto-adding users', VALUE_DEFAULT),
'members' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'member user Id', VALUE_OPTIONAL),
'username' => new external_value(PARAM_RAW, 'member username', VALUE_OPTIONAL),
'role' => new external_value(PARAM_ALPHANUMEXT, 'member role: ' . implode(', ', self::$member_roles))
), 'Group membership')
),
)
)
)
)
);
}
/**
* Create one or more group
*
* @param array $groups An array of groups to create.
* @return array An array of arrays
*/
public static function create_groups($groups) {
global $USER, $WEBSERVICE_INSTITUTION;
// Do basic automatic PARAM checks on incoming data, using params description
$params = self::validate_parameters(self::create_groups_parameters(), array('groups' => $groups));
db_begin();
$groupids = array();
foreach ($params['groups'] as $group) {
// Make sure that the group doesn't already exist
if (!empty($group['name'])) {
// don't checked deleted as the real function doesn't
if (get_record('group', 'name', $group['name'])) {
throw new WebserviceInvalidParameterException(get_string('groupexists', 'auth.webservice', $group['name']));
}
}
// special API controlled group creations
else if (isset($group['shortname']) && strlen($group['shortname'])) {
// check the institution is allowed
if (isset($group['institution']) && strlen($group['institution'])) {
if ($WEBSERVICE_INSTITUTION != $group['institution']) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['name']));
}
if (!$USER->can_edit_institution($group['institution'])) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['name']));
}
}
else {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('instmustbeongroup', 'auth.webservice', $group['name'] . '/' . $group['shortname']));
}
// does the group exist?
if (get_record('group', 'shortname', $group['shortname'], 'institution', $group['institution'])) {
throw new WebserviceInvalidParameterException(get_string('groupexists', 'auth.webservice', $group['shortname']));
}
}
else {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('noname', 'auth.webservice'));
}
// convert the category
if (!empty($group['category'])) {
$groupcategory = get_record('group_category','title', $group['category']);
if (empty($groupcategory)) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('catinvalid', 'auth.webservice', $group['category']));
}
$group['category'] = $groupcategory->id;
}
// validate the join type combinations
if ($group['open'] && $group['request']) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('invalidjointype', 'auth.webservice', 'open+request'));
}
if ($group['open'] && $group['controlled']) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('invalidjointype', 'auth.webservice', 'open+controlled'));
}
if (!$group['open'] && !$group['request'] && !$group['controlled']) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('correctjointype', 'auth.webservice'));
}
if (isset($group['editroles']) && !in_array($group['editroles'], array_keys(group_get_editroles_options()))) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('groupeditroles', 'auth.webservice', $group['editroles'], implode(', ', array_keys(group_get_editroles_options()))));
}
// check that the members exist and we are allowed to administer them
$members = array($USER->get('id') => 'admin');
foreach ($group['members'] as $member) {
if (!empty($member['id'])) {
$dbuser = get_record('usr', 'id', $member['id'], 'deleted', 0);
}
else if (!empty($member['username'])) {
$dbuser = get_record('usr', 'username', $member['username'], 'deleted', 0);
}
else {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('nousernameoridgroup', 'auth.webservice', $group['name']));
}
if (empty($dbuser)) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('invalidusergroup', 'auth.webservice', $member['id'] . '/' . $member['username'], $group['name']));
}
// check user is in this institution if this is an institution controlled group
if ((isset($group['shortname']) && strlen($group['shortname'])) && (isset($group['institution']) && strlen($group['institution']))) {
if (!mahara_external_in_institution($dbuser, $WEBSERVICE_INSTITUTION)) {
throw new WebserviceInvalidParameterException(get_string('notauthforuseridinstitutiongroup', 'auth.webservice', $dbuser->id, $WEBSERVICE_INSTITUTION, $group['shortname']));
}
}
else {
// Make sure auth is valid
if (!$authinstance = get_record('auth_instance', 'id', $dbuser->authinstance)) {
throw new WebserviceInvalidParameterException(get_string('invalidauthtype', 'auth.webservice', $dbuser->authinstance));
}
// check the institution is allowed
// basic check authorisation to edit for the current institution of the user
if (!$USER->can_edit_institution($authinstance->institution)) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('accessdeniedforinstuser', 'auth.webservice', $authinstance->institution, $dbuser->username));
}
}
// check the specified role
if (!in_array($member['role'], self::$member_roles)) {
throw new WebserviceInvalidParameterException('create_groups | ' . get_string('invalidmemroles', 'auth.webservice', $member['role'], $dbuser->username));
}
$members[$dbuser->id]= $member['role'];
}
// set the basic elements
$create = array(
'shortname' => (isset($group['shortname']) ? $group['shortname'] : null),
'name' => (isset($group['name']) ? $group['name'] : null),
'description' => $group['description'],
'institution' => (isset($group['institution']) ? $group['institution'] : null),
'grouptype' => $group['grouptype'],
'members' => $members,
);
// check for the rest
foreach (array('category', 'open', 'controlled', 'request', 'submitpages', 'editroles',
'hidemembers', 'invitefriends', 'suggestfriends', 'hidden', 'quota',
'hidemembersfrommembers', 'public', 'usersautoadded', 'viewnotify',) as $attr) {
if (isset($group[$attr]) && $group[$attr] !== false && $group[$attr] !== null && strlen("" . $group[$attr])) {
$create[$attr] = $group[$attr];
}
}
// create the group
$id = group_create($create);
$groupids[] = array('id'=> $id, 'name'=> $group['name']);
}
db_commit();
return $groupids;
}
/**
* parameter definition for output of create_groups method
*
* Returns description of method result value
* @return external_description
*/
public static function create_groups_returns() {
return new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'group id'),
'name' => new external_value(PARAM_RAW, 'group name'),
)
)
);
}
/**
* parameter definition for input of delete_groups method
*
* Returns description of method parameters
* @return external_function_parameters
*/
public static function delete_groups_parameters() {
return new external_function_parameters(
array(
'groups' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'ID of the group', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'Group name', VALUE_OPTIONAL),
'shortname' => new external_value(PARAM_RAW, 'Group shortname for API only controlled groups', VALUE_OPTIONAL),
'institution' => new external_value(PARAM_TEXT, 'Mahara institution - required for API controlled groups', VALUE_OPTIONAL),
)
)
)
)
);
}
/**
* Delete one or more groups
*
* @param array $groups
*/
public static function delete_groups($groups) {
global $USER, $WEBSERVICE_INSTITUTION;
$params = self::validate_parameters(self::delete_groups_parameters(), array('groups'=>$groups));
db_begin();
foreach ($params['groups'] as $group) {
// Make sure that the group doesn't already exist
if (!empty($group['id'])) {
if (!$dbgroup = get_record('group', 'id', $group['id'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['id']));
}
}
else if (!empty($group['name'])) {
if (!$dbgroup = get_record('group', 'name', $group['name'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['name']));
}
}
else if (!empty($group['shortname'])) {
if (empty($group['institution'])) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('instmustset', 'auth.webservice', $group['shortname']));
}
if (!$dbgroup = get_record('group', 'shortname', $group['shortname'], 'institution', $group['institution'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['shortname'] . '/' . $group['institution']));
}
}
else {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('nogroup', 'auth.webservice'));
}
// are we allowed to delete for this institution
if (!empty($dbgroup->institution)) {
if ($WEBSERVICE_INSTITUTION != $dbgroup->institution) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['name']));
}
if (!$USER->can_edit_institution($dbgroup->institution)) {
throw new WebserviceInvalidParameterException('delete_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['shortname']));
}
}
// now do the delete
group_delete($dbgroup->id);
}
db_commit();
return null;
}
/**
* parameter definition for output of delete_groups method
*
* Returns description of method result value
* @return external_description
*/
public static function delete_groups_returns() {
return null;
}
/**
* parameter definition for input of update_groups method
*
* Returns description of method parameters
* @return external_function_parameters
*/
public static function update_groups_parameters() {
$group_types = group_get_grouptypes();
$group_edit_roles = array_keys(group_get_editroles_options());
return new external_function_parameters(
array(
'groups' =>
new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'ID of the group', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'Group name', VALUE_OPTIONAL),
'shortname' => new external_value(PARAM_RAW, 'Group shortname for API only controlled groups', VALUE_OPTIONAL),
'description' => new external_value(PARAM_NOTAGS, 'Group description'),
'institution' => new external_value(PARAM_TEXT, 'Mahara institution - required for API controlled groups', VALUE_OPTIONAL),
'grouptype' => new external_value(PARAM_ALPHANUMEXT, 'Group type: ' . implode(',', $group_types), VALUE_OPTIONAL),
'category' => new external_value(PARAM_TEXT, 'Group category - the title of an existing group category', VALUE_OPTIONAL),
'editroles' => new external_value(PARAM_ALPHANUMEXT, 'Edit roles allowed: ' . implode(',', $group_edit_roles), VALUE_OPTIONAL),
'open' => new external_value(PARAM_INTEGER, 'Boolean 1/0 open - Users can join the group without approval from group administrators', VALUE_DEFAULT),
'controlled' => new external_value(PARAM_INTEGER, 'Boolean 1/0 controlled - Group administrators can add users to the group without their consent, and members cannot choose to leave', VALUE_DEFAULT),
'request' => new external_value(PARAM_INTEGER, 'Boolean 1/0 request - Users can send membership requests to group administrators', VALUE_DEFAULT),
'submitpages' => new external_value(PARAM_INTEGER, 'Boolean 1/0 submitpages - Members can submit pages to the group', VALUE_DEFAULT),
'public' => new external_value(PARAM_INTEGER, 'Boolean 1/0 public group', VALUE_DEFAULT),
'viewnotify' => new external_value(PARAM_INTEGER, 'Boolean 1/0 for Shared page notifications', VALUE_DEFAULT),
'usersautoadded' => new external_value(PARAM_INTEGER, 'Boolean 1/0 for auto-adding users', VALUE_DEFAULT),
'members' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'member user Id', VALUE_OPTIONAL),
'username' => new external_value(PARAM_RAW, 'member username', VALUE_OPTIONAL),
'role' => new external_value(PARAM_ALPHANUMEXT, 'member role: ' . implode(', ', self::$member_roles))
), 'Group membership')
),
)
)
)
)
);
}
/**
* update one or more users
*
* @param array $users
*/
public static function update_groups($groups) {
global $USER, $WEBSERVICE_INSTITUTION;
// Do basic automatic PARAM checks on incoming data, using params description
$params = self::validate_parameters(self::update_groups_parameters(), array('groups'=>$groups));
db_begin();
$groupids = array();
foreach ($params['groups'] as $group) {
// Make sure that the group doesn't already exist
if (!empty($group['id'])) {
if (!$dbgroup = get_record('group', 'id', $group['id'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['id']));
}
}
else if (!empty($group['shortname'])) {
if (empty($group['institution'])) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('instmustset', 'auth.webservice', $group['shortname']));
}
if (!$dbgroup = get_record('group', 'shortname', $group['shortname'], 'institution', $group['institution'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['shortname'] . '/' . $group['institution']));
}
}
else if (!empty($group['name'])) {
if (!$dbgroup = get_record('group', 'name', $group['name'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('groupnotexist', 'auth.webservice', $group['name']));
}
}
else {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('nogroup', 'auth.webservice'));
}
// are we allowed to delete for this institution
if ($WEBSERVICE_INSTITUTION != $dbgroup->institution) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['name']));
}
if (!$USER->can_edit_institution($dbgroup->institution)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('accessdeniedforinstgroup', 'auth.webservice', $group['institution'], $group['shortname']));
}
// convert the category
if (!empty($group['category'])) {
$groupcategory = get_record('group_category','title', $group['category']);
if (empty($groupcategory)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('catinvalid', 'auth.webservice', $group['category']));
}
$group['category'] = $groupcategory->id;
}
// validate the join type combinations
if (isset($group['open']) || isset($group['request']) || isset($group['controlled'])) {
foreach (array('open', 'request', 'controlled') as $membertype) {
if (!isset($group[$membertype]) || empty($group[$membertype])) {
$group[$membertype] = 0;
}
}
if ($group['open'] && $group['request']) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('invalidjointype', 'auth.webservice', 'open+request'));
}
if ($group['open'] && $group['controlled']) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('invalidjointype', 'auth.webservice', 'open+controlled'));
}
if (!$group['open'] && !$group['request'] && !$group['controlled']) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('correctjointype', 'auth.webservice'));
}
}
if (isset($group['editroles']) && !in_array($group['editroles'], array_keys(group_get_editroles_options()))) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('groupeditroles', 'auth.webservice', $group['editroles'], implode(', ', array_keys(group_get_editroles_options()))));
}
// check that the members exist and we are allowed to administer them
$members = array($USER->get('id') => 'admin');
foreach ($group['members'] as $member) {
if (!empty($member['id'])) {
$dbuser = get_record('usr', 'id', $member['id'], 'deleted', 0);
}
else if (!empty($member['username'])) {
$dbuser = get_record('usr', 'username', $member['username'], 'deleted', 0);
}
else {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('nousernameoridgroup', 'auth.webservice', $group['name']));
}
if (empty($dbuser)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('invalidusergroup', 'auth.webservice', $member['id'] . '/' . $member['username'], $group['name']));
}
// check user is in this institution if this is an institution controlled group
if (!empty($dbgroup->shortname) && !empty($dbgroup->institution)) {
if (!mahara_external_in_institution($dbuser, $WEBSERVICE_INSTITUTION)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('notauthforuseridinstitutiongroup', 'auth.webservice', $dbuser->id, $WEBSERVICE_INSTITUTION, $group['shortname']));
}
}
else {
// Make sure auth is valid
if (!$authinstance = get_record('auth_instance', 'id', $dbuser->authinstance)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('invalidauthtype', 'auth.webservice', $dbuser->authinstance));
}
// check the institution is allowed
// basic check authorisation to edit for the current institution of the user
if (!$USER->can_edit_institution($authinstance->institution)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('accessdeniedforinstuser', 'auth.webservice', $authinstance->institution, $dbuser->username));
}
}
// check the specified role
if (!in_array($member['role'], self::$member_roles)) {
throw new WebserviceInvalidParameterException('update_groups | ' . get_string('invalidmemroles', 'auth.webservice', $member['role'], $dbuser->username));
}
$members[$dbuser->id] = $member['role'];
}
// build up the changes
// not allowed to change these
$newvalues = (object) array('id' => $dbgroup->id,);
foreach (array('name', 'description', 'grouptype', 'category', 'editroles',
'open', 'controlled', 'request', 'submitpages', 'quota',
'hidemembers', 'invitefriends', 'suggestfriends',
'hidden', 'hidemembersfrommembers',
'usersautoadded', 'public', 'viewnotify') as $attr) {
if (isset($group[$attr]) && $group[$attr] !== false && $group[$attr] !== null && strlen("" . $group[$attr])) {
$newvalues->{$attr} = $group[$attr];
}
}
group_update($newvalues);
// now update the group membership
group_update_members($dbgroup->id, $members);
}
db_commit();
return null;
}
/**
* parameter definition for output of update_groups method
*
* Returns description of method result value
* @return external_description
*/
public static function update_groups_returns() {
return null;
}
/**
* parameter definition for input of update_group_members method
*
* Returns description of method parameters
* @return external_function_parameters
*/
public static function update_group_members_parameters() {
return new external_function_parameters(
array(
'groups' =>
new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'ID of the group', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'Group name', VALUE_OPTIONAL),
'shortname' => new external_value(PARAM_RAW, 'Group shortname for API only controlled groups', VALUE_OPTIONAL),
'institution' => new external_value(PARAM_TEXT, 'Mahara institution - required for API controlled groups', VALUE_OPTIONAL),
'members' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_NUMBER, 'member user Id', VALUE_OPTIONAL),
'username' => new external_value(PARAM_RAW, 'member username', VALUE_OPTIONAL),
'role' => new external_value(PARAM_ALPHANUMEXT, 'member role: admin, tutor, member', VALUE_OPTIONAL),
'action' => new external_value(PARAM_ALPHANUMEXT, 'member action: add, or remove')
), 'Group membership actions')
),
)
)
)
)
);
}
/**
* update one or more sets of group membership
*
* @param array $users
*/
public static function update_group_members($groups) {
global $USER, $WEBSERVICE_INSTITUTION;
// Do basic automatic PARAM checks on incoming data, using params description
$params = self::validate_parameters(self::update_group_members_parameters(), array('groups'=>$groups));
db_begin();
$groupids = array();
foreach ($params['groups'] as $group) {
// Make sure that the group doesn't already exist
if (!empty($group['id'])) {
if (!$dbgroup = get_record('group', 'id', $group['id'], 'deleted', 0)) {
throw new WebserviceInvalidParameterException('update_group_members | ' . get_string('groupnotexist', 'auth.webservice', $group['id']));
}