[BUGFIX] Fix T3editor after PSR-7 change
[Packages/TYPO3.CMS.git] / typo3 / sysext / openid / lib / php-openid / Auth / OpenID / PredisStore.php
1 <?php
2
3 /**
4 * Supplies Redis server store backend for OpenID servers and consumers.
5 * Uses Predis library {@see https://github.com/nrk/predis}.
6 * Requires PHP >= 5.3.
7 *
8 * LICENSE: See the COPYING file included in this distribution.
9 *
10 * @package OpenID
11 * @author Ville Mattila <ville@eventio.fi>
12 * @copyright 2008 JanRain Inc., 2013 Eventio Oy / Ville Mattila
13 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
14 * Contributed by Eventio Oy <http://www.eventio.fi/>
15 */
16
17 /**
18 * Import the interface for creating a new store class.
19 */
20 require_once 'Auth/OpenID/Interface.php';
21
22 /**
23 * Supplies Redis server store backend for OpenID servers and consumers.
24 * Uses Predis library {@see https://github.com/nrk/predis}.
25 * Requires PHP >= 5.3.
26 *
27 * @package OpenID
28 */
29 class Auth_OpenID_PredisStore extends Auth_OpenID_OpenIDStore {
30
31 /**
32 * @var \Predis\Client
33 */
34 protected $redis;
35
36 /**
37 * Prefix for Redis keys
38 * @var string
39 */
40 protected $prefix;
41
42 /**
43 * Initializes a new {@link Auth_OpenID_PredisStore} instance.
44 *
45 * @param \Predis\Client $redis Predis client object
46 * @param string $prefix Prefix for all keys stored to the Redis
47 */
48 function Auth_OpenID_PredisStore(\Predis\Client $redis, $prefix = '')
49 {
50 $this->prefix = $prefix;
51 $this->redis = $redis;
52 }
53
54 /**
55 * Store association until its expiration time in Redis server.
56 * Overwrites any existing association with same server_url and
57 * handle. Handles list of associations for every server.
58 */
59 function storeAssociation($server_url, $association)
60 {
61 // create Redis keys for association itself
62 // and list of associations for this server
63 $associationKey = $this->associationKey($server_url,
64 $association->handle);
65 $serverKey = $this->associationServerKey($server_url);
66
67 // save association to server's associations' keys list
68 $this->redis->lpush(
69 $serverKey,
70 $associationKey
71 );
72
73 // Will touch the association list expiration, to avoid filling up
74 $newExpiration = ($association->issued + $association->lifetime);
75
76 $expirationKey = $serverKey.'_expires_at';
77 $expiration = $this->redis->get($expirationKey);
78 if (!$expiration || $newExpiration > $expiration) {
79 $this->redis->set($expirationKey, $newExpiration);
80 $this->redis->expireat($serverKey, $newExpiration);
81 $this->redis->expireat($expirationKey, $newExpiration);
82 }
83
84 // save association itself, will automatically expire
85 $this->redis->setex(
86 $associationKey,
87 $newExpiration - time(),
88 serialize($association)
89 );
90 }
91
92 /**
93 * Read association from Redis. If no handle given
94 * and multiple associations found, returns latest issued
95 */
96 function getAssociation($server_url, $handle = null)
97 {
98 // simple case: handle given
99 if ($handle !== null) {
100 return $this->getAssociationFromServer(
101 $this->associationKey($server_url, $handle)
102 );
103 }
104
105 // no handle given, receiving the latest issued
106 $serverKey = $this->associationServerKey($server_url);
107 $lastKey = $this->redis->lindex($serverKey, -1);
108 if (!$lastKey) {
109 // no previous association with this server
110 return null;
111 }
112
113 // get association, return null if failed
114 return $this->getAssociationFromServer($lastKey);
115 }
116
117 /**
118 * Function to actually receive and unserialize the association
119 * from the server.
120 */
121 private function getAssociationFromServer($associationKey)
122 {
123 $association = $this->redis->get($associationKey);
124 return $association ? unserialize($association) : null;
125 }
126
127 /**
128 * Immediately delete association from Redis.
129 */
130 function removeAssociation($server_url, $handle)
131 {
132 // create Redis keys
133 $serverKey = $this->associationServerKey($server_url);
134 $associationKey = $this->associationKey($server_url,
135 $handle);
136
137 // Removing the association from the server's association list
138 $removed = $this->redis->lrem($serverKey, 0, $associationKey);
139 if ($removed < 1) {
140 return false;
141 }
142
143 // Delete the association itself
144 return $this->redis->del($associationKey);
145 }
146
147 /**
148 * Create nonce for server and salt, expiring after
149 * $Auth_OpenID_SKEW seconds.
150 */
151 function useNonce($server_url, $timestamp, $salt)
152 {
153 global $Auth_OpenID_SKEW;
154
155 // save one request to memcache when nonce obviously expired
156 if (abs($timestamp - time()) > $Auth_OpenID_SKEW) {
157 return false;
158 }
159
160 // SETNX will set the value only of the key doesn't exist yet.
161 $nonceKey = $this->nonceKey($server_url, $salt);
162 $added = $this->redis->setnx($nonceKey, "1");
163 if ($added) {
164 // Will set expiration
165 $this->redis->expire($nonceKey, $Auth_OpenID_SKEW);
166 return true;
167 } else {
168 return false;
169 }
170 }
171
172 /**
173 * Build up nonce key
174 */
175 private function nonceKey($server_url, $salt)
176 {
177 return $this->prefix .
178 'openid_nonce_' .
179 sha1($server_url) . '_' . sha1($salt);
180 }
181
182 /**
183 * Key is prefixed with $prefix and 'openid_association_' string
184 */
185 function associationKey($server_url, $handle = null)
186 {
187 return $this->prefix .
188 'openid_association_' .
189 sha1($server_url) . '_' . sha1($handle);
190 }
191
192 /**
193 * Key is prefixed with $prefix and 'openid_association_server_' string
194 */
195 function associationServerKey($server_url)
196 {
197 return $this->prefix .
198 'openid_association_server_' .
199 sha1($server_url);
200 }
201
202 /**
203 * Report that this storage doesn't support cleanup
204 */
205 function supportsCleanup()
206 {
207 return false;
208 }
209
210 }
211