00001 <?php
00002
00003 require_once 'Auth/OpenID/Interface.php';
00004 require_once 'Auth/OpenID/Nonce.php';
00005
00009 class oxOpenIdDb extends Auth_OpenID_OpenIDStore
00010 {
00016 protected $_sAssociationsTable = null;
00017
00023 protected $_sNoncesTable = null;
00024
00030 protected $_oDB = null;
00031
00037 protected $_iMaxNonceAge = null;
00038
00044 public function __construct()
00045 {
00046 $this->_sAssociationsTable = "oxoidassociations";
00047 $this->_sNoncesTable = "oxoidnonces";
00048 $this->_oDB = oxDb::getDb();
00049 $this->_iMaxNonceAge = 6 * 60 * 60;
00050 }
00051
00061 public function storeAssociation($sServerUrl, $oAssociation)
00062 {
00063 $sSql = "REPLACE INTO " . $this->_sAssociationsTable . " (server_url,handle,secret,issued,lifetime,assoc_type)";
00064 $sSql .= " VALUES ('$sServerUrl','".$oAssociation->handle."','";
00065 $sSql .= $this->blobEncode($oAssociation->secret)."','".$oAssociation->issued."','";
00066 $sSql .= $oAssociation->lifetime."','".$oAssociation->assoc_type."')";
00067
00068 $this->_oDB->execute($sSql);
00069 }
00070
00080 public function removeAssociation($sServerUrl, $sHandle)
00081 {
00082 $aRes = $this->_getAssoc($sServerUrl, $sHandle);
00083 if ( !$aRes ) {
00084 return false;
00085 }
00086
00087 $sSql = "DELETE FROM ".$this->_sAssociationsTable;
00088 $sSql .= " WHERE server_url = '".$sServerUrl."' AND handle = '".$sHandle."'";
00089 $this->_oDB->execute($sSql);
00090
00091 return true;
00092 }
00093
00110 public function getAssociation($sServerUrl, $sHandle = null)
00111 {
00112 $aAssociations = array();
00113 if ($sHandle !== null) {
00114 $aRes = $this->_getAssoc($sServerUrl, $sHandle);
00115
00116 $aAssocs = array();
00117 if ( $aRes->recordCount() > 0 ) {
00118 $aAssocRow = $aRes->fields;
00119 $oAssoc = new Auth_OpenID_Association($aAssocRow['0'],
00120 $aAssocRow['1'],
00121 $aAssocRow['2'],
00122 $aAssocRow['3'],
00123 $aAssocRow['4']);
00124 $oAssoc->secret = $this->blobDecode($oAssoc->secret);
00125
00126 if ($oAssoc->getExpiresIn() == 0) {
00127 $this->removeAssociation($sServerUrl, $oAssoc->handle);
00128 } else {
00129 $aAssociations[] = array($oAssoc->issued, $oAssoc);
00130 }
00131 } else {
00132 return null;
00133 }
00134 } else {
00135 $aAssocs = $this->_getAssocs($sServerUrl);
00136 if ( !$aAssocs || ( $aAssocs->recordCount() == 0 ) ) {
00137 return null;
00138 }
00139 $aAssocRow = $aAssocs->fields;
00140 $oAssoc = new Auth_OpenID_Association($aAssocRow['0'],
00141 $aAssocRow['1'],
00142 $aAssocRow['2'],
00143 $aAssocRow['3'],
00144 $aAssocRow['4']);
00145 $oAssoc->secret = $this->blobDecode($oAssoc->secret);
00146 if ($oAssoc->getExpiresIn() == 0) {
00147 $this->removeAssociation($sServerUrl, $oAssoc->handle);
00148 } else {
00149 $aAssociations[] = array($oAssoc->issued, $oAssoc);
00150 }
00151 }
00152
00153 if ($aAssociations) {
00154 $aIssued = array();
00155 $aAssocs = array();
00156 foreach ($aAssociations as $key => $assoc) {
00157 $aIssued[$key] = $assoc[0];
00158 $aAssocs[$key] = $assoc[1];
00159 }
00160
00161 array_multisort($aIssued, SORT_DESC, $aAssocs, SORT_DESC, $aAssociations);
00162
00163
00164 list($aIssued, $oAssoc) = $aAssociations[0];
00165 return $oAssoc;
00166 } else {
00167 return null;
00168 }
00169
00170 }
00171
00186 public function useNonce($sServerUrl, $sTimestamp, $sSalt)
00187 {
00188 if ( abs($sTimestamp - time()) > $this->_iMaxNonceAge ) {
00189 return false;
00190 }
00191 $sSql = "INSERT INTO " . $this->_sNoncesTable . " (server_url, timestamp, salt) ";
00192 $sSql.= "VALUES ('$sServerUrl', '$sTimestamp', '$sSalt')";
00193 $this->_oDB->execute($sSql);
00194 return true;
00195 }
00196
00202 public function cleanupNonces()
00203 {
00204 $v = time() - $this->_iMaxNonceAge;
00205
00206 $sSql = "DELETE FROM " . $this->_sNoncesTable . " WHERE timestamp < " . $v;
00207 $this->_oDB->execute($sSql);
00208 }
00209
00215 public function cleanupAssociations()
00216 {
00217 $sSql = "DELETE FROM " . $this->_sAssociationsTable . " WHERE issued + lifetime <" . time();
00218 $this->_oDB->execute($sSql);
00219 }
00220
00227 public function reset()
00228 {
00229 $this->_oDB->execute("DELETE FROM " . $this->_sAssociationsTable);
00230 $this->_oDB->execute("DELETE FROM " . $this->_sNoncesTable);
00231 }
00232
00238 public function createTables()
00239 {
00240 $oRet = $this->_oDB->execute("show tables like '".$this->_sNoncesTable."'" );
00241 if ( $oRet->recordCount() == 0 ) {
00242 $sSqlNonces = "CREATE TABLE IF NOT EXISTS ".$this->_sNoncesTable." (";
00243 $sSqlNonces.= "server_url VARCHAR(2047) NOT NULL,";
00244 $sSqlNonces.= "timestamp INTEGER NOT NULL,";
00245 $sSqlNonces.= "salt CHAR(40) NOT NULL,";
00246 $sSqlNonces.= "UNIQUE (server_url(255), timestamp, salt)";
00247 $sSqlNonces.= ") ENGINE=InnoDB";
00248 $this->_oDB->execute($sSqlNonces);
00249 }
00250 $oRet = $this->_oDB->execute("show tables like '".$this->_sAssociationsTable."'" );
00251 if ( $oRet->recordCount() == 0 ) {
00252 $sSqlAssoc = "CREATE TABLE IF NOT EXISTS ".$this->_sAssociationsTable." (";
00253 $sSqlAssoc.= "server_url BLOB NOT NULL,";
00254 $sSqlAssoc.= "handle VARCHAR(255) NOT NULL,";
00255 $sSqlAssoc.= "secret CHAR(255) NOT NULL,";
00256 $sSqlAssoc.= "issued INTEGER NOT NULL,";
00257 $sSqlAssoc.= "lifetime INTEGER NOT NULL,";
00258 $sSqlAssoc.= "assoc_type VARCHAR(64) NOT NULL,";
00259 $sSqlAssoc.= "PRIMARY KEY (server_url(255), handle)";
00260 $sSqlAssoc.= ") ENGINE=InnoDB";
00261 $this->_oDB->execute($sSqlAssoc);
00262 }
00263 }
00264
00274 protected function _getAssoc($sServerUrl, $sHandle)
00275 {
00276 $sSql = "SELECT handle, secret, issued, lifetime, assoc_type FROM ".$this->_sAssociationsTable;
00277 $sSql .= " WHERE server_url = '".$sServerUrl."' AND handle = '".$sHandle."'";
00278 $aRes = $this->_oDB->execute($sSql);
00279 if ($aRes) {
00280 return $aRes;
00281 } else {
00282 return false;
00283 }
00284 }
00285
00293 protected function _getAssocs($sServerUrl)
00294 {
00295 $sSql = "SELECT handle, secret, issued, lifetime, assoc_type FROM ".$this->_sAssociationsTable;
00296 $sSql .= " WHERE server_url = '".$sServerUrl."'";
00297 $aRes = $this->_oDB->execute($sSql);
00298 if ($aRes) {
00299 return $aRes;
00300 } else {
00301 return false;
00302 }
00303 }
00304
00312 public function blobEncode($sSecret)
00313 {
00314 return base64_encode($sSecret);
00315 }
00316
00324 public function blobDecode($sSecret)
00325 {
00326 return base64_decode($sSecret);
00327 }
00328
00329 }