Issues (1)

src/Auth/Source/Twitter.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\authtwitter\Auth\Source;
6
7
use League\OAuth1\Client\Server\Twitter as TwitterServer;
8
use SimpleSAML\Auth;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\Error;
11
use SimpleSAML\Module;
12
use Symfony\Component\HttpFoundation\Request;
13
14
/**
15
 * Authenticate using Twitter.
16
 *
17
 * @package simplesamlphp/simplesamlphp-module-authtwitter
18
 */
19
20
class Twitter extends Auth\Source
21
{
22
    /**
23
     * The string used to identify our states.
24
     */
25
    public const STAGE_INIT = 'twitter:init';
26
27
    /**
28
     * The key of the AuthId field in the state.
29
     */
30
    public const AUTHID = 'twitter:AuthId';
31
32
    /** @var string */
33
    private string $key;
34
35
    /** @var string */
36
    private string $secret;
37
38
    /** @var string */
39
    private string $scope;
40
41
    /** @var bool */
42
    private bool $force_login;
43
44
    /**
45
     * Constructor for this authentication source.
46
     *
47
     * @param array $info  Information about this authentication source.
48
     * @param array $config  Configuration.
49
     */
50
    public function __construct(array $info, array $config)
51
    {
52
        // Call the parent constructor first, as required by the interface
53
        parent::__construct($info, $config);
54
55
        $configObject = Configuration::loadFromArray(
56
            $config,
57
            'authsources[' . var_export($this->authId, true) . ']'
58
        );
59
60
        $this->key = $configObject->getString('key');
61
        $this->secret = $configObject->getString('secret');
62
        $this->scope = $configObject->getOptionalString('scope', null);
63
        $this->force_login = $configObject->getOptionalBoolean('force_login', false);
64
    }
65
66
67
    /**
68
     * Log-in using Twitter platform
69
     *
70
     * @param array &$state  Information about the current authentication.
71
     */
72
    public function authenticate(array &$state): void
73
    {
74
        $this->temporaryCredentials($state);
75
    }
76
77
78
    /**
79
     * Retrieve temporary credentials
80
     *
81
     * @param array &$state  Information about the current authentication.
82
     */
83
    private function temporaryCredentials(array &$state): never
84
    {
85
        // We are going to need the authId in order to retrieve this authentication source later
86
        $state[self::AUTHID] = $this->authId;
87
88
        $stateId = base64_encode(Auth\State::saveState($state, self::STAGE_INIT));
89
90
        $server = new TwitterServer(
91
            [
92
                'identifier' => $this->key,
93
                'secret' => $this->secret,
94
                'callback_uri' => Module::getModuleURL('authtwitter/linkback')
95
                    . '?AuthState=' . $stateId . '&force_login=' . strval($this->force_login),
96
                'scope' => $this->scope,
97
            ]
98
        );
99
100
        // First part of OAuth 1.0 authentication is retrieving temporary credentials.
101
        // These identify you as a client to the server.
102
        $temporaryCredentials = $server->getTemporaryCredentials();
103
104
        $state['authtwitter:authdata:requestToken'] = serialize($temporaryCredentials);
105
        Auth\State::saveState($state, self::STAGE_INIT);
106
107
        $server->authorize($temporaryCredentials);
108
        exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
109
    }
110
111
112
    /**
113
     * @param array &$state
114
     * @param \Symfony\Component\HttpFoundation\Request $request
115
     */
116
    public function finalStep(array &$state, Request $request): void
117
    {
118
        $requestToken = unserialize($state['authtwitter:authdata:requestToken']);
119
120
        $oauth_token = $request->query->get('oauth_token');
121
        if ($oauth_token === null) {
122
            throw new Error\BadRequest("Missing oauth_token parameter.");
123
        }
124
125
        if ($requestToken->getIdentifier() !== $oauth_token) {
126
            throw new Error\BadRequest("Invalid oauth_token parameter.");
127
        }
128
129
        $oauth_verifier = $request->query->get('oauth_verifier');
130
        if ($oauth_verifier === null) {
131
            throw new Error\BadRequest("Missing oauth_verifier parameter.");
132
        }
133
134
        $server = new TwitterServer(
135
            [
136
                'identifier' => $this->key,
137
                'secret' => $this->secret,
138
            ]
139
        );
140
141
        $tokenCredentials = $server->getTokenCredentials(
142
            $requestToken,
143
            $request->query->get('oauth_token'),
144
            $request->query->get('oauth_verifier')
145
        );
146
147
        $state['token_credentials'] = serialize($tokenCredentials);
148
        $userdata = $server->getUserDetails($tokenCredentials);
149
150
        $attributes = [];
151
152
        foreach ($userdata->getIterator() as $key => $value) {
153
            if (is_string($value) && (strlen($value) > 0)) {
154
                $attributes['twitter.' . $key] = [$value];
155
            } else {
156
                // Either the urls or the extra array
157
            }
158
        }
159
160
        $state['Attributes'] = $attributes;
161
    }
162
}
163