4 * Supplies Redis server store backend for OpenID servers and consumers.
5 * Uses Predis library {@see https://github.com/nrk/predis}.
8 * LICENSE: See the COPYING file included in this distribution.
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/>
18 * Import the interface for creating a new store class.
20 require_once 'Auth/OpenID/Interface.php';
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.
29 class Auth_OpenID_PredisStore extends Auth_OpenID_OpenIDStore {
37 * Prefix for Redis keys
43 * Initializes a new {@link Auth_OpenID_PredisStore} instance.
45 * @param \Predis\Client $redis Predis client object
46 * @param string $prefix Prefix for all keys stored to the Redis
48 function Auth_OpenID_PredisStore(\Predis\Client $redis, $prefix = '')
50 $this->prefix = $prefix;
51 $this->redis = $redis;
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.
59 function storeAssociation($server_url, $association)
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);
67 // save association to server's associations' keys list
73 // Will touch the association list expiration, to avoid filling up
74 $newExpiration = ($association->issued + $association->lifetime);
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);
84 // save association itself, will automatically expire
87 $newExpiration - time(),
88 serialize($association)
93 * Read association from Redis. If no handle given
94 * and multiple associations found, returns latest issued
96 function getAssociation($server_url, $handle = null)
98 // simple case: handle given
99 if ($handle !== null) {
100 return $this->getAssociationFromServer(
101 $this->associationKey($server_url, $handle)
105 // no handle given, receiving the latest issued
106 $serverKey = $this->associationServerKey($server_url);
107 $lastKey = $this->redis->lpop($serverKey);
108 if (!$lastKey) { return null; }
110 // get association, return null if failed
111 return $this->getAssociationFromServer($lastKey);
115 * Function to actually receive and unserialize the association
118 private function getAssociationFromServer($associationKey)
120 $association = $this->redis->get($associationKey);
121 return $association ? unserialize($association) : null;
125 * Immediately delete association from Redis.
127 function removeAssociation($server_url, $handle)
130 $serverKey = $this->associationServerKey($server_url);
131 $associationKey = $this->associationKey($server_url,
134 // Removing the association from the server's association list
135 $removed = $this->redis->lrem($serverKey, 0, $associationKey);
140 // Delete the association itself
141 return $this->redis->del($associationKey);
145 * Create nonce for server and salt, expiring after
146 * $Auth_OpenID_SKEW seconds.
148 function useNonce($server_url, $timestamp, $salt)
150 global $Auth_OpenID_SKEW;
152 // save one request to memcache when nonce obviously expired
153 if (abs($timestamp - time()) > $Auth_OpenID_SKEW) {
157 // SETNX will set the value only of the key doesn't exist yet.
158 $nonceKey = $this->nonceKey($server_url, $salt);
159 $added = $this->predis->setnx($nonceKey);
161 // Will set expiration
162 $this->predis->expire($nonceKey, $Auth_OpenID_SKEW);
172 private function nonceKey($server_url, $salt)
174 return $this->prefix .
176 sha1($server_url) . '_' . sha1($salt);
180 * Key is prefixed with $prefix and 'openid_association_' string
182 function associationKey($server_url, $handle = null)
184 return $this->prefix .
185 'openid_association_' .
186 sha1($server_url) . '_' . sha1($handle);
190 * Key is prefixed with $prefix and 'openid_association_server_' string
192 function associationServerKey($server_url)
194 return $this->prefix .
195 'openid_association_server_' .
200 * Report that this storage doesn't support cleanup
202 function supportsCleanup()