/** * Extract the token from the request. * * @param RequestInterface $request * The request. * * @return string * The extracted token. */ protected function extractToken(RequestInterface $request) { $plugin_definition = $this->getPluginDefinition(); $options = $plugin_definition['options']; $key_name = !empty($options['paramName']) ? $options['paramName'] : 'access_token'; // Access token may be on the request, or in the headers. $input = $request->getParsedInput(); return empty($input[$key_name]) ? $request->getHeaders()->get($key_name)->getValueString() : $input[$key_name]; }
/** * {@inheritdoc} * * @see user_login_authenticate_validate(). */ public function authenticate(RequestInterface $request) { $username = $request->getUser(); $password = $request->getPassword(); // Do not allow any login from the current user's IP if the limit has been // reached. Default is 50 failed attempts allowed in one hour. This is // independent of the per-user limit to catch attempts from one IP to log // in to many different user accounts. We have a reasonably high limit // since there may be only one apparent IP for all users at an institution. if (!flood_is_allowed('failed_login_attempt_ip', variable_get('user_failed_login_ip_limit', 50), variable_get('user_failed_login_ip_window', 3600))) { throw new FloodException(format_string('Rejected by ip flood control.')); } if (filter_var($username, FILTER_VALIDATE_EMAIL)) { if (!($uid = db_query_range("SELECT uid FROM {users} WHERE LOWER(mail) = LOWER(:mail) AND status = 1", 0, 1, array(':mail' => $username))->fetchField())) { // Always register an IP-based failed login event. flood_register_event('failed_login_attempt_ip', variable_get('user_failed_login_ip_window', 3600), ip_address()); return null; } else { $username = db_query_range("SELECT name FROM {users} WHERE LOWER(mail) = LOWER(:mail) AND status = 1", 0, 1, array(':mail' => $username))->fetchField(); } } else { if (!($uid = db_query_range("SELECT uid FROM {users} WHERE name = :name AND status = 1", 0, 1, array(':name' => $username))->fetchField())) { // Always register an IP-based failed login event. flood_register_event('failed_login_attempt_ip', variable_get('user_failed_login_ip_window', 3600), ip_address()); return null; } } if (variable_get('user_failed_login_identifier_uid_only', false)) { // Register flood events based on the uid only, so they apply for any // IP address. This is the most secure option. $identifier = $uid; } else { // The default identifier is a combination of uid and IP address. This // is less secure but more resistant to denial-of-service attacks that // could lock out all users with public user names. $identifier = $uid; // . '-' . ip_address(); } // Don't allow login if the limit for this user has been reached. // Default is to allow 5 failed attempts every 6 hours. if (flood_is_allowed('failed_login_attempt_user', variable_get('user_failed_login_user_limit', 5), variable_get('user_failed_login_user_window', 21600), $identifier)) { // We are not limited by flood control, so try to authenticate. if ($uid = user_authenticate($username, $password)) { // Clear the user based flood control. flood_clear_event('failed_login_attempt_user', $identifier); $user = user_load($uid); return user_load($uid); } flood_register_event('failed_login_attempt_user', variable_get('user_failed_login_user_window', 3600), $identifier); } else { flood_register_event('failed_login_attempt_user', variable_get('user_failed_login_user_window', 3600), $identifier); throw new FloodException(format_string('Rejected by user flood control.')); } }
/** * Filter the query for list. * * @returns array * An array of filters to apply. * * @throws \Drupal\restful\Exception\BadRequestException * @throws \Drupal\restful\Exception\UnprocessableEntityException * * @see \RestfulEntityBase::getQueryForList */ protected function parseRequestForListFilter() { if (!$this->request->isListRequest($this->getResourcePath())) { // Not a list request, so we don't need to filter. // We explicitly check this, as this function might be called from a // formatter plugin, after RESTful's error handling has finished, and an // invalid key might be passed. return array(); } $input = $this->getRequest()->getParsedInput(); if (empty($input['filter'])) { // No filtering is needed. return array(); } $url_params = empty($this->options['urlParams']) ? array() : $this->options['urlParams']; if (isset($url_params['filter']) && !$url_params['filter']) { throw new UnprocessableEntityException('Filter parameters have been disabled in server configuration.'); } $filters = array(); foreach ($input['filter'] as $public_field => $value) { if (!static::isNestedField($public_field) && !$this->fieldDefinitions->get($public_field)) { throw new BadRequestException(format_string('The filter @filter is not allowed for this path.', array('@filter' => $public_field))); } $filters[] = static::processFilterInput($value, $public_field); } return $filters; }
/** * {@inheritdoc} */ public function negotiate() { $version = $this->getVersionFromRequest(); list($resource_name, ) = static::getPageArguments($this->request->getPath(FALSE)); try { $resource = $this->getPlugin($resource_name . PluginBase::DERIVATIVE_SEPARATOR . $version[0] . '.' . $version[1]); return $resource->isEnabled() ? $resource : NULL; } catch (PluginNotFoundException $e) { throw new ServerConfigurationException($e->getMessage()); } }
/** * Checks if the passed in request belongs to RESTful. * * @param RequestInterface $request * The path to check. * * @return bool * TRUE if the path belongs to RESTful. */ public static function isRestfulPath(RequestInterface $request) { return ResourceManager::getPageCallback($request->getPath(FALSE)) == static::FRONT_CONTROLLER_CALLBACK; }
/** * Allow altering the request before it is processed. * * @param \Drupal\restful\Http\RequestInterface $request * The request object. */ function hook_restful_parse_request_alter(\Drupal\restful\Http\RequestInterface &$request) { // Allow implementor modules to alter the request object. $request->setApplicationData('csrf_token', 'token'); }
/** * {@inheritdoc} */ public function prepare(RequestInterface $request) { $headers = $this->headers; if ($this->isInformational() || $this->isEmpty()) { $this->setContent(NULL); $headers->remove('Content-Type'); $headers->remove('Content-Length'); } else { // Content-type based on the Request. The content type should have been // set in the RestfulFormatter. // Fix Content-Type $charset = $this->charset ?: 'UTF-8'; $content_type = $headers->get('Content-Type')->getValueString(); if (stripos($content_type, 'text/') === 0 && stripos($content_type, 'charset') === FALSE) { // add the charset $headers->add(HttpHeader::create('Content-Type', $content_type . '; charset=' . $charset)); } // Fix Content-Length if ($headers->has('Transfer-Encoding')) { $headers->remove('Content-Length'); } if ($request->getMethod() == RequestInterface::METHOD_HEAD) { // cf. RFC2616 14.13 $length = $headers->get('Content-Length')->getValueString(); $this->setContent(NULL); if ($length) { $headers->add(HttpHeader::create('Content-Length', $length)); } } } // Fix protocol $server_info = $request->getServer(); if ($server_info['SERVER_PROTOCOL'] != 'HTTP/1.0') { $this->setProtocolVersion('1.1'); } // Check if we need to send extra expire info headers if ($this->getProtocolVersion() == '1.0' && $this->headers->get('Cache-Control')->getValueString() == 'no-cache') { $this->headers->add(HttpHeader::create('pragma', 'no-cache')); $this->headers->add(HttpHeader::create('expires', -1)); } $this->ensureIEOverSSLCompatibility($request); }
/** * Detects whether the script is running from a command line environment. * * @param RequestInterface $request. * The request. * * @return bool * TRUE if a command line environment is detected. FALSE otherwise. */ protected function isCli(RequestInterface $request) { // Needed to detect if run-tests.sh is running the tests. $cli = $request->getHeaders()->get('User-Agent')->getValueString() == 'Drupal command line'; return $cli || drupal_is_cli(); }