📄 filestore.php
字号:
<?php// Check to ensure this file is within the rest of the frameworkdefined('JPATH_BASE') or die();/** * This file supplies a Memcached store backend for OpenID servers and * consumers. * * PHP versions 4 and 5 * * LICENSE: See the COPYING file included in this distribution. * * @package OpenID * @author JanRain, Inc. <openid@janrain.com> * @copyright 2005 Janrain, Inc. * @license http://www.gnu.org/copyleft/lesser.html LGPL * *//** * Require base class for creating a new interface. */require_once 'Auth/OpenID.php';require_once 'Auth/OpenID/Interface.php';require_once 'Auth/OpenID/HMACSHA1.php';/** * This is a filesystem-based store for OpenID associations and * nonces. This store should be safe for use in concurrent systems on * both windows and unix (excluding NFS filesystems). There are a * couple race conditions in the system, but those failure cases have * been set up in such a way that the worst-case behavior is someone * having to try to log in a second time. * * Most of the methods of this class are implementation details. * People wishing to just use this store need only pay attention to * the constructor. * * @package OpenID */class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore { /** * Initializes a new {@link Auth_OpenID_FileStore}. This * initializes the nonce and association directories, which are * subdirectories of the directory passed in. * * @param string $directory This is the directory to put the store * directories in. */ function Auth_OpenID_FileStore($directory) { if (!Auth_OpenID::ensureDir($directory)) { trigger_error('Not a directory and failed to create: ' . $directory, E_USER_ERROR); } $directory = realpath($directory); $this->directory = $directory; $this->active = true; $this->nonce_dir = $directory . DIRECTORY_SEPARATOR . 'nonces'; $this->association_dir = $directory . DIRECTORY_SEPARATOR . 'associations'; // Temp dir must be on the same filesystem as the assciations // $directory and the $directory containing the auth key file. $this->temp_dir = $directory . DIRECTORY_SEPARATOR . 'temp'; $this->auth_key_name = $directory . DIRECTORY_SEPARATOR . 'auth_key'; $this->max_nonce_age = 6 * 60 * 60; // Six hours, in seconds if (!$this->_setup()) { trigger_error('Failed to initialize OpenID file store in ' . $directory, E_USER_ERROR); } } function destroy() { Auth_OpenID_FileStore::_rmtree($this->directory); $this->active = false; } /** * Make sure that the directories in which we store our data * exist. * * @access private */ function _setup() { return (Auth_OpenID::ensureDir(dirname($this->auth_key_name)) && Auth_OpenID::ensureDir($this->nonce_dir) && Auth_OpenID::ensureDir($this->association_dir) && Auth_OpenID::ensureDir($this->temp_dir)); } /** * Create a temporary file on the same filesystem as * $this->auth_key_name and $this->association_dir. * * The temporary directory should not be cleaned if there are any * processes using the store. If there is no active process using * the store, it is safe to remove all of the files in the * temporary directory. * * @return array ($fd, $filename) * @access private */ function _mktemp() { $name = Auth_OpenID_FileStore::_mkstemp($dir = $this->temp_dir); $file_obj = @fopen($name, 'wb'); if ($file_obj !== false) { return array($file_obj, $name); } else { Auth_OpenID_FileStore::_removeIfPresent($name); } } /** * Read the auth key from the auth key file. Will return None if * there is currently no key. * * @return mixed */ function readAuthKey() { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return null; } $auth_key_file = @fopen($this->auth_key_name, 'rb'); if ($auth_key_file === false) { return null; } $key = fread($auth_key_file, filesize($this->auth_key_name)); fclose($auth_key_file); return $key; } /** * Generate a new random auth key and safely store it in the * location specified by $this->auth_key_name. * * @return string $key */ function createAuthKey() { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return null; } $auth_key = Auth_OpenID_CryptUtil::randomString($this->AUTH_KEY_LEN); list($file_obj, $tmp) = $this->_mktemp(); fwrite($file_obj, $auth_key); fflush($file_obj); fclose($file_obj); if (function_exists('link')) { // Posix filesystem $saved = link($tmp, $this->auth_key_name); Auth_OpenID_FileStore::_removeIfPresent($tmp); } else { // Windows filesystem $saved = rename($tmp, $this->auth_key_name); } if (!$saved) { // The link failed, either because we lack the permission, // or because the file already exists; try to read the key // in case the file already existed. $auth_key = $this->readAuthKey(); } return $auth_key; } /** * Retrieve the auth key from the file specified by * $this->auth_key_name, creating it if it does not exist. * * @return string $key */ function getAuthKey() { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return null; } $auth_key = $this->readAuthKey(); if ($auth_key === null) { $auth_key = $this->createAuthKey(); if (strlen($auth_key) != $this->AUTH_KEY_LEN) { $fmt = 'Got an invalid auth key from %s. Expected '. '%d-byte string. Got: %s'; $msg = sprintf($fmt, $this->auth_key_name, $this->AUTH_KEY_LEN, $auth_key); trigger_error($msg, E_USER_WARNING); return null; } } return $auth_key; } /** * Create a unique filename for a given server url and * handle. This implementation does not assume anything about the * format of the handle. The filename that is returned will * contain the domain name from the server URL for ease of human * inspection of the data directory. * * @return string $filename */ function getAssociationFilename($server_url, $handle) { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return null; } if (strpos($server_url, '://') === false) { trigger_error(sprintf("Bad server URL: %s", $server_url), E_USER_WARNING); return null; } list($proto, $rest) = explode('://', $server_url, 2); $parts = explode('/', $rest); $domain = Auth_OpenID_FileStore::_filenameEscape($parts[0]); $url_hash = Auth_OpenID_FileStore::_safe64($server_url); if ($handle) { $handle_hash = Auth_OpenID_FileStore::_safe64($handle); } else { $handle_hash = ''; } $filename = sprintf('%s-%s-%s-%s', $proto, $domain, $url_hash, $handle_hash); return $this->association_dir. DIRECTORY_SEPARATOR . $filename; } /** * Store an association in the association directory. */ function storeAssociation($server_url, $association) { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return false; } $association_s = $association->serialize(); $filename = $this->getAssociationFilename($server_url, $association->handle); list($tmp_file, $tmp) = $this->_mktemp(); if (!$tmp_file) { trigger_error("_mktemp didn't return a valid file descriptor", E_USER_WARNING); return false; } fwrite($tmp_file, $association_s); fflush($tmp_file); fclose($tmp_file); if (@rename($tmp, $filename)) { return true; } else { // In case we are running on Windows, try unlinking the // file in case it exists. @unlink($filename); // Now the target should not exist. Try renaming again, // giving up if it fails. if (@rename($tmp, $filename)) { return true; } } // If there was an error, don't leave the temporary file // around. Auth_OpenID_FileStore::_removeIfPresent($tmp); return false; } /** * Retrieve an association. If no handle is specified, return the * association with the most recent issue time. * * @return mixed $association */ function getAssociation($server_url, $handle = null) { if (!$this->active) { trigger_error("FileStore no longer active", E_USER_ERROR); return null; } if ($handle === null) { $handle = ''; } // The filename with the empty handle is a prefix of all other // associations for the given server URL. $filename = $this->getAssociationFilename($server_url, $handle); if ($handle) { return $this->_getAssociation($filename); } else { $association_files = Auth_OpenID_FileStore::_listdir($this->association_dir); $matching_files = array(); // strip off the path to do the comparison $name = basename($filename); foreach ($association_files as $association_file) { if (strpos($association_file, $name) === 0) { $matching_files[] = $association_file; } } $matching_associations = array(); // read the matching files and sort by time issued
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -