diff --git a/app/assets/less/components/button.less b/app/assets/less/components/button.less index 488399f..3c57b37 100644 --- a/app/assets/less/components/button.less +++ b/app/assets/less/components/button.less @@ -46,6 +46,7 @@ .button-light { .button-variant(@text-light-color, @button-bg-color, @button-hover-color); } .button-github { .button-variant(@button-github-color, @button-github-bg); } +.button-gitlab { .button-variant(@button-gitlab-color, @button-gitlab-bg); } .button-google { .button-variant(@button-google-color, @button-google-bg); } // Outline diff --git a/app/assets/less/variables.less b/app/assets/less/variables.less index ad716d8..fb7f240 100644 --- a/app/assets/less/variables.less +++ b/app/assets/less/variables.less @@ -31,6 +31,7 @@ @brand-info: hsl(210, 70%, 50%); @google-color: #db4437; @github-color: #4183c4; +@gitlab-color: #548; // ---------------------------------- // Font @@ -112,6 +113,9 @@ @button-github-bg: @github-color; @button-github-border: darken(@button-github-bg, 5%); +@button-gitlab-color: white; +@button-gitlab-bg: @gitlab-color; + // ---------------------------------- // Shadows // ---------------------------------- diff --git a/app/config/conf.local.sample.yml b/app/config/conf.local.sample.yml index f365936..8fa5619 100644 --- a/app/config/conf.local.sample.yml +++ b/app/config/conf.local.sample.yml @@ -13,13 +13,7 @@ database: # OAuth #oauth: - #security_salt: value - #debug: 1 - - #Strategy: - # Google: - # client_id: value - # client_secret: value - # GitHub: - # client_id: value - # client_secret: value + #providers: + #github: + #clientId: value + #clientSecret: value diff --git a/app/config/services.php b/app/config/services.php index 0193e1f..34d1fab 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -24,7 +24,8 @@ use Phalcon\Di\FactoryDefault, Phalcon\Mvc\Router; use Httpcb\Auth, - Httpcb\OAuth, + Httpcb\OAuth\Client as OAuthClient, + Httpcb\OAuth\Adapter\League as OAuthAdapter, Httpcb\Acl, Httpcb\Navigation, Httpcb\Menu; @@ -120,7 +121,7 @@ $di->setShared('router', function() { 'action' => 'logout', ))->setName('logout'); - $router->add('/oauth/{strategy:([a-z]+)}/:params', array( + $router->add('/login/{strategy:([a-z]+)}/:params', array( 'controller' => 'auth', 'action' => 'oauth' ))->setName('oauth'); @@ -294,8 +295,18 @@ $di->setShared('flash', function () { return new Phalcon\Flash\Session(); }); -$di->set('oauth', function() use ($config) { - return new OAuth($config); +$di->set('oauth', function($provider) use ($config) { + + if (isset($config->oauth->providers->{$provider})) { + $options = $config->oauth->providers->{$provider}; + $options = $options->toArray(); + } else { + $options = array(); + } + + $adapter = new OAuthAdapter($provider, $options); + + return new OAuthClient($adapter); }); $di->set('auth', function() use ($di, $config) { diff --git a/app/controllers/AuthController.php b/app/controllers/AuthController.php index bc4edae..b3a84ba 100644 --- a/app/controllers/AuthController.php +++ b/app/controllers/AuthController.php @@ -40,16 +40,31 @@ class AuthController extends ControllerBase $this->view->form = $form; } - public function oauthAction() + public function oauthAction($provider_name) { - $response = $this->oauth->perform(); + $client = $this->getDI()->get('oauth', [ $provider_name ]); - if (is_array($response)) { - $this->auth->loginOauth($response['auth']); - $this->response->redirect('/'); - } else { - $this->flash->message('error', 'Failed to authenticate.'); - $this->response->redirect('/login'); + $code = $this->request->get('code'); + $state = $this->request->get('state'); + + // Have code. Authenticate and fetch data. + if (strlen($code) > 0) { + + try { + // NOTE: Should pass $state here also. + $data = $client->authenticate($code); + + $this->auth->loginOauth($data); + $this->response->redirect('/'); + } catch(\Exception $e) { + $this->flash->message('error', 'Failed to authenticate.'); + $this->response->redirect('/login'); + } + } + // No code + else { + // redirect to provider and acquire code. + $this->response->redirect($client->getAuthorizationUrl(), true); } } diff --git a/app/library/Auth.php b/app/library/Auth.php index 0aa51b5..e6e2333 100644 --- a/app/library/Auth.php +++ b/app/library/Auth.php @@ -2,6 +2,7 @@ namespace Httpcb; +use Httpcb\OAuth\UserData\UserDataInterface; use Phalcon\Mvc\User\Component; use App\Model\Data\User; @@ -42,24 +43,19 @@ class Auth extends Component /** * Login using OAuth * - * @param $auth + * @param UserDataInterface $auth */ - public function loginOauth($auth) + public function loginOauth(UserDataInterface $auth) { - $email = ''; - if (isset($auth['info']['email'])) { - $email = $auth['info']['email']; - } - // Look for a user with this email. - $user = User::findFirstByEmail($email); + $user = User::findFirstByEmail($auth->getEmail()); if (!$user) { // Did not find any user. create him. - if (isset($auth['info']['nickname'])) { - $name = $auth['info']['nickname']; - } else if(isset($auth['info']['name'])) { - $name = $auth['info']['name']; + if (strlen($auth->getUsername()) > 0) { + $name = $auth->getUsername(); + } else if(strlen($auth->getName()) > 0) { + $name = $auth->getName(); } else { $name = ''; } @@ -74,7 +70,7 @@ class Auth extends Component $this->setIdentity($user->getId()); $this->_eventsManager->fire('auth:onLogin', $this, - "OAuth {$auth['provider']}"); + "OAuth {$auth->getProvider()}"); } /** diff --git a/app/library/OAuth.php b/app/library/OAuth.php deleted file mode 100644 index c08de76..0000000 --- a/app/library/OAuth.php +++ /dev/null @@ -1,103 +0,0 @@ - '/oauth/', - 'callback_url' => '/oauth/callback' - ); - - protected $_oauth; - - protected $_callbackName = 'callback'; - - public function __construct($config) - { - $config = $this->objectToArray($config->oauth); - - $this->_config = array_merge($this->_config, $config); - - $this->_oauth = new Opauth($this->_config, false); - } - - /** - * @return mixed|null|void - */ - public function perform() - { - $strategy = $this->dispatcher->getParam('strategy', null, false); - - if ($strategy == $this->_callbackName) { - return $this->getResponse(); - } - - $this->_oauth->run(); - exit; - } - - /** - * @return array|string - */ - public function getResponse() - { - $response = null; - switch($this->_oauth->env['callback_transport']) { - case 'session': - $response = $this->session->get('opauth'); - $this->session->remove('opauth'); - break; - case 'post': - $response = unserialize(base64_decode( $_POST['opauth'] )); - break; - case 'get': - $response = unserialize(base64_decode( $_GET['opauth'] )); - break; - } - - $ret = $this->_validate($response, $reason); - if ($ret === false) { - return $reason; - } - return $response; - } - - public function objectToArray($object) - { - if(!is_object($object) && !is_array($object)) - { - return $object; - } - if(is_object($object)) - { - $object = get_object_vars( $object ); - } - return array_map(array($this,"objectToArray"), $object ); - } - - protected function _validate($response, &$reason) - { - if (isset($response['auth']) && - isset($response['timestamp']) && - isset($response['signature'])) { - - $hash = sha1(print_r($response['auth'], true)); - - return $this->_oauth->validate($hash, $response['timestamp'], - $response['signature'], $reason); - } - - $reason = "Invalid auth response"; - return false; - } -} diff --git a/app/library/OAuth/Adapter/AdapterInterface.php b/app/library/OAuth/Adapter/AdapterInterface.php new file mode 100644 index 0000000..676a6f2 --- /dev/null +++ b/app/library/OAuth/Adapter/AdapterInterface.php @@ -0,0 +1,43 @@ + '\League\OAuth2\Client\Provider\Github', + 'gitlab' => '\Omines\OAuth2\Client\Provider\Gitlab', + ); + + /** + * @var AbstractProvider + */ + protected $_provider; + + /** + * @var AccessToken + */ + protected $_accessToken; + + protected $_options; + + /** + * {@inheritDoc} + * @throws Exception + */ + public function __construct($provider_name, $options) + { + if (!array_key_exists($provider_name, $this->_providerClasses)) { + throw new Exception("Provider '{$provider_name}' is not supported."); + } + + $className = $this->_providerClasses[$provider_name]; + $provider = new $className($options); + + if (!($provider instanceof AbstractProvider)) { + // TODO: Throw a better exception class :) + throw new Exception("Provider object must be an instance of League\\OAuth2\\Client\\Provider\\AbstractProvider"); + } + + $this->_provider = $provider; + $this->_options = $options; + } + + /** + * {@inheritDoc} + */ + public function getProviderName() + { + return (new \ReflectionClass($this->_provider))->getShortName(); + } + + /** + * {@inheritDoc} + */ + public function getAuthorizationUrl() + { + return $this->_provider->getAuthorizationUrl($this->_options); + } + + /** + * {@inheritDoc} + */ + public function fetchAccessToken($code) + { + $this->_accessToken = $this->_provider->getAccessToken('authorization_code', [ + 'code' => $code + ]); + } + + /** + * {@inheritDoc} + */ + public function getResourceData() + { + $resource = $this->_provider->getResourceOwner($this->_accessToken); + return $resource->toArray(); + } +} diff --git a/app/library/OAuth/Client.php b/app/library/OAuth/Client.php new file mode 100644 index 0000000..be703e8 --- /dev/null +++ b/app/library/OAuth/Client.php @@ -0,0 +1,59 @@ +_adapter = $adapter; + } + + public function getAuthorizationUrl() + { + return $this->_adapter->getAuthorizationUrl(); + } + + /** + * @param string $code + * @return UserDataInterface + */ + public function authenticate($code) + { + $this->_adapter->fetchAccessToken($code); + + return $this->getUserData(); + } + + /** + * @return UserDataInterface + */ + public function getUserData() + { + $data = $this->_adapter->getResourceData(); + return $this->_createUserData($data); + } + + protected function _createUserData(array $data) + { + $name = $this->_adapter->getProviderName(); + $class = "Httpcb\\OAuth\\UserData\\{$name}"; + return new $class($data); + } +} diff --git a/app/library/OAuth/UserData/Github.php b/app/library/OAuth/UserData/Github.php new file mode 100644 index 0000000..d8b4d13 --- /dev/null +++ b/app/library/OAuth/UserData/Github.php @@ -0,0 +1,56 @@ +data = $data; + } + + /** + * {@inheritDoc} + */ + public function getProvider() + { + return 'Github'; + } + + /** + * {@inheritDoc} + */ + public function getId() + { + return (int) $this->data['id']; + } + + /** + * {@inheritDoc} + */ + public function getUsername() + { + return $this->data['login']; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return $this->data['name']; + } + + /** + * {@inheritDoc} + */ + public function getEmail() + { + return $this->data['email']; + } +} diff --git a/app/library/OAuth/UserData/Gitlab.php b/app/library/OAuth/UserData/Gitlab.php new file mode 100644 index 0000000..697747a --- /dev/null +++ b/app/library/OAuth/UserData/Gitlab.php @@ -0,0 +1,56 @@ +data = $data; + } + + /** + * {@inheritDoc} + */ + public function getProvider() + { + return 'Gitlab'; + } + + /** + * {@inheritDoc} + */ + public function getId() + { + return (int) $this->data['id']; + } + + /** + * {@inheritDoc} + */ + public function getUsername() + { + return $this->data['username']; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return $this->data['name']; + } + + /** + * {@inheritDoc} + */ + public function getEmail() + { + return $this->data['email']; + } +} diff --git a/app/library/OAuth/UserData/UserDataInterface.php b/app/library/OAuth/UserData/UserDataInterface.php new file mode 100644 index 0000000..cf489a3 --- /dev/null +++ b/app/library/OAuth/UserData/UserDataInterface.php @@ -0,0 +1,43 @@ + {{ icon('social-google') }} Google + + + Gitlab + diff --git a/composer.json b/composer.json index 4515289..27c26ec 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,9 @@ { "require": { "robmorgan/phinx": "^0.9.2", - "opauth/google": "^0.2.2", - "opauth/twitter": "^0.3.1", - "opauth/github": "^0.1.0" + "league/oauth2-client": "^2.3", + "league/oauth2-github": "^2.0", + "league/oauth2-google": "^2.2", + "omines/oauth2-gitlab": "^3.1" } } diff --git a/composer.lock b/composer.lock index 711d59a..c412c31 100644 --- a/composer.lock +++ b/composer.lock @@ -4,123 +4,106 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "36a75ff648970b9639580a2cb7013090", - "content-hash": "ac20c7c56c417cb600cb228332de7513", + "hash": "7d98cc9a7b6f4f79576273e599f7b1f4", + "content-hash": "0fd142e805b37679388bfea151fd3970", "packages": [ { - "name": "opauth/github", - "version": "0.1.0", + "name": "guzzlehttp/guzzle", + "version": "6.3.2", "source": { "type": "git", - "url": "https://github.com/opauth/github.git", - "reference": "9c4fe16dc6498b2c94f4c2a41ab93b0fe4b7fa73" + "url": "https://github.com/guzzle/guzzle.git", + "reference": "68d0ea14d5a3f42a20e87632a5f84931e2709c90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opauth/github/zipball/9c4fe16dc6498b2c94f4c2a41ab93b0fe4b7fa73", - "reference": "9c4fe16dc6498b2c94f4c2a41ab93b0fe4b7fa73", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/68d0ea14d5a3f42a20e87632a5f84931e2709c90", + "reference": "68d0ea14d5a3f42a20e87632a5f84931e2709c90", "shasum": "" }, "require": { - "opauth/opauth": ">=0.4.0", - "php": ">=5.2.0" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" }, - "type": "library", - "autoload": { - "psr-0": { - "": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "U-Zyn Chua", - "email": "chua@uzyn.com", - "homepage": "http://uzyn.com" - } - ], - "description": "GitHub authentication strategy for Opauth", - "homepage": "http://opauth.org", - "keywords": [ - "Authentication", - "auth", - "github" - ], - "time": "2012-07-23 06:13:59" - }, - { - "name": "opauth/google", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/opauth/google.git", - "reference": "35df77684c14acb346a8c3753ae3809852d1a47e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opauth/google/zipball/35df77684c14acb346a8c3753ae3809852d1a47e", - "reference": "35df77684c14acb346a8c3753ae3809852d1a47e", - "shasum": "" - }, - "require": { - "opauth/opauth": ">=0.2.0", - "php": ">=5.2.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "U-Zyn Chua", - "email": "chua@uzyn.com", - "homepage": "http://uzyn.com" - } - ], - "description": "Google strategy for Opauth", - "homepage": "http://opauth.org", - "keywords": [ - "Authentication", - "auth", - "google" - ], - "time": "2012-10-18 14:39:52" - }, - { - "name": "opauth/opauth", - "version": "0.4.5", - "source": { - "type": "git", - "url": "https://github.com/opauth/opauth.git", - "reference": "3f979012d0bdf2d447bb02b97f7f7d9f482c77e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opauth/opauth/zipball/3f979012d0bdf2d447bb02b97f7f7d9f482c77e8", - "reference": "3f979012d0bdf2d447bb02b97f7f7d9f482c77e8", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4", + "psr/log": "^1.0" }, "suggest": { - "opauth/facebook": "Allows Facebook authentication", - "opauth/google": "Allows Google authentication", - "opauth/twitter": "Allows Twitter authentication" + "psr/log": "Required for using the Log middleware" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, "autoload": { - "classmap": [ - "lib/Opauth/" + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2018-03-26 16:33:04" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -129,47 +112,117 @@ ], "authors": [ { - "name": "U-Zyn Chua", - "email": "chua@uzyn.com", - "homepage": "http://uzyn.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Multi-provider authentication framework for PHP", - "homepage": "http://opauth.org", + "description": "Guzzle promises library", "keywords": [ - "Authentication", - "OpenId", - "auth", - "facebook", - "google", - "oauth", - "omniauth", - "twitter" + "promise" ], - "time": "2018-02-25 03:18:21" + "time": "2016-12-20 10:07:11" }, { - "name": "opauth/twitter", - "version": "0.3.2", + "name": "guzzlehttp/psr7", + "version": "1.4.2", "source": { "type": "git", - "url": "https://github.com/opauth/twitter.git", - "reference": "9c09fb3d714b8bf7b35ebc235346cf2feced69e3" + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opauth/twitter/zipball/9c09fb3d714b8bf7b35ebc235346cf2feced69e3", - "reference": "9c09fb3d714b8bf7b35ebc235346cf2feced69e3", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "shasum": "" }, "require": { - "opauth/opauth": ">=0.2.0", - "php": ">=5.2.0" + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, "autoload": { - "psr-0": { - "": "." + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-03-20 17:10:46" + }, + { + "name": "league/oauth2-client", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-client.git", + "reference": "aa2e3df188f0bfd87f7880cc880e906e99923580" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/aa2e3df188f0bfd87f7880cc880e906e99923580", + "reference": "aa2e3df188f0bfd87f7880cc880e906e99923580", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "paragonie/random_compat": "^1|^2", + "php": "^5.6|^7.0" + }, + "require-dev": { + "eloquent/liberator": "^2.0", + "eloquent/phony-phpunit": "^1.0|^3.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phpunit/phpunit": "^5.7|^6.0", + "squizlabs/php_codesniffer": "^2.3|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -178,19 +231,294 @@ ], "authors": [ { - "name": "U-Zyn Chua", - "email": "chua@uzyn.com", - "homepage": "http://uzyn.com" + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Woody Gilk", + "homepage": "https://github.com/shadowhand", + "role": "Contributor" } ], - "description": "Twitter strategy for Opauth", - "homepage": "http://opauth.org", + "description": "OAuth 2.0 Client Library", "keywords": [ "Authentication", - "auth", - "twitter" + "SSO", + "authorization", + "identity", + "idp", + "oauth", + "oauth2", + "single sign on" ], - "time": "2017-03-28 05:03:36" + "time": "2018-01-13 05:27:58" + }, + { + "name": "league/oauth2-github", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-github.git", + "reference": "e63d64f3ec167c09232d189c6b0c397458a99357" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-github/zipball/e63d64f3ec167c09232d189c6b0c397458a99357", + "reference": "e63d64f3ec167c09232d189c6b0c397458a99357", + "shasum": "" + }, + "require": { + "league/oauth2-client": "^2.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Steven Maguire", + "email": "stevenmaguire@gmail.com", + "homepage": "https://github.com/stevenmaguire" + } + ], + "description": "Github OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "authorisation", + "authorization", + "client", + "github", + "oauth", + "oauth2" + ], + "time": "2017-01-26 01:14:51" + }, + { + "name": "league/oauth2-google", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-google.git", + "reference": "c0faed29ec6d665ce3234e01f62029516cee4c02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/c0faed29ec6d665ce3234e01f62029516cee4c02", + "reference": "c0faed29ec6d665ce3234e01f62029516cee4c02", + "shasum": "" + }, + "require": { + "league/oauth2-client": "^2.0" + }, + "require-dev": { + "eloquent/phony": "^0.14.6", + "phpunit/phpunit": "^5.7", + "satooshi/php-coveralls": "^2.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "http://shadowhand.me" + } + ], + "description": "Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "Authentication", + "authorization", + "client", + "google", + "oauth", + "oauth2" + ], + "time": "2018-03-19 17:28:55" + }, + { + "name": "omines/oauth2-gitlab", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/omines/oauth2-gitlab.git", + "reference": "e9cf370897b42edeffc6946123a1bd22d6006c33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/omines/oauth2-gitlab/zipball/e9cf370897b42edeffc6946123a1bd22d6006c33", + "reference": "e9cf370897b42edeffc6946123a1bd22d6006c33", + "shasum": "" + }, + "require": { + "league/oauth2-client": "^2.2", + "php": ">=5.6" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "m4tthumphrey/php-gitlab-api": "^9.0.0", + "mockery/mockery": "^1.0", + "php-http/guzzle6-adapter": "^1.1.1", + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "suggest": { + "m4tthumphrey/php-gitlab-api": "For further API usage using the acquired OAuth2 token" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Omines\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niels Keurentjes", + "email": "niels.keurentjes@omines.com", + "homepage": "https://www.omines.nl/" + } + ], + "description": "GitLab OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "authorisation", + "authorization", + "client", + "gitlab", + "oauth", + "oauth2" + ], + "time": "2017-11-01 21:46:33" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.12", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb", + "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2018-04-04 21:24:14" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06 14:39:51" }, { "name": "psr/log",