Completed
Push — master ( d84be1...3db5c9 )
by Vladimir
03:44 queued 02:01
created

Api::authorize()   B

Complexity

Conditions 5
Paths 11

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
cc 5
eloc 14
nc 11
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AcquiroPay;
6
7
use Exception;
8
use GuzzleHttp\Client;
9
use GuzzleHttp\Psr7\Request;
10
use Psr\Log\LoggerInterface;
11
use AcquiroPay\Contracts\Cache;
12
use AcquiroPay\Exceptions\UnauthorizedException;
13
14
class Api
15
{
16
    protected $cache;
17
    protected $http;
18
    protected $logger;
19
20
    protected $url;
21
    protected $username;
22
    protected $password;
23
24
    public function __construct(Cache $cache, Client $http, LoggerInterface $logger = null)
25
    {
26
        $this->cache = $cache;
27
        $this->http = $http;
28
        $this->logger = $logger;
29
    }
30
31
    public function setUrl(string $url): self
32
    {
33
        $this->url = $url;
34
35
        return $this;
36
    }
37
38
    public function setUsername(string $username): self
39
    {
40
        $this->username = $username;
41
42
        return $this;
43
    }
44
45
    public function setPassword(string $password): self
46
    {
47
        $this->password = $password;
48
49
        return $this;
50
    }
51
52
    public function callService(string $service, string $method, string $endpoint, array $parameters = null)
53
    {
54
        return $this->call($method, '/services/'.$service, ['Endpoint' => $endpoint], $parameters);
55
    }
56
57
    public function call(string $method, string $endpoint, array $headers = [], array $parameters = null)
58
    {
59
        $body = null;
60
61
        $headers = array_merge([
62
            'Accept' => 'application/json',
63
            'Content-Type' => 'application/json',
64
            'Authorization' => 'Bearer '.$this->token(),
65
        ], $headers);
66
67
        if (!Str::startsWith($endpoint, ['http://', 'https://'])) {
68
            $endpoint = $this->url.'/'.ltrim($endpoint, '/');
69
        }
70
71
        if ($parameters !== null) {
72
            $body = json_encode($parameters);
73
        }
74
75
        $response = $this->http->send(new Request($method, $endpoint, $headers, $body));
76
77
        $json = json_decode((string) $response->getBody());
78
79
        if (json_last_error() === JSON_ERROR_NONE) {
80
            return $json;
81
        }
82
83
        return (string) $response->getBody();
84
    }
85
86
    /**
87
     * Authorize token for performing request.
88
     *
89
     * @param string $token
90
     * @param string $service
91
     * @param string $method
92
     * @param string $endpoint
93
     *
94
     * @return Consumer
95
     *
96
     * @throws UnauthorizedException
97
     */
98
    public function authorize(string $token, string $service, string $method, string $endpoint): Consumer
99
    {
100
        try {
101
            $headers = ['Content-Type' => 'application/json'];
102
103
            $url = $this->url.'/authorize';
104
105
            $body = json_encode(compact('token', 'service', 'method', 'endpoint'));
106
107
            $response = $this->http->send(new Request('POST', $url, $headers, $body));
108
109
            $json = \GuzzleHttp\json_decode((string) $response->getBody());
110
111
            if (!isset($json->authorized, $json->consumer_id) || $json->authorized !== true) {
112
                throw new UnauthorizedException;
113
            }
114
115
            return Consumer::create($json->consumer_id);
116
        } catch (Exception $exception) {
117
            if ($this->logger) {
118
                $this->logger->error($exception);
119
            }
120
121
            throw new UnauthorizedException('', 0, $exception);
122
        }
123
    }
124
125
    protected function token(): ?string
126
    {
127
        return $this->cache->remember('acquiropay_api_token_'.md5($this->url), 10, function () {
128
            $response = $this->http->post($this->url.'/login', ['form_params' => ['username' => $this->username, 'password' => $this->password]]);
129
130
            return (string) $response->getBody();
131
        });
132
    }
133
}
134