Completed
Pull Request — master (#67)
by Paweł
06:09
created

Authenticator   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 87.88%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 8
dl 0
loc 100
ccs 29
cts 33
cp 0.8788
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A authenticate() 0 19 3
A parse() 0 18 3
A regenerate() 0 10 3
A hasRequiredFields() 0 16 4
1
<?php
2
3
namespace Xsolve\SalesforceClient\Security\Authentication;
4
5
use Xsolve\SalesforceClient\Http\ClientInterface;
6
use Xsolve\SalesforceClient\Http\HttpException;
7
use Xsolve\SalesforceClient\Request\RequestInterface;
8
use Xsolve\SalesforceClient\Security\Authentication\Strategy\RegenerateStrategyInterface;
9
use Xsolve\SalesforceClient\Security\Token\Token;
10
use Xsolve\SalesforceClient\Security\Token\TokenInterface;
11
12
class Authenticator implements AuthenticatorInterface
13
{
14
    const ENDPOINT = '/services/oauth2/token';
15
16
    /**
17
     * @var ClientInterface
18
     */
19
    protected $client;
20
21
    /**
22
     * @var RegenerateStrategyInterface[]
23
     */
24
    protected $regenerateStrategies;
25
26
    /**
27
     * @param ClientInterface               $client
28
     * @param RegenerateStrategyInterface[] $regenerateStrategies
29
     */
30 5
    public function __construct(ClientInterface $client, array $regenerateStrategies = [])
31
    {
32 5
        $this->client = $client;
33 5
        $this->regenerateStrategies = $regenerateStrategies;
34 5
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 4
    public function authenticate(Credentials $credentials): TokenInterface
40
    {
41
        try {
42 4
            $response = $this->client->request(RequestInterface::METHOD_POST, self::ENDPOINT, [
43 4
                'form_params' => $credentials->getParameters(),
44 4
            ])->getBody();
45
        } catch (HttpException $e) {
46
            throw new Exception\AuthenticationRequestException('Authentication request failed.', 400, $e);
47
        }
48
49 4
        $parsedBody = $this->parse($response);
50
51 4
        return new Token(
52 1
            $parsedBody['token_type'],
53
            $parsedBody['access_token'],
54
            $parsedBody['instance_url'],
55 3
            isset($parsedBody['refresh_token']) ? $parsedBody['refresh_token'] : ''
56 1
        );
57
    }
58
59 2
    /**
60 2
     * @throws Exception\InvalidAuthenticationResponseException
61 2
     */
62 2
    private function parse($rawResponse): array
63 2
    {
64
        $parsedBody = json_decode($rawResponse, true);
65
66
        if (!$parsedBody) {
67
            throw new Exception\InvalidAuthenticationResponseException(
68
                sprintf('Cannot decode response: %s', $rawResponse)
69
            );
70 2
        }
71
72 2
        if (!$this->hasRequiredFields($parsedBody)) {
73 2
            throw new Exception\InvalidAuthenticationResponseException(
74 2
                'Response does not contains required fields: token_type, access_token, instance_url.'
75
            );
76
        }
77
78 1
        return $parsedBody;
79
    }
80
81 3
    /**
82
     * {@inheritdoc}
83 3
     */
84 1
    public function regenerate(Credentials $credentials, TokenInterface $token): TokenInterface
85
    {
86
        foreach ($this->regenerateStrategies as $strategy) {
87 2
            if ($strategy->supports($credentials, $token)) {
88
                return $this->authenticate($strategy->getCredentials($credentials, $token));
89
            }
90
        }
91 2
92
        throw new Exception\UnsupportedCredentialsException('Strategy not found for given credentials and token.');
93
    }
94
95 2
    protected function hasRequiredFields(array $array): bool
96
    {
97
        if (!isset($array['token_type'])) {
98
            return false;
99
        }
100
101
        if (!isset($array['access_token'])) {
102
            return false;
103
        }
104
105
        if (!isset($array['instance_url'])) {
106
            return false;
107
        }
108
109
        return true;
110
    }
111
}
112