Passed
Pull Request — master (#29)
by Samuel
05:00 queued 02:51
created

Authenticator::makeRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
ccs 6
cts 6
cp 1
crap 1
1
<?php
2
3
namespace Samerior\MobileMoney\Mpesa\Library;
4
5
use Samerior\MobileMoney\Mpesa\Exceptions\MpesaException;
6
use GuzzleHttp\Exception\RequestException;
7
use Illuminate\Support\Facades\Cache;
8
use Psr\Http\Message\ResponseInterface;
9
use Samerior\MobileMoney\Mpesa\Repositories\EndpointsRepository;
10
11
/**
12
 * Class Authenticator
13
 *
14
 * @package Samerior\MobileMoney\Mpesa\Library
15
 */
16
class Authenticator
17
{
18
19
    /**
20
     * @var string
21
     */
22
    protected $endpoint;
23
    /**
24
     * @var Core
25
     */
26
    protected $engine;
27
    /**
28
     * @var Authenticator
29
     */
30
    protected static $instance;
31
    /**
32
     * @var bool
33
     */
34
    public $alt = false;
35
    /**
36
     * @var string
37
     */
38
    private $credentials;
39
40
    /**
41
     * Authenticator constructor.
42
     *
43
     * @param  Core $core
44
     * @throws MpesaException
45
     */
46 2
    public function __construct(Core $core)
47
    {
48 2
        $this->engine = $core;
49 2
        $this->endpoint = EndpointsRepository::build('auth');
50 2
        self::$instance = $this;
51 2
    }
52
53
    /**
54
     * @param bool $bulk
55
     * @return string
56
     * @throws MpesaException
57
     * @throws \GuzzleHttp\Exception\GuzzleException
58
     */
59 1
    public function authenticate($bulk = false): ?string
60
    {
61 1
        if ($bulk) {
62
            $this->alt = true;
63
        }
64 1
        $this->generateCredentials();
65 1
        if (config('samerior.mpesa.cache_credentials', false) && !empty($key = $this->getFromCache())) {
66
            return $key;
67
        }
68
        try {
69 1
            $response = $this->makeRequest();
70 1
            if ($response->getStatusCode() === 200) {
71
                $body = \json_decode($response->getBody());
72
                $this->saveCredentials($body);
73
                return $body->access_token;
74
            }
75 1
            throw new MpesaException($response->getReasonPhrase());
76 1
        } catch (RequestException $exception) {
77
            $message = $exception->getResponse() ?
78
                $exception->getResponse()->getReasonPhrase() :
79
                $exception->getMessage();
80
81
            throw $this->generateException($message);
82
        }
83
    }
84
85
    /**
86
     * @param $reason
87
     * @return MpesaException
88
     */
89
    private function generateException($reason): ?MpesaException
90
    {
91
        switch (\strtolower($reason)) {
92
            case 'bad request: invalid credentials':
93
                return new MpesaException('Invalid consumer key and secret combination');
94
            default:
95
                return new MpesaException($reason);
96
        }
97
    }
98
99
    /**
100
     * @return $this
101
     */
102 1
    private function generateCredentials(): self
103
    {
104 1
        $key = \config('samerior.mpesa.c2b.consumer_key');
105 1
        $secret = \config('samerior.mpesa.c2b.consumer_secret');
106 1
        if ($this->alt) {
107
            //lazy way to switch to a different app in case of bulk
108
            $key = \config('samerior.mpesa.b2c.consumer_key');
109
            $secret = \config('samerior.mpesa.b2c.consumer_secret');
110
        }
111 1
        $this->credentials = \base64_encode($key . ':' . $secret);
112 1
        return $this;
113
    }
114
115
    /**
116
     * @return ResponseInterface
117
     * @throws \GuzzleHttp\Exception\GuzzleException
118
     */
119 1
    private function makeRequest(): ResponseInterface
120
    {
121 1
        return $this->engine->client->request(
122 1
            'GET',
123 1
            $this->endpoint,
124
            [
125
                'headers' => [
126 1
                    'Authorization' => 'Basic ' . $this->credentials,
127 1
                    'Content-Type' => 'application/json',
128
                ],
129
            ]
130
        );
131
    }
132
133
    /**
134
     * @return mixed
135
     */
136 1
    private function getFromCache()
137
    {
138 1
        return Cache::get($this->credentials);
139
    }
140
141
    /**
142
     * Store the credentials in the cache.
143
     *
144
     * @param $credentials
145
     */
146
    private function saveCredentials($credentials)
147
    {
148
        Cache::put($this->credentials, $credentials->access_token, 30);
149
    }
150
}
151