From 330316975e94b016ff772c7a3b737e061e42f649 Mon Sep 17 00:00:00 2001
From: Tim van Dijen <tvdijen@gmail.com>
Date: Fri, 8 Mar 2019 21:48:36 +0100
Subject: [PATCH] Externalize authtwitter (#1062)

---
 bin/build-release.sh                          |   1 +
 composer.json                                 |   1 +
 modules/authtwitter/default-disable           |   3 -
 modules/authtwitter/docs/oauthtwitter.md      |  35 ----
 .../authtwitter/lib/Auth/Source/Twitter.php   | 169 ------------------
 modules/authtwitter/www/linkback.php          |  45 -----
 6 files changed, 2 insertions(+), 252 deletions(-)
 delete mode 100644 modules/authtwitter/default-disable
 delete mode 100644 modules/authtwitter/docs/oauthtwitter.md
 delete mode 100644 modules/authtwitter/lib/Auth/Source/Twitter.php
 delete mode 100644 modules/authtwitter/www/linkback.php

diff --git a/bin/build-release.sh b/bin/build-release.sh
index c1f0314e8..d6749d1d0 100755
--- a/bin/build-release.sh
+++ b/bin/build-release.sh
@@ -47,6 +47,7 @@ php "$TARGET/composer.phar" config version "$VERSION" -d "$TARGET"
 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-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
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-memcookie
diff --git a/composer.json b/composer.json
index 47037914d..7e9f4c6a6 100644
--- a/composer.json
+++ b/composer.json
@@ -41,6 +41,7 @@
         "phpmailer/phpmailer": "^6.0",
         "robrichards/xmlseclibs": "^3.0",
         "simplesamlphp/saml2": "^3.3",
+        "simplesamlphp/simplesamlphp-module-authtwitter": "^1.0.0",
         "simplesamlphp/simplesamlphp-module-authwindowslive": "^1.0",
         "simplesamlphp/simplesamlphp-module-cdc": "^1.0",
         "simplesamlphp/simplesamlphp-module-memcookie": "^1.2",
diff --git a/modules/authtwitter/default-disable b/modules/authtwitter/default-disable
deleted file mode 100644
index fa0bd82e2..000000000
--- a/modules/authtwitter/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/authtwitter/docs/oauthtwitter.md b/modules/authtwitter/docs/oauthtwitter.md
deleted file mode 100644
index c2507fc11..000000000
--- a/modules/authtwitter/docs/oauthtwitter.md
+++ /dev/null
@@ -1,35 +0,0 @@
-Using the Twitter authentication source with SimpleSAMLphp
-==========================================================
-
-Remember to configure `authsources.php`, with both Consumer key and secret.
-
-To get an API key and a secret, register the application at:
-
- * <http://twitter.com/oauth_clients>
-
-Set the callback URL to be:
-
- * `http://sp.example.org/simplesaml/module.php/authtwitter/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 *twitter* authentication source.
-
-Expected behaviour would then be that you are sent to twitter, and asked to login:
-
-![](http://clippings.erlang.no/ZZ2EE26BF6.jpg)
-
-The first time a user uses your application to login, he/she is asked for consent:
-
-![](http://clippings.erlang.no/ZZ6B18B5D9.jpg)
-
-You will then be authenticated in SimpleSAMLphp and see an attribute set similar to this:
-
-![](http://clippings.erlang.no/ZZ74A6835E.jpg)
-
diff --git a/modules/authtwitter/lib/Auth/Source/Twitter.php b/modules/authtwitter/lib/Auth/Source/Twitter.php
deleted file mode 100644
index 6a0a03e99..000000000
--- a/modules/authtwitter/lib/Auth/Source/Twitter.php
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\authtwitter\Auth\Source;
-
-require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/oauth/libextinc/OAuth.php');
-
-/**
- * Authenticate using Twitter.
- *
- * @author Andreas Ă…kre Solberg, UNINETT AS.
- * @package SimpleSAMLphp
- */
-
-class Twitter extends \SimpleSAML\Auth\Source
-{
-    /**
-     * The string used to identify our states.
-     */
-    const STAGE_INIT = 'twitter:init';
-
-    /**
-     * The key of the AuthId field in the state.
-     */
-    const AUTHID = 'twitter:AuthId';
-
-    /**
-     * @var string
-     */
-    private $key;
-
-    /**
-     * @var string
-     */
-    private $secret;
-
-    /**
-     * @var bool
-     */
-    private $force_login;
-
-    /**
-     * @var bool
-     */
-    private $include_email;
-
-    /**
-     * Constructor for this authentication source.
-     *
-     * @param array $info  Information about this authentication source.
-     * @param array $config  Configuration.
-     */
-    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);
-
-        $configObject = \SimpleSAML\Configuration::loadFromArray(
-            $config,
-            'authsources['.var_export($this->authId, true).']'
-        );
-
-        $this->key = $configObject->getString('key');
-        $this->secret = $configObject->getString('secret');
-        $this->force_login = $configObject->getBoolean('force_login', false);
-        $this->include_email = $configObject->getBoolean('include_email', false);
-    }
-
-    /**
-     * Log-in using Twitter platform
-     *
-     * @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::saveState($state, self::STAGE_INIT);
-
-        $consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret);
-        // Get the request token
-        $linkback = \SimpleSAML\Module::getModuleURL('authtwitter/linkback.php', ['AuthState' => $stateID]);
-        $requestToken = $consumer->getRequestToken(
-            'https://api.twitter.com/oauth/request_token',
-            ['oauth_callback' => $linkback]
-        );
-        \SimpleSAML\Logger::debug("Got a request token from the OAuth service provider [".
-            $requestToken->key."] with the secret [".$requestToken->secret."]");
-
-        $state['authtwitter:authdata:requestToken'] = $requestToken;
-        \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
-
-        // Authorize the request token
-        $url = 'https://api.twitter.com/oauth/authenticate';
-        if ($this->force_login) {
-            $url = \SimpleSAML\Utils\HTTP::addURLParameters($url, ['force_login' => 'true']);
-        }
-        $consumer->getAuthorizeRequest($url, $requestToken);
-    }
-
-
-    /**
-     * @param array &$state
-     * @return void
-     */
-    public function finalStep(&$state)
-    {
-        $requestToken = $state['authtwitter:authdata:requestToken'];
-        $parameters = [];
-
-        if (!isset($_REQUEST['oauth_token'])) {
-            throw new \SimpleSAML\Error\BadRequest("Missing oauth_token parameter.");
-        }
-        if ($requestToken->key !== (string) $_REQUEST['oauth_token']) {
-            throw new \SimpleSAML\Error\BadRequest("Invalid oauth_token parameter.");
-        }
-
-        if (!isset($_REQUEST['oauth_verifier'])) {
-            throw new \SimpleSAML\Error\BadRequest("Missing oauth_verifier parameter.");
-        }
-        $parameters['oauth_verifier'] = (string) $_REQUEST['oauth_verifier'];
-
-        $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
-        $accessToken = $consumer->getAccessToken(
-            'https://api.twitter.com/oauth/access_token',
-            $requestToken,
-            $parameters
-        );
-        \SimpleSAML\Logger::debug("Got an access token from the OAuth service provider [".
-            $accessToken->key."] with the secret [".$accessToken->secret."]");
-
-        $verify_credentials_url = 'https://api.twitter.com/1.1/account/verify_credentials.json';
-        if ($this->include_email) {
-            $verify_credentials_url = $verify_credentials_url.'?include_email=true';
-        }
-        $userdata = $consumer->getUserInfo($verify_credentials_url, $accessToken);
-
-        if (!isset($userdata['id_str']) || !isset($userdata['screen_name'])) {
-            throw new \SimpleSAML\Error\AuthSource(
-                $this->authId,
-                'Authentication error: id_str and screen_name not set.'
-            );
-        }
-
-        $attributes = [];
-        foreach ($userdata as $key => $value) {
-            if (is_string($value)) {
-                $attributes['twitter.'.$key] = [(string) $value];
-            }
-        }
-
-        $attributes['twitter_at_screen_name'] = ['@'.$userdata['screen_name']];
-        $attributes['twitter_screen_n_realm'] = [$userdata['screen_name'].'@twitter.com'];
-        $attributes['twitter_targetedID'] = ['http://twitter.com!'.$userdata['id_str']];
-
-        $state['Attributes'] = $attributes;
-    }
-}
diff --git a/modules/authtwitter/www/linkback.php b/modules/authtwitter/www/linkback.php
deleted file mode 100644
index 78c0382a4..000000000
--- a/modules/authtwitter/www/linkback.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * Handle linkback() response from Twitter.
- */
-
-if (!array_key_exists('AuthState', $_REQUEST) || empty($_REQUEST['AuthState'])) {
-    throw new \SimpleSAML\Error\BadRequest('Missing state parameter on twitter linkback endpoint.');
-}
-$state = \SimpleSAML\Auth\State::loadState(
-    $_REQUEST['AuthState'],
-    \SimpleSAML\Module\authtwitter\Auth\Source\Twitter::STAGE_INIT
-);
-
-// Find authentication source
-if (!array_key_exists(\SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID, $state)) {
-    throw new \SimpleSAML\Error\BadRequest(
-        'No data in state for '.\SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID
-    );
-}
-$sourceId = $state[\SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID];
-
-/** @var \SimpleSAML\Module\authtwitter\Auth\Source\Twitter|null $source */
-$source = \SimpleSAML\Auth\Source::getById($sourceId);
-if ($source === null) {
-    throw new \SimpleSAML\Error\BadRequest(
-        'Could not find authentication source with id '.var_export($sourceId, true)
-    );
-}
-
-try {
-    if (array_key_exists('denied', $_REQUEST)) {
-        throw new \SimpleSAML\Error\UserAborted();
-    }
-    $source->finalStep($state);
-} catch (\SimpleSAML\Error\Exception $e) {
-    \SimpleSAML\Auth\State::throwException($state, $e);
-} catch (\Exception $e) {
-    \SimpleSAML\Auth\State::throwException(
-        $state,
-        new \SimpleSAML\Error\AuthSource($sourceId, 'Error on authtwitter linkback endpoint.', $e)
-    );
-}
-
-\SimpleSAML\Auth\Source::completeAuth($state);
-- 
GitLab