Notification Setup Error

We have detected an error in your notification set-up (Event-ID dab39dc24f564ec7bd4628d1305fd03c). Currently, we cannot inform you about inspection progress. Please check that the user 557058:bca11929-8c2d-43f2-8a82-c5416880d395 still has access to your repository or update the API account.

Completed
Pull Request — develop ( #74 )
by
unknown
23:03 queued 08:21
created

OAuthPlugin   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 206
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 8
dl 0
loc 206
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A doHandleRequest() 0 17 1
A getParametersToSign() 0 10 2
A getOAuthParameters() 0 12 3
A filterOAuthParameters() 0 12 3
A getContentAsParameters() 0 6 1
A isEndpointRequested() 0 4 1
A getSigner() 0 12 2
A initToken() 0 9 3
A initConsumer() 0 10 2
1
<?php
2
3
/**
4
 * This file is part of the bitbucket-api package.
5
 *
6
 * (c) Alexandru G. <[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 Bitbucket\API\Http\Plugin;
13
14
use Http\Client\Common\Plugin;
15
use JacobKiers\OAuth\SignatureMethod\SignatureMethodInterface;
16
use JacobKiers\OAuth\Consumer\ConsumerInterface;
17
use JacobKiers\OAuth\Token\TokenInterface;
18
use JacobKiers\OAuth as OAuth1;
19
use Psr\Http\Message\RequestInterface;
20
21
/**
22
 * @author  Alexandru G.    <[email protected]>
23
 */
24
class OAuthPlugin implements Plugin
25
{
26
    use Plugin\VersionBridgePlugin;
27
28
    const ENDPOINT_REQUEST_TOKEN    = 'oauth/request_token';
29
    const ENDPOINT_ACCESS_TOKEN     = 'oauth/access_token';
30
    const ENDPOINT_AUTHORIZE        = 'oauth/authenticate';
31
32
    /**
33
     * @var array
34
     */
35
    protected $config = array(
36
        'oauth_consumer_key'        => 'anon',
37
        'oauth_consumer_secret'     => 'anon',
38
        'oauth_token'               => '',
39
        'oauth_token_secret'        => '',
40
        'oauth_signature_method'    => 'HMAC-SHA1',
41
        'oauth_callback'            => '',
42
        'oauth_verifier'            => '',
43
        'oauth_version'             => '1.0',
44
    );
45
46
    /**
47
     * @var SignatureMethodInterface
48
     */
49
    protected $signature;
50
51
    /**
52
     * @var TokenInterface
53
     */
54
    protected $token;
55
56
    /**
57
     * @var ConsumerInterface
58
     */
59
    protected $consumer;
60
61
    public function __construct(
62
        array $config,
63
        SignatureMethodInterface $signature = null,
64
        TokenInterface $token = null,
65
        ConsumerInterface $consumer = null
66
    ) {
67
        $this->config       = array_merge($this->config, $config);
68
        $this->signature    = (!is_null($signature)) ? $signature : $this->getSigner();
69
        $this->token        = $this->initToken($token);
70
        $this->consumer     = $this->initConsumer($consumer);
71
    }
72
73
    protected function doHandleRequest(RequestInterface $request, callable $next, callable $first)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Unused Code introduced by
The parameter $first is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
74
    {
75
        $params = $this->getParametersToSign($request);
76
        $req    = OAuth1\Request\Request::fromConsumerAndToken(
77
            $this->consumer,
78
            $this->token,
79
            $request->getMethod(),
80
            (string) $request->getUri(),
81
            $params
82
        );
83
84
        $req->signRequest($this->signature, $this->consumer, $this->token);
0 ignored issues
show
Documentation introduced by
$this->signature is of type object<JacobKiers\OAuth\...gnatureMethodInterface>, but the function expects a string.

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...
85
86
        $header = explode(':', $req->toHeader(), 2);
87
88
        return $next($request->withHeader($header[0], $header[1]));
89
    }
90
91
    /**
92
     * Include OAuth and request body parameters
93
     *
94
     * @access protected
95
     * @param  RequestInterface $request
96
     * @return array
97
     *
98
     * @see http://oauth.net/core/1.0/#sig_norm_param
99
     */
100
    protected function getParametersToSign(RequestInterface $request)
101
    {
102
        $params = $this->getOAuthParameters($request);
103
104
        if (in_array('application/x-www-form-urlencoded', $request->getHeader('Content-Type'), true)) {
105
            $params = array_merge($params, $this->getContentAsParameters($request));
106
        }
107
108
        return $params;
109
    }
110
111
    /**
112
     * Include/exclude optional parameters
113
     *
114
     * The exclusion/inclusion is based on current request resource
115
     *
116
     * @access protected
117
     * @param  RequestInterface $request
118
     * @return array
119
     */
120
    protected function getOAuthParameters(RequestInterface $request)
121
    {
122
        $params = $this->filterOAuthParameters(array('oauth_token', 'oauth_version'));
123
124
        if ($this->isEndpointRequested(self::ENDPOINT_REQUEST_TOKEN, $request)) {
125
            $params = $this->filterOAuthParameters(array('oauth_callback'));
126
        } elseif ($this->isEndpointRequested(self::ENDPOINT_ACCESS_TOKEN, $request)) {
127
            $params = $this->filterOAuthParameters(array('oauth_token', 'oauth_verifier'));
128
        }
129
130
        return $params;
131
    }
132
133
    /**
134
     * White list based filter
135
     *
136
     * @access protected
137
     * @param  string[] $include
138
     * @return array
139
     */
140
    protected function filterOAuthParameters(array $include)
141
    {
142
        $final = array();
143
144
        foreach ($include as $key => $value) {
145
            if (!empty($this->config[$value])) {
146
                $final[$value] = $this->config[$value];
147
            }
148
        }
149
150
        return $final;
151
    }
152
153
    /**
154
     * Transform request content to associative array
155
     *
156
     * @access protected
157
     * @param  RequestInterface $request
158
     * @return array
159
     */
160
    protected function getContentAsParameters(RequestInterface $request)
161
    {
162
        parse_str($request->getBody()->getContents(), $parts);
163
164
        return $parts;
165
    }
166
167
    /**
168
     * Check if specified endpoint is in current request
169
     *
170
     * @param  string           $endpoint
171
     * @param  RequestInterface $request
172
     * @return bool
173
     */
174
    protected function isEndpointRequested($endpoint, RequestInterface $request)
175
    {
176
        return strpos($request->getUri()->getPath(), $endpoint) !== false;
177
    }
178
179
    /**
180
     * Bitbucket supports only HMAC-SHA1 and PlainText signatures.
181
     *
182
     * For better security, HMAC-SHA1 is the default one.
183
     *
184
     * @return \JacobKiers\OAuth\SignatureMethod\SignatureMethodInterface
185
     */
186
    protected function getSigner()
187
    {
188
        $signature = 'HmacSha1';
189
190
        if ($this->config['oauth_signature_method'] == 'PLAINTEXT') {
191
            $signature = 'PlainText';
192
        }
193
194
        $class = '\JacobKiers\OAuth\SignatureMethod\\'.$signature;
195
196
        return new $class();
197
    }
198
199
    /**
200
     * @access public
201
     * @param  TokenInterface|null $token
202
     * @return TokenInterface
203
     */
204
    protected function initToken($token)
205
    {
206
        return (!is_null($token)) ?
207
            $token :
208
            empty($this->config['oauth_token']) ?
209
                new OAuth1\Token\NullToken() :
210
                new OAuth1\Token\Token($this->config['oauth_token'], $this->config['oauth_token_secret'])
211
            ;
212
    }
213
214
    /**
215
     * @access public
216
     * @param  ConsumerInterface|null $consumer
217
     * @return ConsumerInterface
218
     */
219
    protected function initConsumer($consumer)
220
    {
221
        return (!is_null($consumer)) ?
222
            $consumer :
223
            new OAuth1\Consumer\Consumer(
224
                $this->config['oauth_consumer_key'],
225
                $this->config['oauth_consumer_secret']
226
            )
227
            ;
228
    }
229
}
230