Add simpleid-1.0.5
diff --git a/simpleid/www/filesystem.store.php b/simpleid/www/filesystem.store.php
new file mode 100644
index 0000000..7d99a8d
--- /dev/null
+++ b/simpleid/www/filesystem.store.php
@@ -0,0 +1,334 @@
+<?php
+/*
+ * SimpleID
+ *
+ * Copyright (C) Kelvin Mo 2007-9
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+/**
+ * Functions for persistent storage via the file system.
+ *
+ * In general, there are three different sets of data which SimpleID needs
+ * to store:
+ *
+ * - transient data (e.g. OpenID associations, sessions, auto-login)
+ * - application data (e.g. salt for form tokens)
+ * - user data (e.g. user names, passwords and settings)
+ *
+ * Prior to version 0.7, both transient data and application data are stored
+ * using {@link cache.inc}. From version 0.7, application data are now
+ * stored separately from the cache.
+ *
+ * Prior to version 0.7, user data is only stored in the identity file, to which
+ * SimpleID cannot write. This means that if the user wishes to change a setting,
+ * he or she will need to edit the identity file manually. Other user settings
+ * (e.g. RP preferences) are stored using {@link cache.inc}
+ *
+ * From version 0.7, user data is stored in two files, one is the identity
+ * file, the other is the user store file, which SimpleID can write.
+ *
+ * @package simpleid
+ * @filesource
+ */
+
+/**
+ * This variable is a cache of SimpleID's application settings. It is populated
+ * progressively as {@link store_get()} is called.
+ *
+ * @global array $simpleid_settings
+ */
+$simpleid_settings = array();
+
+/**
+ * Returns whether the user name exists in the user store.
+ *
+ * @param string $uid the name of the user to check
+ * @return bool whether the user name exists
+ */
+function store_user_exists($uid) {
+ if (_store_is_valid_name($uid)) {
+ $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
+ return (file_exists($identity_file));
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Loads user data for a specified user name.
+ *
+ * The user name must exist. You should check whether the user name exists with
+ * the {@link store_user_exists()} function
+ *
+ * @param string $uid the name of the user to load
+ * @return mixed data for the specified user
+ */
+function store_user_load($uid) {
+ if (!_store_is_valid_name($uid)) return array();
+ $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
+
+ if (file_exists($store_file)) {
+ $data = unserialize(file_get_contents($store_file));
+ } else {
+ $data = array();
+ }
+
+ $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
+ $data = array_merge($data, parse_ini_file($identity_file, TRUE));
+
+ return $data;
+}
+
+/**
+ * Returns the time which a user's data has been updated.
+ *
+ * The user name must exist. You should check whether the user name exists with
+ * the {@link store_user_exists()} function.
+ *
+ * The time returned can be based on the identity file,
+ * the user store file, or the latter of the two.
+ *
+ * @param string $uid the name of the user to obtain the update time
+ * @param string $type one of: 'identity' (identity file), 'usrstore' (user store
+ * file) or NULL (latter of the two)
+ * @return int the updated time
+ */
+function store_user_updated_time($uid, $type = NULL) {
+ if (!_store_is_valid_name($uid)) return NULL;
+
+ $identity_file = SIMPLEID_IDENTITIES_DIR . "/$uid.identity";
+ $identity_time = filemtime($identity_file);
+
+ $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
+ if (file_exists($store_file)) {
+ $store_time = filemtime($store_file);
+ } else {
+ $store_time = NULL;
+ }
+
+ if ($type == 'identity') {
+ return $identity_time;
+ } elseif ($type == 'usrstore') {
+ return $store_time;
+ } elseif ($type == NULL) {
+ return ($identity_time > $store_time) ? $identity_time : $store_time;
+ } else {
+ return NULL;
+ }
+}
+
+
+/**
+ * Finds the user name from a specified OpenID Identity URI.
+ *
+ * @param string $identity the Identity URI of the user to load
+ * @return string the user name for the Identity URI, or NULL if no user has
+ * the specified Identity URI
+ */
+function store_get_uid($identity) {
+ $uid = cache_get('identity', $identity);
+ if ($uid !== NULL) return $uid;
+
+ $r = NULL;
+
+ $dir = opendir(SIMPLEID_IDENTITIES_DIR);
+
+ while (($file = readdir($dir)) !== false) {
+ $filename = SIMPLEID_IDENTITIES_DIR . '/' . $file;
+
+ if (is_link($filename)) $filename = readlink($filename);
+ if ((filetype($filename) != "file") || (!preg_match('/^(.+)\.identity$/', $file, $matches))) continue;
+
+ $uid = $matches[1];
+ $test_user = store_user_load($uid);
+
+ cache_set('identity', $test_user['identity'], $uid);
+
+ if ($test_user['identity'] == $identity) {
+ $r = $uid;
+ }
+ }
+
+ closedir($dir);
+
+ return $r;
+}
+
+/**
+ * Finds the user name from a specified client SSL certificate string.
+ *
+ * The client SSL certificate string comprises the certificate's serial number
+ * (in capitals hex notation) and the distinguished name of the certificate's issuer
+ * (with components joined using slashes), joined using a semi-colon.
+ *
+ *
+ * @param string $cert the client SSL certificate string of the user to load
+ * @return string the user name matching the client SSL certificate string, or NULL if no user has
+ * client SSL certificate string
+ */
+function store_get_uid_from_cert($cert) {
+ $uid = cache_get('cert', $cert);
+ if ($uid !== NULL) return $uid;
+
+ $r = NULL;
+
+ $dir = opendir(SIMPLEID_IDENTITIES_DIR);
+
+ while (($file = readdir($dir)) !== false) {
+ $filename = SIMPLEID_IDENTITIES_DIR . '/' . $file;
+
+ if (is_link($filename)) $filename = readlink($filename);
+ if ((filetype($filename) != "file") || (!preg_match('/^(.+)\.identity$/', $file, $matches))) continue;
+
+ $uid = $matches[1];
+ $test_user = store_user_load($uid);
+
+ if (isset($test_user['certauth']['cert'])) {
+ if (is_array($test_user['certauth']['cert'])) {
+ foreach ($test_user['certauth']['cert'] as $test_cert) {
+ if (trim($test_cert) != '') cache_set('cert', $test_cert, $uid);
+ }
+ foreach ($test_user['certauth']['cert'] as $test_cert) {
+ if ((trim($test_cert) != '') && ($test_cert == $cert)) $r = $uid;
+ }
+ } else {
+ if (trim($test_cert) != '') {
+ cache_set('cert', $test_user['certauth']['cert'], $uid);
+ if ($test_user['certauth']['cert'] == $cert) $r = $uid;
+ }
+ }
+ }
+ }
+
+ closedir($dir);
+
+ return $r;
+}
+
+/**
+ * Saves user data for a specific user name.
+ *
+ * This data is stored in the user store file.
+ *
+ * @param string $uid the name of the user
+ * @param array $data the data to save
+ * @param array $exclude an array of keys to exclude from the user store file.
+ * These are generally keys which are stored in the identity file.
+ *
+ * @since 0.7
+ */
+function store_user_save($uid, $data, $exclude = array()) {
+ foreach ($exclude as $key) {
+ if (isset($data[$key])) unset($data[$key]);
+ }
+
+ if (!_store_is_valid_name($uid)) {
+ trigger_error("Invalid user name for filesystem store", E_USER_ERROR);
+ return;
+ }
+
+ $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
+ $file = fopen($store_file, 'w');
+ fwrite($file, serialize($data));
+ fclose($file);
+}
+
+/**
+ * Loads an application setting.
+ *
+ * @param string $name the name of the setting to return
+ * @param mixed $default the default value to use if this variable has never been set
+ * @return mixed the value of the setting
+ *
+ */
+function store_get($name, $default = NULL) {
+ global $simpleid_settings;
+
+ if (!_store_is_valid_name($name)) return $default;
+
+ if (!isset($simpleid_settings[$name])) {
+ $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
+
+ if (file_exists($setting_file)) {
+ $simpleid_settings[$name] = unserialize(file_get_contents($setting_file));
+ } else {
+ return $default;
+ }
+ }
+
+ return $simpleid_settings[$name];
+}
+
+/**
+ * Saves an application setting.
+ *
+ * @param string $name the name of the setting to save
+ * @param mixed $value the value of the setting
+ *
+ */
+function store_set($name, $value) {
+ global $simpleid_settings;
+
+ if (!_store_is_valid_name($name)) {
+ trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
+ return;
+ }
+
+ $simpleid_settings[$name] = $value;
+
+ $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
+ $file = fopen($setting_file, 'w');
+ fwrite($file, serialize($value));
+ fclose($file);
+}
+
+/**
+ * Deletes an application setting.
+ *
+ * @param string $name the name of the setting to delete
+ *
+ */
+function store_del($name) {
+ global $simpleid_settings;
+
+ if (!_store_is_valid_name($name)) {
+ trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
+ return;
+ }
+
+ if (isset($simpleid_settings[$name])) unset($simpleid_settings[$name]);
+
+ $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
+ if (file_exists($setting_file)) unlink($setting_file);
+}
+
+/**
+ * Determines whether a name is a valid name for use with this store.
+ *
+ * For file system storage, a name is not valid if it contains either a
+ * directory separator (i.e. / or \).
+ *
+ * @param string $name the name to check
+ * @return boolean whether the name is valid for use with this store
+ *
+ */
+function _store_is_valid_name($name) {
+ return preg_match('!\A[^/\\\\]*\z!', $name);
+}
+?>