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 ( #41 )
by
unknown
14:09
created

OAuthPlugin   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

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

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A handleRequest() 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
    const ENDPOINT_REQUEST_TOKEN    = 'oauth/request_token';
27
    const ENDPOINT_ACCESS_TOKEN     = 'oauth/access_token';
28
    const ENDPOINT_AUTHORIZE        = 'oauth/authenticate';
29
30
    /**
31
     * @var array
32
     */
33
    protected $config = array(
34
        'oauth_consumer_key'        => 'anon',
35
        'oauth_consumer_secret'     => 'anon',
36
        'oauth_token'               => '',
37
        'oauth_token_secret'        => '',
38
        'oauth_signature_method'    => 'HMAC-SHA1',
39
        'oauth_callback'            => '',
40
        'oauth_verifier'            => '',
41
        'oauth_version'             => '1.0',
42
    );
43
44
    /**
45
     * @var SignatureMethodInterface
46
     */
47
    protected $signature;
48
49
    /**
50
     * @var TokenInterface
51
     */
52
    protected $token;
53
54
    /**
55
     * @var ConsumerInterface
56
     */
57
    protected $consumer;
58
59
    public function __construct(
60
        array $config,
61
        SignatureMethodInterface $signature = null,
62
        TokenInterface $token = null,
63
        ConsumerInterface $consumer = null
64
    ) {
65
        $this->config       = array_merge($this->config, $config);
66
        $this->signature    = (!is_null($signature)) ? $signature : $this->getSigner();
67
        $this->token        = $this->initToken($token);
68
        $this->consumer     = $this->initConsumer($consumer);
69
    }
70
71
    public function handleRequest(\Psr\Http\Message\RequestInterface $request, callable $next, callable $first)
72
    {
73
        $params = $this->getParametersToSign($request);
74
        $req    = OAuth1\Request\Request::fromConsumerAndToken(
75
            $this->consumer,
76
            $this->token,
77
            $request->getMethod(),
78
            (string) $request->getUri(),
79
            $params
80
        );
81
82
        $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...
83
84
        $header = explode(':', $req->toHeader(), 2);
85
86
        return $next($request->withHeader($header[0], $header[1]));
87
    }
88
89
    /**
90
     * Include OAuth and request body parameters
91
     *
92
     * @access protected
93
     * @param  RequestInterface $request
94
     * @return array
95
     *
96
     * @see http://oauth.net/core/1.0/#sig_norm_param
97
     */
98
    protected function getParametersToSign(RequestInterface $request)
99
    {
100
        $params = $this->getOAuthParameters($request);
101
102
        if (in_array('application/x-www-form-urlencoded', $request->getHeader('Content-Type'), true)) {
103
            $params = array_merge($params, $this->getContentAsParameters($request));
104
        }
105
106
        return $params;
107
    }
108
109
    /**
110
     * Include/exclude optional parameters
111
     *
112
     * The exclusion/inclusion is based on current request resource
113
     *
114
     * @access protected
115
     * @param  RequestInterface $request
116
     * @return array
117
     */
118
    protected function getOAuthParameters(RequestInterface $request)
119
    {
120
        $params = $this->filterOAuthParameters(array('oauth_token', 'oauth_version'));
121
122
        if ($this->isEndpointRequested(self::ENDPOINT_REQUEST_TOKEN, $request)) {
123
            $params = $this->filterOAuthParameters(array('oauth_callback'));
124
        } elseif ($this->isEndpointRequested(self::ENDPOINT_ACCESS_TOKEN, $request)) {
125
            $params = $this->filterOAuthParameters(array('oauth_token', 'oauth_verifier'));
126
        }
127
128
        return $params;
129
    }
130
131
    /**
132
     * White list based filter
133
     *
134
     * @access protected
135
     * @param  string[] $include
136
     * @return array
137
     */
138
    protected function filterOAuthParameters(array $include)
139
    {
140
        $final = array();
141
142
        foreach ($include as $key => $value) {
143
            if (!empty($this->config[$value])) {
144
                $final[$value] = $this->config[$value];
145
            }
146
        }
147
148
        return $final;
149
    }
150
151
    /**
152
     * Transform request content to associative array
153
     *
154
     * @access protected
155
     * @param  RequestInterface $request
156
     * @return array
157
     */
158
    protected function getContentAsParameters(RequestInterface $request)
159
    {
160
        parse_str($request->getBody()->getContents(), $parts);
161
162
        return $parts;
163
    }
164
165
    /**
166
     * Check if specified endpoint is in current request
167
     *
168
     * @param  string           $endpoint
169
     * @param  RequestInterface $request
170
     * @return bool
171
     */
172
    protected function isEndpointRequested($endpoint, RequestInterface $request)
173
    {
174
        return strpos($request->getUri()->getPath(), $endpoint) !== false;
175
    }
176
177
    /**
178
     * Bitbucket supports only HMAC-SHA1 and PlainText signatures.
179
     *
180
     * For better security, HMAC-SHA1 is the default one.
181
     *
182
     * @return \JacobKiers\OAuth\SignatureMethod\SignatureMethodInterface
183
     */
184
    protected function getSigner()
185
    {
186
        $signature = 'HmacSha1';
187
188
        if ($this->config['oauth_signature_method'] == 'PLAINTEXT') {
189
            $signature = 'PlainText';
190
        }
191
192
        $class = '\JacobKiers\OAuth\SignatureMethod\\'.$signature;
193
194
        return new $class();
195
    }
196
197
    /**
198
     * @access public
199
     * @param  TokenInterface|null $token
200
     * @return TokenInterface
201
     */
202
    protected function initToken($token)
203
    {
204
        return (!is_null($token)) ?
205
            $token :
206
            empty($this->config['oauth_token']) ?
207
                new OAuth1\Token\NullToken() :
208
                new OAuth1\Token\Token($this->config['oauth_token'], $this->config['oauth_token_secret'])
209
            ;
210
    }
211
212
    /**
213
     * @access public
214
     * @param  ConsumerInterface|null $consumer
215
     * @return ConsumerInterface
216
     */
217
    protected function initConsumer($consumer)
218
    {
219
        return (!is_null($consumer)) ?
220
            $consumer :
221
            new OAuth1\Consumer\Consumer(
222
                $this->config['oauth_consumer_key'],
223
                $this->config['oauth_consumer_secret']
224
            )
225
            ;
226
    }
227
}
228