OAuthRequest   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 43
dl 0
loc 283
rs 8.3157
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A to_postdata() 0 3 1
A generate_timestamp() 0 3 1
A get_signable_parameters() 0 12 2
A to_url() 0 9 2
A generate_nonce() 0 13 1
A get_parameters() 0 3 1
A __toString() 0 3 1
A unset_parameter() 0 3 1
A get_normalized_http_method() 0 3 1
A sign_request() 0 9 1
C from_request() 0 47 9
A get_parameter() 0 3 2
A to_header() 0 19 4
A set_parameter() 0 13 4
A getRequest() 0 10 1
A __construct() 0 6 2
A build_signature() 0 5 1
A get_signature_base_string() 0 11 1
B get_normalized_http_url() 0 18 7

How to fix   Complexity   

Complex Class

Complex classes like OAuthRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use OAuthRequest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Omnipay\Pesapal\OAuth;
4
5
class OAuthRequest
6
{
7
    private $parameters;
8
    private $http_method;
9
    private $http_url;
10
    // for debug purposes
11
    public $base_string;
12
    public static $version = '1.0';
13
    public static $POST_INPUT = 'php://input';
14
15
    public function __construct($http_method, $http_url, $parameters = null)
16
    {
17
        @$parameters or $parameters = [];
18
        $this->parameters = $parameters;
19
        $this->http_method = $http_method;
20
        $this->http_url = $http_url;
21
    }
22
23
    /**
24
     * attempt to build up a request from what was passed to the server.
25
     */
26
    public static function from_request($http_method = null, $http_url = null, $parameters = null)
27
    {
28
        $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on')
29
            ? 'http'
30
            : 'https';
31
        @$http_url or $http_url = $scheme.
32
                                  '://'.$_SERVER['HTTP_HOST'].
33
                                  ':'.
34
                                  $_SERVER['SERVER_PORT'].
35
                                  $_SERVER['REQUEST_URI'];
36
        @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
37
38
        // We weren't handed any parameters, so let's find the ones relevant to
39
        // this request.
40
        // If you run XML-RPC or similar you should use this to provide your own
41
        // parsed parameter-list
42
        if (!$parameters) {
43
            // Find request headers
44
            $request_headers = OAuthUtil::get_headers();
45
46
            // Parse the query-string to find GET parameters
47
            $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
48
49
            // It's a POST request of the proper content-type, so parse POST
50
            // parameters and add those overriding any duplicates from GET
51
            if ($http_method == 'POST'
52
                && @strstr(
53
                    $request_headers['Content-Type'],
54
                    'application/x-www-form-urlencoded')
55
            ) {
56
                $post_data = OAuthUtil::parse_parameters(
57
                    file_get_contents(self::$POST_INPUT)
58
                );
59
                $parameters = array_merge($parameters, $post_data);
60
            }
61
62
            // We have a Authorization-header with OAuth data. Parse the header
63
            // and add those overriding any duplicates from GET or POST
64
            if (@substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
65
                $header_parameters = OAuthUtil::split_header(
66
                    $request_headers['Authorization']
67
                );
68
                $parameters = array_merge($parameters, $header_parameters);
69
            }
70
        }
71
72
        return new self($http_method, $http_url, $parameters);
73
    }
74
75
    /**
76
     * @param $consumer
77
     * @param $http_url
78
     *
79
     * @return OAuthRequest
80
     */
81
    public static function getRequest($consumer, $http_url): self
82
    {
83
        $defaults = [
84
            'oauth_version'      => self::$version,
85
            'oauth_nonce'        => self::generate_nonce(),
86
            'oauth_timestamp'    => self::generate_timestamp(),
87
            'oauth_consumer_key' => $consumer->key,
88
        ];
89
90
        return new self('GET', $http_url, $defaults);
91
    }
92
93
    public function set_parameter($name, $value, $allow_duplicates = true)
94
    {
95
        if ($allow_duplicates && isset($this->parameters[$name])) {
96
            // We have already added parameter(s) with this name, so add to the list
97
            if (is_scalar($this->parameters[$name])) {
98
                // This is the first duplicate, so transform scalar (string)
99
                // into an array so we can add the duplicates
100
                $this->parameters[$name] = [$this->parameters[$name]];
101
            }
102
103
            $this->parameters[$name][] = $value;
104
        } else {
105
            $this->parameters[$name] = $value;
106
        }
107
    }
108
109
    public function get_parameter($name)
110
    {
111
        return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
112
    }
113
114
    public function get_parameters()
115
    {
116
        return $this->parameters;
117
    }
118
119
    public function unset_parameter($name)
120
    {
121
        unset($this->parameters[$name]);
122
    }
123
124
    /**
125
     * The request parameters, sorted and concatenated into a normalized string.
126
     *
127
     * @return string
128
     */
129
    public function get_signable_parameters()
130
    {
131
        // Grab all parameters
132
        $params = $this->parameters;
133
134
        // Remove oauth_signature if present
135
        // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
136
        if (isset($params['oauth_signature'])) {
137
            unset($params['oauth_signature']);
138
        }
139
140
        return OAuthUtil::build_http_query($params);
141
    }
142
143
    /**
144
     * Returns the base string of this request.
145
     *
146
     * The base string defined as the method, the url
147
     * and the parameters (normalized), each urlencoded
148
     * and the concated with &.
149
     */
150
    public function get_signature_base_string()
151
    {
152
        $parts = [
153
            $this->get_normalized_http_method(),
154
            $this->get_normalized_http_url(),
155
            $this->get_signable_parameters(),
156
        ];
157
158
        $parts = OAuthUtil::urlencode_rfc3986($parts);
159
160
        return implode('&', $parts);
161
    }
162
163
    /**
164
     * just uppercases the http method.
165
     */
166
    public function get_normalized_http_method()
167
    {
168
        return strtoupper($this->http_method);
169
    }
170
171
    /**
172
     * parses the url and rebuilds it to be
173
     * scheme://host/path.
174
     */
175
    public function get_normalized_http_url()
176
    {
177
        $parts = parse_url($this->http_url);
178
179
        $port = @$parts['port'];
180
        $scheme = $parts['scheme'];
181
        $host = $parts['host'];
182
        $path = @$parts['path'];
183
184
        $port or $port = ($scheme == 'https') ? '443' : '80';
185
186
        if (($scheme == 'https' && $port != '443')
187
            || ($scheme == 'http' && $port != '80')
188
        ) {
189
            $host = "$host:$port";
190
        }
191
192
        return "$scheme://$host$path";
193
    }
194
195
    /**
196
     * builds a url usable for a GET request.
197
     */
198
    public function to_url()
199
    {
200
        $post_data = $this->to_postdata();
201
        $out = $this->get_normalized_http_url();
202
        if ($post_data) {
203
            $out .= '?'.$post_data;
204
        }
205
206
        return $out;
207
    }
208
209
    /**
210
     * builds the data one would send in a POST request.
211
     */
212
    public function to_postdata()
213
    {
214
        return OAuthUtil::build_http_query($this->parameters);
215
    }
216
217
    /**
218
     * builds the Authorization: header.
219
     */
220
    public function to_header()
221
    {
222
        $out = 'Authorization: OAuth realm=""';
223
        $total = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $total is dead and can be removed.
Loading history...
224
        foreach ($this->parameters as $k => $v) {
225
            if (substr($k, 0, 5) != 'oauth') {
226
                continue;
227
            }
228
            if (is_array($v)) {
229
                throw new Exception('Arrays not supported in headers');
0 ignored issues
show
Bug introduced by
The type Omnipay\Pesapal\OAuth\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
230
            }
231
            $out .= ','.
232
                    OAuthUtil::urlencode_rfc3986($k).
0 ignored issues
show
Bug introduced by
Are you sure Omnipay\Pesapal\OAuth\OA...::urlencode_rfc3986($k) of type string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

232
                    /** @scrutinizer ignore-type */ OAuthUtil::urlencode_rfc3986($k).
Loading history...
233
                    '="'.
234
                    OAuthUtil::urlencode_rfc3986($v).
0 ignored issues
show
Bug introduced by
Are you sure Omnipay\Pesapal\OAuth\OA...::urlencode_rfc3986($v) of type string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

234
                    /** @scrutinizer ignore-type */ OAuthUtil::urlencode_rfc3986($v).
Loading history...
235
                    '"';
236
        }
237
238
        return $out;
239
    }
240
241
    public function __toString()
242
    {
243
        return $this->to_url();
244
    }
245
246
    public function sign_request($signature_method, $consumer)
247
    {
248
        $this->set_parameter(
249
            'oauth_signature_method',
250
            $signature_method->get_name(),
251
            false
252
        );
253
        $signature = $this->build_signature($signature_method, $consumer, null);
254
        $this->set_parameter('oauth_signature', $signature, false);
255
    }
256
257
    public function build_signature($signature_method, $consumer, $token)
258
    {
259
        $signature = $signature_method->build_signature($this, $consumer, $token);
260
261
        return $signature;
262
    }
263
264
    /**
265
     * util function: current timestamp.
266
     */
267
    private static function generate_timestamp()
268
    {
269
        return time();
270
    }
271
272
    /**
273
     * util function: current nonce.
274
     */
275
    private static function generate_nonce()
276
    {
277
        mt_srand((float) microtime() * 10000); //optional for php 4.2.0 and up.
0 ignored issues
show
Bug introduced by
(double)microtime() * 10000 of type double is incompatible with the type integer expected by parameter $seed of mt_srand(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

277
        mt_srand(/** @scrutinizer ignore-type */ (float) microtime() * 10000); //optional for php 4.2.0 and up.
Loading history...
278
        $charid = strtoupper(md5(uniqid(rand(), true)));
279
        $hyphen = chr(45); // "-"
280
        $uuid = chr(123)// "{"
281
                .substr($charid, 0, 8).$hyphen
282
                .substr($charid, 8, 4).$hyphen
283
                .substr($charid, 12, 4).$hyphen
284
                .substr($charid, 16, 4).$hyphen
285
                .substr($charid, 20, 12)
286
                .chr(125); // "}"
287
        return $uuid;
288
    }
289
}
290