SessionStorage::storeCSRFState()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 2
c 3
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * Class SessionStorage
4
 *
5
 * @created      09.07.2017
6
 * @author       Smiley <[email protected]>
7
 * @copyright    2017 Smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\OAuth\Storage;
12
13
use chillerlan\OAuth\Core\AccessToken;
14
use chillerlan\OAuth\OAuthOptions;
15
use chillerlan\Settings\SettingsContainerInterface;
16
use function array_key_exists;
17
use function array_keys;
18
use function session_start;
19
use function session_status;
20
use function session_write_close;
21
use const PHP_SESSION_NONE;
22
23
/**
24
 * Implements a session storage adapter. Session storage is half persistent as tokens are stored for the duration of the session.
25
 */
26
class SessionStorage extends OAuthStorageAbstract{
27
28
	/**
29
	 * the key name for the token storage array in $_SESSION
30
	 */
31
	protected string $tokenVar;
32
33
	/**
34
	 * the key name for the CSRF token storage array in $_SESSION
35
	 */
36
	protected string $stateVar;
37
38
	/**
39
	 * SessionStorage constructor.
40
	 */
41
	public function __construct(OAuthOptions|SettingsContainerInterface $options = null){
42
		parent::__construct($options);
43
44
		$this->tokenVar = $this->options->sessionTokenVar;
0 ignored issues
show
Bug Best Practice introduced by
The property $sessionTokenVar is declared protected in chillerlan\OAuth\OAuthOptions. Since you implement __get, consider adding a @property or @property-read.
Loading history...
45
		$this->stateVar = $this->options->sessionStateVar;
0 ignored issues
show
Bug Best Practice introduced by
The property $sessionStateVar is declared protected in chillerlan\OAuth\OAuthOptions. Since you implement __get, consider adding a @property or @property-read.
Loading history...
46
47
		// Determine if the session has started.
48
		// @link http://stackoverflow.com/a/18542272/1470961
49
		if($this->options->sessionStart && !(session_status() !== PHP_SESSION_NONE)){
0 ignored issues
show
Bug Best Practice introduced by
The property $sessionStart is declared protected in chillerlan\OAuth\OAuthOptions. Since you implement __get, consider adding a @property or @property-read.
Loading history...
50
			session_start();
51
		}
52
53
		if(!isset($_SESSION[$this->tokenVar])){
54
			$_SESSION[$this->tokenVar] = [];
55
		}
56
57
		if(!isset($_SESSION[$this->stateVar])){
58
			$_SESSION[$this->stateVar] = [];
59
		}
60
61
	}
62
63
	/**
64
	 * SessionStorage destructor.
65
	 *
66
	 * @codeCoverageIgnore
67
	 */
68
	public function __destruct(){
69
		if($this->options->sessionStart){
0 ignored issues
show
Bug Best Practice introduced by
The property $sessionStart is declared protected in chillerlan\OAuth\OAuthOptions. Since you implement __get, consider adding a @property or @property-read.
Loading history...
70
			session_write_close();
71
		}
72
	}
73
74
	/**
75
	 * @inheritDoc
76
	 */
77
	public function storeAccessToken(AccessToken $token, string $service = null):OAuthStorageInterface{
78
		$_SESSION[$this->tokenVar][$this->getServiceName($service)] = $this->toStorage($token);
79
80
		return $this;
81
	}
82
83
	/**
84
	 * @inheritDoc
85
	 */
86
	public function getAccessToken(string $service = null):AccessToken{
87
88
		if($this->hasAccessToken($service)){
89
			return $this->fromStorage($_SESSION[$this->tokenVar][$this->getServiceName($service)]);
90
		}
91
92
		throw new OAuthStorageException('token not found');
93
	}
94
95
	/**
96
	 * @inheritDoc
97
	 */
98
	public function hasAccessToken(string $service = null):bool{
99
		return isset($_SESSION[$this->tokenVar], $_SESSION[$this->tokenVar][$this->getServiceName($service)]);
100
	}
101
102
	/**
103
	 * @inheritDoc
104
	 */
105
	public function clearAccessToken(string $service = null):OAuthStorageInterface{
106
		$serviceName = $this->getServiceName($service);
107
108
		if(array_key_exists($serviceName, $_SESSION[$this->tokenVar])){
109
			unset($_SESSION[$this->tokenVar][$serviceName]);
110
		}
111
112
		return $this;
113
	}
114
115
	/**
116
	 * @inheritDoc
117
	 */
118
	public function clearAllAccessTokens():OAuthStorageInterface{
119
120
		foreach(array_keys($_SESSION[$this->tokenVar]) as $service){
121
			unset($_SESSION[$this->tokenVar][$service]);
122
		}
123
124
		unset($_SESSION[$this->tokenVar]);
125
126
		return $this;
127
	}
128
129
	/**
130
	 * @inheritDoc
131
	 */
132
	public function storeCSRFState(string $state, string $service = null):OAuthStorageInterface{
133
		$_SESSION[$this->stateVar][$this->getServiceName($service)] = $state;
134
135
		return $this;
136
	}
137
138
	/**
139
	 * @inheritDoc
140
	 */
141
	public function getCSRFState(string $service = null):string{
142
143
		if($this->hasCSRFState($service)){
144
			return $_SESSION[$this->stateVar][$this->getServiceName($service)];
145
		}
146
147
		throw new OAuthStorageException('state not found');
148
	}
149
150
	/**
151
	 * @inheritDoc
152
	 */
153
	public function hasCSRFState(string $service = null):bool{
154
		return isset($_SESSION[$this->stateVar], $_SESSION[$this->stateVar][$this->getServiceName($service)]);
155
	}
156
157
	/**
158
	 * @inheritDoc
159
	 */
160
	public function clearCSRFState(string $service = null):OAuthStorageInterface{
161
		$serviceName = $this->getServiceName($service);
162
163
		if(array_key_exists($serviceName, $_SESSION[$this->stateVar])){
164
			unset($_SESSION[$this->stateVar][$serviceName]);
165
		}
166
167
		return $this;
168
	}
169
170
	/**
171
	 * @inheritDoc
172
	 */
173
	public function clearAllCSRFStates():OAuthStorageInterface{
174
		unset($_SESSION[$this->stateVar]);
175
176
		return $this;
177
	}
178
179
}
180