GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

AbstractResourceOwner   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 305
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Importance

Changes 0
Metric Value
wmc 29
lcom 2
cbo 9
dl 0
loc 305
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 26 3
A configure() 0 4 1
A getName() 0 4 1
A setName() 0 4 1
A getOption() 0 8 2
A addPaths() 0 4 1
A refreshAccessToken() 0 4 1
A revokeToken() 0 4 1
A getUserResponse() 0 9 2
A normalizeUrl() 0 9 3
A getResponseContent() 0 15 3
A generateNonce() 0 4 1
doGetTokenRequest() 0 1 ?
doGetUserInformationRequest() 0 1 ?
C httpRequest() 0 35 7
B configureOptions() 0 25 2
1
<?php
2
3
/*
4
 * This file is part of the HWIOAuthBundle package.
5
 *
6
 * (c) Hardware.Info <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace HWI\Bundle\OAuthBundle\OAuth\ResourceOwner;
13
14
use Buzz\Client\ClientInterface as HttpClientInterface;
15
use Buzz\Exception\ClientException;
16
use Buzz\Message\MessageInterface as HttpMessageInterface;
17
use Buzz\Message\Request as HttpRequest;
18
use Buzz\Message\RequestInterface as HttpRequestInterface;
19
use Buzz\Message\Response as HttpResponse;
20
use HWI\Bundle\OAuthBundle\OAuth\Exception\HttpTransportException;
21
use HWI\Bundle\OAuthBundle\OAuth\RequestDataStorageInterface;
22
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwnerInterface;
23
use HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse;
24
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
25
use Symfony\Component\OptionsResolver\OptionsResolver;
26
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
27
use Symfony\Component\Security\Core\Exception\AuthenticationException;
28
use Symfony\Component\Security\Http\HttpUtils;
29
30
/**
31
 * AbstractResourceOwner
32
 *
33
 * @author Geoffrey Bachelet <[email protected]>
34
 * @author Alexander <[email protected]>
35
 * @author Francisco Facioni <[email protected]>
36
 * @author Joseph Bielawski <[email protected]>
37
 */
38
abstract class AbstractResourceOwner implements ResourceOwnerInterface
39
{
40
    /**
41
     * @var array
42
     */
43
    protected $options = array();
44
45
    /**
46
     * @var array
47
     */
48
    protected $paths = array();
49
50
    /**
51
     * @var HttpClientInterface
52
     */
53
    protected $httpClient;
54
55
    /**
56
     * @var HttpUtils
57
     */
58
    protected $httpUtils;
59
60
    /**
61
     * @var string
62
     */
63
    protected $name;
64
65
    /**
66
     * @var string
67
     */
68
    protected $state;
69
70
    /**
71
     * @var RequestDataStorageInterface
72
     */
73
    protected $storage;
74
75
    /**
76
     * @param HttpClientInterface         $httpClient Buzz http client
77
     * @param HttpUtils                   $httpUtils  Http utils
78
     * @param array                       $options    Options for the resource owner
79
     * @param string                      $name       Name for the resource owner
80
     * @param RequestDataStorageInterface $storage    Request token storage
81
     */
82
    public function __construct(HttpClientInterface $httpClient, HttpUtils $httpUtils, array $options, $name, RequestDataStorageInterface $storage)
83
    {
84
        $this->httpClient = $httpClient;
85
        $this->httpUtils  = $httpUtils;
86
        $this->name       = $name;
87
        $this->storage    = $storage;
88
89
        if (!empty($options['paths'])) {
90
            $this->addPaths($options['paths']);
91
        }
92
        unset($options['paths']);
93
94
        if (!empty($options['options'])) {
95
            $options += $options['options'];
96
            unset($options['options']);
97
        }
98
        unset($options['options']);
99
100
        // Resolve merged options
101
        $resolver = new OptionsResolver();
102
        $this->configureOptions($resolver);
103
        $options = $resolver->resolve($options);
104
        $this->options = $options;
105
106
        $this->configure();
107
    }
108
109
    /**
110
     * Gives a chance for extending providers to customize stuff
111
     */
112
    public function configure()
113
    {
114
115
    }
116
117
    /**
118
     * {@inheritDoc}
119
     */
120
    public function getName()
121
    {
122
        return $this->name;
123
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128
    public function setName($name)
129
    {
130
        $this->name = $name;
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136
    public function getOption($name)
137
    {
138
        if (!array_key_exists($name, $this->options)) {
139
            throw new \InvalidArgumentException(sprintf('Unknown option "%s"', $name));
140
        }
141
142
        return $this->options[$name];
143
    }
144
145
    /**
146
     * Add extra paths to the configuration.
147
     *
148
     * @param array $paths
149
     */
150
    public function addPaths(array $paths)
151
    {
152
        $this->paths = array_merge($this->paths, $paths);
153
    }
154
155
    /**
156
     * Refresh an access token using a refresh token.
157
     *
158
     * @param string $refreshToken    Refresh token
159
     * @param array  $extraParameters An array of parameters to add to the url
160
     *
161
     * @return array Array containing the access token and it's 'expires_in' value,
162
     *               along with any other parameters returned from the authentication
163
     *               provider.
164
     *
165
     * @throws AuthenticationException If an OAuth error occurred or no access token is found
166
     */
167
    public function refreshAccessToken($refreshToken, array $extraParameters = array())
168
    {
169
        throw new AuthenticationException('OAuth error: "Method unsupported."');
170
    }
171
172
    /**
173
     * Revoke an OAuth access token or refresh token.
174
     *
175
     * @param string $token The token (access token or a refresh token) that should be revoked.
176
     *
177
     * @return Boolean Returns True if the revocation was successful, otherwise False.
178
     *
179
     * @throws AuthenticationException If an OAuth error occurred
180
     */
181
    public function revokeToken($token)
182
    {
183
        throw new AuthenticationException('OAuth error: "Method unsupported."');
184
    }
185
186
    /**
187
     * Get the response object to return.
188
     *
189
     * @return UserResponseInterface
190
     */
191
    protected function getUserResponse()
192
    {
193
        $response = new $this->options['user_response_class'];
194
        if ($response instanceof PathUserResponse) {
195
            $response->setPaths($this->paths);
196
        }
197
198
        return $response;
199
    }
200
201
    /**
202
     * @param string $url
203
     * @param array  $parameters
204
     *
205
     * @return string
206
     */
207
    protected function normalizeUrl($url, array $parameters = array())
208
    {
209
        $normalizedUrl = $url;
210
        if (!empty($parameters)) {
211
            $normalizedUrl .= (false !== strpos($url, '?') ? '&' : '?').http_build_query($parameters, '', '&');
212
        }
213
214
        return $normalizedUrl;
215
    }
216
217
    /**
218
     * Performs an HTTP request
219
     *
220
     * @param string $url           The url to fetch
221
     * @param string|array $content The content of the request
0 ignored issues
show
Documentation introduced by
Should the type for parameter $content not be string|array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
222
     * @param array  $headers       The headers of the request
223
     * @param string $method        The HTTP method to use
0 ignored issues
show
Documentation introduced by
Should the type for parameter $method not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
224
     *
225
     * @return HttpResponse The response content
226
     */
227
    protected function httpRequest($url, $content = null, $headers = array(), $method = null)
228
    {
229
        if (null === $method) {
230
            $method = null === $content || '' === $content ? HttpRequestInterface::METHOD_GET : HttpRequestInterface::METHOD_POST;
231
        }
232
233
        $request  = new HttpRequest($method, $url);
234
        $response = new HttpResponse();
235
236
        $contentLength = 0;
237
        if (is_string($content)) {
238
            $contentLength = strlen($content);
239
        } elseif (is_array($content)) {
240
            $contentLength = strlen(implode('', $content));
241
        }
242
243
        $headers = array_merge(
244
            array(
245
                'User-Agent: HWIOAuthBundle (https://github.com/hwi/HWIOAuthBundle)',
246
                'Content-Length: ' . $contentLength,
247
            ),
248
            $headers
249
        );
250
251
        $request->setHeaders($headers);
252
        $request->setContent($content);
0 ignored issues
show
Bug introduced by
It seems like $content defined by parameter $content on line 227 can also be of type array or null; however, Buzz\Message\AbstractMessage::setContent() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
253
254
        try {
255
            $this->httpClient->send($request, $response);
256
        } catch (ClientException $e) {
257
            throw new HttpTransportException('Error while sending HTTP request', $this->getName(), $e->getCode(), $e);
258
        }
259
260
        return $response;
261
    }
262
263
    /**
264
     * Get the 'parsed' content based on the response headers.
265
     *
266
     * @param HttpMessageInterface $rawResponse
267
     *
268
     * @return array
269
     */
270
    protected function getResponseContent(HttpMessageInterface $rawResponse)
271
    {
272
        // First check that content in response exists, due too bug: https://bugs.php.net/bug.php?id=54484
273
        $content = $rawResponse->getContent();
274
        if (!$content) {
275
            return array();
276
        }
277
278
        $response = json_decode($content, true);
279
        if (JSON_ERROR_NONE !== json_last_error()) {
280
            parse_str($content, $response);
281
        }
282
283
        return $response;
284
    }
285
286
    /**
287
     * Generate a non-guessable nonce value.
288
     *
289
     * @return string
290
     */
291
    protected function generateNonce()
292
    {
293
        return md5(microtime(true).uniqid('', true));
294
    }
295
296
    /**
297
     * @param string $url
298
     * @param array  $parameters
299
     *
300
     * @return HttpResponse
301
     */
302
    abstract protected function doGetTokenRequest($url, array $parameters = array());
303
304
    /**
305
     * @param string $url
306
     * @param array  $parameters
307
     *
308
     * @return HttpResponse
309
     */
310
    abstract protected function doGetUserInformationRequest($url, array $parameters = array());
311
312
    /**
313
     * Configure the option resolver
314
     *
315
     * @param OptionsResolverInterface $resolver
316
     */
317
    protected function configureOptions(OptionsResolverInterface $resolver)
318
    {
319
        $resolver->setRequired(array(
320
            'client_id',
321
            'client_secret',
322
            'authorization_url',
323
            'access_token_url',
324
            'infos_url',
325
        ));
326
327
        $resolver->setDefaults(array(
328
            'scope'               => null,
329
            'csrf'                => false,
330
            'user_response_class' => 'HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse',
331
            'auth_with_one_url'   => false,
332
        ));
333
334
        if (method_exists($resolver, 'setDefined')) {
335
            $resolver->setAllowedValues('csrf', array(true, false));
0 ignored issues
show
Documentation introduced by
'csrf' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to OptionsResolverInterface::setAllowedValues() has too many arguments starting with array(true, false).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
336
        } else {
337
            $resolver->setAllowedValues(array(
338
                'csrf' => array(true, false),
339
            ));
340
        }
341
    }
342
}
343