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->lindex($serverKey, -1);
109 // no previous association with this server
113 // get association, return null if failed
114 return $this->getAssociationFromServer($lastKey);
118 * Function to actually receive and unserialize the association
121 private function getAssociationFromServer($associationKey)
123 $association = $this->redis->get($associationKey);
124 return $association ? unserialize($association) : null;
128 * Immediately delete association from Redis.
130 function removeAssociation($server_url, $handle)
133 $serverKey = $this->associationServerKey($server_url);
134 $associationKey = $this->associationKey($server_url,
137 // Removing the association from the server's association list
138 $removed = $this->redis->lrem($serverKey, 0, $associationKey);
143 // Delete the association itself
144 return $this->redis->del($associationKey);
148 * Create nonce for server and salt, expiring after
149 * $Auth_OpenID_SKEW seconds.
151 function useNonce($server_url, $timestamp, $salt)
153 global $Auth_OpenID_SKEW;
155 // save one request to memcache when nonce obviously expired
156 if (abs($timestamp - time()) > $Auth_OpenID_SKEW) {
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");
164 // Will set expiration
165 $this->redis->expire($nonceKey, $Auth_OpenID_SKEW);
175 private function nonceKey($server_url, $salt)
177 return $this->prefix .
179 sha1($server_url) . '_' . sha1($salt);
183 * Key is prefixed with $prefix and 'openid_association_' string
185 function associationKey($server_url, $handle = null)
187 return $this->prefix .
188 'openid_association_' .
189 sha1($server_url) . '_' . sha1($handle);
193 * Key is prefixed with $prefix and 'openid_association_server_' string
195 function associationServerKey($server_url)
197 return $this->prefix .
198 'openid_association_server_' .
203 * Report that this storage doesn't support cleanup
205 function supportsCleanup()