Issues (3)

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

Labels
Severity
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 string STAGE_INIT = 'twitter:init';
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 25 at column 24
Loading history...
26
27
    /**
28
     * The key of the AuthId field in the state.
29
     */
30
    public const string AUTHID = 'twitter:AuthId';
31
32
33
    private string $key;
34
35
    private string $secret;
36
37
    private string $scope;
38
39
    private bool $force_login;
40
41
42
    /**
43
     * Constructor for this authentication source.
44
     *
45
     * @param array<mixed> $info  Information about this authentication source.
46
     * @param array<mixed> $config  Configuration.
47
     */
48
    public function __construct(array $info, array $config)
49
    {
50
        // Call the parent constructor first, as required by the interface
51
        parent::__construct($info, $config);
52
53
        $configObject = Configuration::loadFromArray(
54
            $config,
55
            'authsources[' . var_export($this->authId, true) . ']',
56
        );
57
58
        $this->key = $configObject->getString('key');
59
        $this->secret = $configObject->getString('secret');
60
        $this->scope = $configObject->getOptionalString('scope', null);
61
        $this->force_login = $configObject->getOptionalBoolean('force_login', false);
62
    }
63
64
65
    /**
66
     * Log-in using Twitter platform
67
     *
68
     * @param array<mixed> &$state  Information about the current authentication.
69
     */
70
    public function authenticate(array &$state): void
71
    {
72
        $this->temporaryCredentials($state);
73
    }
74
75
76
    /**
77
     * Retrieve temporary credentials
78
     *
79
     * @param array<mixed> &$state  Information about the current authentication.
80
     */
81
    private function temporaryCredentials(array &$state): never
82
    {
83
        // We are going to need the authId in order to retrieve this authentication source later
84
        $state[self::AUTHID] = $this->authId;
85
86
        $stateId = base64_encode(Auth\State::saveState($state, self::STAGE_INIT));
87
88
        $server = new TwitterServer(
89
            [
90
                'identifier' => $this->key,
91
                'secret' => $this->secret,
92
                'callback_uri' => Module::getModuleURL('authtwitter/linkback')
93
                    . '?AuthState=' . $stateId . '&force_login=' . strval($this->force_login),
94
                'scope' => $this->scope,
95
            ],
96
        );
97
98
        // First part of OAuth 1.0 authentication is retrieving temporary credentials.
99
        // These identify you as a client to the server.
100
        $temporaryCredentials = $server->getTemporaryCredentials();
101
102
        $state['authtwitter:authdata:requestToken'] = serialize($temporaryCredentials);
103
        Auth\State::saveState($state, self::STAGE_INIT);
104
105
        $server->authorize($temporaryCredentials);
106
        exit;
107
    }
108
109
110
    /**
111
     * @param array<mixed> &$state
112
     * @param \Symfony\Component\HttpFoundation\Request $request
113
     */
114
    public function finalStep(array &$state, Request $request): void
115
    {
116
        $requestToken = unserialize($state['authtwitter:authdata:requestToken']);
117
118
        $oauth_token = $request->query->get('oauth_token');
119
        if ($oauth_token === null) {
120
            throw new Error\BadRequest("Missing oauth_token parameter.");
121
        }
122
123
        if ($requestToken->getIdentifier() !== $oauth_token) {
124
            throw new Error\BadRequest("Invalid oauth_token parameter.");
125
        }
126
127
        $oauth_verifier = $request->query->get('oauth_verifier');
128
        if ($oauth_verifier === null) {
129
            throw new Error\BadRequest("Missing oauth_verifier parameter.");
130
        }
131
132
        $server = new TwitterServer(
133
            [
134
                'identifier' => $this->key,
135
                'secret' => $this->secret,
136
            ],
137
        );
138
139
        $tokenCredentials = $server->getTokenCredentials(
140
            $requestToken,
141
            $request->query->get('oauth_token'),
142
            $request->query->get('oauth_verifier'),
143
        );
144
145
        $state['token_credentials'] = serialize($tokenCredentials);
146
        $userdata = $server->getUserDetails($tokenCredentials);
147
148
        $attributes = [];
149
150
        foreach ($userdata->getIterator() as $key => $value) {
151
            if (is_string($value) && (strlen($value) > 0)) {
152
                $attributes['twitter.' . $key] = [$value];
153
            } else {
154
                // Either the urls or the extra array
155
            }
156
        }
157
158
        $state['Attributes'] = $attributes;
159
    }
160
}
161