From 5582e70ec073407d29c294c9acfff0d2c63614d3 Mon Sep 17 00:00:00 2001 From: Tim van Dijen <tvdijen@gmail.com> Date: Mon, 11 Mar 2019 18:15:23 +0100 Subject: [PATCH] Externalize authlinkedin (#1065) --- bin/build-release.sh | 1 + composer.json | 1 + modules/authlinkedin/default-disable | 3 - modules/authlinkedin/docs/oauthlinkedin.md | 26 --- .../authlinkedin/lib/Auth/Source/LinkedIn.php | 200 ------------------ modules/authlinkedin/www/linkback.php | 34 --- 6 files changed, 2 insertions(+), 263 deletions(-) delete mode 100644 modules/authlinkedin/default-disable delete mode 100644 modules/authlinkedin/docs/oauthlinkedin.md delete mode 100644 modules/authlinkedin/lib/Auth/Source/LinkedIn.php delete mode 100644 modules/authlinkedin/www/linkback.php diff --git a/bin/build-release.sh b/bin/build-release.sh index b44cba258..18f46d8bf 100755 --- a/bin/build-release.sh +++ b/bin/build-release.sh @@ -48,6 +48,7 @@ php "$TARGET/composer.phar" install --no-dev --prefer-dist -o -d "$TARGET" # Install external modules php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authfacebook +php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authlinkedin php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authtwitter php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authwindowslive php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-cdc diff --git a/composer.json b/composer.json index 2c1704bdb..41404e9a7 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,7 @@ "robrichards/xmlseclibs": "^3.0", "simplesamlphp/saml2": "^3.3", "simplesamlphp/simplesamlphp-module-authfacebook": "^1.0", + "simplesamlphp/simplesamlphp-module-authlinkedin": "^1.0", "simplesamlphp/simplesamlphp-module-authtwitter": "^1.0", "simplesamlphp/simplesamlphp-module-authwindowslive": "^1.0", "simplesamlphp/simplesamlphp-module-cdc": "^1.0", diff --git a/modules/authlinkedin/default-disable b/modules/authlinkedin/default-disable deleted file mode 100644 index fa0bd82e2..000000000 --- a/modules/authlinkedin/default-disable +++ /dev/null @@ -1,3 +0,0 @@ -This file indicates that the default state of this module -is disabled. To enable, create a file named enable in the -same directory as this file. diff --git a/modules/authlinkedin/docs/oauthlinkedin.md b/modules/authlinkedin/docs/oauthlinkedin.md deleted file mode 100644 index df437006f..000000000 --- a/modules/authlinkedin/docs/oauthlinkedin.md +++ /dev/null @@ -1,26 +0,0 @@ -Using the LinkedIn authentication source with SimpleSAMLphp -=========================================================== - -Remember to configure `authsources.php`, with both Consumer key and secret. Optionally you can set which attributes are requested from LinkedIn, the list of available attributes can be found here <https://developer.linkedin.com/docs/fields>. - -To get an API key and a secret, register the application at: - - * <https://www.linkedin.com/secure/developer> - -Set the callback URL to be: - - * `http://sp.example.org/simplesaml/module.php/authlinkedin/linkback.php` - -Replace `sp.example.org` with your hostname. - -## Testing authentication - -On the SimpleSAMLphp frontpage, go to the *Authentication* tab, and use the link: - - * *Test configured authentication sources* - -Then choose the *linkedin* authentication source. - -Expected behaviour would then be that you are sent to LinkedIn and asked to login. -There is no consent screen for attribute release. - diff --git a/modules/authlinkedin/lib/Auth/Source/LinkedIn.php b/modules/authlinkedin/lib/Auth/Source/LinkedIn.php deleted file mode 100644 index f270834c7..000000000 --- a/modules/authlinkedin/lib/Auth/Source/LinkedIn.php +++ /dev/null @@ -1,200 +0,0 @@ -<?php - -namespace SimpleSAML\Module\authlinkedin\Auth\Source; - -require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/oauth/libextinc/OAuth.php'); - -/** - * Authenticate using LinkedIn. - * - * @author Brook Schofield, TERENA. - * @package SimpleSAMLphp - */ - -class LinkedIn extends \SimpleSAML\Auth\Source -{ - /** - * The string used to identify our states. - */ - const STAGE_INIT = 'authlinkedin:init'; - - /** - * The key of the AuthId field in the state. - */ - const AUTHID = 'authlinkedin:AuthId'; - - /** @var string */ - private $key; - - /** @var string */ - private $secret; - - /** @var string */ - private $attributes; - - - /** - * Constructor for this authentication source. - * - * @param array $info Information about this authentication source. - * @param array $config Configuration. - * @throws \Exception - */ - public function __construct($info, $config) - { - assert(is_array($info)); - assert(is_array($config)); - - // Call the parent constructor first, as required by the interface - parent::__construct($info, $config); - - if (!array_key_exists('key', $config)) { - throw new \Exception('LinkedIn authentication source is not properly configured: missing [key]'); - } - - $this->key = $config['key']; - - if (!array_key_exists('secret', $config)) { - throw new \Exception('LinkedIn authentication source is not properly configured: missing [secret]'); - } - - $this->secret = $config['secret']; - - if (array_key_exists('attributes', $config)) { - $this->attributes = $config['attributes']; - } else { - // Default values if the attributes are not set in config (ref https://developer.linkedin.com/docs/fields) - $this->attributes = 'id,first-name,last-name,headline,summary,specialties,picture-url,email-address'; - } - } - - - /** - * Log-in using LinkedIn platform - * Documentation at: http://developer.linkedin.com/docs/DOC-1008 - * - * @param array &$state Information about the current authentication. - * @return void - */ - public function authenticate(&$state) - { - assert(is_array($state)); - - // We are going to need the authId in order to retrieve this authentication source later - $state[self::AUTHID] = $this->authId; - - $stateID = \SimpleSAML\Auth\State::getStateId($state); - \SimpleSAML\Logger::debug('authlinkedin auth state id = '.$stateID); - - $consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret); - - // Get the request token - $requestToken = $consumer->getRequestToken( - 'https://api.linkedin.com/uas/oauth/requestToken', - [ - 'oauth_callback' => \SimpleSAML\Module::getModuleUrl('authlinkedin').'/linkback.php?stateid='.$stateID - ] - ); - - \SimpleSAML\Logger::debug( - "Got a request token from the OAuth service provider [". - $requestToken->key."] with the secret [".$requestToken->secret."]" - ); - - $state['authlinkedin:requestToken'] = $requestToken; - - // Update the state - \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT); - - // Authorize the request token - $consumer->getAuthorizeRequest('https://www.linkedin.com/uas/oauth/authenticate', $requestToken); - } - - - /** - * @param array &$state - * @return void - */ - public function finalStep(&$state) - { - $requestToken = $state['authlinkedin:requestToken']; - - $consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret); - - \SimpleSAML\Logger::debug( - "oauth: Using this request token [". - $requestToken->key."] with the secret [".$requestToken->secret."]" - ); - - // Replace the request token with an access token (via GET method) - $accessToken = $consumer->getAccessToken( - 'https://api.linkedin.com/uas/oauth/accessToken', - $requestToken, - ['oauth_verifier' => $state['authlinkedin:oauth_verifier']] - ); - - \SimpleSAML\Logger::debug( - "Got an access token from the OAuth service provider [". - $accessToken->key."] with the secret [".$accessToken->secret."]" - ); - - $userdata = $consumer->getUserInfo( - 'https://api.linkedin.com/v1/people/~:('.$this->attributes.')', - $accessToken, - ['http' => ['header' => 'x-li-format: json']] - ); - - $attributes = $this->flatten($userdata, 'linkedin.'); - - // TODO: pass accessToken: key, secret + expiry as attributes? - - if (array_key_exists('id', $userdata)) { - $attributes['linkedin_targetedID'] = ['http://linkedin.com!'.$userdata['id']]; - $attributes['linkedin_user'] = [$userdata['id'].'@linkedin.com']; - } - - \SimpleSAML\Logger::debug('LinkedIn Returned Attributes: '.implode(", ", array_keys($attributes))); - - $state['Attributes'] = $attributes; - } - - /** - * takes an associative array, traverses it and returns the keys concatenated with a dot - * - * e.g.: - * - * [ - * 'linkedin' => [ - * 'location' => [ - * 'id' => '123456' - * 'country' => [ - * 'code' => 'de' - * ] - * ] - * ] - * - * become: - * - * [ - * 'linkedin.location.id' => [0 => '123456'], - * 'linkedin.location.country.code' => [0 => 'de'] - * ] - * - * @param array $array - * @param string $prefix - * - * @return array the array with the new concatenated keys - */ - protected function flatten($array, $prefix = '') - { - $result = []; - foreach ($array as $key => $value) { - if (is_array($value)) { - $result = $result + $this->flatten($value, $prefix.$key.'.'); - } else { - $result[$prefix.$key] = [$value]; - } - } - return $result; - } -} diff --git a/modules/authlinkedin/www/linkback.php b/modules/authlinkedin/www/linkback.php deleted file mode 100644 index 922e157fc..000000000 --- a/modules/authlinkedin/www/linkback.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -/** - * Handle linkback() response from LinkedIn. - */ - -if (!array_key_exists('stateid', $_REQUEST)) { - throw new \Exception('Lost OAuth Client State'); -} -$state = \SimpleSAML\Auth\State::loadState( - $_REQUEST['stateid'], - \SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::STAGE_INIT -); - -// http://developer.linkedin.com/docs/DOC-1008#2_Redirect_the_User_to_our_Authorization_Server -if (array_key_exists('oauth_verifier', $_REQUEST)) { - $state['authlinkedin:oauth_verifier'] = $_REQUEST['oauth_verifier']; -} else { - throw new Exception('OAuth verifier not returned.'); -} - -// Find authentication source -assert(array_key_exists(\SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::AUTHID, $state)); -$sourceId = $state[\SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::AUTHID]; - -/** @var \SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn|null $source */ -$source = \SimpleSAML\Auth\Source::getById($sourceId); -if ($source === null) { - throw new \Exception('Could not find authentication source with id '.$sourceId); -} - -$source->finalStep($state); - -\SimpleSAML\Auth\Source::completeAuth($state); -- GitLab