Completed
Push — master ( e8bfdb...2ef65b )
by Tobias
10:25 queued 47s
created

ClientProvider   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 15
Bugs 2 Features 3
Metric Value
wmc 14
c 15
b 2
f 3
lcom 1
cbo 5
dl 0
loc 152
ccs 0
cts 70
cp 0
rs 10

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 \Happyr\GoogleSiteAuthenticatorBundle\Model\TokenConfig config
16
     */
17
    private $config;
18
19
    /**
20
     * @var CacheItemPoolInterface storage
21
     */
22
    private $pool;
23
24
    /**
25
     * @param TokenConfig            $config
26
     * @param CacheItemPoolInterface $pool
27
     */
28
    public function __construct(TokenConfig $config, CacheItemPoolInterface $pool)
29
    {
30
        $this->config = $config;
31
        $this->pool = $pool;
32
    }
33
34
    /**
35
     * @param string|null $tokenName
36
     *
37
     * @return \Google_Client
38
     */
39
    public function getClient($tokenName = null)
40
    {
41
        $client = new \Google_Client();
42
43
        // Set values from configuration
44
        $client->setApplicationName($this->config->getApplicationName());
45
        $client->setClientId($this->config->getClientId($tokenName));
46
        $client->setClientSecret($this->config->getSecret($tokenName));
47
        $client->setRedirectUri($this->config->getRedirectUrl($tokenName));
48
        $client->setScopes($this->config->getScopes($tokenName));
49
50
        if (null !== $accessToken = $this->getAccessToken($tokenName)) {
51
            // set access token to client if we got one
52
            $client->setAccessToken((string) $accessToken);
53
54
            // make sure to refresh the stored access token
55
            $this->refreshToken($client);
56
        }
57
58
        return $client;
59
    }
60
61
    /**
62
     * Check if a token is valid.
63
     * This is an expensive operation that makes multiple API calls.
64
     *
65
     * @param string|null $tokenName
66
     *
67
     * @return bool
68
     */
69
    public function isTokenValid($tokenName = null)
70
    {
71
        // We must fetch the client here. A client will automatically refresh the stored access token.
72
        $client = $this->getClient($tokenName);
73
        if (null === $accessToken = $client->getAccessToken()) {
74
            return false;
75
        }
76
77
        // Get the token string from access token
78
        $token = json_decode($accessToken)->access_token;
79
        $url = sprintf('https://www.google.com/accounts/AuthSubTokenInfo?bearer_token=%s', $token);
80
        if (false === @file_get_contents($url)) {
81
            return false;
82
        }
83
84
        // Retrieve HTTP status code
85
        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...
86
87
        return $statusCode == 200;
88
    }
89
90
    /**
91
     * Store the access token in the storage.
92
     *
93
     * @param string      $accessToken
94
     * @param string|null $tokenName
95
     */
96
    public function setAccessToken($accessToken, $tokenName = null)
97
    {
98
        $name = $this->config->getKey($tokenName);
0 ignored issues
show
Bug introduced by
It seems like $tokenName defined by parameter $tokenName on line 96 can also be of type string; however, Happyr\GoogleSiteAuthent...l\TokenConfig::getKey() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
99
        $cacheKey = $this->creteCacheKey($name);
100
101
        if ($accessToken === null) {
102
            $this->pool->deleteItem($cacheKey);
103
104
            return;
105
        }
106
107
        $item = $this->pool->getItem($cacheKey)->set(new AccessToken($name, $accessToken));
108
        $this->pool->save($item);
109
    }
110
111
    /**
112
     * Get access token from storage.
113
     *
114
     * @param string|null $tokenName
115
     *
116
     * @return AccessToken|null
117
     */
118
    protected function getAccessToken($tokenName = null)
119
    {
120
        $cacheKey = $this->creteCacheKey($this->config->getKey($tokenName));
0 ignored issues
show
Bug introduced by
It seems like $tokenName defined by parameter $tokenName on line 118 can also be of type string; however, Happyr\GoogleSiteAuthent...l\TokenConfig::getKey() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
121
        $item = $this->pool->getItem($cacheKey);
122
123
        if (!$item->isHit()) {
124
            return;
125
        }
126
127
        return $item->get();
128
    }
129
130
    /**
131
     * If we got a refresh token, use it to retrieve a good access token.
132
     *
133
     * @param \Google_Client $client
134
     */
135
    private function refreshToken(\Google_Client $client)
136
    {
137
        $accessToken = $client->getAccessToken();
138
        $data = json_decode($accessToken, true);
139
140
        try {
141
            if (isset($data['refresh_token'])) {
142
                $client->refreshToken($data['refresh_token']);
143
144
                return true;
145
            }
146
        } 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...
147
        }
148
149
        return false;
150
    }
151
152
    /**
153
     * Create a cache key.
154
     *
155
     * @param string $name
156
     *
157
     * @return string
158
     */
159
    private function creteCacheKey($name)
160
    {
161
        return sha1('happyr_google-site-authenticator_'.$name);
162
    }
163
}
164