Completed
Pull Request — master (#4)
by Gregorio
02:19
created

Http::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 7
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 7
loc 7
rs 9.4285
cc 2
eloc 3
nc 2
nop 3
1
<?php
2
3
namespace Ghc\Rosetta\Connectors;
4
5
use Exception;
6
use Ghc\Rosetta\Messages\HttpResponse;
7
use gomes81\GuzzleHttp\Subscriber\CookieAuth;
8
use GuzzleHttp\Client;
9
use GuzzleHttp\HandlerStack;
10
use GuzzleHttp\Subscriber\Oauth\Oauth1;
11
use kamermans\OAuth2\OAuth2Middleware;
12
13
class Http extends Connector
14
{
15
    /**
16
     * Basic HTTP auth.
17
     * Config example: ['type' => self::AUTH_BASIC, 'username' => 'USER', 'password' => 'PASSWD'].
18
     */
19
    const AUTH_BASIC = 'basic';
20
21
    /**
22
     * Digest HTTP auth.
23
     * Config example: ['type' => self::AUTH_DIGEST, 'username' => 'USER', 'password' => 'PASSWD'].
24
     */
25
    const AUTH_DIGEST = 'digest';
26
27
    /**
28
     * Microsoft NTLM HTTP auth.
29
     * Config example: ['type' => self::AUTH_NTLM, 'username' => 'USER', 'password' => 'PASSWD'].
30
     */
31
    const AUTH_NTLM = 'ntlm';
32
33
    /**
34
     * Oauth1 auth.
35
     * Config example: ['type' => self::AUTH_OAUTH1, 'consumer_key' => 'my_key', 'consumer_secret' => 'my_secret', 'token' => 'my_token', 'token_secret' => 'my_token_secret'].
36
     *
37
     * @link https://github.com/guzzle/oauth-subscriber
38
     */
39
    const AUTH_OAUTH1 = 'oauth1';
40
41
    /**
42
     * Oauth2 auth.
43
     * Config example: ['type' => self::AUTH_OAUTH2, "uri" => "access_token_uri", "grant_type" => "client_credentials", "client_id" => "my_client_id", "client_secret" => "my_client_secret",]
44
     * Grant types: authorization_code, client_credentials, password_credentials, refresh_token.
45
     *
46
     * @link https://github.com/kamermans/guzzle-oauth2-subscriber
47
     */
48
    const AUTH_OAUTH2 = 'oauth2';
49
50
    /**
51
     * Cookie auth.
52
     * Config example: ['type' => self::AUTH_COOKIE, 'uri' => 'form_uri', 'fields' => ['username' => 'USER', 'password' => 'PASSWD', 'foo' => 'bar'], 'method' => 'POST', 'cookies' => 'cookie_string_or_cookie_string_array_or_cookie_jar'].
53
     */
54
    const AUTH_COOKIE = 'cookie';
55
56
    /**
57
     * Custom handler stack auth.
58
     * Config example: ['type' => self::AUTH_CUSTOM, 'handler' => $handlerStack', 'auth' => 'authName'].
59
     */
60
    const AUTH_CUSTOM = 'custom';
61
62
    /**
63
     * HTTP client.
64
     *
65
     * @var Client
66
     */
67
    protected $client;
68
69
    /**
70
     * Boot Connector.
71
     */
72
    protected function boot()
73
    {
74
    }
75
76
    /**
77
     * @param Client $client
78
     *
79
     * @return Http
80
     */
81
    public function setClient($client)
82
    {
83
        $this->client = $client;
84
85
        return $this;
86
    }
87
88
    /**
89
     * @return Client
90
     */
91
    public function getClient()
92
    {
93
        if (!$this->client) {
94
            $this->bootClient();
95
        }
96
97
        return $this->client;
98
    }
99
100
    /**
101
     * @return Client
102
     */
103
    public function bootClient()
104
    {
105
        if ($authConfig = $this->config->get('auth_config')) {
106
            $this->config->set('auth_config', null);
107
            $this->setAuth($authConfig);
108
        }
109
110
        $this->setClient(new Client($this->config->all()));
111
    }
112
113
    /**
114
     * @param array $config
115
     * @throws Exception
116
     * @uses  getClientConfigAuthBasic
117
     * @uses  getClientConfigAuthDigest
118
     * @uses  getClientConfigAuthNtlm
119
     * @uses  getClientConfigAuthOauth1
120
     * @uses  getClientConfigAuthOauth2
121
     * @uses  getClientConfigAuthCookie
122
     * @uses  getClientConfigAuthCustom
123
     */
124
    public function setAuth($config = [])
125
    {
126
        $type = $config['type'];
127
        unset($config['type']);
128
129
        $method = 'getClientConfigAuth' . ucfirst($type);
130
        if (!method_exists($this, $method)) {
131
            throw new Exception("Invalid auth type: $type");
132
        }
133
134
        /** @var array $clientConfig */
135
        $clientConfig = call_user_func([$this, $method], $config);
136
137
        foreach ($clientConfig as $key => $value) {
138
            $this->setConfig($key, $value);
139
        }
140
    }
141
142
    /**
143
     * @param array $config
144
     * @return array
145
     */
146
    private function getClientConfigAuthBasic($config = [])
147
    {
148
        return [
149
            'auth' => [
150
                $config['username'],
151
                $config['password']
152
            ]
153
        ];
154
    }
155
156
    /**
157
     * @param array $config
158
     * @return array
159
     */
160 View Code Duplication
    private function getClientConfigAuthDigest($config = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
    {
162
        return [
163
            'auth' => [
164
                $config['username'],
165
                $config['password'],
166
                'digest',
167
            ]
168
        ];
169
    }
170
171
    /**
172
     * @param array $config
173
     * @return array
174
     */
175 View Code Duplication
    private function getClientConfigAuthNtlm($config = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
    {
177
        return [
178
            'auth' => [
179
                $config['username'],
180
                $config['password'],
181
                'ntlm',
182
            ]
183
        ];
184
    }
185
186
    /**
187
     * @param array $config
188
     * @return array
189
     */
190
    private function getClientConfigAuthOauth1($config = [])
191
    {
192
        $stack = HandlerStack::create();
193
        $middleware = new Oauth1($config);
194
        $stack->push($middleware);
195
        $clientConfig['handler'] = $stack;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$clientConfig was never initialized. Although not strictly required by PHP, it is generally a good practice to add $clientConfig = array(); before regardless.
Loading history...
196
        $clientConfig['auth'] = 'oauth';
197
198
        return [
199
            'auth' => 'oauth',
200
            'handler' => $stack
201
        ];
202
    }
203
204
    /**
205
     * @param array $config
206
     * @return array
207
     */
208
    private function getClientConfigAuthOauth2($config = [])
209
    {
210
        $authClient = new Client(['base_uri' => $config['uri']]);
211
        $grantType = '\\kamermans\\OAuth2\\GrantType\\'.studly_case($config['grant_type']);
212
        unset($config['uri']);
213
        unset($config['grant_type']);
214
        /** @var \kamermans\OAuth2\GrantType\GrantTypeInterface $grant_type */
215
        $grant_type = new $grantType($authClient, $config);
216
        $oauth = new OAuth2Middleware($grant_type);
217
        $stack = HandlerStack::create();
218
        $stack->push($oauth);
219
220
        return [
221
            'auth' => 'oauth',
222
            'handler' => $stack
223
        ];
224
    }
225
226
    /**
227
     * @param array $config
228
     * @return array
229
     */
230
    private function getClientConfigAuthCookie($config = [])
231
    {
232
        $stack = HandlerStack::create();
233
        if (!isset($config['cookies'])) {
234
            $config['cookies'] = null;
235
        }
236
        if (!isset($config['method'])) {
237
            $config['method'] = 'POST';
238
        }
239
        $middleware = new CookieAuth(
240
            $config['uri'],
241
            $config['fields'],
242
            $config['method'],
243
            $config['cookies']
244
        );
245
        $stack->push($middleware);
246
247
        return [
248
            'auth' => 'cookie',
249
            'handler' => $stack
250
        ];
251
    }
252
253
    /**
254
     * @param array $config
255
     * @return array
256
     */
257
    private function getClientConfigAuthCustom($config = [])
258
    {
259
        return [
260
            'auth' => $config['auth'],
261
            'handler' => $config['handler']
262
        ];
263
    }
264
265
    /**
266
     * @param string $uri
267
     * @param array  $options
268
     *
269
     * @return mixed
270
     */
271
    public function show($uri, $options = [])
272
    {
273
        return new HttpResponse($this->getClient()->request('GET', $uri, $options));
274
    }
275
276
    /**
277
     * @param string     $uri
278
     * @param null|mixed $data
279
     * @param array      $options
280
     *
281
     * @return mixed
282
     */
283 View Code Duplication
    public function create($uri, $data = null, $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
284
    {
285
        if (!is_null($data)) {
286
            $options['form_params'] = $data;
287
        }
288
289
        return new HttpResponse($this->getClient()->request('POST', $uri, $options));
290
    }
291
292
    /**
293
     * @param string     $uri
294
     * @param null|mixed $data
295
     * @param array      $options
296
     *
297
     * @return mixed
298
     */
299 View Code Duplication
    public function update($uri, $data = null, $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
300
    {
301
        if (!is_null($data)) {
302
            $options['form_params'] = $data;
303
        }
304
305
        return new HttpResponse($this->getClient()->request('PATCH', $uri, $options));
306
    }
307
308
    /**
309
     * @param string     $uri
310
     * @param null|mixed $data
311
     * @param array      $options
312
     *
313
     * @return mixed
314
     */
315 View Code Duplication
    public function replace($uri, $data = null, $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
316
    {
317
        if (!is_null($data)) {
318
            $options['form_params'] = $data;
319
        }
320
321
        return new HttpResponse($this->getClient()->request('PUT', $uri, $options));
322
    }
323
324
    /**
325
     * @param string $uri
326
     * @param array  $options
327
     *
328
     * @return mixed
329
     */
330
    public function delete($uri, $options = [])
331
    {
332
        return new HttpResponse($this->getClient()->request('DELETE', $uri, $options));
333
    }
334
}
335