array( 'retrieve' => array( 'help' => 'Retrieves a user', 'callback' => '_user_resource_retrieve', 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'access callback' => '_user_resource_access', 'access arguments' => array('view'), 'access arguments append' => TRUE, 'args' => array( array( 'name' => 'uid', 'type' => 'int', 'description' => 'The uid of the user to retrieve.', 'source' => array('path' => '0'), 'optional' => FALSE, ), ), ), 'create' => array( 'help' => 'Creates a user', 'callback' => '_user_resource_create', 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'access callback' => '_user_resource_access', 'access arguments' => array('create'), 'access arguments append' => FALSE, 'args' => array( array( 'name' => 'account', 'type' => 'struct', 'description' => 'The user object', 'source' => 'data', 'optional' => FALSE, ), ), ), 'update' => array( 'help' => 'Updates a user', 'callback' => '_user_resource_update', 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'access callback' => '_user_resource_access', 'access arguments' => array('update'), 'access arguments append' => TRUE, 'args' => array( array( 'name' => 'uid', 'type' => 'int', 'description' => 'Unique identifier for this user', 'source' => array('path' => 0), 'optional' => FALSE, ), array( 'name' => 'data', 'type' => 'struct', 'description' => 'The user object with updated information', 'source' => 'data', 'optional' => FALSE, ), ), ), 'delete' => array( 'help' => 'Deletes a user', 'callback' => '_user_resource_delete', 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'access callback' => '_user_resource_access', 'access arguments' => array('delete'), 'access arguments append' => TRUE, 'args' => array( array( 'name' => 'nid', 'type' => 'int', 'description' => 'The id of the note to delete', 'source' => array('path' => '0'), 'optional' => FALSE, ), ), ), 'index' => array( 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'callback' => '_user_resource_index', 'args' => array( array( 'name' => 'page', 'optional' => TRUE, 'type' => 'int', 'description' => 'The zero-based index of the page to get, defaults to 0.', 'default value' => 1, 'source' => array('param' => 'page'), ), array( 'name' => 'fields', 'optional' => TRUE, 'type' => 'string', 'description' => 'The fields to get.', 'default value' => '*', 'source' => array('param' => 'fields'), ), array( 'name' => 'parameters', 'optional' => TRUE, 'type' => 'struct', 'description' => 'Parameters', 'default value' => NULL, 'source' => array('param' => 'parameters'), ), ), 'access arguments' => array('access user profiles'), 'access arguments append' => FALSE, ), 'actions' => array( 'login' => array( 'help' => 'Login a user for a new session', 'callback' => '_user_resource_login', 'args' => array( array( 'name' => 'username', 'type' => 'string', 'description' => 'A valid username', 'source' => 'data', 'optional' => FALSE, ), array( 'name' => 'password', 'type' => 'string', 'description' => 'A valid password', 'source' => 'data', 'optional' => FALSE, ), ), 'access callback' => 'services_access_menu', 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), ), 'logout' => array( 'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'), 'help' => 'Logout a user session', 'callback' => '_user_resource_logout', 'access callback' => 'services_access_menu', ), ), ), ); } /** * Get user details. * * @param $uid * UID of the user to be loaded. * * @return * A user object. * * @see user_load() */ function _user_resource_retrieve($uid) { $account = user_load($uid); if (empty($account)) { return services_error(t('There is no user with such ID.'), 404); } // Everything went right. return $account; } /** * Create a new user. * * This function uses drupal_execute() and as such exepects all input to match * the submitting form in question. * * @param $account * A object containing account information. The $account object should * contain, at minimum, the following properties: * - name (user name) * - mail (email address) * - pass (plain text unencrypted password) * * These properties can be passed but are optional * - status (0 for blocked, otherwise will be active by default) * - notify (1 to notify user of new account, will not notify by default) * * Roles can be passed in a roles property which is an associative * array formatted with '' => '', not including * the authenticated user role, which is given by default. * * @return * The user object of the newly created user. */ function _user_resource_create($account) { // Load the required includes for saving profile information // with drupal_execute(). module_load_include('inc', 'user', 'user.pages'); // Any logged in user is by default authenticated, // and leaving this role set in the user's roles array // causes big problems because of a FAPI hack that controls // this checkbox on the user create and edit form (and thus // causes problems with drupal_execute()). Therefore we just // force it to 0 here. if (isset($account->roles[2])) { $account->roles[2] = 0; } // register a new user $form_state['values'] = (array) $account; $form_state['values']['pass'] = array( 'pass1' => $account->pass, 'pass2' => $account->pass, ); $form_state['values']['op'] = t('Create new account'); $ret = drupal_form_submit('user_register_form', $form_state); // Error if needed. if ($errors = form_get_errors()) { return services_error(implode(" ", $errors), 406); } else { $user = array('uid' => $form_state['user']->uid); if ($uri = services_resource_uri(array('user', $user['uid']))) { $user['uri'] = $uri; } return $user; } } /** * Update an existing user. * * This function uses drupal_execute() and as such exepects all input to match * the submitting form in question. * * @param $uid * Unique identifier for this user * @param $account * Fields to modify for this user. * * @return * The modified user object. */ function _user_resource_update($uid, $account) { $account->uid = $uid; // Load the required includes for saving profile information // with drupal_execute(). module_load_include('inc', 'user', 'user.pages'); // Any logged in user is by default authenticated, // and leaving this role set in the user's roles array // causes big problems because of a FAPI hack that controls // this checkbox on the user create and edit form (and thus // causes problems with drupal_execute()). Therefore we just // force it to 0 here. if (isset($account->roles[2])) { $account->roles[2] = 0; } // If a profile category was passed in, use it. Otherwise default // to 'account' (for saving core user data.) $category = 'account'; if (isset($account->category)) { $category = $account->category; unset($account->category); } // Drop any passed in values into the $account var. Anything // unused by the form just gets ignored. foreach ($account as $key => $value) { $form_state['values'][$key] = $value; } if(!isset($account->pass1) && !isset($account->pass2)) { $account->pass1 = $account->pass; $account->pass2 = $account->pass; } $form_state['values']['op'] = 'Save'; $form_state['values']['pass']['pass1'] = $account->pass1; $form_state['values']['pass']['pass2'] = $account->pass1; $form_state['values']['#user_category'] = $category; $form_state['values']['#account'] = (object)$account; $ret = drupal_form_submit('user_profile_form', $form_state, $account, $category); // Error if needed. if ($errors = form_get_errors()) { return services_error(implode(" ", $errors), 406); } else { return $account; } } /** * Delete a user. * * @param $uid * UID of the user to be deleted. * * @see user_delete() */ function _user_resource_delete($uid) { $account = user_load($uid); if (empty($account)) { return services_error(t('There is no user with such ID.'), 404); } user_delete($uid); // Everything went right. return TRUE; } /** * Login a user using the specified credentials. * * Note this will transfer a plaintext password. * * @param $username * Username to be logged in. * @param $password * Password, must be plain text and not hashed. * * @return * A valid session object. */ function _user_resource_login($username, $password) { global $user; if ($user->uid) { // user is already logged in return services_error(t('Already logged in as !user.', array('!user' => $user->name)), 406); } $user = user_load(user_authenticate($username, $password)); if ($user->uid) { // Regenerate the session ID to prevent against session fixation attacks. drupal_session_regenerate(); module_invoke_all('user', 'login', NULL, $user); $return = new stdClass(); $return->sessid = session_id(); $return->session_name = session_name(); $return->user = $user; return $return; } session_destroy(); watchdog('user', 'Invalid login attempt.', array('%name' => theme('placeholder', $user->name))); return services_error(t('Wrong username or password.'), 401); } /** * Logout the current user. */ function _user_resource_logout() { global $user; if (!$user->uid) { // User is not logged in return services_error(t('User is not logged in.'), 406); } watchdog('user', 'Session closed for %name.', array('%name' => theme('placeholder', $user->name))); // Destroy the current session: session_destroy(); module_invoke_all('user', 'logout', NULL, $user); // Load the anonymous user $user = drupal_anonymous_user(); return TRUE; } /** * Return an array of optionally paged nids baed on a set of criteria. * * An example request might look like * * http://domain/endpoint/user?fields=uid,name,mail¶meters[uid]=1 * * This would return an array of objects with only uid, name and mail defined, * where uid = 1. * * @param $page * Page number of results to return (in pages of 20). * @param $fields * The fields you want returned. * @param $parameters * An array of fields and values used to build a sql WHERE clause indicating * what items should be deleted. * @return * An array of user objects. * * @see _node_resource_index() for more notes **/ function _user_resource_index($page = 1, $fields = '*', $parameters = array()) { $user_select = db_select('users', 'u')->extend('PagerDefault'); if($fields == '*') { $user_select->fields('u'); } else { $fields = explode(',', $fields); $user_select->fields('u', $fields); } $user_select->orderBy('created', 'DESC'); $user_select->limit($page * 20); $result = $user_select->execute(); foreach($result as $user) { if ($uri = services_resource_uri(array('user', $user->uid))) { $user->uri = $uri; } $users[] = $user; } return $users; } /** * Access check callback for user resource. */ function _user_resource_access($op = 'view', $args = array()) { global $user; switch($op) { case 'view': $account = user_load($args[0]); if(!$account->uid) { return services_error('That user ID does not exist', 406); } return user_view_access($account); case 'update': $account = user_load($args[1]->uid); if(!$account->uid) { return services_error('That user ID does not exist', 406); } return ($user->uid == $account->uid || user_access('administer users')); case 'create': return user_access('administer users'); case 'delete': $account = user_load($args[0]); if(!$account->uid) { return services_error('That user ID does not exist', 406); } return user_access('administer users'); } }