fields(array( 'pass' => "ZZZservices_security", )) ->condition('created', 1377892483, '>=') ->execute(); drupal_set_message($result . ' users were updated'); } function services_security_user_update_finished($success, $results, $operations) { if ($success) { drupal_set_message(t('@count users passwords were reset.', array('@count' => count($results)))); services_security_user_update_finish(); } else { $error_operation = reset($operations); drupal_set_message( t('An error occurred while processing @operation with arguments : @args', array( '@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE), ) ) ); } } /** * Executes final tasks at the end of the security update follow up. */ function services_security_user_update_finish() { drupal_set_message('Services security update follow up is complete.'); variable_set('services_security_update_1', TRUE); if (!drupal_is_cli()) { drupal_goto('admin/reports/status'); } } function services_security_update_reset_users_with_password_one() { $users = array(); // Query the database to get all user ID $query = db_select('users', 'u') ->fields('u', array('uid')); $users = $query->execute()->fetchAll(); $num_of_users = count($users); $progress = 0; // where to start $limit = variable_get('services_security_reset_limit_per_batch', 10); // how many to process for each run $max = $num_of_users; // how many records to process until stop //Set up our batch operations while ($progress < $max) { $operations[] = array('services_security_update_reset_users_with_password_one_op', array($progress, $limit, $max)); $progress = $progress + $limit; } // build the batch instructions $batch = array( 'operations' => $operations, 'finished' => 'services_security_user_update_finished', 'file' => drupal_get_path('module', 'services') . '/services.admin.inc', 'progress_message' => t('Processed batch #@current out of @total.'), ); return $batch; } function services_security_update_reset_users_with_password_one_op($progress, $limit, $max, &$context) { //Set default starting values if (empty($context['sandbox'])) { $context['sandbox'] = array(); $context['sandbox']['progress'] = 0; $context['sandbox']['current_user'] = 0; $context['sandbox']['max'] = $limit; } //required for user_check_password require_once('./includes/password.inc'); //Set the password we are looking for. $password = "1"; //Fetch all users in our current range. $result = db_select('users', 'u') ->fields('u', array('uid', 'pass',)) ->orderBy('u.uid', 'ASC') ->range($progress, $limit) ->execute() ->fetchAll(); // Loop through our ranged results and check their password. foreach ($result as $row) { $uid = $row->uid; $pass = $row->pass; //Setup account object, much faster than user_load $account = new stdClass(); $account->uid = $uid; $account->pass = $pass; // Check the current user's password against the password. if (user_check_password($password, $account)) { // This means we have a matched password. // Process the user $updated_user = db_update('users') ->fields(array( 'pass' => "ZZZservices_security", )) ->condition('uid', $uid) ->execute(); $context['results'][] = 'Updating user uid: '. $uid; } // Update our progress information. $context['sandbox']['progress']++; $context['sandbox']['current_user'] = $uid; // update progress for message $shown_progress = $progress + $limit; // update message during each run so you know where you are in the process $context['message'] = 'Checking user uid: '. $uid; } // Inform the batch engine that we are not finished, // and provide an estimation of the completion level we reached. if ($context['sandbox']['progress'] != $context['sandbox']['max']) { $context['finished'] = (($context['sandbox']['max'] - $context['sandbox']['progress']) <= $limit) || ($context['sandbox']['progress'] >= $context['sandbox']['max']); } } /** * Implements hook_help(). */ function services_help($path, $arg) { $output = NULL; switch ($path) { case 'admin/help#services': $output = '
' . t('Visit the Services Handbook for help and information.', array('@handbook_url' => 'http://drupal.org/node/109782')) . '
'; break; case 'admin/structure/services': $output = '' . t('Services are collections of methods available to remote applications. They are defined in modules, and may be accessed in a number of ways through server modules. Visit the Services Handbook for help and information.', array('@handbook_url' => 'http://drupal.org/node/109782')) . '
'; $output .= '' . t('All enabled services and methods are shown. Click on any method to view information or test.') . '
'; break; } return $output; } /** * Implements hook_perm(). */ function services_permission() { return array( 'administer services' => array( 'title' => t('Administer services'), 'description' => t('Configure and setup services module.'), ), // File resource permissions 'get any binary files' => array( 'title' => t('Get any binary files'), 'description' => t(''), ), 'get own binary files' => array( 'title' => t('Get own binary files'), 'description' => t(''), ), 'save file information' => array( 'title' => t('Save file information'), 'description' => t(''), ), // System resource permissions 'get a system variable' => array( 'title' => t('Get a system variable'), 'description' => t(''), ), 'set a system variable' => array( 'title' => t('Set a system variable'), 'description' => t(''), ), // Query-limiting permissions 'perform unlimited index queries' => array( 'title' => t('Perform unlimited index queries'), 'description' => t('This permission will allow user to perform index queries with unlimited number of results.'), ), ); } /** * Implements hook_hook_info(). */ function services_hook_info() { $hooks['services_resources'] = array( 'group' => 'services', ); return $hooks; } /** * Implements hook_menu(). * * Services UI is defined in the export-ui plugin. */ function services_menu() { $items = array(); if (module_exists('ctools')) { $endpoints = services_endpoint_load_all(); foreach ($endpoints as $endpoint) { if (empty($endpoint->disabled)) { $items[$endpoint->path] = array( 'title' => 'Services endpoint', 'access callback' => 'services_access_menu', 'page callback' => 'services_endpoint_callback', 'page arguments' => array($endpoint->name), 'type' => MENU_CALLBACK, ); } } } $items['services/session/token'] = array( 'page callback' => '_services_session_token', 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); $items['admin/config/services/services-security'] = array( 'type' => MENU_NORMAL_ITEM, 'title' => 'Services Security update', 'description' => 'Services module security updates', 'page callback' => 'drupal_get_form', 'page arguments' => array('services_security_admin_form'), 'access arguments' => array('administer site configuration'), 'file' => 'services.admin.inc', ); return $items; } /** * Implements of hook_ctools_plugin_api(). */ function services_ctools_plugin_api($module, $api) { if ($module == 'services' && $api == 'plugins') { return array('version' => 3); } } /** * Implement of hook_ctools_plugin_directory(). */ function services_ctools_plugin_directory($module, $type) { // Safety: go away if CTools is not at an appropriate version. if (!module_invoke('ctools', 'api_version', SERVICES_REQUIRED_CTOOLS_API)) { return; } if ($type =='export_ui') { return 'plugins/export_ui'; } } /** * Access callback that always returns TRUE. * * This callback is necessary for services like login and logout that should * always be wide open and accessible. * * *** USE THIS WITH GREAT CAUTION *** * * If you think you need it you are almost certainly wrong. */ function services_access_menu() { return TRUE; } /** * Implements hook_theme(). */ function services_theme() { return array( 'services_endpoint_index' => array( 'template' => 'services_endpoint_index', 'arguments' => array('endpoints' => NULL), ), 'services_resource_table' => array( 'render element' => 'table', 'file' => 'services.admin.inc', ), ); } /** * Returns information about the installed server modules on the system. * * @return array * An associative array keyed after module name containing information about * the installed server implementations. */ function services_get_servers($reset = FALSE) { $servers = &drupal_static(__FUNCTION__); if (!$servers || $reset) { $servers = array(); foreach (module_implements('server_info') as $module) { if ($module != 'sqlsrv') { $servers[$module] = call_user_func($module . '_server_info'); } } } return $servers; } /** * Menu system page callback for server endpoints. * * @param string $endpoint * The endpoint name. * @return void */ function services_endpoint_callback($endpoint_name) { module_load_include('inc', 'services', 'includes/services.runtime'); // Explicitly set the title to avoid expensive menu calls in token // and elsewhere. if (!($title = drupal_set_title())) { drupal_set_title('Services endpoint'); } $endpoint = services_endpoint_load($endpoint_name); $server = $endpoint->server; if (function_exists($server . '_server')) { // call the server services_set_server_info_from_array(array( 'module' => $server, 'endpoint' => $endpoint_name, 'endpoint_path' => $endpoint->path, 'debug' => $endpoint->debug, 'settings' => $endpoint->server_settings, )); if ($endpoint->debug) { watchdog('services', 'Calling server: %server', array('%server' => $server . '_server'), WATCHDOG_DEBUG); watchdog('services', 'Server info main object:@info', array('@info' => print_r(services_server_info_object(), TRUE)), WATCHDOG_DEBUG); } print call_user_func($server . '_server'); // Do not let this output drupal_page_footer(); exit(); } // return 404 if the server doesn't exist drupal_not_found(); } /** * Create a new endpoint with defaults appropriately set from schema. * * @return stdClass * An endpoint initialized with the default values. */ function services_endpoint_new() { ctools_include('export'); return ctools_export_new_object('services_endpoint'); } /** * Load a single endpoint. * * @param string $name * The name of the endpoint. * @return stdClass * The endpoint configuration. */ function services_endpoint_load($name) { ctools_include('export'); $result = ctools_export_load_object('services_endpoint', 'names', array($name)); if (isset($result[$name])) { return $result[$name]; } return FALSE; } /** * Load all endpoints. * * @return array * Array of endpoint objects keyed by endpoint names. */ function services_endpoint_load_all() { ctools_include('export'); return ctools_export_load_object('services_endpoint'); } /** * Saves an endpoint in the database. * * @return void */ function services_endpoint_save($endpoint) { if (is_array($endpoint) && isset($endpoint['build_info'])) { $endpoint = $endpoint['build_info']['args'][0]; } // Set a default of an array if the value is not present. foreach (array('server_settings', 'resources', 'authentication') as $endpoint_field) { if (empty($endpoint->{$endpoint_field})) { $endpoint->{$endpoint_field} = array(); } } ctools_include('export'); ctools_export_crud_save('services_endpoint', $endpoint); ctools_export_load_object_reset('services_endpoint'); menu_rebuild(); cache_clear_all('services:' . $endpoint->name . ':', 'cache', TRUE); } /** * Remove an endpoint. * * @return void */ function services_endpoint_delete($endpoint) { ctools_include('export'); ctools_export_crud_delete('services_endpoint', $endpoint); ctools_export_load_object_reset('services_endpoint'); menu_rebuild(); cache_clear_all('services:' . $endpoint->name . ':', 'cache', TRUE); } /** * Export an endpoint. * * @return string */ function services_endpoint_export($endpoint, $indent = '') { ctools_include('export'); return ctools_export_object('services_endpoint', $endpoint, $indent); } /** * Gets all resource definitions. * * @param string $endpoint_name * Optional. The endpoint endpoint that's being used. * @return array * An array containing all resources. */ function services_get_resources($endpoint_name = '') { $cache_key = 'services:' . $endpoint_name . ':resources'; $resources = array(); if (($cache = cache_get($cache_key)) && isset($cache->data)) { $resources = $cache->data; } else { module_load_include('inc', 'services', 'includes/services.resource_build'); $resources = _services_build_resources($endpoint_name); cache_set($cache_key, $resources); } return $resources; } /** * Load the resources of the endpoint. * * @return array */ function services_get_resources_apply_settings($endpoint_name) { $resources = services_get_resources($endpoint_name); module_load_include('inc', 'services', 'includes/services.resource_build'); $endpoint = services_endpoint_load($endpoint_name); _services_apply_endpoint($resources, $endpoint, TRUE); return $resources; } /** * Returns information about resource API version information. * The resource API is the way modules expose resources to services, * not the API that is exposed to the consumers of your services. * * @return array * API version information. 'default_version' is the version that's assumed * if the module doesn't declare an API version. 'versions' is an array * containing the known API versions. 'current_version' is the current * version number. */ function services_resource_api_version_info() { $info = array( 'default_version' => 3001, 'versions' => array(3002), ); $info['current_version'] = max($info['versions']); return $info; } /** * Implements hook_services_resources(). */ function services_services_resources() { module_load_include('inc', 'services', 'includes/services.resource_build'); // Return resources representing legacy services return _services_core_resources(); } /** * Implementation of hook_services_authentication_info(). */ function services_services_authentication_info() { return array( 'title' => t('Session authentication'), 'description' => t("Uses Drupal's built in sessions to authenticate."), 'authenticate_call' => '_services_sessions_authenticate_call', ); } /** * Authenticates a call using Drupal's built in sessions * * @return string * Error message in case error occured. */ function _services_sessions_authenticate_call($module, $controller) { global $user; $original_user = services_get_server_info('original_user'); if ($original_user->uid == 0) { return; } if ($controller['callback'] != '_user_resource_get_token') { $non_safe_method_called = !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD', 'OPTIONS', 'TRACE')); $csrf_token_invalid = !isset($_SERVER['HTTP_X_CSRF_TOKEN']) || !drupal_valid_token($_SERVER['HTTP_X_CSRF_TOKEN'], 'services'); if ($non_safe_method_called && $csrf_token_invalid) { return t('CSRF validation failed'); } } if ($user->uid != $original_user->uid) { $user = $original_user; } } /** * Get operation class information. * * @return array An array with operation class information keyed by operation machine name. */ function services_operation_class_info() { return array( 'operations' => array( 'title' => t('CRUD operations'), 'name' => t('CRUD operation'), 'class_singular' => 'operation', ), 'actions' => array( 'title' => t('Actions'), 'name' => t('action'), 'class_singular' => 'action', ), 'relationships' => array( 'title' => t('Relationships'), 'name' => t('relationship'), 'class_singular' => 'relationship', ), 'targeted_actions' => array( 'title' => t('Targeted actions'), 'name' => t('targeted action'), 'class_singular' => 'targeted_action', ), ); } /** * Returns all the controller names for a endpoint. * * @param string $endpoint * The endpoint that should be used. * @return array * An array containing all controller names. */ function services_controllers_list($endpoint) { $controllers = array(); $class_info = services_operation_class_info(); $resources = services_get_resources($endpoint); foreach ($resources as $resource_name => $resource) { foreach ($class_info as $class_name => $class) { if (empty($resource[$class_name])) { continue; } foreach ($resource[$class_name] as $op_name => $op) { $method = "{$resource_name}.{$op_name}"; if (empty($controllers[$method])) { $controllers[$method] = $method; } else { watchdog('services', 'Naming collision when listing controllers as methods. The %class %operation is not included in the listing.', array( '%class' => $class['name'], '%operation' => $op_name, ), WATCHDOG_WARNING); } } } } return $controllers; } /** * Returns the requested controller. * * @param string $name * The name of the controller in the format: {resource}.{name} or * {resource}.{operation}. Examples: "node.retrieve", "system.getVariable". * @param string $endpoint * The endpoint that should be used. */ function services_controller_get($name, $endpoint) { list($resource_name, $method) = explode('.', $name); $resources = services_get_resources($endpoint); if (isset($resources[$resource_name])) { $res = $resources[$resource_name]; if (isset($res[$method])) { return $res[$method]; } else { $class_info = services_operation_class_info(); // Handle extended operations foreach ($class_info as $class => $info) { if (isset($res[$class]) && isset($res[$class][$method])) { return $res[$class][$method]; } } } } } /** * Returns an array of available updates versions for a resource. * * @return * If services has updates, an array of available updates sorted by version. * Otherwise, array(). */ function services_get_updates() { $updates = &drupal_static(__FUNCTION__, array()); if (!isset($updates) || empty($updates)) { $updates = array(); module_load_include('inc', 'services', 'includes/services.resource_build'); // Load the resources for services. _services_core_resources(); // Prepare regular expression to match all possible defined // _resource_resource_method_update_N_N(). $regexp = '/_(?P