diff --git a/Module.php b/Module.php index 8ac7ff5..87cfb3d 100755 --- a/Module.php +++ b/Module.php @@ -48,6 +48,9 @@ class Module extends \yii\base\Module */ public $storageMap = []; + /** + * @var array GrantTypes map + */ public $grantTypes = []; public $tokenParamName; @@ -60,39 +63,77 @@ class Module extends \yii\base\Module public function init() { parent::init(); - $this->registerComponents(); $this->registerTranslations(); } /** - * Translate module message + * Gets Oauth2 Server * - * @param string $category - * @param string $message - * @param array $params - * @param string $language - * @return string + * @return \filsh\yii2\oauth2server\Server + * @throws \yii\base\InvalidConfigException */ - public static function t($category, $message, $params = [], $language = null) + public function getServer() { - return Yii::t('modules/oauth2/' . $category, $message, $params, $language); + if(!$this->has('server')) { + $storages = []; + foreach(array_keys($this->storageMap) as $name) { + $storages[$name] = \Yii::$container->get($name); + } + + $grantTypes = []; + foreach($this->grantTypes as $name => $options) { + if(!isset($storages[$name]) || empty($options['class'])) { + throw new \yii\base\InvalidConfigException('Invalid grant types configuration.'); + } + + $class = $options['class']; + unset($options['class']); + + $reflection = new \ReflectionClass($class); + $config = array_merge([0 => $storages[$name]], [$options]); + + $instance = $reflection->newInstanceArgs($config); + $grantTypes[$name] = $instance; + } + + $server = \Yii::$container->get(Server::className(), [ + $this, + $storages, + [ + 'token_param_name' => $this->tokenParamName, + 'access_lifetime' => $this->tokenAccessLifetime, + /** add more ... */ + ], + $grantTypes + ]); + + $this->set('server', $server); + } + return $this->get('server'); } - protected function registerComponents() + public function getRequest() { - $this->setComponents([ - 'server' => $this->createServer(), - 'request' => Request::createFromGlobals(), - 'response' => new Response() - ]); + if(!$this->has('request')) { + $this->set('request', Request::createFromGlobals()); + } + return $this->get('request'); } + public function getResponse() + { + if(!$this->has('response')) { + $this->set('response', new Response()); + } + return $this->get('response'); + } + /** * Register translations for this module * * @return array */ - protected function registerTranslations() + public function registerTranslations() { if(!isset(Yii::$app->get('i18n')->translations['modules/oauth2/*'])) { Yii::$app->get('i18n')->translations['modules/oauth2/*'] = [ @@ -102,36 +143,17 @@ protected function registerTranslations() } } - protected function createServer() + /** + * Translate module message + * + * @param string $category + * @param string $message + * @param array $params + * @param string $language + * @return string + */ + public static function t($category, $message, $params = [], $language = null) { - $storages = []; - foreach(array_keys($this->storageMap) as $name) { - $storages[$name] = \Yii::$container->get($name); - } - $server = \Yii::$container->get(Server::className(), [ - $storages, - [ - 'token_param_name' => $this->tokenParamName, - 'access_lifetime' => $this->tokenAccessLifetime, - /** add more ... */ - ] - ]); - - foreach($this->grantTypes as $name => $options) { - if(!isset($storages[$name]) || empty($options['class'])) { - throw new \yii\base\InvalidConfigException('Invalid grant types configuration.'); - } - - $class = $options['class']; - unset($options['class']); - - $reflection = new \ReflectionClass($class); - $config = array_merge([0 => $storages[$name]], [$options]); - - $instance = $reflection->newInstanceArgs($config); - $server->addGrantType($instance); - } - - return $server; + return Yii::t('modules/oauth2/' . $category, $message, $params, $language); } } diff --git a/Server.php b/Server.php index f85ee20..669d341 100644 --- a/Server.php +++ b/Server.php @@ -17,19 +17,19 @@ public function __construct(Module $module, $storage = array(), array $config = parent::__construct($storage, $config, $grantTypes, $responseTypes, $tokenType, $scopeUtil, $clientAssertionType); } - public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) + public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $scope = null) { if($request === null) { - $request = $this->module->get('request'); + $request = $this->module->getRequest(); } - return parent::handleTokenRequest($request, $response); + parent::verifyResourceRequest($request, $response, $scope); } - public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $scope = null) + public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) { if($request === null) { - $request = $this->module->get('request'); + $request = $this->module->getRequest(); } - parent::verifyResourceRequest($request, $response, $scope); + return parent::handleTokenRequest($request, $response); } } diff --git a/controllers/DefaultController.php b/controllers/DefaultController.php index 1fb6201..34bab9b 100755 --- a/controllers/DefaultController.php +++ b/controllers/DefaultController.php @@ -22,7 +22,7 @@ public function behaviors() public function actionToken() { - $response = $this->module->get('server')->handleTokenRequest(); + $response = $this->module->getServer()->handleTokenRequest(); return $response->getParameters(); } } \ No newline at end of file diff --git a/exceptions/HttpException.php b/exceptions/HttpException.php new file mode 100644 index 0000000..a5cda38 --- /dev/null +++ b/exceptions/HttpException.php @@ -0,0 +1,25 @@ +errorUri = $errorUri; + parent::__construct($status, $message, $code, $previous); + } +} \ No newline at end of file diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index f64838e..7b13e44 100755 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -5,9 +5,13 @@ use Yii; use yii\base\Controller; use filsh\yii2\oauth2server\Module; +use filsh\yii2\oauth2server\exceptions\HttpException; class ErrorToExceptionFilter extends \yii\base\Behavior { + /** + * @inheritdoc + */ public function events() { return [Controller::EVENT_AFTER_ACTION => 'afterAction']; @@ -20,20 +24,23 @@ public function events() */ public function afterAction($event) { - $response = Yii::$app->getModule('oauth2')->get('response'); + $response = Yii::$app->getModule('oauth2')->getServer()->getResponse(); $isValid = true; if($response !== null) { $isValid = $response->isInformational() || $response->isSuccessful() || $response->isRedirection(); } if(!$isValid) { - $status = $response->getStatusCode(); - // TODO: необходимо также пробрасывать error_uri - $message = Module::t('common', $response->getParameter('error_description')); - if($message === null) { - $message = Module::t('common', 'An internal server error occurred.'); - } - throw new \yii\web\HttpException($status, $message); + throw new HttpException($response->getStatusCode(), $this->getErrorMessage($response), $response->getParameter('error_uri')); + } + } + + protected function getErrorMessage(\OAuth2\Response $response) + { + $message = Module::t('common', $response->getParameter('error_description')); + if($message === null) { + $message = Module::t('common', 'An internal server error occurred.'); } + return $message; } } diff --git a/grants/UserAuthCredentials.php b/grants/UserAuthCredentials.php deleted file mode 100755 index efac5e4..0000000 --- a/grants/UserAuthCredentials.php +++ /dev/null @@ -1,65 +0,0 @@ -userStorage = $userStorage; - parent::__construct($storage, $config); - } - - public function getQuerystringIdentifier() - { - return 'user_authkey_credentials'; - } - - public function createAccessToken(\OAuth2\ResponseType\AccessTokenInterface $accessToken, $client_id, $user_id, $scope) - { - return $accessToken->createAccessToken($client_id, $user_id, $scope); - } - - public function getUserId() - { - return $this->userInfo['user_id']; - } - - public function getScope() - { - return isset($this->userInfo['scope']) ? $this->userInfo['scope'] : null; - } - - public function validateRequest(\OAuth2\RequestInterface $request, \OAuth2\ResponseInterface $response) - { - if (!$request->request('authkey') || !$request->request('username')) { - $response->setError(400, 'invalid_request', 'Missing parameters: "authkey" and "username" required'); - return null; - } - - if (!$this->userStorage->findIdentityByAccessToken($request->request('authkey'))) { - $response->setError(401, 'invalid_grant', 'Invalid user authkey'); - return null; - } - - $userInfo = $this->userStorage->getUserDetails($request->request('username')); - - if (empty($userInfo)) { - $response->setError(400, 'invalid_grant', 'Unable to retrieve user information'); - return null; - } - - if (!isset($userInfo['user_id'])) { - throw new \LogicException('you must set the user_id on the array returned by getUserDetails'); - } - - $this->userInfo = $userInfo; - - return parent::validateRequest($request, $response); - } -} \ No newline at end of file