From e5084e39f303f47f5c6093e2509b730eeb8279e4 Mon Sep 17 00:00:00 2001 From: Dmitri Savustjan Date: Fri, 3 Jul 2015 15:44:48 +0300 Subject: [PATCH 01/44] Update Server.php fixed verifyResourceRequest. It prevented function from return result of parent check. Always returned null (false). --- Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server.php b/Server.php index 78e78ac..5535573 100644 --- a/Server.php +++ b/Server.php @@ -28,7 +28,7 @@ public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, if($request === null) { $request = $this->module->getRequest(); } - parent::verifyResourceRequest($request, $response, $scope); + return parent::verifyResourceRequest($request, $response, $scope); } public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) From 3a32949f446b73b3e604f7efefcc58a13e1d0cad Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 6 Jul 2015 10:30:53 +0200 Subject: [PATCH 02/44] Updated Module params phpDocs --- Module.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Module.php b/Module.php index 108ccb2..cf9b792 100755 --- a/Module.php +++ b/Module.php @@ -48,12 +48,12 @@ class Module extends \yii\base\Module public $grantTypes = []; /** - * @var string name of access token parameter + * @var string Name of access token parameter */ public $tokenParamName; /** - * @var type max access lifetime + * @var integer Max access token lifetime in seconds */ public $tokenAccessLifetime; From b005ade43a30688697162c546067ed34be90cc1a Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 6 Jul 2015 10:35:34 +0200 Subject: [PATCH 03/44] Added option to set custom ResponseTypes --- Module.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Module.php b/Module.php index cf9b792..eb68adc 100755 --- a/Module.php +++ b/Module.php @@ -46,6 +46,11 @@ class Module extends \yii\base\Module * @var array GrantTypes collection */ public $grantTypes = []; + + /** + * @var array ResponseTypes collection + */ + public $responseTypes = []; /** * @var string Name of access token parameter @@ -104,7 +109,8 @@ public function getServer() 'access_lifetime' => $this->tokenAccessLifetime, /** add more ... */ ], - $grantTypes + $grantTypes, + $this->responseTypes ]); $this->set('server', $server); From e2bf9559baf0ae2cbb8d30c9061d218c1ca790f4 Mon Sep 17 00:00:00 2001 From: Rodrigo Zani Date: Mon, 13 Jul 2015 17:34:41 -0300 Subject: [PATCH 04/44] adding support when OAuth2 is nested to another module --- Bootstrap.php | 62 +++++++++++++++++++++++----------- filters/auth/CompositeAuth.php | 28 +++++++++++++-- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/Bootstrap.php b/Bootstrap.php index b9b15db..755b37e 100644 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -6,54 +6,76 @@ class Bootstrap implements \yii\base\BootstrapInterface { + /** * @var array Model's map */ private $_modelMap = [ - 'OauthClients' => 'filsh\yii2\oauth2server\models\OauthClients', - 'OauthAccessTokens' => 'filsh\yii2\oauth2server\models\OauthAccessTokens', - 'OauthAuthorizationCodes' => 'filsh\yii2\oauth2server\models\OauthAuthorizationCodes', - 'OauthRefreshTokens' => 'filsh\yii2\oauth2server\models\OauthRefreshTokens', - 'OauthScopes' => 'filsh\yii2\oauth2server\models\OauthScopes', + 'OauthClients' => 'filsh\yii2\oauth2server\models\OauthClients', + 'OauthAccessTokens' => 'filsh\yii2\oauth2server\models\OauthAccessTokens', + 'OauthAuthorizationCodes' => 'filsh\yii2\oauth2server\models\OauthAuthorizationCodes', + 'OauthRefreshTokens' => 'filsh\yii2\oauth2server\models\OauthRefreshTokens', + 'OauthScopes' => 'filsh\yii2\oauth2server\models\OauthScopes', ]; - + /** * @var array Storage's map */ private $_storageMap = [ - 'access_token' => 'filsh\yii2\oauth2server\storage\Pdo', - 'authorization_code' => 'filsh\yii2\oauth2server\storage\Pdo', - 'client_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', - 'client' => 'filsh\yii2\oauth2server\storage\Pdo', - 'refresh_token' => 'filsh\yii2\oauth2server\storage\Pdo', - 'user_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', - 'public_key' => 'filsh\yii2\oauth2server\storage\Pdo', - 'jwt_bearer' => 'filsh\yii2\oauth2server\storage\Pdo', - 'scope' => 'filsh\yii2\oauth2server\storage\Pdo', + 'access_token' => 'filsh\yii2\oauth2server\storage\Pdo', + 'authorization_code' => 'filsh\yii2\oauth2server\storage\Pdo', + 'client_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', + 'client' => 'filsh\yii2\oauth2server\storage\Pdo', + 'refresh_token' => 'filsh\yii2\oauth2server\storage\Pdo', + 'user_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', + 'public_key' => 'filsh\yii2\oauth2server\storage\Pdo', + 'jwt_bearer' => 'filsh\yii2\oauth2server\storage\Pdo', + 'scope' => 'filsh\yii2\oauth2server\storage\Pdo', ]; - + /** * @inheritdoc */ public function bootstrap($app) { /** @var $module Module */ - if ($app->hasModule('oauth2') && ($module = $app->getModule('oauth2')) instanceof Module) { + $module = $this->getModuleNested('oauth2', $app); + + if ($module instanceof Module) { $this->_modelMap = array_merge($this->_modelMap, $module->modelMap); foreach ($this->_modelMap as $name => $definition) { \Yii::$container->set("filsh\\yii2\\oauth2server\\models\\" . $name, $definition); $module->modelMap[$name] = is_array($definition) ? $definition['class'] : $definition; } - + $this->_storageMap = array_merge($this->_storageMap, $module->storageMap); foreach ($this->_storageMap as $name => $definition) { \Yii::$container->set($name, $definition); $module->storageMap[$name] = is_array($definition) ? $definition['class'] : $definition; } - + if ($app instanceof \yii\console\Application) { $module->controllerNamespace = 'filsh\yii2\oauth2server\commands'; } } } -} \ No newline at end of file + + public function getModuleNested($needle, $app) + { + /** @var $module Module */ + if (($module = $app->getModule($needle)) !== null) + return $module; + + foreach ($app->getModules() as $id => $module) { + $server = $app->getModule($id)->getModule($needle); + if ($server != null) { + return $server; + } else { + $this->getModuleNested($module->getModules()); + } + } + + return false; + } + +} diff --git a/filters/auth/CompositeAuth.php b/filters/auth/CompositeAuth.php index 3363d59..6a0b912 100755 --- a/filters/auth/CompositeAuth.php +++ b/filters/auth/CompositeAuth.php @@ -6,14 +6,36 @@ class CompositeAuth extends \yii\filters\auth\CompositeAuth { + /** * @inheritdoc */ public function beforeAction($action) { - $server = Yii::$app->getModule('oauth2')->getServer(); + $module = $this->getModuleNested('oauth2', Yii::$app); + + $server = $module->getServer(); $server->verifyResourceRequest(); - + return parent::beforeAction($action); } -} \ No newline at end of file + + public function getModuleNested($needle, $app) + { + /** @var $module Module */ + if (($module = $app->getModule($needle)) !== null) + return $module; + + foreach ($app->getModules() as $id => $module) { + $server = $app->getModule($id)->getModule($needle); + if ($server != null) { + return $server; + } else { + $this->getModuleNested($module->getModules()); + } + } + + return false; + } + +} From 009b1af0da5b15716dad480e431a60fd27fbd1f9 Mon Sep 17 00:00:00 2001 From: Igor Maliy Date: Wed, 17 Jun 2015 01:36:28 +0300 Subject: [PATCH 05/44] v2.0.0 --- .gitignore | 0 Bootstrap.php | 57 +++++++++ LICENSE | 0 Module.php | 108 +++++------------- README.md | 0 commands/empty | 0 composer.json | 1 + controllers/DefaultController.php | 0 filters/ErrorToExceptionFilter.php | 5 +- filters/auth/CompositeAuth.php | 0 grants/UserAuthCredentials.php | 0 messages/en/{oauth2server.php => common.php} | 0 .../m140501_075311_add_oauth2_server.php | 0 models/OauthAccessTokens.php | 0 models/OauthAuthorizationCodes.php | 0 models/OauthClients.php | 0 models/OauthRefreshTokens.php | 0 models/OauthScopes.php | 0 storage/Pdo.php | 0 19 files changed, 90 insertions(+), 81 deletions(-) mode change 100644 => 100755 .gitignore create mode 100644 Bootstrap.php mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Module.php mode change 100644 => 100755 README.md create mode 100644 commands/empty mode change 100644 => 100755 composer.json mode change 100644 => 100755 controllers/DefaultController.php mode change 100644 => 100755 filters/ErrorToExceptionFilter.php mode change 100644 => 100755 filters/auth/CompositeAuth.php mode change 100644 => 100755 grants/UserAuthCredentials.php rename messages/en/{oauth2server.php => common.php} (100%) mode change 100644 => 100755 mode change 100644 => 100755 migrations/m140501_075311_add_oauth2_server.php mode change 100644 => 100755 models/OauthAccessTokens.php mode change 100644 => 100755 models/OauthAuthorizationCodes.php mode change 100644 => 100755 models/OauthClients.php mode change 100644 => 100755 models/OauthRefreshTokens.php mode change 100644 => 100755 models/OauthScopes.php mode change 100644 => 100755 storage/Pdo.php diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/Bootstrap.php b/Bootstrap.php new file mode 100644 index 0000000..bd65763 --- /dev/null +++ b/Bootstrap.php @@ -0,0 +1,57 @@ + 'filsh\yii2\oauth2server\models\OauthClients', + 'OauthAccessTokens' => 'filsh\yii2\oauth2server\models\OauthAccessTokens', + 'OauthAuthorizationCodes' => 'filsh\yii2\oauth2server\models\OauthAuthorizationCodes', + 'OauthRefreshTokens' => 'filsh\yii2\oauth2server\models\OauthRefreshTokens', + 'OauthScopes' => 'filsh\yii2\oauth2server\models\OauthScopes', + ]; + + /** + * @var array Storage's map + */ + private $_storageMap = [ + 'access_token' => 'filsh\yii2\oauth2server\storage\Pdo', + 'authorization_code' => 'filsh\yii2\oauth2server\storage\Pdo', + 'client_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', + 'client' => 'filsh\yii2\oauth2server\storage\Pdo', + 'refresh_token' => 'filsh\yii2\oauth2server\storage\Pdo', + 'user_credentials' => 'filsh\yii2\oauth2server\storage\Pdo', + 'public_key' => 'filsh\yii2\oauth2server\storage\Pdo', + 'jwt_bearer' => 'filsh\yii2\oauth2server\storage\Pdo', + 'scope' => 'filsh\yii2\oauth2server\storage\Pdo', + ]; + + /** + * @inheritdoc + */ + public function bootstrap($app) + { + /** @var $module Module */ + if ($app->hasModule('oauth2') && ($module = $app->getModule('oauth2')) instanceof Module) { + $this->_modelMap = array_merge($this->_modelMap, $module->modelMap); + foreach ($this->_modelMap as $name => $definition) { + \Yii::$container->set("filsh\\yii2\\oauth2server\\models\\" . $name, $definition); + $module->modelMap[$name] = is_array($definition) ? $definition['class'] : $definition; + } + + $this->_storageMap = array_merge($this->_storageMap, $module->storageMap); + foreach ($this->_storageMap as $name => $definition) { + \Yii::$container->set($name, $definition); + $module->storageMap[$name] = is_array($definition) ? $definition['class'] : $definition; + } + + if ($app instanceof \yii\console\Application) { + $module->controllerNamespace = 'filsh\yii2\oauth2server\commands'; + } + } + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Module.php b/Module.php old mode 100644 new mode 100755 index 496b276..afdd713 --- a/Module.php +++ b/Module.php @@ -3,6 +3,7 @@ namespace filsh\yii2\oauth2server; use \Yii; +use yii\i18n\PhpMessageSource; /** * For example, @@ -35,31 +36,35 @@ */ class Module extends \yii\base\Module { - public $options = []; + const VERSION = '2.0.0'; + /** + * @var array Model's map + */ + public $modelMap = []; + + /** + * @var array Storage's map + */ public $storageMap = []; - public $storageDefault = 'filsh\yii2\oauth2server\storage\Pdo'; - public $grantTypes = []; - public $modelClasses = []; - public $i18n; - + public $options = []; + + public $grantTypes = []; + private $_server; private $_request; - private $_models = []; - /** * @inheritdoc */ public function init() { parent::init(); - $this->modelClasses = array_merge($this->getDefaultModelClasses(), $this->modelClasses); $this->registerTranslations(); } @@ -71,7 +76,10 @@ public function init() public function getServer($force = false) { if($this->_server === null || $force === true) { - $storages = $this->createStorages(); + $storages = []; + foreach($this->storageMap as $name => $value) { + $storages[$name] = \Yii::$container->get($name); + } $server = new \OAuth2\Server($storages, $this->options); foreach($this->grantTypes as $name => $options) { @@ -114,57 +122,11 @@ public function getResponse() { return new \OAuth2\Response(); } - - /** - * Create storages - * @return type - */ - public function createStorages() - { - $connection = Yii::$app->getDb(); - if(!$connection->getIsActive()) { - $connection->open(); - } - - $storages = []; - foreach($this->storageMap as $name => $storage) { - $storages[$name] = Yii::createObject($storage); - } - - $defaults = [ - 'access_token', - 'authorization_code', - 'client_credentials', - 'client', - 'refresh_token', - 'user_credentials', - 'public_key', - 'jwt_bearer', - 'scope', - ]; - foreach($defaults as $name) { - if(!isset($storages[$name])) { - $storages[$name] = Yii::createObject($this->storageDefault); - } - } - - return $storages; - } - /** - * Get object instance of model - * @param string $name - * @param array $config - * @return ActiveRecord - */ - public function model($name, $config = []) - { - if(!isset($this->_models[$name])) { - $className = $this->modelClasses[ucfirst($name)]; - $this->_models[$name] = Yii::createObject(array_merge(['class' => $className], $config)); - } - return $this->_models[$name]; - } + + + + /** * Register translations for this module @@ -172,28 +134,16 @@ public function model($name, $config = []) */ public function registerTranslations() { - Yii::setAlias('@oauth2server', dirname(__FILE__)); - if (empty($this->i18n)) { - $this->i18n = [ - 'class' => 'yii\i18n\PhpMessageSource', - 'basePath' => '@oauth2server/messages', + if(!isset(Yii::$app->get('i18n')->translations['modules/oauth2/*'])) { + Yii::$app->get('i18n')->translations['modules/oauth2/*'] = [ + 'class' => PhpMessageSource::className(), + 'basePath' => __DIR__ . '/messages', ]; } - Yii::$app->i18n->translations['oauth2server'] = $this->i18n; } - - /** - * Get default model classes - * @return array - */ - protected function getDefaultModelClasses() + + public static function t($category, $message, $params = [], $language = null) { - return [ - 'Clients' => 'filsh\yii2\oauth2server\models\OauthClients', - 'AccessTokens' => 'filsh\yii2\oauth2server\models\OauthAccessTokens', - 'AuthorizationCodes' => 'filsh\yii2\oauth2server\models\OauthAuthorizationCodes', - 'RefreshTokens' => 'filsh\yii2\oauth2server\models\OauthRefreshTokens', - 'Scopes' => 'filsh\yii2\oauth2server\models\OauthScopes', - ]; + return Yii::t('modules/oauth2/' . $category, $message, $params, $language); } } diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/commands/empty b/commands/empty new file mode 100644 index 0000000..e69de29 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 458ac9d..4799e2d --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ } }, "extra": { + "bootstrap": "filsh\\yii2\\oauth2server\\Bootstrap", "branch-alias": { "dev-master": "1.0.x-dev" } diff --git a/controllers/DefaultController.php b/controllers/DefaultController.php old mode 100644 new mode 100755 diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php old mode 100644 new mode 100755 index 9f6f4c7..2c38d8b --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -4,6 +4,7 @@ use Yii; use yii\base\Controller; +use filsh\yii2\oauth2server\Module; class ErrorToExceptionFilter extends \yii\base\Behavior { @@ -28,9 +29,9 @@ public function afterAction($event) if(!$isValid) { $status = $response->getStatusCode(); // TODO: необходимо также пробрасывать error_uri - $message = Yii::t('oauth2server', $response->getParameter('error_description')); + $message = Module::t('common', $response->getParameter('error_description')); if($message === null) { - $message = Yii::t('yii', 'An internal server error occurred.'); + $message = Module::t('common', 'An internal server error occurred.'); } throw new \yii\web\HttpException($status, $message); } diff --git a/filters/auth/CompositeAuth.php b/filters/auth/CompositeAuth.php old mode 100644 new mode 100755 diff --git a/grants/UserAuthCredentials.php b/grants/UserAuthCredentials.php old mode 100644 new mode 100755 diff --git a/messages/en/oauth2server.php b/messages/en/common.php old mode 100644 new mode 100755 similarity index 100% rename from messages/en/oauth2server.php rename to messages/en/common.php diff --git a/migrations/m140501_075311_add_oauth2_server.php b/migrations/m140501_075311_add_oauth2_server.php old mode 100644 new mode 100755 diff --git a/models/OauthAccessTokens.php b/models/OauthAccessTokens.php old mode 100644 new mode 100755 diff --git a/models/OauthAuthorizationCodes.php b/models/OauthAuthorizationCodes.php old mode 100644 new mode 100755 diff --git a/models/OauthClients.php b/models/OauthClients.php old mode 100644 new mode 100755 diff --git a/models/OauthRefreshTokens.php b/models/OauthRefreshTokens.php old mode 100644 new mode 100755 diff --git a/models/OauthScopes.php b/models/OauthScopes.php old mode 100644 new mode 100755 diff --git a/storage/Pdo.php b/storage/Pdo.php old mode 100644 new mode 100755 From 519f154960ddc0ffda26d3f5e13499b2764f7e47 Mon Sep 17 00:00:00 2001 From: Igor Maliy Date: Wed, 17 Jun 2015 11:02:26 +0300 Subject: [PATCH 06/44] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4799e2d..e8432ff 100755 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "yiisoft/yii2": "*", - "bshaffer/oauth2-server-php": "v1.3" + "bshaffer/oauth2-server-php": "~1.7.1" }, "autoload": { "psr-4": { From baf3ac9460396ba4b1ad9cd4a6f37c723f2de308 Mon Sep 17 00:00:00 2001 From: Igor Maliy Date: Thu, 18 Jun 2015 08:46:31 +0300 Subject: [PATCH 07/44] Oauth module v2.0 --- Module.php | 114 +++++++++++++---------------- Request.php | 8 ++ Response.php | 8 ++ Server.php | 35 +++++++++ composer.json | 2 +- controllers/DefaultController.php | 5 +- filters/ErrorToExceptionFilter.php | 2 +- filters/auth/CompositeAuth.php | 5 +- traits/ClassNamespace.php | 11 +++ 9 files changed, 118 insertions(+), 72 deletions(-) create mode 100644 Request.php create mode 100644 Response.php create mode 100644 Server.php create mode 100644 traits/ClassNamespace.php diff --git a/Module.php b/Module.php index afdd713..8ac7ff5 100755 --- a/Module.php +++ b/Module.php @@ -48,16 +48,11 @@ class Module extends \yii\base\Module */ public $storageMap = []; - - - - public $options = []; - public $grantTypes = []; - private $_server; - - private $_request; + public $tokenParamName; + + public $tokenAccessLifetime; /** * @inheritdoc @@ -65,74 +60,39 @@ class Module extends \yii\base\Module public function init() { parent::init(); + $this->registerComponents(); $this->registerTranslations(); } /** - * Get oauth2 server instance - * @param type $force - * @return \OAuth2\Server + * Translate module message + * + * @param string $category + * @param string $message + * @param array $params + * @param string $language + * @return string */ - public function getServer($force = false) + public static function t($category, $message, $params = [], $language = null) { - if($this->_server === null || $force === true) { - $storages = []; - foreach($this->storageMap as $name => $value) { - $storages[$name] = \Yii::$container->get($name); - } - $server = new \OAuth2\Server($storages, $this->options); - - 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); - } - - $this->_server = $server; - } - return $this->_server; + return Yii::t('modules/oauth2/' . $category, $message, $params, $language); } - /** - * Get oauth2 request instance from global variables - * @return \OAuth2\Request - */ - public function getRequest($force = false) + protected function registerComponents() { - if ($this->_request === null || $force) { - $this->_request = \OAuth2\Request::createFromGlobals(); - }; - return $this->_request; + $this->setComponents([ + 'server' => $this->createServer(), + 'request' => Request::createFromGlobals(), + 'response' => new Response() + ]); } - /** - * Get oauth2 response instance - * @return \OAuth2\Response - */ - public function getResponse() - { - return new \OAuth2\Response(); - } - - - - - - /** * Register translations for this module + * * @return array */ - public function registerTranslations() + protected function registerTranslations() { if(!isset(Yii::$app->get('i18n')->translations['modules/oauth2/*'])) { Yii::$app->get('i18n')->translations['modules/oauth2/*'] = [ @@ -142,8 +102,36 @@ public function registerTranslations() } } - public static function t($category, $message, $params = [], $language = null) + protected function createServer() { - return Yii::t('modules/oauth2/' . $category, $message, $params, $language); + $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; } } diff --git a/Request.php b/Request.php new file mode 100644 index 0000000..b8c03df --- /dev/null +++ b/Request.php @@ -0,0 +1,8 @@ +module = $module; + parent::__construct($storage, $config, $grantTypes, $responseTypes, $tokenType, $scopeUtil, $clientAssertionType); + } + + public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) + { + if($request === null) { + $request = $this->module->get('request'); + } + return parent::handleTokenRequest($request, $response); + } + + public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $scope = null) + { + if($request === null) { + $request = $this->module->get('request'); + } + parent::verifyResourceRequest($request, $response, $scope); + } +} diff --git a/composer.json b/composer.json index e8432ff..7052c37 100755 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "yiisoft/yii2": "*", - "bshaffer/oauth2-server-php": "~1.7.1" + "bshaffer/oauth2-server-php": "~1.7" }, "autoload": { "psr-4": { diff --git a/controllers/DefaultController.php b/controllers/DefaultController.php index 255850d..1fb6201 100755 --- a/controllers/DefaultController.php +++ b/controllers/DefaultController.php @@ -22,10 +22,7 @@ public function behaviors() public function actionToken() { - $server = $this->module->getServer(); - $request = $this->module->getRequest(); - $response = $server->handleTokenRequest($request); - + $response = $this->module->get('server')->handleTokenRequest(); return $response->getParameters(); } } \ No newline at end of file diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index 2c38d8b..f64838e 100755 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -20,7 +20,7 @@ public function events() */ public function afterAction($event) { - $response = Yii::$app->getModule('oauth2')->getServer()->getResponse(); + $response = Yii::$app->getModule('oauth2')->get('response'); $isValid = true; if($response !== null) { diff --git a/filters/auth/CompositeAuth.php b/filters/auth/CompositeAuth.php index 38ad308..3363d59 100755 --- a/filters/auth/CompositeAuth.php +++ b/filters/auth/CompositeAuth.php @@ -11,9 +11,8 @@ class CompositeAuth extends \yii\filters\auth\CompositeAuth */ public function beforeAction($action) { - $oauthServer = Yii::$app->getModule('oauth2')->getServer(); - $oauthRequest = Yii::$app->getModule('oauth2')->getRequest(); - $oauthServer->verifyResourceRequest($oauthRequest); + $server = Yii::$app->getModule('oauth2')->getServer(); + $server->verifyResourceRequest(); return parent::beforeAction($action); } diff --git a/traits/ClassNamespace.php b/traits/ClassNamespace.php new file mode 100644 index 0000000..fa5b8e0 --- /dev/null +++ b/traits/ClassNamespace.php @@ -0,0 +1,11 @@ + Date: Fri, 19 Jun 2015 08:12:03 +0300 Subject: [PATCH 08/44] Oauth module v2.0 --- Module.php | 114 +++++++++++++++++------------ Server.php | 12 +-- controllers/DefaultController.php | 2 +- exceptions/HttpException.php | 25 +++++++ filters/ErrorToExceptionFilter.php | 23 ++++-- grants/UserAuthCredentials.php | 65 ---------------- 6 files changed, 115 insertions(+), 126 deletions(-) create mode 100644 exceptions/HttpException.php delete mode 100755 grants/UserAuthCredentials.php 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 From a3d59182e2c9ce12b952017eb3e52b67556a3f51 Mon Sep 17 00:00:00 2001 From: Maliy Igor Date: Fri, 19 Jun 2015 15:30:06 +0300 Subject: [PATCH 09/44] v2.0.0 --- Bootstrap.php | 2 ++ Module.php | 28 +++++++++---------- Server.php | 6 ++++ ...faultController.php => RestController.php} | 2 +- 4 files changed, 23 insertions(+), 15 deletions(-) rename controllers/{DefaultController.php => RestController.php} (91%) diff --git a/Bootstrap.php b/Bootstrap.php index bd65763..b9b15db 100644 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -2,6 +2,8 @@ namespace filsh\yii2\oauth2server; +use yii\web\GroupUrlRule; + class Bootstrap implements \yii\base\BootstrapInterface { /** diff --git a/Module.php b/Module.php index 87cfb3d..108ccb2 100755 --- a/Module.php +++ b/Module.php @@ -11,26 +11,20 @@ * ```php * 'oauth2' => [ * 'class' => 'filsh\yii2\oauth2server\Module', - * 'options' => [ - * 'token_param_name' => 'accessToken', - * 'access_lifetime' => 3600 - * ], + * 'tokenParamName' => 'accessToken', + * 'tokenAccessLifetime' => 3600 * 24, * 'storageMap' => [ - * 'user_credentials' => 'common\models\User' + * 'user_credentials' => 'common\models\User', * ], * 'grantTypes' => [ - * 'client_credentials' => [ - * 'class' => '\OAuth2\GrantType\ClientCredentials', - * 'allow_public_clients' => false - * ], * 'user_credentials' => [ - * 'class' => '\OAuth2\GrantType\UserCredentials' + * 'class' => 'OAuth2\GrantType\UserCredentials', * ], * 'refresh_token' => [ - * 'class' => '\OAuth2\GrantType\RefreshToken', + * 'class' => 'OAuth2\GrantType\RefreshToken', * 'always_issue_new_refresh_token' => true * ] - * ], + * ] * ] * ``` */ @@ -49,12 +43,18 @@ class Module extends \yii\base\Module public $storageMap = []; /** - * @var array GrantTypes map + * @var array GrantTypes collection */ public $grantTypes = []; + /** + * @var string name of access token parameter + */ public $tokenParamName; + /** + * @var type max access lifetime + */ public $tokenAccessLifetime; /** @@ -95,7 +95,7 @@ public function getServer() $instance = $reflection->newInstanceArgs($config); $grantTypes[$name] = $instance; } - + $server = \Yii::$container->get(Server::className(), [ $this, $storages, diff --git a/Server.php b/Server.php index 669d341..78e78ac 100644 --- a/Server.php +++ b/Server.php @@ -17,6 +17,12 @@ public function __construct(Module $module, $storage = array(), array $config = parent::__construct($storage, $config, $grantTypes, $responseTypes, $tokenType, $scopeUtil, $clientAssertionType); } + public function createAccessToken($clientId, $userId, $scope = null, $includeRefreshToken = true) + { + $accessToken = $this->getAccessTokenResponseType(); + return $accessToken->createAccessToken($clientId, $userId, $scope, $includeRefreshToken); + } + public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $scope = null) { if($request === null) { diff --git a/controllers/DefaultController.php b/controllers/RestController.php similarity index 91% rename from controllers/DefaultController.php rename to controllers/RestController.php index 34bab9b..c9978b3 100755 --- a/controllers/DefaultController.php +++ b/controllers/RestController.php @@ -6,7 +6,7 @@ use yii\helpers\ArrayHelper; use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter; -class DefaultController extends \yii\rest\Controller +class RestController extends \yii\rest\Controller { /** * @inheritdoc From b8af7cf344ab79ee0a735a164bd10314c147479f Mon Sep 17 00:00:00 2001 From: Dmitri Savustjan Date: Fri, 3 Jul 2015 15:44:48 +0300 Subject: [PATCH 10/44] Update Server.php fixed verifyResourceRequest. It prevented function from return result of parent check. Always returned null (false). --- Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server.php b/Server.php index 78e78ac..5535573 100644 --- a/Server.php +++ b/Server.php @@ -28,7 +28,7 @@ public function verifyResourceRequest(\OAuth2\RequestInterface $request = null, if($request === null) { $request = $this->module->getRequest(); } - parent::verifyResourceRequest($request, $response, $scope); + return parent::verifyResourceRequest($request, $response, $scope); } public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) From 5ae72fa434850242ba7374ee911fbfcbb1e6c593 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 6 Jul 2015 10:30:53 +0200 Subject: [PATCH 11/44] Updated Module params phpDocs --- Module.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Module.php b/Module.php index 108ccb2..cf9b792 100755 --- a/Module.php +++ b/Module.php @@ -48,12 +48,12 @@ class Module extends \yii\base\Module public $grantTypes = []; /** - * @var string name of access token parameter + * @var string Name of access token parameter */ public $tokenParamName; /** - * @var type max access lifetime + * @var integer Max access token lifetime in seconds */ public $tokenAccessLifetime; From f609415be7085a198de412f46c65c754e19fab50 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 6 Jul 2015 10:35:34 +0200 Subject: [PATCH 12/44] Added option to set custom ResponseTypes --- Module.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Module.php b/Module.php index cf9b792..eb68adc 100755 --- a/Module.php +++ b/Module.php @@ -46,6 +46,11 @@ class Module extends \yii\base\Module * @var array GrantTypes collection */ public $grantTypes = []; + + /** + * @var array ResponseTypes collection + */ + public $responseTypes = []; /** * @var string Name of access token parameter @@ -104,7 +109,8 @@ public function getServer() 'access_lifetime' => $this->tokenAccessLifetime, /** add more ... */ ], - $grantTypes + $grantTypes, + $this->responseTypes ]); $this->set('server', $server); From 276b1058279972bdc4d4126084ca7c061d1087d3 Mon Sep 17 00:00:00 2001 From: Maliy Igor Date: Tue, 14 Jul 2015 11:48:20 +0300 Subject: [PATCH 13/44] Added support refresh_token_lifetime option --- Module.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Module.php b/Module.php index eb68adc..838a7ec 100755 --- a/Module.php +++ b/Module.php @@ -62,6 +62,11 @@ class Module extends \yii\base\Module */ public $tokenAccessLifetime; + /** + * @var integer Max refresh token lifetime in seconds + */ + public $tokenRefreshLifetime; + /** * @inheritdoc */ @@ -107,6 +112,7 @@ public function getServer() [ 'token_param_name' => $this->tokenParamName, 'access_lifetime' => $this->tokenAccessLifetime, + 'refresh_token_lifetime' => $this->tokenRefreshLifetime, /** add more ... */ ], $grantTypes, From 50231c62f15e2dbc3f418dc8794b93e37a4a67e5 Mon Sep 17 00:00:00 2001 From: Maliy Igor Date: Tue, 14 Jul 2015 13:18:05 +0300 Subject: [PATCH 14/44] Remove a fixed module ID --- Bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bootstrap.php b/Bootstrap.php index 72f6529..094fe38 100644 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -4,7 +4,7 @@ /** * Instead use bootstrap module - * must be removed in v2.1 + * should be removed in v2.1 version * * @deprecated v2.0.1 */ From a7c95fdcce0d9fa8d10608cbbcf0367dbc39b2bf Mon Sep 17 00:00:00 2001 From: Igor Maliy Date: Tue, 14 Jul 2015 13:29:57 +0300 Subject: [PATCH 15/44] Update README.md --- README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d186ca2..6c0b10e 100755 --- a/README.md +++ b/README.md @@ -25,20 +25,23 @@ to the require section of your composer.json. To use this extension, simply add the following code in your application configuration: ```php -'oauth2' => [ - 'class' => 'filsh\yii2\oauth2server\Module', - 'tokenParamName' => 'accessToken', - 'tokenAccessLifetime' => 3600 * 24, - 'storageMap' => [ - 'user_credentials' => 'common\models\User', - ], - 'grantTypes' => [ - 'user_credentials' => [ - 'class' => 'OAuth2\GrantType\UserCredentials', +'bootstrap' => ['oauth2'], +'modules' => [ + 'oauth2' => [ + 'class' => 'filsh\yii2\oauth2server\Module', + 'tokenParamName' => 'accessToken', + 'tokenAccessLifetime' => 3600 * 24, + 'storageMap' => [ + 'user_credentials' => 'common\models\User', ], - 'refresh_token' => [ - 'class' => 'OAuth2\GrantType\RefreshToken', - 'always_issue_new_refresh_token' => true + 'grantTypes' => [ + 'user_credentials' => [ + 'class' => 'OAuth2\GrantType\UserCredentials', + ], + 'refresh_token' => [ + 'class' => 'OAuth2\GrantType\RefreshToken', + 'always_issue_new_refresh_token' => true + ] ] ] ] From 4a98bc0ee3d99c1c994b8d59d5a673cb939fe911 Mon Sep 17 00:00:00 2001 From: femike Date: Sun, 20 Sep 2015 13:45:58 +0500 Subject: [PATCH 16/44] Created helpers for Authorization Code and update README.md --- Module.php | 31 ++++++++++++++++++++++++++++ README.md | 35 +++++++++++++++++++++++++++++++- Server.php | 11 ++++++++++ controllers/RestController.php | 37 ++++++++++++++++++---------------- 4 files changed, 96 insertions(+), 18 deletions(-) diff --git a/Module.php b/Module.php index 317247d..f3e911c 100755 --- a/Module.php +++ b/Module.php @@ -154,6 +154,37 @@ public function getResponse() return $this->get('response'); } + /** + * @param $response + */ + public function setResponse($response) + { + Yii::$app->response->setStatusCode($response->getStatusCode()); + $headers = Yii::$app->response->getHeaders(); + + foreach ($response->getHttpHeaders() as $name => $value) + $headers->set($name, $value); + } + + /** + * @param $is_authorized + * @param $user_id + * @return \OAuth2\ResponseInterface + * @throws \yii\base\InvalidConfigException + */ + public function handleAuthorizeRequest($is_authorized, $user_id) + { + $response = $this->getServer()->handleAuthorizeRequest( + $this->getRequest(), + $this->getResponse(), + $is_authorized, + $user_id + ); + $this->setResponse($response); + + return $response; + } + /** * Register translations for this module * diff --git a/README.md b/README.md index 6c0b10e..de96fb0 100755 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ add url rule to urlManager ```php 'urlManager' => [ 'rules' => [ - 'POST oauth2/' => 'oauth2/default/', + 'POST oauth2/' => 'oauth2/rest/', ... ] ] @@ -103,4 +103,37 @@ class Controller extends \yii\rest\Controller } ``` +Create action authorize in site controller for Authorization Code + +`https://api.mysite.com/authorize?response_type=code&client_id=TestClient&redirect_uri=https://fake/` + +[see more](http://bshaffer.github.io/oauth2-server-php-docs/grant-types/authorization-code/) + +```php +/** + * SiteController + */ +class SiteController extends Controller +{ + /** + * @return mixed + */ + public function actionAuthorize() + { + if (Yii::$app->getUser()->getIsGuest()) + return $this->redirect('login'); + + /** @var $module \filsh\yii2\oauth2server\Module */ + $module = Yii::$app->getModule('oauth2'); + $response = $module->handleAuthorizeRequest(!Yii::$app->getUser()->getIsGuest(), Yii::$app->getUser()->getId()); + + /** @var object $response \OAuth2\Response */ + Yii::$app->getResponse()->format = \yii\web\Response::FORMAT_JSON; + + return $response->getParameters(); + } +} +``` + + For more, see https://github.com/bshaffer/oauth2-server-php diff --git a/Server.php b/Server.php index 5535573..a7be272 100644 --- a/Server.php +++ b/Server.php @@ -38,4 +38,15 @@ public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OA } return parent::handleTokenRequest($request, $response); } + + public function handleAuthorizeRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $is_authorized = false, $user_id = null) + { + if($request === null) + $request = $this->module->getRequest(); + + if($response === null) + $response = $this->module->getResponse(); + + return parent::handleAuthorizeRequest($request, $response, $is_authorized, $user_id); + } } diff --git a/controllers/RestController.php b/controllers/RestController.php index c9978b3..32bb884 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -8,21 +8,24 @@ class RestController extends \yii\rest\Controller { - /** - * @inheritdoc - */ - public function behaviors() - { - return ArrayHelper::merge(parent::behaviors(), [ - 'exceptionFilter' => [ - 'class' => ErrorToExceptionFilter::className() - ], - ]); - } - - public function actionToken() - { - $response = $this->module->getServer()->handleTokenRequest(); - return $response->getParameters(); - } + /** + * @inheritdoc + */ + public function behaviors() + { + return ArrayHelper::merge(parent::behaviors(), [ + 'exceptionFilter' => [ + 'class' => ErrorToExceptionFilter::className() + ], + ]); + } + + public function actionToken() + { + $response = $this->module->getServer()->handleTokenRequest(); + + /** @var $response \OAuth2\Response */ + + return $response->getParameters(); + } } \ No newline at end of file From dfd349660bfbaf31c55511abb1b1df2d8d3a5480 Mon Sep 17 00:00:00 2001 From: Maliy Igor Date: Tue, 22 Sep 2015 10:17:02 +0300 Subject: [PATCH 17/44] Update codestyle --- Module.php | 13 ++++++------ Server.php | 13 ++++++------ controllers/RestController.php | 38 ++++++++++++++++------------------ 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Module.php b/Module.php index f3e911c..2de8d95 100755 --- a/Module.php +++ b/Module.php @@ -162,23 +162,24 @@ public function setResponse($response) Yii::$app->response->setStatusCode($response->getStatusCode()); $headers = Yii::$app->response->getHeaders(); - foreach ($response->getHttpHeaders() as $name => $value) + foreach ($response->getHttpHeaders() as $name => $value) { $headers->set($name, $value); + } } /** - * @param $is_authorized - * @param $user_id + * @param $isAuthorized + * @param $userId * @return \OAuth2\ResponseInterface * @throws \yii\base\InvalidConfigException */ - public function handleAuthorizeRequest($is_authorized, $user_id) + public function handleAuthorizeRequest($isAuthorized, $userId) { $response = $this->getServer()->handleAuthorizeRequest( $this->getRequest(), $this->getResponse(), - $is_authorized, - $user_id + $isAuthorized, + $userId ); $this->setResponse($response); diff --git a/Server.php b/Server.php index a7be272..df41d4a 100644 --- a/Server.php +++ b/Server.php @@ -39,14 +39,15 @@ public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OA return parent::handleTokenRequest($request, $response); } - public function handleAuthorizeRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $is_authorized = false, $user_id = null) + public function handleAuthorizeRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $isAuthorized = false, $userId = null) { - if($request === null) + if($request === null) { $request = $this->module->getRequest(); - - if($response === null) + } + if($response === null) { $response = $this->module->getResponse(); - - return parent::handleAuthorizeRequest($request, $response, $is_authorized, $user_id); + } + + return parent::handleAuthorizeRequest($request, $response, $isAuthorized, $userId); } } diff --git a/controllers/RestController.php b/controllers/RestController.php index 32bb884..a2d6770 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -8,24 +8,22 @@ class RestController extends \yii\rest\Controller { - /** - * @inheritdoc - */ - public function behaviors() - { - return ArrayHelper::merge(parent::behaviors(), [ - 'exceptionFilter' => [ - 'class' => ErrorToExceptionFilter::className() - ], - ]); - } + /** + * @inheritdoc + */ + public function behaviors() + { + return ArrayHelper::merge(parent::behaviors(), [ + 'exceptionFilter' => [ + 'class' => ErrorToExceptionFilter::className() + ], + ]); + } - public function actionToken() - { - $response = $this->module->getServer()->handleTokenRequest(); - - /** @var $response \OAuth2\Response */ - - return $response->getParameters(); - } -} \ No newline at end of file + public function actionToken() + { + /** @var $response \OAuth2\Response */ + $response = $this->module->getServer()->handleTokenRequest(); + return $response->getParameters(); + } +} From 1b7aebc6610c6a231c55c022650a72f001546de8 Mon Sep 17 00:00:00 2001 From: dmtux Date: Mon, 26 Oct 2015 18:17:33 +0200 Subject: [PATCH 18/44] Enforce State and Implicit Grant Type --- Module.php | 12 ++++++++++++ README.md | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/Module.php b/Module.php index 2de8d95..2a66070 100755 --- a/Module.php +++ b/Module.php @@ -68,6 +68,16 @@ class Module extends \yii\base\Module implements \yii\base\BootstrapInterface * @var integer Max refresh token lifetime in seconds */ public $tokenRefreshLifetime; + + /** + * @var bool enforce state flag + */ + public $enforceState; + + /** + * @var bool allow_implicit flag + */ + public $allowImplicit; /** * @inheritdoc @@ -127,6 +137,8 @@ public function getServer() 'token_param_name' => $this->tokenParamName, 'access_lifetime' => $this->tokenAccessLifetime, 'refresh_token_lifetime' => $this->tokenRefreshLifetime, + 'enforce_state' => $this->enforceState, + 'allow_implicit' => $this->allowImplicit /** add more ... */ ], $grantTypes, diff --git a/README.md b/README.md index de96fb0..17413f4 100755 --- a/README.md +++ b/README.md @@ -49,6 +49,12 @@ To use this extension, simply add the following code in your application config ```common\models\User``` - user model implementing an interface ```\OAuth2\Storage\UserCredentialsInterface```, so the oauth2 credentials data stored in user table +Additional OAuth2 Flags: + +```enforceState``` - Flag that switch that state controller should allow to use "state" param in the "Authorization Code" Grant Type + +```allowImplicit``` - Flag that switch that controller should allow the "implicit" grant type + The next step your shold run migration ```php @@ -135,5 +141,18 @@ class SiteController extends Controller } ``` +Also if you set ```allowImplicit => true``` you can use Implicit Grant Type - [see more](http://bshaffer.github.io/oauth2-server-php-docs/grant-types/implicit/) + +Request example: + +`https://api.mysite.com/authorize?response_type=token&client_id=TestClient&redirect_uri=https://fake/cb` + +With redirect response: + +`https://fake/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600` + + + + For more, see https://github.com/bshaffer/oauth2-server-php From 71866ae209e173270d42d5cd01e48dfe96dd2072 Mon Sep 17 00:00:00 2001 From: Denis Melskiy Date: Mon, 26 Oct 2015 18:19:45 +0200 Subject: [PATCH 19/44] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 17413f4..c731ee1 100755 --- a/README.md +++ b/README.md @@ -152,7 +152,4 @@ With redirect response: `https://fake/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600` - - - For more, see https://github.com/bshaffer/oauth2-server-php From d8c3aba65510f24945c5a984c8cfe2a670f7790b Mon Sep 17 00:00:00 2001 From: "Stefano D. Mtangoo" Date: Wed, 6 Jan 2016 01:46:54 +0300 Subject: [PATCH 20/44] Add Support for JWT Tokens --- Module.php | 95 +++++++++++++----------------------------------------- 1 file changed, 23 insertions(+), 72 deletions(-) diff --git a/Module.php b/Module.php index 2a66070..375a36d 100755 --- a/Module.php +++ b/Module.php @@ -4,6 +4,7 @@ use \Yii; use yii\i18n\PhpMessageSource; +use \array_key_exists; /** * For example, @@ -28,10 +29,8 @@ * ] * ``` */ -class Module extends \yii\base\Module implements \yii\base\BootstrapInterface +class Module extends \yii\base\Module { - use BootstrapTrait; - const VERSION = '2.0.0'; /** @@ -48,48 +47,20 @@ class Module extends \yii\base\Module implements \yii\base\BootstrapInterface * @var array GrantTypes collection */ public $grantTypes = []; - - /** - * @var array ResponseTypes collection - */ - public $responseTypes = []; /** - * @var string Name of access token parameter + * @var string name of access token parameter */ public $tokenParamName; /** - * @var integer Max access token lifetime in seconds + * @var type max access lifetime */ public $tokenAccessLifetime; - /** - * @var integer Max refresh token lifetime in seconds + * @var whether to use JWT tokens */ - public $tokenRefreshLifetime; - - /** - * @var bool enforce state flag - */ - public $enforceState; - - /** - * @var bool allow_implicit flag - */ - public $allowImplicit; - - /** - * @inheritdoc - */ - public function bootstrap($app) - { - $this->initModule($this); - - if ($app instanceof \yii\console\Application) { - $this->controllerNamespace = 'filsh\yii2\oauth2server\commands'; - } - } + public $useJwtToken = false;//ADDED /** * @inheritdoc @@ -110,6 +81,21 @@ public function getServer() { if(!$this->has('server')) { $storages = []; + + if($this->useJwtToken) + { + if(!array_key_exists('access_token', $this->storageMap) || !array_key_exists('public_key', $this->storageMap)) { + throw new \yii\base\InvalidConfigException('access_token and public_key must be set or set useJwtToken to false'); + } + //define dependencies when JWT is used instead of normal token + \Yii::$container->clear('public_key'); //remove old definition + \Yii::$container->set('public_key', $this->storageMap['public_key']); + \Yii::$container->set('OAuth2\Storage\PublicKeyInterface', $this->storageMap['public_key']); + + \Yii::$container->clear('access_token'); //remove old definition + \Yii::$container->set('access_token', $this->storageMap['access_token']); + } + foreach(array_keys($this->storageMap) as $name) { $storages[$name] = \Yii::$container->get($name); } @@ -134,15 +120,12 @@ public function getServer() $this, $storages, [ + 'use_jwt_access_tokens' => $this->useJwtToken,//ADDED 'token_param_name' => $this->tokenParamName, 'access_lifetime' => $this->tokenAccessLifetime, - 'refresh_token_lifetime' => $this->tokenRefreshLifetime, - 'enforce_state' => $this->enforceState, - 'allow_implicit' => $this->allowImplicit /** add more ... */ ], - $grantTypes, - $this->responseTypes + $grantTypes ]); $this->set('server', $server); @@ -166,38 +149,6 @@ public function getResponse() return $this->get('response'); } - /** - * @param $response - */ - public function setResponse($response) - { - Yii::$app->response->setStatusCode($response->getStatusCode()); - $headers = Yii::$app->response->getHeaders(); - - foreach ($response->getHttpHeaders() as $name => $value) { - $headers->set($name, $value); - } - } - - /** - * @param $isAuthorized - * @param $userId - * @return \OAuth2\ResponseInterface - * @throws \yii\base\InvalidConfigException - */ - public function handleAuthorizeRequest($isAuthorized, $userId) - { - $response = $this->getServer()->handleAuthorizeRequest( - $this->getRequest(), - $this->getResponse(), - $isAuthorized, - $userId - ); - $this->setResponse($response); - - return $response; - } - /** * Register translations for this module * From d8c921321f1d192930d185f34ae4f089596c457d Mon Sep 17 00:00:00 2001 From: "Stefano D. Mtangoo" Date: Wed, 6 Jan 2016 01:52:47 +0300 Subject: [PATCH 21/44] Explaining how to use JWT --- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/README.md b/README.md index c731ee1..64e1263 100755 --- a/README.md +++ b/README.md @@ -151,5 +151,79 @@ With redirect response: `https://fake/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600` +If you want to get Json Web Token (JWT) instead of convetional token, you will need to set `'useJwtToken' => true` in module and then define two more configurations: +`'public_key' => 'app\storage\PublicKeyStorage'` which is the class that implements [PublickKeyInterface](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/PublicKeyInterface.php) and `'access_token' => 'app\storage\JwtAccessToken'` which implements [JwtAccessTokenInterface.php](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessTokenInterface.php) + +For Oauth2 base library provides the default [access_token](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessToken.php) which works great except that it tries to save the token in the database. So I decided to inherit from it and override the part that tries to save (token size is too big and crashes with VARCHAR(40) in the database. + +TL;DR, here are the sample classes +**access_token** +```php + + */ +class JwtAccessToken extends \OAuth2\Storage\JwtAccessToken +{ + public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null) + { + + } + + public function unsetAccessToken($access_token) + { + + } +} + +``` + +and **public_key** + +```php +pbk = file_get_contents('privkey.pem', true); + $this->pvk = file_get_contents('pubkey.pem', true); + } + + public function getPublicKey($client_id = null){ + return $this->pbk; + } + + public function getPrivateKey($client_id = null){ + return $this->pvk; + } + + public function getEncryptionAlgorithm($client_id = null){ + return 'HS256'; + } + +} + +``` + For more, see https://github.com/bshaffer/oauth2-server-php From d4c6cf49277d0dcdd0d195d599ed95430e896988 Mon Sep 17 00:00:00 2001 From: "Stefano D. Mtangoo" Date: Sun, 7 Feb 2016 21:50:46 +0300 Subject: [PATCH 22/44] Fix documentation to simplify things in JWT things - Fixed code bug in PublicKeyStorage class - The Other class is really option --- README.md | 56 ++++++++++++++----------------------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 64e1263..bfacdfe 100755 --- a/README.md +++ b/README.md @@ -22,6 +22,13 @@ or add to the require section of your composer.json. +To use the latest features (Like JWT tokens), you need to use 2.0.1 branch. +Edit your compose.json and add + +```json +"filsh/yii2-oauth2-server": "2.0.1.x-dev" +``` + To use this extension, simply add the following code in your application configuration: ```php @@ -150,37 +157,11 @@ Request example: With redirect response: `https://fake/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600` - +### JWT Tokens (2.0.1 branch only) If you want to get Json Web Token (JWT) instead of convetional token, you will need to set `'useJwtToken' => true` in module and then define two more configurations: -`'public_key' => 'app\storage\PublicKeyStorage'` which is the class that implements [PublickKeyInterface](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/PublicKeyInterface.php) and `'access_token' => 'app\storage\JwtAccessToken'` which implements [JwtAccessTokenInterface.php](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessTokenInterface.php) +`'public_key' => 'app\storage\PublicKeyStorage'` which is the class that implements [PublickKeyInterface](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/PublicKeyInterface.php) and `'access_token' => 'OAuth2\Storage\JwtAccessToken'` which implements [JwtAccessTokenInterface.php](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessTokenInterface.php) -For Oauth2 base library provides the default [access_token](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessToken.php) which works great except that it tries to save the token in the database. So I decided to inherit from it and override the part that tries to save (token size is too big and crashes with VARCHAR(40) in the database. - -TL;DR, here are the sample classes -**access_token** -```php - - */ -class JwtAccessToken extends \OAuth2\Storage\JwtAccessToken -{ - public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null) - { - - } - - public function unsetAccessToken($access_token) - { - - } -} - -``` +For Oauth2 base library provides the default [access_token](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessToken.php) which works great except. Just use it and everything will be fine. and **public_key** @@ -196,17 +177,8 @@ class PublicKeyStorage implements \OAuth2\Storage\PublicKeyInterface{ public function __construct() { - //files should be in same directory as this file - //keys can be generated using OpenSSL tool with command: - /* - private key: - openssl genrsa -out privkey.pem 2048 - - public key: - openssl rsa -in privkey.pem -pubout -out pubkey.pem - */ - $this->pbk = file_get_contents('privkey.pem', true); - $this->pvk = file_get_contents('pubkey.pem', true); + $this->pvk = file_get_contents('privkey.pem', true); + $this->pbk = file_get_contents('pubkey.pem', true); } public function getPublicKey($client_id = null){ @@ -218,12 +190,12 @@ class PublicKeyStorage implements \OAuth2\Storage\PublicKeyInterface{ } public function getEncryptionAlgorithm($client_id = null){ - return 'HS256'; + return 'RS256'; } } -``` +``` For more, see https://github.com/bshaffer/oauth2-server-php From 0cb8034eb65d6bafb55f4fd988948097f77f56a7 Mon Sep 17 00:00:00 2001 From: Andrii Vasyliev Date: Wed, 17 Feb 2016 12:44:29 +0000 Subject: [PATCH 23/44] added `Module::$options` in a compatible fashion --- Module.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Module.php b/Module.php index 375a36d..2573aab 100755 --- a/Module.php +++ b/Module.php @@ -48,6 +48,11 @@ class Module extends \yii\base\Module */ public $grantTypes = []; + /** + * @var array server options + */ + public $options = []; + /** * @var string name of access token parameter */ @@ -119,12 +124,12 @@ public function getServer() $server = \Yii::$container->get(Server::className(), [ $this, $storages, - [ + array_merge(array_filter([ 'use_jwt_access_tokens' => $this->useJwtToken,//ADDED 'token_param_name' => $this->tokenParamName, 'access_lifetime' => $this->tokenAccessLifetime, /** add more ... */ - ], + ]), $this->options), $grantTypes ]); From 60a555b6ef9bd193c7ee210ad51f53f41c62f78f Mon Sep 17 00:00:00 2001 From: lisps Date: Thu, 7 Apr 2016 17:20:18 +0200 Subject: [PATCH 24/44] add revoke request action --- controllers/RestController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/controllers/RestController.php b/controllers/RestController.php index a2d6770..d953ae7 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -26,4 +26,11 @@ public function actionToken() $response = $this->module->getServer()->handleTokenRequest(); return $response->getParameters(); } + + public function actionRevoke() + { + /** @var $response \OAuth2\Response */ + $response = $this->module->getServer()->handleRevokeRequest(); + return $response->getParameters(); + } } From 6af49834dea3767d638a4d646b8864fc8267e794 Mon Sep 17 00:00:00 2001 From: lisps Date: Thu, 7 Apr 2016 17:22:14 +0200 Subject: [PATCH 25/44] add revoke request to Server.php --- Server.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Server.php b/Server.php index df41d4a..718b0eb 100644 --- a/Server.php +++ b/Server.php @@ -38,6 +38,14 @@ public function handleTokenRequest(\OAuth2\RequestInterface $request = null, \OA } return parent::handleTokenRequest($request, $response); } + + public function handleRevokeRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) + { + if($request === null) { + $request = $this->module->getRequest(); + } + return parent::handleRevokeRequest($request, $response); + } public function handleAuthorizeRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null, $isAuthorized = false, $userId = null) { From d4938c26e7a24775c78d440ecf8b0474ce83b06b Mon Sep 17 00:00:00 2001 From: Eric Bus Date: Fri, 29 Apr 2016 11:58:37 +0200 Subject: [PATCH 26/44] Manual merge of https://github.com/Filsh/yii2-oauth2-server/pull/75/files --- Module.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Module.php b/Module.php index 375a36d..bf00c90 100755 --- a/Module.php +++ b/Module.php @@ -48,6 +48,11 @@ class Module extends \yii\base\Module */ public $grantTypes = []; + /** + * @var array server options + */ + public $options = []; + /** * @var string name of access token parameter */ @@ -119,12 +124,12 @@ public function getServer() $server = \Yii::$container->get(Server::className(), [ $this, $storages, - [ + array_merge(array_filter([ 'use_jwt_access_tokens' => $this->useJwtToken,//ADDED 'token_param_name' => $this->tokenParamName, 'access_lifetime' => $this->tokenAccessLifetime, /** add more ... */ - ], + ]), $this->options), $grantTypes ]); From 54a1d41a66b42d23a9ea941c9f946baf97a27b26 Mon Sep 17 00:00:00 2001 From: Ruslan Bes Date: Tue, 12 Jul 2016 11:53:25 +0200 Subject: [PATCH 27/44] Fix for migration error [Issue 45] https://github.com/Filsh/yii2-oauth2-server/issues/45 Renamed primaryKey() -> primaryKeyDefinition() to avoid naming collision with \yii\db\SchemaBuilderTrait::primaryKey() also renamed foreignKey() -> foreignkeyDefinition() for consistency --- .../m140501_075311_add_oauth2_server.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/migrations/m140501_075311_add_oauth2_server.php b/migrations/m140501_075311_add_oauth2_server.php index a34fccb..3f1fd1d 100755 --- a/migrations/m140501_075311_add_oauth2_server.php +++ b/migrations/m140501_075311_add_oauth2_server.php @@ -9,11 +9,11 @@ public function mysql($yes,$no='') { return $this->db->driverName === 'mysql' ? $yes : $no; } - public function primaryKey($columns) { + public function primaryKeyDefinition($columns) { return 'PRIMARY KEY (' . $this->db->getQueryBuilder()->buildColumns($columns) . ')'; } - public function foreignKey($columns,$refTable,$refColumns,$onDelete = null,$onUpdate = null) { + public function foreignKeyDefinition($columns,$refTable,$refColumns,$onDelete = null,$onUpdate = null) { $builder = $this->db->getQueryBuilder(); $sql = ' FOREIGN KEY (' . $builder->buildColumns($columns) . ')' . ' REFERENCES ' . $this->db->quoteTableName($refTable) @@ -46,7 +46,7 @@ public function up() 'grant_types' => Schema::TYPE_STRING . '(100) NOT NULL', 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', - $this->primaryKey('client_id'), + $this->primaryKeyDefinition('client_id'), ], $tableOptions); $this->createTable('{{%oauth_access_tokens}}', [ @@ -55,8 +55,8 @@ public function up() 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', - $this->primaryKey('access_token'), - $this->foreignKey('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), + $this->primaryKeyDefinition('access_token'), + $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), ], $tableOptions); $this->createTable('{{%oauth_refresh_tokens}}', [ @@ -65,8 +65,8 @@ public function up() 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', - $this->primaryKey('refresh_token'), - $this->foreignKey('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), + $this->primaryKeyDefinition('refresh_token'), + $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), ], $tableOptions); $this->createTable('{{%oauth_authorization_codes}}', [ @@ -76,8 +76,8 @@ public function up() 'redirect_uri' => Schema::TYPE_STRING . '(1000) NOT NULL', 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', - $this->primaryKey('authorization_code'), - $this->foreignKey('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), + $this->primaryKeyDefinition('authorization_code'), + $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), ], $tableOptions); $this->createTable('{{%oauth_scopes}}', [ @@ -89,7 +89,7 @@ public function up() 'client_id' => Schema::TYPE_STRING . '(32) NOT NULL', 'subject' => Schema::TYPE_STRING . '(80) DEFAULT NULL', 'public_key' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', - $this->primaryKey('client_id'), + $this->primaryKeyDefinition('client_id'), ], $tableOptions); $this->createTable('{{%oauth_users}}', [ @@ -97,7 +97,7 @@ public function up() 'password' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', 'first_name' => Schema::TYPE_STRING . '(255) DEFAULT NULL', 'last_name' => Schema::TYPE_STRING . '(255) DEFAULT NULL', - $this->primaryKey('username'), + $this->primaryKeyDefinition('username'), ], $tableOptions); $this->createTable('{{%oauth_public_keys}}', [ From d7e798df33bfbb102a3cbb4404713d6a96f6f15f Mon Sep 17 00:00:00 2001 From: Eric Bus Date: Tue, 23 Aug 2016 10:25:38 +0200 Subject: [PATCH 28/44] Added storageName property to grantTypes map. --- Module.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Module.php b/Module.php index 2573aab..6c42106 100755 --- a/Module.php +++ b/Module.php @@ -107,7 +107,8 @@ public function getServer() $grantTypes = []; foreach($this->grantTypes as $name => $options) { - if(!isset($storages[$name]) || empty($options['class'])) { + $storageName = !empty($options['storageName']) ? $options['storageName'] : $name; + if(!isset($storages[$storageName]) || empty($options['class'])) { throw new \yii\base\InvalidConfigException('Invalid grant types configuration.'); } @@ -115,7 +116,7 @@ public function getServer() unset($options['class']); $reflection = new \ReflectionClass($class); - $config = array_merge([0 => $storages[$name]], [$options]); + $config = array_merge([0 => $storages[$storageName]], [$options]); $instance = $reflection->newInstanceArgs($config); $grantTypes[$name] = $instance; From 5103178dcb2e7e28fbda764f2076a48cb1e1da02 Mon Sep 17 00:00:00 2001 From: Eric Bus Date: Tue, 23 Aug 2016 11:09:52 +0200 Subject: [PATCH 29/44] Add the HTTP headers when parsing a OAuth2 response. --- filters/ErrorToExceptionFilter.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index 2b6967d..5307fc9 100755 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -25,6 +25,12 @@ public function events() public function afterAction($event) { $response = Module::getInstance()->getServer()->getResponse(); + $headers = $response->getHttpHeaders(); + if (!empty($headers)) { + foreach ($headers as $k => $v) { + Yii::$app->response->headers[$k] = $v; + } + } $isValid = true; if($response !== null) { From ba7c7f0bf622114d1842db5a80103486cb976925 Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Mon, 7 Nov 2016 19:54:06 -0800 Subject: [PATCH 30/44] Add OpenID Connect UserInfo end-point to REST controller --- Server.php | 9 +++++++++ controllers/RestController.php | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/Server.php b/Server.php index 718b0eb..fbd158b 100644 --- a/Server.php +++ b/Server.php @@ -58,4 +58,13 @@ public function handleAuthorizeRequest(\OAuth2\RequestInterface $request = null, return parent::handleAuthorizeRequest($request, $response, $isAuthorized, $userId); } + + public function handleUserInfoRequest(\OAuth2\RequestInterface $request = null, \OAuth2\ResponseInterface $response = null) + { + if($request === null) { + $request = $this->module->getRequest(); + } + return parent::handleUserInfoRequest($request, $response); + } + } diff --git a/controllers/RestController.php b/controllers/RestController.php index d953ae7..8e88eda 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -33,4 +33,10 @@ public function actionRevoke() $response = $this->module->getServer()->handleRevokeRequest(); return $response->getParameters(); } + + public function actionUserInfo() + { + $response = $this->module->getServer()->handleUserInfoRequest(); + return $response->getParameters(); + } } From 91cb3bf56925c6e89c04abfb3d287ffe27ede9b6 Mon Sep 17 00:00:00 2001 From: ldrc2895 Date: Thu, 18 Jan 2018 11:15:44 -0600 Subject: [PATCH 31/44] Migration Support for Oracle --- .gitignore | 1 + .../m140501_075311_add_oauth2_server.php | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 3542b8e..217ce5d 100755 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ nbproject Thumbs.db *.sublime-project *.sublime-workspace +composer.lock diff --git a/migrations/m140501_075311_add_oauth2_server.php b/migrations/m140501_075311_add_oauth2_server.php index 3f1fd1d..1880dd3 100755 --- a/migrations/m140501_075311_add_oauth2_server.php +++ b/migrations/m140501_075311_add_oauth2_server.php @@ -5,10 +5,39 @@ class m140501_075311_add_oauth2_server extends \yii\db\Migration { + private $driverKeyWords = [ + "CURRENT_TIMESTAMP"=>[ + 'oci'=>'CURRENT_TIMESTAMP', + 'mysql'=>'CURRENT_TIMESTAMP', + 'default'=>'now' + ] + ]; + + + public function getCurrentTimestampKeyWord() + { + $driverKeywords = $this->driverKeyWords["CURRENT_TIMESTAMP"]; + $driver = $this->db->driverName; + if(key_exists($driver,$driverKeywords)) + { + return $driverKeywords[$driver]; + } + return $driverKeywords['default']; + } + + public function mysql($yes,$no='') { return $this->db->driverName === 'mysql' ? $yes : $no; } + public function isOracle($yes,$no='') + { + return $this->db->driverName =='oci'? $yes:$no; + } + + + + public function primaryKeyDefinition($columns) { return 'PRIMARY KEY (' . $this->db->getQueryBuilder()->buildColumns($columns) . ')'; } @@ -22,7 +51,8 @@ public function foreignKeyDefinition($columns,$refTable,$refColumns,$onDelete = $sql .= ' ON DELETE ' . $onDelete; } if ($onUpdate !== null) { - $sql .= ' ON UPDATE ' . $onUpdate; + + $sql .= $this->isOracle('',' ON UPDATE ' . $onUpdate); } return $sql; } @@ -34,7 +64,7 @@ public function up() $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; } - $now = $this->mysql('CURRENT_TIMESTAMP',"'now'"); + $now = $this->getCurrentTimestampKeyWord(); $on_update_now = $this->mysql("ON UPDATE $now"); $transaction = $this->db->beginTransaction(); @@ -53,7 +83,7 @@ public function up() 'access_token' => Schema::TYPE_STRING . '(40) NOT NULL', 'client_id' => Schema::TYPE_STRING . '(32) NOT NULL', 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', - 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", + 'expires' => Schema::TYPE_TIMESTAMP . " DEFAULT $now $on_update_now NOT NULL ", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', $this->primaryKeyDefinition('access_token'), $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), @@ -63,7 +93,7 @@ public function up() 'refresh_token' => Schema::TYPE_STRING . '(40) NOT NULL', 'client_id' => Schema::TYPE_STRING . '(32) NOT NULL', 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', - 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", + 'expires' => Schema::TYPE_TIMESTAMP . " DEFAULT $now $on_update_now NOT NULL ", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', $this->primaryKeyDefinition('refresh_token'), $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), @@ -74,7 +104,7 @@ public function up() 'client_id' => Schema::TYPE_STRING . '(32) NOT NULL', 'user_id' => Schema::TYPE_INTEGER . ' DEFAULT NULL', 'redirect_uri' => Schema::TYPE_STRING . '(1000) NOT NULL', - 'expires' => Schema::TYPE_TIMESTAMP . " NOT NULL DEFAULT $now $on_update_now", + 'expires' => Schema::TYPE_TIMESTAMP . " DEFAULT $now $on_update_now NOT NULL ", 'scope' => Schema::TYPE_STRING . '(2000) DEFAULT NULL', $this->primaryKeyDefinition('authorization_code'), $this->foreignKeyDefinition('client_id','{{%oauth_clients}}','client_id','CASCADE','CASCADE'), From a3d4fe89ce3abb385b3e3ef8932cf4378b736699 Mon Sep 17 00:00:00 2001 From: ldrc2895 Date: Thu, 18 Jan 2018 12:20:10 -0600 Subject: [PATCH 32/44] Fix readme.md --- README.md | 168 +----------------------------------------------------- 1 file changed, 3 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index d2dde18..bfacdfe 100755 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ or add to the require section of your composer.json. -<<<<<<< HEAD To use the latest features (Like JWT tokens), you need to use 2.0.1 branch. Edit your compose.json and add @@ -49,155 +48,13 @@ To use this extension, simply add the following code in your application config 'refresh_token' => [ 'class' => 'OAuth2\GrantType\RefreshToken', 'always_issue_new_refresh_token' => true -======= -To use this extension, simply add the following code in your application configuration as a new module: - -```php -'modules'=>[ - //other modules ..... - 'oauth2' => [ - 'class' => 'filsh\yii2\oauth2server\Module', - 'tokenParamName' => 'accessToken', - 'tokenAccessLifetime' => 3600 * 24, - 'storageMap' => [ - 'user_credentials' => 'app\models\User', - ], - 'grantTypes' => [ - 'user_credentials' => [ - 'class' => 'OAuth2\GrantType\UserCredentials', - ], - 'refresh_token' => [ - 'class' => 'OAuth2\GrantType\RefreshToken', - 'always_issue_new_refresh_token' => true - ] ->>>>>>> master ] ] - ], -``` -If you want to get Json Web Token (JWT) instead of convetional token, you will need to set `'useJwtToken' => true` in module and then define two more configurations: -`'public_key' => 'app\storage\PublicKeyStorage'` which is the class that implements [PublickKeyInterface](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/PublicKeyInterface.php) and `'access_token' => 'app\storage\JwtAccessToken'` which implements [JwtAccessTokenInterface.php](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessTokenInterface.php) - -For Oauth2 base library provides the default [access_token](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessToken.php) which works great except that it tries to save the token in the database. So I decided to inherit from it and override the part that tries to save (token size is too big and crashes with VARCHAR(40) in the database. - -TL;DR, here are the sample classes -**access_token** -```php - - */ -class JwtAccessToken extends \OAuth2\Storage\JwtAccessToken -{ - public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null) - { - - } - - public function unsetAccessToken($access_token) - { - - } -} - -``` - -and **public_key** - -```php -pbk = file_get_contents('privkey.pem', true); - $this->pvk = file_get_contents('pubkey.pem', true); - } - - public function getPublicKey($client_id = null){ - return $this->pbk; - } - - public function getPrivateKey($client_id = null){ - return $this->pvk; - } - - public function getEncryptionAlgorithm($client_id = null){ - return 'HS256'; - } - -} - -``` -**NOTE:** You will need [this](https://github.com/bshaffer/oauth2-server-php/pull/690) PR applied or you can patch it yourself by checking changes in [this diff](https://github.com/hosannahighertech/oauth2-server-php/commit/ec79732663547065c041e279109137a423eac0cb). The other part of PR is only if you want to use firebase JWT library (which is not mandatory anyway). - -Also, extend ```common\models\User``` - user model - implementing the interface ```\OAuth2\Storage\UserCredentialsInterface```, so the oauth2 credentials data stored in user table. -You should implement: -- findIdentityByAccessToken() -- checkUserCredentials() -- getUserDetails() - -You can extend the model if you prefer it (please, remember to update the config files) : + ] +] ``` -use Yii; -class User extends common\models\User implements \OAuth2\Storage\UserCredentialsInterface -{ - - /** - * Implemented for Oauth2 Interface - */ - public static function findIdentityByAccessToken($token, $type = null) - { - /** @var \filsh\yii2\oauth2server\Module $module */ - $module = Yii::$app->getModule('oauth2'); - $token = $module->getServer()->getResourceController()->getToken(); - return !empty($token['user_id']) - ? static::findIdentity($token['user_id']) - : null; - } - - /** - * Implemented for Oauth2 Interface - */ - public function checkUserCredentials($username, $password) - { - $user = static::findByUsername($username); - if (empty($user)) { - return false; - } - return $user->validatePassword($password); - } - - /** - * Implemented for Oauth2 Interface - */ - public function getUserDetails($username) - { - $user = static::findByUsername($username); - return ['user_id' => $user->getId()]; - } -} -``` +```common\models\User``` - user model implementing an interface ```\OAuth2\Storage\UserCredentialsInterface```, so the oauth2 credentials data stored in user table Additional OAuth2 Flags: @@ -217,7 +74,6 @@ add url rule to urlManager ```php 'urlManager' => [ - 'enablePrettyUrl' => true, //only if you want to use petty URLs 'rules' => [ 'POST oauth2/' => 'oauth2/rest/', ... @@ -260,7 +116,6 @@ class Controller extends \yii\rest\Controller } ``` -<<<<<<< HEAD Create action authorize in site controller for Authorization Code `https://api.mysite.com/authorize?response_type=code&client_id=TestClient&redirect_uri=https://fake/` @@ -343,21 +198,4 @@ class PublicKeyStorage implements \OAuth2\Storage\PublicKeyInterface{ ``` -======= -To get access token (js example): - -```js -var url = window.location.host + "/oauth2/token"; -var data = { - 'grant_type':'password', - 'username':'', - 'password':'', - 'client_id':'testclient', - 'client_secret':'testpass' -}; -//ajax POST `data` to `url` here -// -``` - ->>>>>>> master For more, see https://github.com/bshaffer/oauth2-server-php From 24d4b58f2493dc2aca146029cbc6ec441dbe59bf Mon Sep 17 00:00:00 2001 From: ldrc2895 Date: Thu, 18 Jan 2018 12:46:57 -0600 Subject: [PATCH 33/44] Error To Exception Filter fix --- filters/ErrorToExceptionFilter.php | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index 4d1d967..a0650d4 100755 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -1,12 +1,9 @@ 'afterAction']; } - /** * @param ActionEvent $event * @return boolean @@ -25,7 +21,6 @@ public function events() public function afterAction($event) { $response = Module::getInstance()->getServer()->getResponse(); - $isValid = true; if($response !== null) { $isValid = $response->isInformational() || $response->isSuccessful() || $response->isRedirection(); @@ -34,25 +29,13 @@ public function afterAction($event) 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.'); - $response = Yii::$app->getModule('oauth2')->getServer()->getResponse(); - $optional = $event->action->controller->getBehavior('authenticator')->optional; - $currentAction = $event->action->id; - $isValid = true; - if (!in_array($currentAction, $optional)) { - if ($response !== null) { - $isValid = $response->isInformational() || $response->isSuccessful() || $response->isRedirection(); - } - if (!$isValid) { - throw new HttpException($response->getStatusCode(), $this->getErrorMessage($response), - $response->getParameter('error_uri')); - } } return $message; } -} +} \ No newline at end of file From 09cc3a76546105fa0a5e2fc6355bd73062bc7e2e Mon Sep 17 00:00:00 2001 From: ldrc2895 Date: Thu, 18 Jan 2018 12:59:00 -0600 Subject: [PATCH 34/44] Module fix --- Module.php | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/Module.php b/Module.php index 2788f28..418bd4a 100755 --- a/Module.php +++ b/Module.php @@ -3,9 +3,10 @@ use \Yii; use yii\i18n\PhpMessageSource; use \array_key_exists; +use yii\helpers\ArrayHelper; /** * For example, - * + * * ```php * 'oauth2' => [ * 'class' => 'filsh\yii2\oauth2server\Module', @@ -29,27 +30,22 @@ class Module extends \yii\base\Module { const VERSION = '2.0.0'; - /** * @var array Model's map */ public $modelMap = []; - /** * @var array Storage's map */ public $storageMap = []; - /** * @var array GrantTypes collection */ public $grantTypes = []; - /** * @var string name of access token parameter */ public $tokenParamName; - /** * @var type max access lifetime */ @@ -58,7 +54,6 @@ class Module extends \yii\base\Module * @var whether to use JWT tokens */ public $useJwtToken = false;//ADDED - /** * @inheritdoc */ @@ -67,10 +62,9 @@ public function init() parent::init(); $this->registerTranslations(); } - /** * Gets Oauth2 Server - * + * * @return \filsh\yii2\oauth2server\Server * @throws \yii\base\InvalidConfigException */ @@ -78,11 +72,10 @@ public function getServer() { if(!$this->has('server')) { $storages = []; - if($this->useJwtToken) { if(!array_key_exists('access_token', $this->storageMap) || !array_key_exists('public_key', $this->storageMap)) { - throw new \yii\base\InvalidConfigException('access_token and public_key must be set or set useJwtToken to false'); + throw new \yii\base\InvalidConfigException('access_token and public_key must be set or set useJwtToken to false'); } //define dependencies when JWT is used instead of normal token \Yii::$container->clear('public_key'); //remove old definition @@ -91,11 +84,9 @@ public function getServer() \Yii::$container->clear('access_token'); //remove old definition \Yii::$container->set('access_token', $this->storageMap['access_token']); } - 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'])) { @@ -108,7 +99,6 @@ public function getServer() $instance = $reflection->newInstanceArgs($config); $grantTypes[$name] = $instance; } - $server = \Yii::$container->get(Server::className(), [ $this, $storages, @@ -124,25 +114,23 @@ public function getServer() } return $this->get('server'); } - public function getRequest() { - if(!$this->has('request')) { + if(!ArrayHelper::keyExists('request', $this->getComponents())) { $this->set('request', Request::createFromGlobals()); } return $this->get('request'); } - public function getResponse() { - if(!$this->has('response')) { + if(!ArrayHelper::keyExists('request', $this->getComponents())) { $this->set('response', new Response()); } return $this->get('response'); } /** * Register translations for this module - * + * * @return array */ public function registerTranslations() @@ -154,10 +142,9 @@ public function registerTranslations() ]; } } - /** * Translate module message - * + * * @param string $category * @param string $message * @param array $params From 07b8024c600c2c0f7cc1a822e8371015c380a467 Mon Sep 17 00:00:00 2001 From: Riza Date: Wed, 13 Feb 2019 16:03:26 +0700 Subject: [PATCH 35/44] Add Support Cors --- controllers/RestController.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/controllers/RestController.php b/controllers/RestController.php index 8e88eda..788ef57 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -5,6 +5,7 @@ use Yii; use yii\helpers\ArrayHelper; use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter; +use yii\filters\Cors; class RestController extends \yii\rest\Controller { @@ -17,9 +18,20 @@ public function behaviors() 'exceptionFilter' => [ 'class' => ErrorToExceptionFilter::className() ], + 'corsFilter' => [ + 'class' => Cors::className() // some custom config inside the class + ], ]); } + public function actionOptions() + { + + Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', ['OPTIONS', 'POST'])); + + } + + public function actionToken() { /** @var $response \OAuth2\Response */ From 401218783100a86fbf124afeadfb026fcb7f7195 Mon Sep 17 00:00:00 2001 From: Synida Date: Wed, 27 Mar 2019 19:11:32 +0300 Subject: [PATCH 36/44] Fixing the error message problem in the exception file --- README.md | 4 ++-- composer.json | 2 +- filters/ErrorToExceptionFilter.php | 10 +++++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dceda81..5b84511 100755 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ add "repositories": [ { "type": "vcs", - "url": "https://github.com/miolae/yii2-oauth2-server.git" + "url": "https://github.com/Synida/yii2-oauth2-server.git" } ], "require": { - "filsh/yii2-oauth2-server": "dev-master", + "filsh/yii2-oauth2-server": "~2.0", } ``` diff --git a/composer.json b/composer.json index 9b02cc2..f4c1038 100755 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ }, "require": { "yiisoft/yii2": "*", - "bshaffer/oauth2-server-php": "~1.10.0" + "bshaffer/oauth2-server-php": "~1.11.1" }, "autoload": { "psr-4": { diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index aa48ac0..6651364 100755 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -8,6 +8,10 @@ use filsh\yii2\oauth2server\Module; use filsh\yii2\oauth2server\exceptions\HttpException; +/** + * Class ErrorToExceptionFilter + * @package filsh\yii2\oauth2server\filters + */ class ErrorToExceptionFilter extends \yii\base\Behavior { /** @@ -38,9 +42,13 @@ public function afterAction($event) $response->getParameter('error_uri')); } } - return $message; + return $isValid; } + /** + * @param Response $response + * @return mixed + */ protected function getErrorMessage(Response $response) { return $response->getParameter('error'); From fa532077bd2a69b8ab19ca314388013fbd0f288e Mon Sep 17 00:00:00 2001 From: Synida Date: Wed, 27 Mar 2019 19:28:34 +0300 Subject: [PATCH 37/44] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b84511..28d1479 100755 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ add } ], "require": { - "filsh/yii2-oauth2-server": "~2.0", + "filsh/yii2-oauth2-server": "dev-master", } ``` From 694e31ffc66b77dc7040f49dc8683b34752a7dc5 Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Tue, 24 Dec 2019 20:01:16 -0800 Subject: [PATCH 38/44] Use newer bshaffer package --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7052c37..1e26929 100755 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "yiisoft/yii2": "*", - "bshaffer/oauth2-server-php": "~1.7" + "bshaffer/oauth2-server-php": "~1.11" }, "autoload": { "psr-4": { From 9bb54002aa13cba924d93f53f82195d5cf56e7fa Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Tue, 24 Dec 2019 20:07:09 -0800 Subject: [PATCH 39/44] Rename package and update readme --- README.md | 56 +++++---------------------------------------------- composer.json | 6 +++--- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 4d29c61..687401e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -yii2-oauth2-server +yii2-oauth2-authorization-server ================== +## This is a fork of [filsh/yii2-oauth2-server](https://github.org/filsh/yii2-oauth2-server) with latest patches from various forks thereof. + A wrapper for implementing an OAuth2 Server(https://github.com/bshaffer/oauth2-server-php) Installation @@ -11,24 +13,17 @@ The preferred way to install this extension is through [composer](http://getcomp Either run ``` -php composer.phar require --prefer-dist filsh/yii2-oauth2-server "*" +php composer.phar require --prefer-dist pinfirestudios/yii2-oauth2-authorization-server "*" ``` or add ```json -"filsh/yii2-oauth2-server": "~2.0" +"pinirestudios/yii2-oauth2-authorization-server": "~2.1" ``` to the require section of your composer.json. -To use the latest features (Like JWT tokens), you need to use 2.0.1 branch. -Edit your compose.json and add - -```json -"filsh/yii2-oauth2-server": "2.0.1.x-dev" -``` - To use this extension, simply add the following code in your application configuration: ```php @@ -277,45 +272,4 @@ Request example: With redirect response: `https://fake/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=bearer&expires_in=3600` -### JWT Tokens (2.0.1 branch only) -If you want to get Json Web Token (JWT) instead of convetional token, you will need to set `'useJwtToken' => true` in module and then define two more configurations: -`'public_key' => 'app\storage\PublicKeyStorage'` which is the class that implements [PublickKeyInterface](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/PublicKeyInterface.php) and `'access_token' => 'OAuth2\Storage\JwtAccessToken'` which implements [JwtAccessTokenInterface.php](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessTokenInterface.php) - -For Oauth2 base library provides the default [access_token](https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Storage/JwtAccessToken.php) which works great except. Just use it and everything will be fine. - -and **public_key** - -```php -pvk = file_get_contents('privkey.pem', true); - $this->pbk = file_get_contents('pubkey.pem', true); - } - - public function getPublicKey($client_id = null){ - return $this->pbk; - } - - public function getPrivateKey($client_id = null){ - return $this->pvk; - } - - public function getEncryptionAlgorithm($client_id = null){ - return 'RS256'; - } - -} - -``` - - For more, see https://github.com/bshaffer/oauth2-server-php diff --git a/composer.json b/composer.json index 1e26929..0b90d5c 100755 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name": "filsh/yii2-oauth2-server", - "description": "OAuth2 Server for PHP", + "name": "pinfirestudios/yii2-oauth2-authorization-server", + "description": "OAuth2 Authorization Server for Yii2. Fork of abandoned filsh/yii2-oauth2-server package", "keywords": ["yii", "extension", "module", "oauth", "oauth2"], - "homepage": "https://github.com/filsh/yii2-oauth2-server", + "homepage": "https://github.com/pinfirestudios/yii2-oauth2-authorization-server", "type": "yii2-extension", "license": "MIT", "support": { From 71335ef2ff037618976e77c5d34296c40d0b06cd Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Tue, 24 Dec 2019 20:12:21 -0800 Subject: [PATCH 40/44] Rename branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0b90d5c..6555e29 100755 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "extra": { "bootstrap": "filsh\\yii2\\oauth2server\\Bootstrap", "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.1.x-dev" } } } From 0de53af1bff1c42f26a4c82d7e96d75399a6aeda Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Tue, 24 Dec 2019 23:49:09 -0800 Subject: [PATCH 41/44] Add filter that lets you validate a request has a valid 'Client Credentials'-type token --- filters/auth/ClientTokenAuth.php | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 filters/auth/ClientTokenAuth.php diff --git a/filters/auth/ClientTokenAuth.php b/filters/auth/ClientTokenAuth.php new file mode 100644 index 0000000..0a881ae --- /dev/null +++ b/filters/auth/ClientTokenAuth.php @@ -0,0 +1,65 @@ +getServer(); + $server->verifyResourceRequest(); + + $token = $server->getResourceController()->getToken(); + if (empty($token['user_id'])) { + return true; + } + + if ($this->denyCallback !== null) { + call_user_func($this->denyCallback, $action); + } else { + $this->denyAccess(); + } + + return false; + } + + /** + * Denies the access of the user. + * The default implementation will throw a 403 HTTP exception. + * @throws ForbiddenHttpException + */ + protected function denyAccess() + { + throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.')); + } +} From a36ffa770c3f8abac86e074bcfa38d048cb8c379 Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Wed, 25 Dec 2019 02:42:05 -0800 Subject: [PATCH 42/44] Rewrite ErrorToExceptionFilter to actually be an ActionFilter, not just emulating one --- filters/ErrorToExceptionFilter.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/filters/ErrorToExceptionFilter.php b/filters/ErrorToExceptionFilter.php index 2b6967d..ff5b0ef 100644 --- a/filters/ErrorToExceptionFilter.php +++ b/filters/ErrorToExceptionFilter.php @@ -7,22 +7,13 @@ use filsh\yii2\oauth2server\Module; use filsh\yii2\oauth2server\exceptions\HttpException; -class ErrorToExceptionFilter extends \yii\base\Behavior +class ErrorToExceptionFilter extends \yii\base\ActionFilter { /** * @inheritdoc - */ - public function events() - { - return [Controller::EVENT_AFTER_ACTION => 'afterAction']; - } - - /** - * @param ActionEvent $event - * @return boolean * @throws HttpException when the request method is not allowed. */ - public function afterAction($event) + public function afterAction($action, $result) { $response = Module::getInstance()->getServer()->getResponse(); From 714b3604b5b3c6ecedd01c6ad6c8738bcfa1f16d Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Wed, 25 Dec 2019 03:26:06 -0800 Subject: [PATCH 43/44] Typo fix from merges in Module::getResponse --- Module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Module.php b/Module.php index 1fba8d0..aa4d79d 100644 --- a/Module.php +++ b/Module.php @@ -151,7 +151,7 @@ public function getRequest() public function getResponse() { - if(!ArrayHelper::keyExists('request', $this->getComponents())) { + if(!ArrayHelper::keyExists('response', $this->getComponents())) { $this->set('response', new Response()); } return $this->get('response'); From 81238311027962d7559b8c0bf1b943fa53e0e21d Mon Sep 17 00:00:00 2001 From: Justin Cherniak Date: Wed, 25 Dec 2019 04:02:05 -0800 Subject: [PATCH 44/44] Add Introspect endpoint Cherry picked from https://github.com/mobilejazz-contrib/yii2-oauth2-server/commit/2770631110efd9cb5e05f8f45a8e2df76877864b --- controllers/RestController.php | 40 ++++++++++++++++++++++++++++++---- messages/en/common.php | 3 ++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/controllers/RestController.php b/controllers/RestController.php index 788ef57..8046d38 100755 --- a/controllers/RestController.php +++ b/controllers/RestController.php @@ -5,6 +5,7 @@ use Yii; use yii\helpers\ArrayHelper; use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter; +use filsh\yii2\oauth2server\models\OauthAccessTokens; use yii\filters\Cors; class RestController extends \yii\rest\Controller @@ -18,7 +19,7 @@ public function behaviors() 'exceptionFilter' => [ 'class' => ErrorToExceptionFilter::className() ], - 'corsFilter' => [ + 'corsFilter' => [ 'class' => Cors::className() // some custom config inside the class ], ]); @@ -26,9 +27,7 @@ public function behaviors() public function actionOptions() { - Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', ['OPTIONS', 'POST'])); - } @@ -38,7 +37,7 @@ public function actionToken() $response = $this->module->getServer()->handleTokenRequest(); return $response->getParameters(); } - + public function actionRevoke() { /** @var $response \OAuth2\Response */ @@ -51,4 +50,37 @@ public function actionUserInfo() $response = $this->module->getServer()->handleUserInfoRequest(); return $response->getParameters(); } + + public function actionIntrospect() + { + $server = Module::getInstance()->getServer(); + $server->verifyResourceRequest(); + + if (!Yii::$app->request->post('token')) + { + $message = Yii::t('oauth2server', 'Missing parameter: "token" is required'); + if($message === null) { + $message = Yii::t('yii', 'An internal server error occurred.'); + } + throw new \yii\web\HttpException(400, $message); + + } + + $response["active"] = false; + + $token = OauthAccessTokens::findOne(["access_token"=>Yii::$app->request->post('token')]); + if ($token) + { + $expires = strtotime($token->expires); + if (time() < $expires) + $response["active"] = true; + $response["scope"] = $token->scope; + $response["user_id"] = $token->user_id; + $response["client_id"] = $token->client_id; + $response["exp"] = $expires; + } + + return $response; + } + } diff --git a/messages/en/common.php b/messages/en/common.php index 11aab5e..b0c296a 100755 --- a/messages/en/common.php +++ b/messages/en/common.php @@ -50,5 +50,6 @@ 'This client is invalid or must authenticate using a client secret' => 'This client is invalid or must authenticate using a client secret', 'Unable to retrieve user information' => 'Unable to retrieve user information', 'When putting the token in the body, the method must be POST' => 'When putting the token in the body, the method must be POST', - 'you must set the user_id on the array returned by getUserDetails' => 'you must set the user_id on the array returned by getUserDetails', + 'you must set the user_id on the array returned by getUserDetails' => 'you must set the user_id on the array returned by getUserDetails', + 'Missing parameter: "token" is required' => 'Missing parameter: "token" is required', ];