MDL-55942 core_message: removed WS function core_user_update_user

This function was ignoring any capabilities and was only used to
update the preferences, but could be potentially used to update
any user attribute. A new WS function has been introduced to
handle user preferences with the necessary capability checks.
This commit is contained in:
Mark Nelson
2016-10-07 16:26:40 +08:00
parent ebf4e53209
commit c598f278ca
5 changed files with 88 additions and 147 deletions
+9 -9
View File
@@ -1025,15 +1025,6 @@ $functions = array(
'type' => 'write',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_user_update_user' => array(
'classname' => 'core_user_external',
'methodname' => 'update_user',
'classpath' => 'user/externallib.php',
'description' => 'Update logged in user',
'type' => 'write',
'capabilities' => 'moodle/user:update',
'ajax' => true,
),
'core_user_update_users' => array(
'classname' => 'core_user_external',
'methodname' => 'update_users',
@@ -1043,6 +1034,15 @@ $functions = array(
'capabilities' => 'moodle/user:update',
'ajax' => true,
),
'core_user_update_user_preferences' => array(
'classname' => 'core_user_external',
'methodname' => 'update_user_preferences',
'classpath' => 'user/externallib.php',
'description' => 'Update a user\'s preferences',
'type' => 'write',
'capabilities' => 'moodle/user:editownmessageprofile, moodle/user:editmessageprofile',
'ajax' => true,
),
'core_user_view_user_list' => array(
'classname' => 'core_user_external',
'methodname' => 'view_user_list',
+7 -9
View File
@@ -74,16 +74,14 @@ define(['jquery', 'core/ajax', 'core/notification',
container.addClass('loading');
var request = {
methodname: 'core_user_update_user',
methodname: 'core_user_update_user_preferences',
args: {
user: {
preferences: [
{
type: checkbox.attr('data-preference-key'),
value: ischecked ? 1 : 0,
}
]
}
preferences: [
{
type: checkbox.attr('data-preference-key'),
value: ischecked ? 1 : 0,
}
]
}
};
+12 -13
View File
@@ -158,22 +158,21 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p
}
var args = {
user: {
preferences: [
{
type: this.getLoggedInPreferenceKey(),
value: loggedInValue,
},
{
type: this.getLoggedOffPreferenceKey(),
value: loggedOffValue,
},
],
}
userid : this.userId,
preferences: [
{
type: this.getLoggedInPreferenceKey(),
value: loggedInValue,
},
{
type: this.getLoggedOffPreferenceKey(),
value: loggedOffValue,
},
],
};
var request = {
methodname: 'core_user_update_user',
methodname: 'core_user_update_user_preferences',
args: args,
};
@@ -98,11 +98,10 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/custom_interaction_eve
container.addClass('loading');
var request = {
methodname: 'core_user_update_user',
methodname: 'core_user_update_user_preferences',
args: {
user: {
emailstop: ischecked ? 1 : 0,
}
userid: this.userId,
emailstop: ischecked ? 1 : 0,
}
};
+57 -112
View File
@@ -323,140 +323,88 @@ class core_user_external extends external_api {
}
/**
* Returns description of method parameters
* Returns description of method parameters.
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function update_user_parameters() {
public static function update_user_preferences_parameters() {
return new external_function_parameters(
array(
'user' => new external_single_structure(
array(
'username' =>
new external_value(core_user::get_property_type('username'), 'Username policy is defined in Moodle security config.',
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
'password' =>
new external_value(core_user::get_property_type('password'), 'Plain text password consisting of any characters', VALUE_OPTIONAL,
'', NULL_NOT_ALLOWED),
'firstname' =>
new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'lastname' =>
new external_value(core_user::get_property_type('lastname'), 'The family name of the user', VALUE_OPTIONAL),
'email' =>
new external_value(core_user::get_property_type('email'), 'A valid and unique email address', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'emailstop' =>
new external_value(core_user::get_property_type('emailstop'), 'Enable or disable notifications for this user', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'auth' =>
new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, imap, etc', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'idnumber' =>
new external_value(core_user::get_property_type('idnumber'), 'An arbitrary ID code number perhaps from the institution',
VALUE_OPTIONAL),
'lang' =>
new external_value(core_user::get_property_type('lang'), 'Language code such as "en", must exist on server',
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
'calendartype' =>
new external_value(core_user::get_property_type('calendartype'), 'Calendar type such as "gregorian", must exist on server',
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
'theme' =>
new external_value(core_user::get_property_type('theme'), 'Theme name such as "standard", must exist on server',
VALUE_OPTIONAL),
'timezone' =>
new external_value(core_user::get_property_type('timezone'), 'Timezone code such as Australia/Perth, or 99 for default',
VALUE_OPTIONAL),
'mailformat' =>
new external_value(core_user::get_property_type('mailformat'), 'Mail format code is 0 for plain text, 1 for HTML etc',
VALUE_OPTIONAL),
'description' =>
new external_value(core_user::get_property_type('description'), 'User profile description, no HTML', VALUE_OPTIONAL),
'city' =>
new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_OPTIONAL),
'country' =>
new external_value(core_user::get_property_type('country'), 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
'firstnamephonetic' =>
new external_value(core_user::get_property_type('firstnamephonetic'), 'The first name(s) phonetically of the user', VALUE_OPTIONAL),
'lastnamephonetic' =>
new external_value(core_user::get_property_type('lastnamephonetic'), 'The family name phonetically of the user', VALUE_OPTIONAL),
'middlename' =>
new external_value(core_user::get_property_type('middlename'), 'The middle name of the user', VALUE_OPTIONAL),
'alternatename' =>
new external_value(core_user::get_property_type('alternatename'), 'The alternate name of the user', VALUE_OPTIONAL),
'customfields' => new external_multiple_structure(
new external_single_structure(
array(
'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
'value' => new external_value(PARAM_RAW, 'The value of the custom field')
)
), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
'preferences' => new external_multiple_structure(
new external_single_structure(
array(
'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'),
'value' => new external_value(PARAM_RAW, 'The value of the preference')
)
), 'User preferences', VALUE_OPTIONAL),
)
'userid' => new external_value(PARAM_INT, 'id of the user, default to current user', VALUE_DEFAULT, 0),
'emailstop' => new external_value(core_user::get_property_type('emailstop'),
'Enable or disable notifications for this user', VALUE_DEFAULT, null),
'preferences' => new external_multiple_structure(
new external_single_structure(
array(
'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'),
'value' => new external_value(PARAM_RAW, 'The value of the preference')
)
), 'User preferences', VALUE_DEFAULT, array()
)
)
);
}
/**
* Update the currently logged in user
* Update the user's preferences.
*
* @param array $users
* @param int $userid
* @param bool|null $emailstop
* @param array $preferences
* @return null
* @since Moodle 3.2
*/
public static function update_user($user) {
public static function update_user_preferences($userid, $emailstop = null, $preferences = array()) {
global $USER, $CFG;
global $USER, $CFG, $DB;
require_once($CFG->dirroot."/user/lib.php");
require_once($CFG->dirroot."/user/profile/lib.php"); // Required for customfields related function.
require_once($CFG->dirroot . '/user/lib.php');
$params = self::validate_parameters(
self::update_user_parameters(),
array('user' => $user)
);
$user = $params['user'];
$user['id'] = $USER->id;
$transaction = $DB->start_delegated_transaction();
user_update_user($user, true, false);
// Update user custom fields.
if (!empty($user['customfields'])) {
foreach ($user['customfields'] as $customfield) {
// Profile_save_data() saves profile file it's expecting a user with the correct id,
// and custom field to be named profile_field_"shortname".
$user["profile_field_".$customfield['type']] = $customfield['value'];
}
profile_save_data((object) $user);
if (empty($userid)) {
$userid = $USER->id;
}
// Trigger event.
\core\event\user_updated::create_from_userid($user['id'])->trigger();
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
$params = array(
'userid' => $userid,
'emailstop' => $emailstop,
'preferences' => $preferences
);
self::validate_parameters(self::update_user_preferences_parameters(), $params);
if ($userid == $USER->id) {
require_capability('moodle/user:editownmessageprofile', $systemcontext);
} else {
$personalcontext = context_user::instance($userid);
require_capability('moodle/user:editmessageprofile', $personalcontext);
// No editing of guest user account.
if (isguestuser($userid)) {
print_error('guestnoeditmessageother', 'message');
}
// No editing of admins by non-admins.
if (is_siteadmin($userid) and !is_siteadmin($USER)) {
print_error('useradmineditadmin');
}
}
// Preferences.
if (!empty($user['preferences'])) {
foreach ($user['preferences'] as $preference) {
set_user_preference($preference['type'], $preference['value'], $user['id']);
if (!empty($preferences)) {
foreach ($preferences as $preference) {
set_user_preference($preference['type'], $preference['value'], $userid);
}
}
$transaction->allow_commit();
// Check if they want to update the email.
if ($emailstop !== null) {
$user = new stdClass();
$user->id = $userid;
$user->emailstop = $emailstop;
user_update_user($user);
// Everything went well, update the $USER.
foreach ($user as $property => $value) {
// If the $USER knows about this value.
if (isset($USER, $property)) {
$USER->$property = $value;
// Update the $USER if we should.
if ($userid == $USER->id) {
$USER->emailstop = $emailstop;
}
}
@@ -469,7 +417,7 @@ class core_user_external extends external_api {
* @return null
* @since Moodle 3.2
*/
public static function update_user_returns() {
public static function update_user_preferences_returns() {
return null;
}
@@ -501,9 +449,6 @@ class core_user_external extends external_api {
'email' =>
new external_value(core_user::get_property_type('email'), 'A valid and unique email address', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'emailstop' =>
new external_value(core_user::get_property_type('emailstop'), 'Enable or disable notifications for this user', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),
'auth' =>
new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, imap, etc', VALUE_OPTIONAL, '',
NULL_NOT_ALLOWED),