Passed
Pull Request — master (#102)
by Daniel
04:06
created

GmailConnection::haveReadScope()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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