/**
  * 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();
 }