/** * Retrieves or creates a user based on header data * * @param \Cake\Network\Request $request Request object. * @return mixed Either false or an array of user information */ protected function _getUser(Request $request) { $config = $this->_config; $username = $request->header($config['headers']['username']); $result = $this->_query($username)->first(); if (!empty($result)) { return $result; } $data = [$config['fields']['username'] => $username, $config['fields']['password'] => '', $config['fields']['name'] => $request->header($config['headers']['name']), $config['fields']['email'] => $request->header($config['headers']['email'])]; $table = TableRegistry::get($config['userModel']); $result = $table->newEntity($data); if (!$table->save($result)) { return false; } return $result; }
/** * Handle unauthenticated access attempt. In implementation valid return values * can be: * * - Null - No action taken, AuthComponent should return appropriate response. * - Cake\Network\Response - A response object, which will cause AuthComponent to * simply return that response. * * @param \Cake\Network\Request $request A request object. * @param \Cake\Network\Response $response A response object. * @return \Cake\Network\Response|bool */ public function unauthenticated(Request $request, Response $response) { $response->type('json'); $deviceId = $request->header($this->config('headerDeviceId')); $token = $request->header($this->config('headerToken')); if ($deviceId == null || $token == null) { return $this->unauthorizedResponse($response); } $generatedToken = $this->generateToken($deviceId); //Log::debug("CREATED TOKEN: ".$generatedToken); //Log::debug("SENT TOKEN: ".$token); if ($token != $generatedToken) { return $this->unauthorizedResponse($response); } return true; }
/** * Authenticate callback * Reads the stored cookie and auto login the user * * @param Request $request Cake request object. * @param Response $response Cake response object. * @return mixed */ public function authenticate(Request $request, Response $response) { $cookieName = Configure::read('Users.RememberMe.Cookie.name'); if (!$this->_registry->Cookie->check($cookieName)) { return false; } $cookie = $this->_registry->Cookie->read($cookieName); $this->config('fields.username', 'id'); $user = $this->_findUser($cookie['id']); if ($user && !empty($cookie['user_agent']) && $request->header('User-Agent') === $cookie['user_agent']) { return $user; } return false; }
/** * {@inheritDoc} */ public function getUser(Request $request) { $auth = $request->header('Authorization'); if (empty($auth) && function_exists('apache_request_headers')) { $headers = apache_request_headers(); $auth = empty($headers['Authorization']) ? null : $headers['Authorization']; } if (empty($auth)) { return false; } if (strpos($auth, ' ') === false) { return false; } list($authType, $authString) = explode(' ', $auth, 2); $authParams = explode(',', $authString); if (count($authParams) < 3) { return false; } switch (strtolower($authType)) { case 'url-encoded-api-key': $postFields = ['messageDigest' => $authParams[1], 'timestamp' => $authParams[2], 'message' => Router::fullBaseUrl() . $request->here()]; break; case 'nonce-encoded-api-key': case 'nonce-encoded-wssession-key': $postFields = ['nonceKey' => $authParams[1], 'messageDigest' => $authParams[2]]; break; default: //unknown auth type return false; } $postFields['wsId'] = $authParams[0]; $result = $this->client()->post("https://ws.byu.edu/authentication/services/rest/v1/provider/{$authType}/validate", $postFields); if (!$result || !$result->isOk()) { return false; } $response = json_decode($result->body(), true); if (empty($response['netId'])) { return false; } $response['username'] = $response['netId']; return $response; }
/** * Determines the content type of the data the client has sent (i.e. in a POST request) * * @param string|array $type Can be null (or no parameter), a string type name, or an array of types * @return mixed If a single type is supplied a boolean will be returned. If no type is provided * The mapped value of CONTENT_TYPE will be returned. If an array is supplied the first type * in the request content type will be returned. */ public function requestedWith($type = null) { if (!$this->request->is('post') && !$this->request->is('put')) { return null; } if (is_array($type)) { foreach ($type as $t) { if ($this->requestedWith($t)) { return $t; } } return false; } list($contentType) = explode(';', $this->request->env('CONTENT_TYPE')); if ($contentType === '') { list($contentType) = explode(';', $this->request->header('CONTENT_TYPE')); } if (!$type) { return $this->response->mapType($contentType); } if (is_string($type)) { return $type === $this->response->mapType($contentType); } }
/** * Setup access for origin and methods on cross origin requests * * This method allow multiple ways to setup the domains, see the examples * * ### Full URI * ``` * cors($request, 'http://www.cakephp.org'); * ``` * * ### URI with wildcard * ``` * cors($request, 'http://*.cakephp.org'); * ``` * * ### Ignoring the requested protocol * ``` * cors($request, 'www.cakephp.org'); * ``` * * ### Any URI * ``` * cors($request, '*'); * ``` * * ### Whitelist of URIs * ``` * cors($request, ['http://www.cakephp.org', '*.google.com', 'https://myproject.github.io']); * ``` * * @param \Cake\Network\Request $request Request object * @param string|array $allowedDomains List of allowed domains, see method description for more details * @param string|array $allowedMethods List of HTTP verbs allowed * @param string|array $allowedHeaders List of HTTP headers allowed * @return void */ public function cors(Request $request, $allowedDomains, $allowedMethods = [], $allowedHeaders = []) { $origin = $request->header('Origin'); if (!$origin) { return; } $allowedDomains = $this->_normalizeCorsDomains((array) $allowedDomains, $request->is('ssl')); foreach ($allowedDomains as $domain) { if (!preg_match($domain['preg'], $origin)) { continue; } $this->header('Access-Control-Allow-Origin', $domain['original'] === '*' ? '*' : $origin); $allowedMethods && $this->header('Access-Control-Allow-Methods', implode(', ', (array) $allowedMethods)); $allowedHeaders && $this->header('Access-Control-Allow-Headers', implode(', ', (array) $allowedHeaders)); break; } }
/** * Validate the request data against the cookie token. * * @param \Cake\Network\Request $request The request to validate against. * @throws \Cake\Network\Exception\InvalidCsrfTokenException when the CSRF token is invalid or missing. * @return void */ protected function _validateToken(Request $request) { $cookie = $request->cookie($this->_config['cookieName']); $post = $request->data($this->_config['field']); $header = $request->header('X-CSRF-Token'); if (empty($cookie)) { throw new InvalidCsrfTokenException(__d('cake', 'Missing CSRF token cookie')); } if ($post !== $cookie && $header !== $cookie) { throw new InvalidCsrfTokenException(__d('cake', 'CSRF token mismatch.')); } }
/** * Test getting headers * * @return void */ public function testHeader() { $request = new Request(['environment' => ['HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-ca) AppleWebKit/534.8+ (KHTML, like Gecko) Version/5.0 Safari/533.16']]); $this->assertEquals($request->env('HTTP_HOST'), $request->header('host')); $this->assertEquals($request->env('HTTP_USER_AGENT'), $request->header('User-Agent')); }
/** * Validate the request data against the cookie token. * * @param \Cake\Network\Request $request The request to validate against. * @throws \Cake\Network\Exception\ForbiddenException when the CSRF token is invalid or missing. * @return void */ protected function _validateToken(Request $request) { $cookie = $request->cookie($this->_config['cookieName']); $post = $request->data($this->_config['field']); $header = $request->header('X-CSRF-Token'); if ($post !== $cookie && $header !== $cookie) { throw new ForbiddenException(__d('cake', 'Invalid CSRF token.')); } }
/** * Setup access for origin and methods on cross origin requests * * This method allow multiple ways to setup the domains, see the examples * * ### Full URI * ``` * cors($request, 'http://www.cakephp.org'); * ``` * * ### URI with wildcard * ``` * cors($request, 'http://*.cakephp.org'); * ``` * * ### Ignoring the requested protocol * ``` * cors($request, 'www.cakephp.org'); * ``` * * ### Any URI * ``` * cors($request, '*'); * ``` * * ### Whitelist of URIs * ``` * cors($request, ['http://www.cakephp.org', '*.google.com', 'https://myproject.github.io']); * ``` * * *Note* The `$allowedDomains`, `$allowedMethods`, `$allowedHeaders` parameters are deprecated. * Instead the builder object should be used. * * @param \Cake\Network\Request $request Request object * @param string|array $allowedDomains List of allowed domains, see method description for more details * @param string|array $allowedMethods List of HTTP verbs allowed * @param string|array $allowedHeaders List of HTTP headers allowed * @return \Cake\Network\CorsBuilder A builder object the provides a fluent interface for defining * additional CORS headers. */ public function cors(Request $request, $allowedDomains = [], $allowedMethods = [], $allowedHeaders = []) { $origin = $request->header('Origin'); $ssl = $request->is('ssl'); $builder = new CorsBuilder($this, $origin, $ssl); if (!$origin) { return $builder; } if (empty($allowedDomains) && empty($allowedMethods) && empty($allowedHeaders)) { return $builder; } $builder->allowOrigin($allowedDomains)->allowMethods((array) $allowedMethods)->allowHeaders((array) $allowedHeaders)->build(); return $builder; }
/** * Get the api key from the header * * @param Request $request request * @return string api key */ public function header(Request $request) { $name = $this->config('name'); return $request->header($name); }
/** * Get token from header or query string. * * @param \Cake\Network\Request|null $request Request object. * @return string|null Token string if found else null. */ public function getToken($request = null) { $config = $this->_config; if (!$request) { return $this->_token; } $header = $request->header($config['header']); if ($header) { return $this->_token = str_ireplace($config['prefix'] . ' ', '', $header); } if (!empty($this->_config['parameter'])) { $token = $request->query($this->_config['parameter']); } return $this->_token = $token; }
/** * Test getting headers * * @return void */ public function testHeader() { $request = new Request(['environment' => ['HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-ca) AppleWebKit/534.8+ (KHTML, like Gecko) Version/5.0 Safari/533.16', 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => 1337, 'HTTP_CONTENT_MD5' => 'abc123']]); $this->assertEquals($request->env('HTTP_HOST'), $request->header('host')); $this->assertEquals($request->env('HTTP_USER_AGENT'), $request->header('User-Agent')); $this->assertEquals($request->env('CONTENT_LENGTH'), $request->header('content-length')); $this->assertEquals($request->env('CONTENT_TYPE'), $request->header('content-type')); $this->assertEquals($request->env('HTTP_CONTENT_MD5'), $request->header('content-md5')); }
/** * Get token information from the request. * * @param Request $request Request object. * @return mixed Either false or an array of user information */ public function getUser(Request $request) { if (!empty($this->_config['header'])) { $token = $request->header($this->_config['header']); if ($token) { return $this->_findUser($token); } } if (!empty($this->_config['parameter']) && !empty($request->query[$this->_config['parameter']])) { $token = $request->query[$this->_config['parameter']]; return $this->_findUser($token); } return false; }