Passed
Pull Request — master (#140)
by
unknown
04:07 queued 01:40
created

GmailConnection::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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