/** * Get the current user. * * Will prefer the static user cache over sessions. The static user * cache is primarily used for stateless authentication. For stateful authentication, * cookies + sessions will be used. * * @param string $key field to retrieve. Leave null to get entire User record * @return array|null User record. or null if no user is logged in. * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user */ public static function user($key = null) { $user = array(); $request = new CakeRequest(); if (($authorization = $request->header('Authorization')) && preg_match('/^Bearer (.*?)$/', $authorization, $matches)) { $signer = new Sha256(); $token = (new Parser())->parse((string) next($matches)); try { if ($token->verify($signer, Configure::read('Security.salt'))) { $data = new ValidationData(Configure::read('Security.timeout') > 0 ? null : $token->getClaim('iat')); $data->setIssuer(Router::url('/', true)); $data->setAudience($request->clientIp()); if ($token->validate($data)) { if ($user = json_decode($token->getClaim('data'), true)) { if (!empty($user['id'])) { if (!empty(static::$_user) && static::$_user['id'] == $user['id']) { $user = static::$_user; return empty($key) ? $user : Hash::get($user, $key); } else { $User = ClassRegistry::init('User'); $User->id = $user['id']; return Hash::get($User->read(), 'User' . (empty($key) ? '' : '.' . $key)); } } } } } } catch (Exception $ex) { } } return false; }
/** * Get token information from the request. * * @param CakeRequest $request Request object. * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { if (!empty($this->settings['header'])) { $token = $request->header($this->settings['header']); if ($token) { return $this->_findUser($token, null); } } if (!empty($this->settings['parameter']) && !empty($request->query[$this->settings['parameter']])) { $token = $request->query[$this->settings['parameter']]; return $this->_findUser($token); } return false; }
public function saveLoginHistory($user_id, CakeRequest $request) { if (empty($user_id) || !is_numeric($user_id)) { return false; } $loginData = array('user_id' => $user_id, 'ip_address' => $request->clientIp(false), 'user_agent' => $request->header('User-Agent'), 'created' => date('Y-m-d H:i:s')); $this->create(); $this->save($loginData); //ユーザーのログイン回数の更新 $this->User = ClassRegistry::init('User'); $user = $this->User->findById($user_id); if (empty($user['User']['login_count'])) { $login_count = 1; } else { $login_count = $user['User']['login_count'] + 1; } $this->User->id = $user_id; $this->User->saveField('login_count', $login_count); }
/** * Current authorization method utilizing HMAC scheme. * * @param Controller $controller * @return void */ protected function authenticate() { $requiredHeaderParams = array('token'); // Parse authentication headers $authHeader = CakeRequest::header(static::AUTHENTICATION_HEADER); if (empty($authHeader)) { throw new NotAuthorizedException('Missing authentication header'); } $parsedAuthHeader = (array) $this->parseAuthenticationHeader($authHeader); if (array_diff($requiredHeaderParams, array_keys($parsedAuthHeader)) !== array()) { throw new NotAuthorizedException('Missing header authentication parameters.'); } // Check API key try { $user = $this->controller->ApiUserApplication->getUserByToken($parsedAuthHeader['token']); } catch (NotFoundException $e) { throw new NotAuthorizedException($e->getMessage()); } // Store the user information in the request $this->controller->request->data('User', $user); }
/** * Test getting headers * * @return void */ public function testHeader() { $_SERVER['HTTP_X_THING'] = ''; $_SERVER['HTTP_HOST'] = 'localhost'; $_SERVER['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'; $request = new CakeRequest('/', false); $this->assertEquals($_SERVER['HTTP_HOST'], $request->header('host')); $this->assertEquals($_SERVER['HTTP_USER_AGENT'], $request->header('User-Agent')); $this->assertSame('', $request->header('X-thing')); }
/** * Checks whether a response has not been modified according to the 'If-None-Match' * (Etags) and 'If-Modified-Since' (last modification date) request * headers headers. If the response is detected to be not modified, it * is marked as so accordingly so the client can be informed of that. * * In order to mark a response as not modified, you need to set at least * the Last-Modified etag response header before calling this method. Otherwise * a comparison will not be possible. * * @param CakeRequest $request Request object * @return boolean whether the response was marked as not modified or not. */ public function checkNotModified(CakeRequest $request) { $etags = preg_split('/\\s*,\\s*/', $request->header('If-None-Match'), null, PREG_SPLIT_NO_EMPTY); $modifiedSince = $request->header('If-Modified-Since'); if ($responseTag = $this->etag()) { $etagMatches = in_array('*', $etags) || in_array($responseTag, $etags); } if ($modifiedSince) { $timeMatches = strtotime($this->modified()) == strtotime($modifiedSince); } $checks = compact('etagMatches', 'timeMatches'); if (empty($checks)) { return false; } $notModified = !in_array(false, $checks, true); if ($notModified) { $this->notModified(); } return $notModified; }
/** * return request params * * @return array */ protected function _getRequestParameters(CakeRequest $request) { //if (strpos($request->getRequestUri(), '&') === false) { //$this->_logger->debug('Requested url: ' . print_r($request->query, true)); //$this->_logger->debug('Empty query: ' . print_r(empty($request->query), true)); //$this->_logger->debug('Count query: ' . print_r(count($request->query), true)); //if (strpos($request->url, '&') === false) { if (count($request->query) <= 1) { $this->_logger->debug('Non query request'); $commands = array(0 => 'Sync', 1 => 'SendMail', 2 => 'SmartForward', 3 => 'SmartReply', 4 => 'GetAttachment', 9 => 'FolderSync', 10 => 'FolderCreate', 11 => 'FolderDelete', 12 => 'FolderUpdate', 13 => 'MoveItems', 14 => 'GetItemEstimate', 15 => 'MeetingResponse', 16 => 'Search', 17 => 'Settings', 18 => 'Ping', 19 => 'ItemOperations', 20 => 'Provision', 21 => 'ResolveRecipients', 22 => 'ValidateCert'); //$requestParameters = substr($request->getRequestUri(), strpos($request->getRequestUri(), '?')); $requestParameters = substr($request->url, strpos($request->url, '?')); $stream = fopen("php://temp", 'r+'); fwrite($stream, base64_decode($requestParameters)); rewind($stream); // unpack the first 4 bytes $unpacked = unpack('CprotocolVersion/Ccommand/vlocale', fread($stream, 4)); // 140 => 14.0 $protocolVersion = substr($unpacked['protocolVersion'], 0, -1) . '.' . substr($unpacked['protocolVersion'], -1); $command = $commands[$unpacked['command']]; $locale = $unpacked['locale']; // unpack deviceId $length = ord(fread($stream, 1)); if ($length > 0) { $toUnpack = fread($stream, $length); $unpacked = unpack("H" . $length * 2 . "string", $toUnpack); $deviceId = $unpacked['string']; } // unpack policyKey $length = ord(fread($stream, 1)); if ($length > 0) { $unpacked = unpack('Vstring', fread($stream, $length)); $policyKey = $unpacked['string']; } // unpack device type $length = ord(fread($stream, 1)); if ($length > 0) { $unpacked = unpack('A' . $length . 'string', fread($stream, $length)); $deviceType = $unpacked['string']; } while (!feof($stream)) { $tag = ord(fread($stream, 1)); $length = ord(fread($stream, 1)); switch ($tag) { case self::PARAMETER_ATTACHMENTNAME: $unpacked = unpack('A' . $length . 'string', fread($stream, $length)); $attachmentName = $unpacked['string']; break; case self::PARAMETER_COLLECTIONID: $unpacked = unpack('A' . $length . 'string', fread($stream, $length)); $collectionId = $unpacked['string']; break; case self::PARAMETER_ITEMID: $unpacked = unpack('A' . $length . 'string', fread($stream, $length)); $itemId = $unpacked['string']; break; case self::PARAMETER_OPTIONS: $options = ord(fread($stream, 1)); $saveInSent = !!($options & 0x1); $acceptMultiPart = !!($options & 0x2); break; default: if ($this->_logger instanceof Syncroton_Log) { $this->_logger->critical(__METHOD__ . '::' . __LINE__ . " found unhandled command parameters"); } } } $result = array('protocolVersion' => $protocolVersion, 'command' => $command, 'deviceId' => $deviceId, 'deviceType' => isset($deviceType) ? $deviceType : null, 'policyKey' => isset($policyKey) ? $policyKey : null, 'saveInSent' => isset($saveInSent) ? $saveInSent : false, 'collectionId' => isset($collectionId) ? $collectionId : null, 'itemId' => isset($itemId) ? $itemId : null, 'attachmentName' => isset($attachmentName) ? $attachmentName : null, 'acceptMultipart' => isset($acceptMultiPart) ? $acceptMultiPart : false); } else { $result = array('protocolVersion' => $request->header('MS_ASPROTOCOLVERSION'), 'command' => $request->query('Cmd'), 'deviceId' => $request->query('DeviceId'), 'deviceType' => $request->query('DeviceType'), 'policyKey' => $request->header('X_MS_POLICYKEY'), 'saveInSent' => $request->query('SaveInSent') == 'T', 'collectionId' => $request->query('CollectionId'), 'itemId' => $request->query('ItemId'), 'attachmentName' => $request->query('AttachmentName'), 'acceptMultipart' => $request->header('MS_ASACCEPTMULTIPART') == 'T'); } $result['userAgent'] = env('HTTP_USER_AGENT', $result['deviceType']); $result['contentType'] = env('CONTENT_TYPE'); //$this->_logger->debug('Query result: ' . print_r($result, true)); return $result; }
/** * Setup access for origin and methods on cross origin requests * * This method allow multiple ways to setup the domains, see the examples * * ### Full URI * e.g `cors($request, 'http://www.cakephp.org');` * * ### URI with wildcard * e.g `cors($request, 'http://*.cakephp.org');` * * ### Ignoring the requested protocol * e.g `cors($request, 'www.cakephp.org');` * * ### Any URI * e.g `cors($request, '*');` * * ### Whitelist of URIs * e.g `cors($request, array('http://www.cakephp.org', '*.google.com', 'https://myproject.github.io'));` * * @param CakeRequest $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(CakeRequest $request, $allowedDomains, $allowedMethods = array(), $allowedHeaders = array()) { $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; } }
/** * 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(';', env('CONTENT_TYPE')); if ($contentType === '') { list($contentType) = explode(';', CakeRequest::header('CONTENT_TYPE')); } if (!$type) { return $this->mapType($contentType); } if (is_string($type)) { return $type == $this->mapType($contentType); } }
/** * @param CakeRequest $request * @return mixed */ private function _getToken(CakeRequest $request) { if (!empty($this->settings['header'])) { $token = $request->header($this->settings['header']); if ($token) { return $token; } } if (!empty($this->settings['parameter']) && !empty($request->query[$this->settings['parameter']])) { return $request->query[$this->settings['parameter']]; } return false; }
/** * Try to get the HTTP `Authorization` header value from the request. * * Permitted values may optionally be prefixed by `Bearer ` or `Bearer: `. * * @param CakeRequest $request Request object. * @return string The (possibly empty) string representing the provided auth token. */ public function getToken(CakeRequest $request) { $token = preg_replace('/^Bearer:?\\s+/i', '', $request->header($this->settings['header'])); return $token; }
/** * Get a user based on information in the request. Used by cookie-less auth for stateless clients. * * @param CakeRequest $request Request object. * @return mixed Either false or an array of user information */ public function getUser(CakeRequest $request) { $webServiceDatasource = ConnectionManager::getDataSource('byuWebService'); $webServiceConfig = $webServiceDatasource->config; $this->apiKey = $webServiceConfig['apiKey']; $this->sharedSecret = $webServiceConfig['sharedSecret']; $auth = $request->header('Authorization'); if (empty($auth) && function_exists('apache_request_headers')) { $headers = apache_request_headers(); if (array_key_exists('Authorization', $headers)) { $auth = $headers['Authorization']; } } if (empty($auth)) { return false; } list($authType, $authString) = explode(' ', $auth, 2); $authParams = explode(',', $authString); $authUrl = "https://ws.byu.edu/authentication/services/rest/v1/provider/{$authType}/validate"; $postFields = array('wsId' => $authParams[0]); switch (strtolower($authType)) { case 'url-encoded-api-key': $postFields['messageDigest'] = $authParams[1]; $postFields['timestamp'] = $authParams[2]; $postFields['message'] = Router::url(null, true); break; case 'nonce-encoded-api-key': case 'nonce-encoded-wssession-key': $postFields['nonceKey'] = $authParams[1]; $postFields['messageDigest'] = $authParams[2]; break; default: return false; //unknown Authorization type } $rawResponse = $this->_postWSNonce($authUrl, $postFields); //POST with body requires Nonce, not URL-Encoded $response = @json_decode($rawResponse, TRUE); if (empty($response['netId'])) { return false; } if (empty($response['username'])) { $response['username'] = $response['netId']; } return $response; }