Passed
Pull Request — master (#140)
by
unknown
04:46
created

GmailConnection::setBothAccessToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Ddomanskyi\LaravelGmail;
4
5
use Ddomanskyi\LaravelGmail\Traits\Configurable;
6
use Google_Client;
7
use Google_Service_Gmail;
8
use Illuminate\Container\Container;
9
use Illuminate\Support\Facades\Request;
10
use Illuminate\Support\Facades\Storage;
11
12
class GmailConnection extends Google_Client
13
{
14
15
	use Configurable {
16
		__construct as configConstruct;
17
	}
18
19
	protected $emailAddress;
20
	protected $refreshToken;
21
	protected $app;
22
	protected $accessToken;
23
	protected $token;
24
	private $configuration;
25
	public $tokenFile;
26
27
	public function __construct($config = null, $tokenFile = null)
28
	{
29
		$this->app = Container::getInstance();
30
31
		$this->userId = $userId;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $userId seems to be never defined.
Loading history...
Bug Best Practice introduced by
The property userId does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
32
33
		$this->configConstruct($config);
34
35
		$this->configuration = $config;
36
37
		$this->tokenFile = $tokenFile;
38
39
		parent::__construct($this->getConfigs());
40
41
		$this->configApi();
42
43
		if ($this->checkPreviouslyLoggedIn()) {
44
			$this->refreshTokenIfNeeded();
45
		}
46
47
	}
48
49
	/**
50
	 * Check and return true if the user has previously logged in without checking if the token needs to refresh
51
	 *
52
	 * @return bool
53
	 */
54
	public function checkPreviouslyLoggedIn()
55
	{
56
		$fileName = $this->getFileName();
57
		$file = "gmail/tokens/$fileName.json";
58
		$allowJsonEncrypt = $this->_config['gmail.allow_json_encrypt'];
59
60
		if (Storage::disk('local')->exists($file)) {
61
			if ($allowJsonEncrypt) {
62
				$savedConfigToken = json_decode(decrypt(Storage::disk('local')->get($file)), true);
63
			} else {
64
				$savedConfigToken = json_decode(Storage::disk('local')->get($file), true);
65
			}
66
67
			return !empty($savedConfigToken['access_token']);
68
69
		}
70
71
		return false;
72
	}
73
74
	/**
75
	 * Refresh the auth token if needed
76
	 *
77
	 * @return mixed|null
78
	 */
79
	private function refreshTokenIfNeeded()
80
	{
81
		if ($this->isAccessTokenExpired()) {
82
			$this->fetchAccessTokenWithRefreshToken($this->getRefreshToken());
83
			$token = $this->getAccessToken();
84
			$this->setBothAccessToken($token);
85
86
			return $token;
87
		}
88
89
		return $this->token;
90
	}
91
92
	/**
93
	 * Check if token exists and is expired
94
	 * Throws an AuthException when the auth file its empty or with the wrong token
95
	 *
96
	 *
97
	 * @return bool Returns True if the access_token is expired.
98
	 */
99
	public function isAccessTokenExpired()
100
	{
101
		$token = $this->getToken();
102
103
		if ($token) {
104
			$this->setAccessToken($token);
105
		}
106
107
		return parent::isAccessTokenExpired();
108
	}
109
110
	public function getToken()
111
	{
112
		return parent::getAccessToken() ?: $this->config();
113
	}
114
115
	public function setToken($token)
116
	{
117
		$this->setAccessToken($token);
118
	}
119
120
	public function getAccessToken()
121
	{
122
		$token = parent::getAccessToken() ?: $this->config();
123
124
		return $token;
125
	}
126
127
	/**
128
	 * @param  array|string  $token
129
	 */
130
	public function setAccessToken($token)
131
	{
132
		parent::setAccessToken($token);
133
	}
134
135
	/**
136
	 * @param $token
137
	 */
138
	public function setBothAccessToken($token)
139
	{
140
		$this->setAccessToken($token);
141
		$this->saveAccessToken($token);
142
	}
143
144
	/**
145
	 * Save the credentials in a file
146
	 *
147
	 * @param  array  $config
148
	 */
149
	public function saveAccessToken(array $config)
150
	{
151
		if (isset($config['email'])) {
152
			$fileName = $config['email'];
153
		} else {
154
			$fileName = $this->tokenFile;
155
		}
156
157
		$disk = Storage::disk('local');
158
		$file = "gmail/tokens/$fileName.json";
159
		$allowJsonEncrypt = $this->_config['gmail.allow_json_encrypt'];
160
		$config['email'] = $this->emailAddress;
161
162
		if ($disk->exists($file)) {
163
164
			if (empty($config['email'])) {
165
				if ($allowJsonEncrypt) {
166
					$savedConfigToken = json_decode(decrypt($disk->get($file)), true);
167
				} else {
168
					$savedConfigToken = json_decode($disk->get($file), true);
169
				}
170
				if(isset( $savedConfigToken['email'])) {
171
					$config['email'] = $savedConfigToken['email'];
172
				}
173
			}
174
175
			$disk->delete($file);
176
		}
177
178
		if ($allowJsonEncrypt) {
179
			$disk->put($file, encrypt(json_encode($config)));
180
		} else {
181
			$disk->put($file, json_encode($config));
182
		}
183
184
	}
185
186
	/**
187
	 * @return array|string
188
	 * @throws \Exception
189
	 */
190
	public function makeToken()
191
	{
192
		if (!$this->check()) {
193
			$request = Request::capture();
194
			$code = (string) $request->input('code', null);
195
			if (!is_null($code) && !empty($code)) {
0 ignored issues
show
introduced by
The condition is_null($code) is always false.
Loading history...
196
				$accessToken = $this->fetchAccessTokenWithAuthCode($code);
197
				if($this->haveReadScope()) {
198
					$me = $this->getProfile();
199
					if (property_exists($me, 'emailAddress')) {
200
						$this->emailAddress = $me->emailAddress;
201
						$accessToken['email'] = $me->emailAddress;
202
					}
203
				}
204
				$this->setBothAccessToken($accessToken);
205
206
				return $accessToken;
207
			} else {
208
				throw new \Exception('No access token');
209
			}
210
		} else {
211
			return $this->getAccessToken();
212
		}
213
	}
214
215
	/**
216
	 * Check
217
	 *
218
	 * @return bool
219
	 */
220
	public function check()
221
	{
222
		return !$this->isAccessTokenExpired();
223
	}
224
225
	/**
226
	 * Gets user profile from Gmail
227
	 *
228
	 * @return \Google_Service_Gmail_Profile
229
	 */
230
	public function getProfile()
231
	{
232
		$service = new Google_Service_Gmail($this);
233
234
		return $service->users->getProfile('me');
235
	}
236
237
	/**
238
	 * Revokes user's permission and logs them out
239
	 */
240
	public function logout()
241
	{
242
		$this->revokeToken();
243
	}
244
245
	/**
246
	 * Delete the credentials in a file
247
	 */
248
	public function deleteAccessToken()
249
	{
250
		$disk = Storage::disk('local');
251
		$fileName = $this->getFileName();
252
		$file = "gmail/tokens/$fileName.json";
253
254
		$allowJsonEncrypt = $this->_config['gmail.allow_json_encrypt'];
255
256
		if ($disk->exists($file)) {
257
			$disk->delete($file);
258
		}
259
260
		if ($allowJsonEncrypt) {
261
			$disk->put($file, encrypt(json_encode([])));
262
		} else {
263
			$disk->put($file, json_encode([]));
264
		}
265
266
	}
267
268
	private function haveReadScope()
269
	{
270
		$scopes = $this->getUserScopes();
271
272
		return in_array(Google_Service_Gmail::GMAIL_READONLY, $scopes);
273
	}
274
275
}
276