Passed
Push — master ( a4754c...e0c6ec )
by Nazar
05:32
created

OAuth2::get_token()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 51
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 38
nc 6
nop 1
dl 0
loc 51
rs 6.9743
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package   OAuth2
4
 * @category  modules
5
 * @author    Nazar Mokrynskyi <[email protected]>
6
 * @copyright Copyright (c) 2011-2017, Nazar Mokrynskyi
7
 * @license   MIT License, see license.txt
8
 */
9
namespace cs\modules\OAuth2;
10
use
11
	cs\Cache\Prefix,
12
	cs\Config,
13
	cs\Request,
14
	cs\Session,
15
	cs\User,
16
	cs\DB\Accessor,
17
	cs\Singleton;
18
19
/**
20
 * @todo Use CRUD trait
21
 *
22
 * @method static $this instance($check = false)
23
 */
24
class OAuth2 {
25
	use
26
		Accessor,
27
		Singleton;
28
	/**
29
	 * @var bool
30
	 */
31
	protected $automatic_prolongation;
32
	/**
33
	 * @var int
34
	 */
35
	protected $expiration;
36
	/**
37
	 * @var Prefix
38
	 */
39
	protected $cache;
40
	public function construct () {
41
		$this->cache                  = new Prefix('OAuth2');
42
		$module_data                  = Config::instance()->module('OAuth2');
43
		$this->automatic_prolongation = $module_data->automatic_prolongation;
0 ignored issues
show
Bug Best Practice introduced by
The property automatic_prolongation does not exist on cs\Config\Module_Properties. Since you implemented __get, consider adding a @property annotation.
Loading history...
44
		$this->expiration             = $module_data->expiration;
0 ignored issues
show
Documentation Bug introduced by
It seems like $module_data->expiration can also be of type false. However, the property $expiration is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
Bug Best Practice introduced by
The property expiration does not exist on cs\Config\Module_Properties. Since you implemented __get, consider adding a @property annotation.
Loading history...
45
	}
46
	/**
47
	 * Returns database index
48
	 *
49
	 * @return int
50
	 */
51
	protected function cdb () {
52
		return Config::instance()->module('OAuth2')->db('oauth2');
53
	}
54
	/**
55
	 * Add new client
56
	 *
57
	 * @param string $name
58
	 * @param string $domain
59
	 * @param int    $active
60
	 *
61
	 * @return false|string            <i>false</i> on failure, id of created client otherwise
62
	 */
63
	public function add_client ($name, $domain, $active) {
64
		if (
65
			!$domain ||
66
			strpos($domain, '/') !== false
67
		) {
68
			return false;
69
		}
70
		/**
71
		 * Generate hash in cycle, to obtain unique value
72
		 */
73
		/** @noinspection LoopWhichDoesNotLoopInspection */
74
		while (true) {
75
			$id = md5(random_bytes(1000));
76
			if ($this->db_prime()->qf(
77
				"SELECT `id`
0 ignored issues
show
Bug introduced by
EncapsedNode of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qf(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

77
				/** @scrutinizer ignore-type */ "SELECT `id`
Loading history...
78
				FROM `[prefix]oauth2_clients`
79
				WHERE `id` = '$id'
80
				LIMIT 1"
81
			)
82
			) {
83
				continue;
84
			}
85
			$this->db_prime()->q(
86
				"INSERT INTO `[prefix]oauth2_clients`
87
					(
88
						`id`,
89
						`secret`,
90
						`name`,
91
						`domain`,
92
						`active`
93
					) VALUES (
94
						'%s',
95
						'%s',
96
						'%s',
97
						'%s',
98
						'%s'
99
					)",
100
				$id,
0 ignored issues
show
Bug introduced by
$id of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
				/** @scrutinizer ignore-type */ $id,
Loading history...
101
				md5(random_bytes(1000)),
102
				xap($name),
103
				xap($domain),
104
				(int)(bool)$active
0 ignored issues
show
Bug introduced by
(int)(bool)$active of type integer is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
				/** @scrutinizer ignore-type */ (int)(bool)$active
Loading history...
105
			);
106
			unset($this->cache->$id);
107
			return $id;
108
		}
109
	}
110
	/**
111
	 * Get client data
112
	 *
113
	 * @param string $id
114
	 *
115
	 * @return array|false
116
	 */
117
	public function get_client ($id) {
118
		if (!is_md5($id)) {
119
			return false;
120
		}
121
		return $this->cache->get(
122
			$id,
123
			function () use ($id) {
124
				return $this->db()->qf(
125
					"SELECT *
0 ignored issues
show
Bug introduced by
'SELECT * FROM `[pr...d` = '%s' LIMIT 1' of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qf(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
					/** @scrutinizer ignore-type */ "SELECT *
Loading history...
126
					FROM `[prefix]oauth2_clients`
127
					WHERE `id`	= '%s'
128
					LIMIT 1",
129
					$id
130
				);
131
			}
132
		);
133
	}
134
	/**
135
	 * Set client data
136
	 *
137
	 * @param string $id
138
	 * @param string $secret
139
	 * @param string $name
140
	 * @param string $domain
141
	 * @param int    $active
142
	 *
143
	 * @return bool
144
	 */
145
	public function set_client ($id, $secret, $name, $domain, $active) {
146
		if (
147
			!is_md5($id) ||
148
			!is_md5($secret) ||
149
			!$domain ||
150
			strpos($domain, '/') !== false
151
		) {
152
			return false;
153
		}
154
		$result = $this->db_prime()->q(
155
			"UPDATE `[prefix]oauth2_clients`
156
			SET
157
				`secret`		= '%s',
158
				`name`			= '%s',
159
				`domain`		= '%s',
160
				`active`		= '%s'
161
			WHERE `id` = '%s'",
162
			$secret,
0 ignored issues
show
Bug introduced by
$secret of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
			/** @scrutinizer ignore-type */ $secret,
Loading history...
163
			xap($name),
164
			xap($domain),
165
			(int)(bool)$active,
0 ignored issues
show
Bug introduced by
(int)(bool)$active of type integer is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
			/** @scrutinizer ignore-type */ (int)(bool)$active,
Loading history...
166
			$id
167
		);
168
		unset($this->cache->$id);
169
		return !!$result;
170
	}
171
	/**
172
	 * Delete client
173
	 *
174
	 * @param string $id
175
	 *
176
	 * @return bool
177
	 */
178
	public function del_client ($id) {
179
		$result = $this->db_prime()->q(
180
			[
181
				"DELETE FROM `[prefix]oauth2_clients`
182
				WHERE `id` = '%s'",
183
				"DELETE FROM `[prefix]oauth2_clients_grant_access`
184
				WHERE `id`	= '%s'",
185
				"DELETE FROM `[prefix]oauth2_clients_sessions`
186
				WHERE `id`	= '%s'"
187
			],
188
			$id
0 ignored issues
show
Bug introduced by
$id of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
			/** @scrutinizer ignore-type */ $id
Loading history...
189
		);
190
		unset($this->cache->{'/'});
191
		return !!$result;
192
	}
193
	/**
194
	 * Get clients list in form of associative array
195
	 *
196
	 * @return array|false
197
	 */
198
	public function clients_list () {
199
		return $this->db()->qfa(
200
			'SELECT *
0 ignored issues
show
Bug introduced by
'SELECT * FROM `[prefix]oauth2_clients`' of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qfa(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

200
			/** @scrutinizer ignore-type */ 'SELECT *
Loading history...
201
			FROM `[prefix]oauth2_clients`'
202
		);
203
	}
204
	/**
205
	 * Grant access for specified client
206
	 *
207
	 * @param string $client
208
	 *
209
	 * @return bool
210
	 */
211
	public function add_access ($client) {
212
		$User = User::instance();
213
		if (!$User->user() || !$this->get_client($client)) {
214
			return false;
215
		}
216
		$result = $this->db_prime()->q(
217
			"INSERT IGNORE INTO `[prefix]oauth2_clients_grant_access`
218
				(
219
					`id`,
220
					`user`
221
				) VALUES (
222
					'%s',
223
					'%s'
224
				)",
225
			$client,
0 ignored issues
show
Bug introduced by
$client of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

225
			/** @scrutinizer ignore-type */ $client,
Loading history...
226
			$User->id
0 ignored issues
show
Bug introduced by
$User->id of type integer is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

226
			/** @scrutinizer ignore-type */ $User->id
Loading history...
227
		);
228
		unset($this->cache->{"grant_access/$User->id"});
229
		return $result;
230
	}
231
	/**
232
	 * Check granted access for specified client
233
	 *
234
	 * @param string   $client
235
	 * @param bool|int $user If not specified - current user assumed
236
	 *
237
	 * @return bool
238
	 */
239
	public function get_access ($client, $user = false) {
240
		$user = (int)$user ?: User::instance()->id;
241
		if ($user == User::GUEST_ID) {
242
			return false;
243
		}
244
		$clients = $this->cache->get(
245
			"grant_access/$user",
246
			function () use ($user) {
247
				return $this->db()->qfas(
248
					"SELECT `id`
0 ignored issues
show
Bug introduced by
'SELECT `id` FROM `... WHERE `user` = '%s'' of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qfas(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

248
					/** @scrutinizer ignore-type */ "SELECT `id`
Loading history...
249
					FROM `[prefix]oauth2_clients_grant_access`
250
					WHERE `user`	= '%s'",
251
					$user
0 ignored issues
show
Bug introduced by
$user of type integer is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qfas(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

251
					/** @scrutinizer ignore-type */ $user
Loading history...
252
				);
253
			}
254
		);
255
		return $clients ? in_array($client, $clients) : false;
256
	}
257
	/**
258
	 * Deny access for specified client/
259
	 *
260
	 * @param string   $client If '' - access for all clients will be denied
261
	 * @param bool|int $user   If not specified - current user assumed
262
	 *
263
	 * @return bool
264
	 */
265
	public function del_access ($client = '', $user = false) {
266
		$user = (int)$user ?: User::instance()->id;
267
		if ($user == User::GUEST_ID) {
268
			return false;
269
		}
270
		$result = $client ? $this->db_prime()->q(
271
			[
272
				"DELETE FROM `[prefix]oauth2_clients_grant_access`
273
				WHERE
274
					`user`	= $user AND
275
					`id`	= '%s'",
276
				"DELETE FROM `[prefix]oauth2_clients_sessions`
277
				WHERE
278
					`user`	= $user AND
279
					`id`	= '%s'"
280
			],
281
			$client
0 ignored issues
show
Bug introduced by
$client of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

281
			/** @scrutinizer ignore-type */ $client
Loading history...
282
		) : $this->db_prime()->q(
283
			[
284
				"DELETE FROM `[prefix]oauth2_clients_grant_access`
285
				WHERE
286
					`user`	= $user",
287
				"DELETE FROM `[prefix]oauth2_clients_sessions`
288
				WHERE
289
					`user`	= $user"
290
			]
291
		);
292
		unset($this->cache->{"grant_access/$user"});
293
		return $result;
294
	}
295
	/**
296
	 * Adds new code for specified client, code is used to obtain token
297
	 *
298
	 * @param string $client
299
	 * @param string $response_type 'code' or 'token'
300
	 * @param string $redirect_uri
301
	 *
302
	 * @return false|string                    <i>false</i> on failure or code for token access otherwise
303
	 */
304
	public function add_code ($client, $response_type, $redirect_uri = '') {
305
		$Session = Session::instance();
306
		$client  = $this->get_client($client);
307
		if (
308
			!$client ||
0 ignored issues
show
introduced by
The condition ! $client || ! $Session-...t_access($client['id']) can never be false.
Loading history...
309
			!$Session->user() ||
310
			!$this->get_access($client['id'])
311
		) {
312
			return false;
313
		}
314
		$Request                        = Request::instance();
315
		$user_agent                     = $Request->header('user-agent');
316
		$current_session                = $Session->get_id();
317
		$Request->headers['user-agent'] = "OAuth2-$client[name]-$client[id]";
318
		$Session->add($Session->get_user(), false);
319
		$new_session                    = $Session->get_id();
320
		$Request->headers['user-agent'] = $user_agent;
321
		$Session->load($current_session);
322
		unset($user_agent, $current_session);
323
		/** @noinspection LoopWhichDoesNotLoopInspection */
324
		while (true) {
325
			$access_token  = md5(random_bytes(1000));
326
			$refresh_token = md5($access_token.random_bytes(1000));
327
			$code          = md5($refresh_token.random_bytes(1000));
328
			if ($this->db_prime()->qf(
329
				"SELECT `id`
330
				FROM `[prefix]oauth2_clients_sessions`
331
				WHERE
332
					`access_token`	= '$access_token' OR
333
					`refresh_token`	= '$refresh_token' OR
334
					`code`			= '$code'
335
				LIMIT 1"
336
			)
337
			) {
338
				continue;
339
			}
340
			$result = $this->db_prime()->q(
341
				"INSERT INTO `[prefix]oauth2_clients_sessions`
342
					(
343
						`id`,
344
						`user`,
345
						`session`,
346
						`created`,
347
						`expire`,
348
						`access_token`,
349
						`refresh_token`,
350
						`code`,
351
						`type`,
352
						`redirect_uri`
353
					) VALUES (
354
						'%s',
355
						'%s',
356
						'%s',
357
						'%s',
358
						'%s',
359
						'%s',
360
						'%s',
361
						'%s',
362
						'%s',
363
						'%s'
364
					)",
365
				$client['id'],
366
				$Session->get_user(),
367
				$new_session,
368
				time(),
369
				time() + $this->expiration,
370
				$access_token,
371
				$refresh_token,
372
				$code,
373
				$response_type,
374
				md5($redirect_uri)
375
			);
376
			return $result ? $code : false;
377
		}
378
		return false;
379
	}
380
	/**
381
	 * Get code data (tokens)
382
	 *
383
	 * @param string $code
384
	 * @param string $client Client id
385
	 * @param string $secret Client secret
386
	 * @param string $redirect_uri
387
	 *
388
	 * @return array|false                    <i>false</i> on failure, otherwise array
389
	 *                                        ['access_token' => md5, 'refresh_token' => md5, 'expires_in' => seconds, 'token_type' => 'bearer']<br>
390
	 *                                        <i>expires_in</i> may be negative
391
	 */
392
	public function get_code ($code, $client, $secret, $redirect_uri = '') {
393
		$client = $this->get_client($client);
394
		if (!is_md5($code) || !$client || $client['secret'] != $secret) {
0 ignored issues
show
introduced by
The condition ! is_md5($code) || ! $cl...nt['secret'] != $secret can never be false.
Loading history...
395
			return false;
396
		}
397
		$data = $this->db_prime()->qf(
398
			"SELECT
399
				`access_token`,
400
				`refresh_token`,
401
				`expire`,
402
				`user`
403
			FROM `[prefix]oauth2_clients_sessions`
404
			WHERE
405
				`id`			= '%s' AND
406
				`code`			= '%s' AND
407
				`redirect_uri`	= '%s'
408
			LIMIT 1",
409
			$client['id'],
410
			$code,
411
			md5($redirect_uri)
412
		);
413
		if (!$data) {
414
			return false;
415
		}
416
		$this->db_prime()->q(
417
			"UPDATE `[prefix]oauth2_clients_sessions`
418
			SET `code` = ''
419
			WHERE
420
				`id`			= '%s' AND
421
				`code`			= '%s' AND
422
				`redirect_uri`	= '%s'",
423
			$client['id'],
424
			$code,
425
			md5($redirect_uri)
426
		);
427
		return [
428
			'access_token'  => $data['access_token'],
429
			'refresh_token' => $data['refresh_token'],
430
			'expires_in'    => $data['expire'] - time(),
431
			'token_type'    => 'bearer',
432
			'user_id'       => $data['user']
433
		];
434
	}
435
	/**
436
	 * Get token data
437
	 *
438
	 * @param string $access_token
439
	 *
440
	 * @return array|false                    <i>false</i> on failure, array ['user' => id, 'session' => id, 'expire' => unix time, 'type' => 'code'|'token']
441
	 */
442
	public function get_token ($access_token) {
443
		if (!is_md5($access_token)) {
444
			return false;
445
		}
446
		$Cache = $this->cache;
447
		$data  = $Cache->get(
448
			"tokens/$access_token",
449
			function () use ($access_token) {
450
				return $this->db()->qf(
451
					"SELECT
0 ignored issues
show
Bug introduced by
'SELECT `id` AS `c...n` = '%s' LIMIT 1' of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qf(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

451
					/** @scrutinizer ignore-type */ "SELECT
Loading history...
452
						`id` AS `client_id`,
453
						`user`,
454
						`session`,
455
						`expire`,
456
						`type`
457
					FROM `[prefix]oauth2_clients_sessions`
458
					WHERE
459
						`access_token`	= '%s'
460
					LIMIT 1",
461
					$access_token
462
				);
463
			}
464
		);
465
		if ($data) {
466
			if ($data['expire'] < time()) {
467
				return false;
468
			}
469
			if (!$this->get_access($data['client_id'], $data['user'])) {
470
				$this->db_prime()->q(
471
					"DELETE FROM `[prefix]oauth2_clients_sessions`
472
					WHERE `access_token` = '%s'",
473
					$access_token
0 ignored issues
show
Bug introduced by
$access_token of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

473
					/** @scrutinizer ignore-type */ $access_token
Loading history...
474
				);
475
				unset($Cache->{"tokens/$access_token"});
476
				$data = false;
477
				/**
478
				 * Automatic prolongation of tokens' expiration time if configured
479
				 */
480
			} elseif ($this->automatic_prolongation && $data['expire'] < time() - $this->expiration * Config::instance()->core['update_ratio'] / 100) {
481
				$data['expire'] = time() + $this->expiration;
482
				$this->db_prime()->q(
483
					"UPDATE `[prefix]oauth2_clients_sessions`
484
					SET `expire` = '%s'
485
					WHERE `access_token`	= '%s'",
486
					$data['expire'],
487
					$access_token
488
				);
489
				$Cache->{"tokens/$access_token"} = $data;
490
			}
491
		}
492
		return $data;
493
	}
494
	/**
495
	 * Del token data (invalidate token)
496
	 *
497
	 * @param string $access_token
498
	 *
499
	 * @return bool
500
	 */
501
	public function del_token ($access_token) {
502
		if (!is_md5($access_token)) {
503
			return false;
504
		}
505
		$session = $this->db_prime()->qfs(
506
			"SELECT `session`
0 ignored issues
show
Bug introduced by
'SELECT `session` FRO...ken` = '%s' LIMIT 1' of type string is incompatible with the type string[] expected by parameter $query of cs\DB\_Abstract::qfs(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

506
			/** @scrutinizer ignore-type */ "SELECT `session`
Loading history...
507
			FROM `[prefix]oauth2_clients_sessions`
508
			WHERE
509
				`access_token`	= '%s'
510
			LIMIT 1",
511
			$access_token
512
		);
513
		if ($this->db_prime()->q(
514
			"DELETE FROM `[prefix]oauth2_clients_sessions`
515
			WHERE `access_token`	= '%s'",
516
			$access_token
0 ignored issues
show
Bug introduced by
$access_token of type string is incompatible with the type array expected by parameter $parameters of cs\DB\_Abstract::q(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

516
			/** @scrutinizer ignore-type */ $access_token
Loading history...
517
		)
518
		) {
519
			unset($this->cache->{"tokens/$access_token"});
520
			Session::instance()->del($session);
0 ignored issues
show
Bug introduced by
It seems like $session can also be of type false; however, parameter $session_id of cs\Session::del() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

520
			Session::instance()->del(/** @scrutinizer ignore-type */ $session);
Loading history...
521
			return true;
522
		}
523
		return false;
524
	}
525
	/**
526
	 * Get new access_token with refresh_token
527
	 *
528
	 * @param string $refresh_token
529
	 * @param string $client Client id
530
	 * @param string $secret Client secret
531
	 *
532
	 * @return array|false <i>false</i> on failure, otherwise array ['access_token' => md5, 'refresh_token' => md5, 'expires_in' => seconds, 'token_type' =>
533
	 *                     'bearer']
534
	 */
535
	public function refresh_token ($refresh_token, $client, $secret) {
536
		$client = $this->get_client($client);
537
		if (!is_md5($refresh_token) || !$client || $client['secret'] != $secret) {
0 ignored issues
show
introduced by
The condition ! is_md5($refresh_token)...nt['secret'] != $secret can never be false.
Loading history...
538
			return false;
539
		}
540
		$data = $this->db_prime()->qf(
541
			"SELECT
542
				`user`,
543
				`access_token`,
544
				`session`
545
			FROM `[prefix]oauth2_clients_sessions`
546
			WHERE
547
				`id`			= '%s' AND
548
				`refresh_token`	= '%s'
549
			LIMIT 1",
550
			$client['id'],
551
			$refresh_token
552
		);
553
		if (!$data) {
554
			return false;
555
		}
556
		$this->db_prime()->q(
557
			"DELETE FROM `[prefix]oauth2_clients_sessions`
558
			WHERE
559
				`id`			= '%s' AND
560
				`refresh_token`	= '%s'",
561
			$client['id'],
562
			$refresh_token
563
		);
564
		unset($this->cache->{"tokens/$data[access_token]"});
565
		$Session = Session::instance();
566
		$id      = $Session->load($data['session']);
567
		if ($id != $data['user']) {
568
			return false;
569
		}
570
		$Session->add($id);
571
		$code = $this->add_code($client['id'], 'code');
572
		if (!$code) {
573
			return false;
574
		}
575
		$result = $this->get_code($code, $client['id'], $client['secret']);
576
		$Session->del();
577
		return $result;
578
	}
579
}
580