ClientProvider   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 123
ccs 0
cts 70
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getClient() 0 21 2
A isTokenValid() 0 20 3
A setAccessToken() 0 14 2
A getAccessToken() 0 11 2
A refreshToken() 0 16 3
A creteCacheKey() 0 4 1
1
<?php
2
3
namespace Happyr\GoogleSiteAuthenticatorBundle\Service;
4
5
use Happyr\GoogleSiteAuthenticatorBundle\Model\AccessToken;
6
use Happyr\GoogleSiteAuthenticatorBundle\Model\TokenConfig;
7
use Psr\Cache\CacheItemPoolInterface;
8
9
/**
10
 * @author Tobias Nyholm <[email protected]>
11
 */
12
class ClientProvider
13
{
14
    /**
15
     * @var TokenConfig config
16
     */
17
    private $config;
18
19
    /**
20
     * @var CacheItemPoolInterface storage
21
     */
22
    private $pool;
23
24
    public function __construct(TokenConfig $config, CacheItemPoolInterface $pool)
25
    {
26
        $this->config = $config;
27
        $this->pool = $pool;
28
    }
29
30
    public function getClient(string $tokenName = null): \Google_Client
31
    {
32
        $client = new \Google_Client();
33
34
        // Set values from configuration
35
        $client->setApplicationName($this->config->getApplicationName());
36
        $client->setClientId($this->config->getClientId($tokenName));
37
        $client->setClientSecret($this->config->getSecret($tokenName));
38
        $client->setRedirectUri($this->config->getRedirectUrl($tokenName));
39
        $client->setScopes($this->config->getScopes($tokenName));
40
41
        if (null !== $accessToken = $this->getAccessToken($tokenName)) {
42
            // set access token to client if we got one
43
            $client->setAccessToken((string) $accessToken);
44
45
            // make sure to refresh the stored access token
46
            $this->refreshToken($client);
47
        }
48
49
        return $client;
50
    }
51
52
    /**
53
     * Check if a token is valid.
54
     * This is an expensive operation that makes multiple API calls.
55
     */
56
    public function isTokenValid(string $tokenName = null): bool
57
    {
58
        // We must fetch the client here. A client will automatically refresh the stored access token.
59
        $client = $this->getClient($tokenName);
60
        if (null === $accessToken = $client->getAccessToken()) {
61
            return false;
62
        }
63
64
        // Get the token string from access token
65
        $token = \json_decode($accessToken)->access_token;
66
        $url = \sprintf('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s', $token);
67
        if (false === @\file_get_contents($url)) {
68
            return false;
69
        }
70
71
        // Retrieve HTTP status code
72
        list($version, $statusCode, $msg) = \explode(' ', $http_response_header[0], 3);
0 ignored issues
show
Unused Code introduced by
The assignment to $version is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $msg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
73
74
        return 200 === (int) $statusCode;
75
    }
76
77
    /**
78
     * Store the access token in the storage.
79
     */
80
    public function setAccessToken(?string $accessToken, string $tokenName = null)
81
    {
82
        $name = $this->config->getKey($tokenName);
83
        $cacheKey = $this->creteCacheKey($name);
84
85
        if (null === $accessToken) {
86
            $this->pool->deleteItem($cacheKey);
87
88
            return;
89
        }
90
91
        $item = $this->pool->getItem($cacheKey)->set(new AccessToken($name, $accessToken));
92
        $this->pool->save($item);
93
    }
94
95
    /**
96
     * Get access token from storage.
97
     */
98
    protected function getAccessToken(string $tokenName = null): ?AccessToken
99
    {
100
        $cacheKey = $this->creteCacheKey($this->config->getKey($tokenName));
101
        $item = $this->pool->getItem($cacheKey);
102
103
        if (!$item->isHit()) {
104
            return null;
105
        }
106
107
        return $item->get();
108
    }
109
110
    /**
111
     * If we got a refresh token, use it to retrieve a good access token.
112
     */
113
    private function refreshToken(\Google_Client $client): bool
114
    {
115
        $accessToken = $client->getAccessToken();
116
        $data = \json_decode($accessToken, true);
117
118
        try {
119
            if (isset($data['refresh_token'])) {
120
                $client->refreshToken($data['refresh_token']);
121
122
                return true;
123
            }
124
        } catch (\Google_Auth_Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
125
        }
126
127
        return false;
128
    }
129
130
    private function creteCacheKey(string $name): string
131
    {
132
        return \sha1('happyr_google-site-authenticator_'.$name);
133
    }
134
}
135