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
Push — develop ( a55da1...39a772 )
by
unknown
27:43 queued 12:35
created

OAuthPlugin::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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