From 5de592b1246c5de760c57eca8a7bfef62df95919 Mon Sep 17 00:00:00 2001 From: moodler Date: Wed, 16 Sep 2009 06:50:31 +0000 Subject: [PATCH] Checking in proposed new externallib.php for Petr to look at. --- user/externallib.php | 156 +++++++++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 66 deletions(-) diff --git a/user/externallib.php b/user/externallib.php index 9a8e4277c5..f36e585f71 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -28,93 +28,100 @@ require_once("$CFG->libdir/externallib.php"); class moodle_user_external extends external_api { - public static function get_users($params) { - $context = get_context_instance(CONTEXT_SYSTEM); - requier_capability('moodle/user:viewdetails', $context); - self::validate_context($context); - - $search = validate_param($params['search'], PARAM_RAW); - - //TODO: this search is probably useless for external systems because it is not exact - // 1/ we should specify multiple search parameters including the mnet host id - // 2/ custom profile fileds not inlcuded - - return get_users(true, $search, false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country'); - } - +/// Public descriptions of parameters and returned variables for validation and documentation + +/// Create_users + $userpreference = new object(); + $userpreference->name = array(PARAM_ALPHANUMEXT, 'The name of the preference to set'); + $userpreference->value = array(PARAM_RAW, 'The value of the preference'); + + $usercustomfields = new object(); + $usercustomfields->name = array(PARAM_ALPHANUMEXT, 'The name of the custom field (must exist)'); + $usercustomfields->value = array(PARAM_RAW, 'The value of the custom field'); + + $usertocreate = new object(); + $usertocreate->username = array(PARAM_USERNAME, 'Username policy is defined in Moodle security config', REQUIRED); + $usertocreate->password = array(PARAM_RAW, 'Moodle passwords can consist of any character', REQUIRED); + $usertocreate->firstname = array(PARAM_NOTAGS, 'The first name(s) of the user', REQUIRED); + $usertocreate->lastname = array(PARAM_NOTAGS, 'The family name of the user', REQUIRED); + $usertocreate->email = array(PARAM_EMAIL, 'A valid and unique email address', REQUIRED); + $usertocreate->auth = array(PARAM_AUTH, 'Auth plugins include manual, ldap, imap, etc'); + $usertocreate->confirmed = array(PARAM_NUMBER, 'Active user: 1 if confirmed, 0 otherwise'); + $usertocreate->idnumber = array(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution'); + $usertocreate->emailstop = array(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise'); + $usertocreate->lang = array(PARAM_LANG, 'Language code such as "en_utf8", must exist on server'); + $usertocreate->theme = array(PARAM_THEME, 'Theme name such as "standard", must exist on server'); + $usertocreate->timezone = array(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default'); + $usertocreate->mailformat = array(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc'); + $usertocreate->description = array(PARAM_TEXT, 'User profile description, as HTML'); + $usertocreate->city = array(PARAM_NOTAGS, 'Home city of the user'); + $usertocreate->country = array(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ'); + $usertocreate->preferences = array('multiple' => $userpreference); + $usertocreate->custom = array('multiple' -> $usercustomfields); + + $createusersparams = new object(); + $createusersparams->users = array('multiple' => $usertocreate); + + $createusersreturn = new object(); + $createusersreturn->userids = array('multiple' => PARAM_NUMBER); + + /* + * Create one or more users + * + * @param $params An array of users to create. Each user is defined by $usertocreate above. + * + * @return $return An array of userids, one for each user that was created + */ public static function create_users($params) { global $CFG, $DB; + // Ensure the current user is allowed to run this function $context = get_context_instance(CONTEXT_SYSTEM); - requier_capability('moodle/user:create', $context); + require_capability('moodle/user:create', $context); self::validate_context($context); - //TODO: this list is incomplete - we have preferences and custom fields too - $accepted = array( - 'password' => PARAM_RAW, - 'auth' => PARAM_SAFEDIR, - 'username' => PARAM_RAW, - 'idnumber' => PARAM_RAW, - 'firstname' => PARAM_CLEAN, - 'lastname' => PARAM_CLEAN, - 'email' => PARAM_EMAIL, - 'emailstop' => PARAM_BOOL, - 'lang' => PARAM_SAFEDIR, // validate using list of available langs - ignored if wrong - 'theme' => PARAM_SAFEDIR, - 'timezone' => PARAM_ALPHANUMEXT, - 'mailformat' => PARAM_ALPHA, - 'description' => PARAM_RAW, - 'city' => PARAM_CLEAN, - 'country' => PARAM_ALPHANUMEXT, - ); - - $required = array('username', 'firstname', 'lastname', 'email', 'password'); //TODO: password may not be required in some cases - $langs = get_list_of_languages(); - - // verify data first, only then start creating records + // Do basic automatic PARAM checks on incoming data, using params description + // This checks to make sure that: + // 1) No extra data was sent + // 2) All required items were sent + // 3) All data passes clean_param without changes (yes this is strict) + // If any problems are found then exceptions are thrown with helpful error messages + self::validate_params($params, $this->createuserparams); + + + // Perform further checks and build up a clean array of user data + // Nothing is actually performed until the whole dataset is checked $users = array(); - foreach ($params as $data) { - $user = array(); - foreach ($accepted as $key=>$type) { - if (array_key_exists($key, $data)) { - $user[$key] = validate_param($data[$key], $type); - unset($data[$key]); - } - } - if (!empty($data)) { - throw new invalid_parameter_exception('Unsupported parameters in user array'); - } - foreach ($required as $req) { - if (!array_key_exists($req, $user) or empty($user[$req])) { - throw new invalid_parameter_exception("$req is required in user array"); - } - } - if (!isset($user['auth'])) { + foreach ($params as $user) { + + // Empty or no auth is assumed to be manual + if (empty($user['auth'])) { $user['auth'] = 'manual'; } - if (!exists_auth_plugin($user['auth'])) { - throw new invalid_parameter_exception($user['auth']." is not valid authentication plugin"); - } - if (isset($user['lang']) and !isset($langs[$user['lang']])) { + // Lang must be a real code, not empty string + if (isset($user['lang']) && empty($user['lang'])) { unset($user['lang']); } - //TODO: add more param validations here: username, etc. - + // Make sure that the username doesn't already exist if ($DB->get_record('user', array('username'=>$user['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) { throw new invalid_parameter_exception($user['username']." username is already taken, sorry"); } + // Make sure that incoming data doesn't contain duplicate usernames if (isset($users[$user['username']])) { throw new invalid_parameter_exception("multiple users with the same username requested"); } - $users[$user['username']] = $user; + + // TODO: More checks here? + + $users[$user['username']] = $user; // Add this data to an array (mem overflows?) } $result = array(); - foreach ($users as $user) { + foreach ($users as $user) { // Actually create the user accounts now $record = create_user_record($user['username'], $user['password'], $user['auth']); unset($user['username']); unset($user['password']); @@ -126,8 +133,10 @@ class moodle_user_external extends external_api { } $DB->update_record('user', $record); - unset($record->password); // lets keep this as a secret ;-) - $result[$record->id] = $record; + $result[] = $record->id; + + // TODO: Save all the preferences and custom fields here + } return $result; @@ -142,4 +151,19 @@ class moodle_user_external extends external_api { public static function update_users($params) { //TODO } -} \ No newline at end of file + + public static function get_users($params) { + $context = get_context_instance(CONTEXT_SYSTEM); + require_capability('moodle/user:viewdetails', $context); + self::validate_context($context); + + $search = validate_param($params['search'], PARAM_RAW); + + //TODO: this search is probably useless for external systems because it is not exact + // 1/ we should specify multiple search parameters including the mnet host id + // 2/ custom profile fileds not inlcuded + + return get_users(true, $search, false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country'); + } + +} -- 2.39.5