1<?php 2 3/** 4 * In-memory OpenID store implementation for testing only 5 */ 6require_once "Auth/OpenID/Interface.php"; 7require_once 'Auth/OpenID/Nonce.php'; 8 9class ServerAssocs { 10 function __construct() 11 { 12 $this->assocs = []; 13 } 14 15 function set($assoc) 16 { 17 $this->assocs[$assoc->handle] = $assoc; 18 } 19 20 function get($handle) 21 { 22 return Auth_OpenID::arrayGet($this->assocs, $handle); 23 } 24 25 function remove($handle) 26 { 27 if (array_key_exists($handle, $this->assocs)) { 28 unset($this->assocs[$handle]); 29 return true; 30 } else { 31 return false; 32 } 33 } 34 35 /* 36 * Returns association with the oldest issued date. 37 * 38 * or null if there are no associations. 39 */ 40 function best() 41 { 42 $best = null; 43 foreach ($this->assocs as $handle => $assoc) { 44 if (($best === null) || ($best->issued < $assoc->issued)) { 45 $best = $assoc; 46 } 47 } 48 return $best; 49 } 50 51 /* 52 * Remove expired associations. 53 * 54 * @return (removed associations, remaining associations) 55 */ 56 function cleanup() 57 { 58 $remove = []; 59 foreach ($this->assocs as $handle => $assoc) { 60 if ($assoc->getExpiresIn() == 0) { 61 $remove[] = $handle; 62 } 63 } 64 65 foreach ($remove as $handle) { 66 unset($this->assocs[$handle]); 67 } 68 69 return [count($remove), count($this->assocs)]; 70 } 71} 72 73/* 74 * In-process memory store. 75 * 76 * Use for single long-running processes. No persistence supplied. 77 */ 78class Tests_Auth_OpenID_MemStore extends Auth_OpenID_OpenIDStore { 79 function __construct() 80 { 81 $this->server_assocs = []; 82 $this->nonces = []; 83 } 84 85 function &_getServerAssocs($server_url) 86 { 87 if (!array_key_exists($server_url, $this->server_assocs)) { 88 $this->server_assocs[$server_url] = new ServerAssocs(); 89 } 90 91 return $this->server_assocs[$server_url]; 92 } 93 94 function storeAssociation($server_url, $assoc) 95 { 96 $assocs =& $this->_getServerAssocs($server_url); 97 $assocs->set($assoc); 98 } 99 100 function getAssociation($server_url, $handle=null) 101 { 102 $assocs =& $this->_getServerAssocs($server_url); 103 if ($handle === null) { 104 return $assocs->best(); 105 } else { 106 return $assocs->get($handle); 107 } 108 } 109 110 function removeAssociation($server_url, $handle) 111 { 112 $assocs =& $this->_getServerAssocs($server_url); 113 return $assocs->remove($handle); 114 } 115 116 function useNonce($server_url, $timestamp, $salt) 117 { 118 global $Auth_OpenID_SKEW; 119 120 if (abs($timestamp - time()) > $Auth_OpenID_SKEW) { 121 return false; 122 } 123 124 $anonce = [$server_url, intval($timestamp), $salt]; 125 126 if (in_array($anonce, $this->nonces)) { 127 return false; 128 } else { 129 array_push($this->nonces, $anonce); 130 return true; 131 } 132 } 133 134 function cleanupNonces() 135 { 136 global $Auth_OpenID_SKEW; 137 138 $now = time(); 139 $expired = []; 140 foreach ($this->nonces as $anonce) { 141 if (abs($anonce[1] - $now) > $Auth_OpenID_SKEW) { 142 // removing items while iterating over the set could 143 // be bad. 144 $expired[] = $anonce; 145 } 146 } 147 148 foreach ($expired as $anonce) { 149 unset($this->nonces[array_search($anonce, $this->nonces)]); 150 } 151 152 return count($expired); 153 } 154 155 function cleanupAssociations() 156 { 157 $remove_urls = []; 158 $removed_assocs = 0; 159 foreach ($this->server_assocs as $server_url => $assocs) { 160 list($removed, $remaining) = $assocs->cleanup(); 161 $removed_assocs += $removed; 162 if (!$remaining) { 163 $remove_urls[] = $server_url; 164 } 165 } 166 167 // Remove entries from server_assocs that had none remaining. 168 foreach ($remove_urls as $server_url) { 169 unset($this->server_assocs[$server_url]); 170 } 171 172 return $removed_assocs; 173 } 174} 175 176 177