summaryrefslogtreecommitdiff
path: root/apps/um/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/um/lib')
-rw-r--r--apps/um/lib/DB.class.php164
-rw-r--r--apps/um/lib/Database.class.php403
-rw-r--r--apps/um/lib/Hasher.class.php18
-rw-r--r--apps/um/lib/Login.class.php41
-rw-r--r--apps/um/lib/Plugin.class.php25
-rw-r--r--apps/um/lib/PluginManager.class.php99
-rw-r--r--apps/um/lib/Site.class.php32
7 files changed, 782 insertions, 0 deletions
diff --git a/apps/um/lib/DB.class.php b/apps/um/lib/DB.class.php
new file mode 100644
index 0000000..ac8dafe
--- /dev/null
+++ b/apps/um/lib/DB.class.php
@@ -0,0 +1,164 @@
+<?php
+require_once('Auth.class.php');
+require_once('Login.class.php');
+require_once('Database.class.php');
+
+class DB {
+ public static function set($table, $unit, $key, $value, $orig_value) {
+ $value_base = $orig_value;
+
+ $doit = true;
+ $forked = false;
+ $have_old = ($value_base!==null);
+ if ($have_old) {
+ $we_changed_it = $value_base != $value;
+ if ($we_changed_it) {
+ $value_fork = $this->getConfString($key);
+ $someone_else_changed_it =
+ $value_fork != $value_base;
+ if ($someone_else_changed_it) {
+ if ($value == $value_fork) {
+ // we might as well not have
+ $we_changed_it = false;
+ } else {
+ $forked = true;
+ }
+ }
+ }
+ if (!$we_changed_it) {
+ $doit = false;// nothing to do
+ }
+ }
+ if ($doit) {
+ return $this->setConf($key, $value);
+ }
+ if ($forked) {
+ return $value_fork;
+ }
+ }
+
+ public static function get($table, $unit, $key) {
+ switch ($table) {
+ case 'conf':
+ case 'plugins':
+ return self::admin_get($unit, $key);
+ break;
+ case 'users':
+ return self::user_get($unit, $key);
+ break;
+ default:
+ return false;
+ }
+ }
+ public static function raw_set($table, $unit, $key, $value) {
+ switch ($table) {
+ case 'conf':
+ case 'plugins':
+ return self::admin_get($unit, $key, $value);
+ break;
+ case 'users':
+ return self::user_set($unit, $key, $value);
+ break;
+ default:
+ return false;
+ }
+ }
+
+ private static function user_get($uid, $key) {
+ $user = Auth::getInstance($uid);
+ $logged_in_user = Auth::getInstance(Login::isLoggedIn());
+
+ $post_key = $key."[$uid]";
+ @$value = $_POST[$post_key];
+ $editable = $user->canEdit();
+
+ switch ($key) {
+ case 'auth_uid':
+ $value = $user->getUID();
+ $editable = false;
+ break;
+ case 'auth_name':
+ $value = $user->getName();
+ break;
+ case 'auth_user':
+ $editable = $editable && $logged_in_user->isAdmin();
+ $value = $user->isUser()?'true':'false';
+ break;
+ case 'auth_admin':
+ $editable = $editable && $logged_in_user->isAdmin();
+ $value = $user->isAdmin()?'true':'false';
+ break;
+ case 'auth_delete':
+ $editable = $editable && $logged_in_user->isAdmin();
+ $value = 'false';
+ break;
+ default:
+ $value = $user->getConf($key);
+ if ($value===false) $value='';
+ break;
+ }
+
+ return array('value'=>$value,
+ 'post_key'=>$post_key,
+ 'editable'=>$editable);
+ }
+ private static function user_set($uid, $key, $value) {
+ $user = Auth::getInstance($uid);
+
+ switch ($key) {
+ case 'auth_uid':
+ return false;
+ break;
+ case 'auth_name':
+ return $user->setName($value);
+ break;
+ case 'auth_user':
+ return $user->setUser($value=='true');
+ break;
+ case 'auth_admin':
+ return $user->setAdmin($value=='true');
+ break;
+ case 'auth_delete':
+ if ($value=='true') return $user->delete();
+ default:
+ return $user->setConf($key, $value);
+ break;
+ }
+ }
+
+ private static function admin_get($plugin, $key) {
+ $db = Database::getInstance();
+ $user = Auth::getInstance(Login::isLoggedIn());
+ if ($user->isAdmin()) {
+ $editable = true;
+ switch ($plugin) {
+ case 'system':
+ $value = $db->getSysConf($key);
+ break;
+ default:
+ $value = $db->getPluginConf($plugin, $key);
+ break;
+ }
+ } else {
+ $editable = false;
+ $value = false;
+ }
+
+ return array('value'=>$value,
+ 'post_key'=>'to be implemented',// FIXME
+ 'editable'=>$editable);
+ }
+ private static function admin_set($plugin, $key, $value) {
+ $db = Database::getInstance();
+ $user = Auth::getInstance(Login::isLoggedIn());
+ if (!$user->isAdmin()) {
+ return false;
+ }
+ switch ($plugin) {
+ case 'system':
+ return $db->setSysConf($key, $value);
+ default:
+ return $db->setPluginConf($plugin, $key, $value);
+ }
+ }
+}
diff --git a/apps/um/lib/Database.class.php b/apps/um/lib/Database.class.php
new file mode 100644
index 0000000..a76d891
--- /dev/null
+++ b/apps/um/lib/Database.class.php
@@ -0,0 +1,403 @@
+<?php
+require_once('Singleton.class.php');
+require_once('Hasher.class.php');
+
+class Database extends Singleton {
+ private static $me = null;
+ private $conf;
+ private $mysql;
+ private $db_prefix;
+
+ public function __construct($conf_file) {
+ $this->conf = $conf_file;
+ self::$me = $this;
+ }
+ public static function getInstance() {
+ return self::$me;
+ }
+
+ // Low-Level SQL functions /////////////////////////////////////////////
+
+ private function mysql() {
+ if (!isset($this->mysql)) {
+ $this->mysql_init();
+ }
+ return $this->mysql;
+ }
+ private function mysql_init() {
+ global $db_config;
+ require($this->conf);
+ $this->mysql = mysql_connect($db_config['host'],
+ $db_config['user'],
+ $db_config['password']);
+ mysql_set_charset($db_config['charset'], $this->mysql);
+ mysql_select_db($db_config['name'], $this->mysql);
+ $this->db_prefix = $db_config['prefix'];
+ unset($db_config);
+ }
+ private function mysql_table($table_name) {
+ $mysql = $this->mysql();
+ $prefix = $this->db_prefix;
+ return $prefix.mysql_real_escape_string($table_name, $mysql);
+ }
+ private function mysql_escape($string) {
+ $mysql = $this->mysql();
+ return mysql_real_escape_string($string, $mysql);
+ }
+ private function mysql_query($query) {
+ $mysql = $this->mysql();
+ return mysql_query($query, $mysql);
+ }
+ public function mysql_error() {
+ $mysql = $this->mysql();
+ return mysql_error($mysql);
+ }
+
+ // High-Level SQL functions ////////////////////////////////////////////
+
+ // The 'auth' table
+
+ public function getUID($username) {
+ $t = $this->mysql_table('auth');
+ $v = $this->mysql_escape($username);
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE name='$v' ;";
+ $q = $this->mysql_query($query);
+ $user = mysql_fetch_array($q);
+ if (isset($user['uid'])) {
+ return (int)$user['uid'];
+ } else {
+ return false;
+ }
+ }
+ public function getUsername($uid) {
+ if (!is_int($uid)) return false;
+ $t = $this->mysql_table('auth');
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ $user = mysql_fetch_array($q);
+ if (isset($user['name'])) {
+ return $user['name'];
+ } else {
+ return false;
+ }
+ }
+ public function setUsername($uid, $username) {
+ if (!is_int($uid)) return false;
+ if ($this->getUID($username) !== false) {
+ return false;
+ }
+ $table = $this->mysql_table('auth');
+ $name = $this->mysql_escape($username);
+ $query =
+ "UPDATE $table \n".
+ "SET name='$name' \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+ public function getPasswordHash($uid) {
+ if (!is_int($uid)) return false;
+
+ $table = $this->mysql_table('auth');
+ $query =
+ "SELECT * \n".
+ "FROM $table \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ $user = mysql_fetch_array($q);
+ if (isset($user['hash'])) {
+ return $user['hash'];
+ } else {
+ return false;
+ }
+ }
+ public function setPassword($uid, $password) {
+ if (!is_int($uid)) return false;
+ $table = $this->mysql_table('auth');
+
+ $hasher = Hasher::getInstance();
+ @$hash = $hasher->hash($password);
+ $query =
+ "UPDATE $table \n".
+ "SET hash='$hash' \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+ public function addUser($username, $password) {
+ $user_exits = $this->getUID($username);
+ if ($user_exists) {
+ return false;
+ }
+
+ $table = $this->mysql_table('auth');
+ $user = $this->mysql_escape($username);
+ $hasher = Hasher::getInstance();
+ @$hash = $hasher->hash($password);
+ $status = 0;
+ $query =
+ "INSERT INTO $table ( name, hash , status) \n".
+ "VALUES ('$user', '$hash', $status) ;";
+ $this->mysql_query($query);
+ $uid = $this->getUID($username);
+ return $uid;
+ }
+ public function getStatus($uid) {
+ if (!is_int($uid)) return false;
+ $table = $this->mysql_table('auth');
+ $query =
+ "SELECT * \n".
+ "FROM $table \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ $user = mysql_fetch_array($q);
+ if (isset($user['status'])) {
+ return (int)$user['status'];
+ } else {
+ return false;
+ }
+ }
+ public function setStatus($uid, $status) {
+ if (!is_int($uid)) return false;
+ $table = $this->mysql_table('auth');
+ $s = $this->mysql_escape($status);
+ $query =
+ "UPDATE $table \n".
+ "SET status=$s \n".
+ "WHERE uid=$uid ;";
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+ public function countUsers() {
+ $table = $this->mysql_table('auth');
+ $query = "SELECT COUNT(*) FROM $table;";
+ $q = $this->mysql_query($query);
+ $row = mysql_fetch_array($q);
+ $count = $row[0];
+ return $count;
+ }
+ public function listGroups() {
+ $table = $this->mysql_table('auth');
+ $query =
+ "SELECT uid \n".
+ "FROM $table \n".
+ "WHERE status=3 ;";
+ $q = $this->mysql_query($query);
+ $groups = array();
+ while (($row = mysql_fetch_array($q)) !==false) {
+ $groups[] = (int)$row[0];
+ }
+ return $groups;
+ }
+ public function listGroupNames() {
+ $table = $this->mysql_table('auth');
+ $query =
+ "SELECT name \n".
+ "FROM $table \n".
+ "WHERE status=3 ;";
+ $q = $this->mysql_query($query);
+ $groups = array();
+ while (($row = mysql_fetch_array($q)) !==false) {
+ $groups[] = $row[0].'';
+ }
+ return $groups;
+ }
+ public function listUsers() {
+ $table = $this->mysql_table('auth');
+ $query =
+ "SELECT uid \n".
+ "FROM $table \n".
+ "WHERE status < 3 ;";
+ $q = $this->mysql_query($query);
+ $users = array();
+ while (($row = mysql_fetch_array($q)) !==false) {
+ $users[] = (int)$row[0];
+ }
+ return $users;
+ }
+
+ // The 'users' table
+
+ public function findUser($setting, $value) {
+ $t = $this->mysql_table('users');
+ $k = $this->mysql_escape($setting);
+ $v = $this->mysql_escape($value);
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE k = '$k' \n".
+ "AND UPPER(v)=UPPER('$v') ;";
+ $q = $this->mysql_query($query);
+ $user = mysql_fetch_array($q);
+ if (isset($user['uid'])) {
+ return $user['uid'];
+ } else {
+ return false;
+ }
+ }
+ public function getUserConf($uid, $setting) {
+ if (!is_int($uid)) return false;
+ $t = $this->mysql_table('users');
+ $k = $this->mysql_escape($setting);
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE k='$k' \n".
+ "AND uid=$uid ;";
+ $q = $this->mysql_query($query);
+ $row = mysql_fetch_array($q);
+ if (isset($row['v'])) {
+ return $row['v'];
+ } else {
+ return false;
+ }
+ }
+ public function setUserConf($uid, $setting, $value) {
+ if (!is_int($uid)) return false;
+ $isset = ($this->getUserConf($uid, $setting) !== false);
+ $t = $this->mysql_table('users');
+ $k = $this->mysql_escape($setting);
+ $v = $this->mysql_escape($value);
+ if ($isset) {
+ $query =
+ "UPDATE $t \n".
+ "SET v = '$v' \n".
+ "WHERE k = '$k' \n".
+ "AND uid = $uid ;";
+ } else {
+ $query =
+ "INSERT INTO $t ( uid, k , v ) \n".
+ "VALUES ($uid, '$k', '$v') ;";
+ }
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+ public function getUsersInGroup($groupname) {
+ $table = $this->mysql_table('users');
+ $group = $this->mysql_escape($groupname);
+ $query =
+ "SELECT uid \n".
+ "FROM $table \n".
+ "WHERE k='groups' \n".
+ "AND v LIKE '%,$group,%' ;";
+ $q = $this->mysql_query($query);
+ $users = array();
+ while (($row = mysql_fetch_array($q)) !==false) {
+ $users[] = $row[0];
+ }
+ return $users;
+ }
+
+ // The 'plugins' table
+
+ public function getPluginConf($plugin, $key) {
+ $t = $this->mysql_table('plugins');
+ $p = $this->mysql_escape($plugin);
+ $k = $this->mysql_escape($key);
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE k='$k' \n".
+ "AND plugin='$p' ;";
+ $q = $this->mysql_query($query);
+ $row = mysql_fetch_array($q);
+ if (isset($row['v'])) {
+ return $row['v'];
+ } else {
+ return false;
+ }
+ }
+ public function setPluginConf($plugin, $key, $value) {
+ $isset = ($this->getPluginConf($plugin, $key) !== false);
+ $t = $this->mysql_table('plugins');
+ $p = $this->mysql_escape($plugin);
+ $k = $this->mysql_escape($key);
+ $v = $this->mysql_escape($value);
+ if ($isset) {
+ $query =
+ "UPDATE $t \n".
+ "SET v = '$v' \n".
+ "WHERE k = '$k' \n".
+ "AND plugin = '$p' ;";
+ } else {
+ $query =
+ "INSERT INTO $t (plugin, k , v ) \n".
+ "VALUES ('$p' , '$k', '$v') ;";
+ }
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+
+ // The 'conf' table
+
+ public function getSysConf($key) {
+ $t = $this->mysql_table('conf');
+ $k = $this->mysql_escape($key);
+ $query =
+ "SELECT * \n".
+ "FROM $t \n".
+ "WHERE k='$k' ;";
+ $q = $this->mysql_query($query);
+ $row = mysql_fetch_array($q);
+ if (isset($row['v'])) {
+ return $row['v'];
+ } else {
+ return false;
+ }
+ }
+ public function setSysConf($key, $value) {
+ $isset = ($this->getSysConf($key) !== false);
+ $t = $this->mysql_table('conf');
+ $k = $this->mysql_escape($key);
+ $v = $this->mysql_escape($value);
+ if ($isset) {
+ $query =
+ "UPDATE $t \n".
+ "SET v = '$v' \n".
+ "WHERE k = '$k' ;";
+ } else {
+ $query =
+ "INSERT INTO $t ( k , v ) \n".
+ "VALUES ('$k', '$v') ;";
+ }
+ $q = $this->mysql_query($query);
+ return ($q?true:false);
+ }
+
+ /**
+ * Strip out empty group names and duplicates, sort.
+ */
+ private static function sanitizeArray($in) {
+ $out = array();
+ foreach ($in as $item) {
+ if (($item !== '')&&(!in_array($item, $out))) {
+ $out[] = $item;
+ }
+ }
+ natsort($out);
+ return $out;
+ }
+ /**
+ * Translate an array into a value suitable to be stored into a
+ * key-value store in the database.
+ */
+ public static function arrayToValue($list) {
+ $out_list = self::sanitizeArray($list);
+ return ','.implode(',', $out_list).',';
+ }
+ /**
+ * Translate a value from arrayToValue() back into an array.
+ */
+ public static function valueToArray($value) {
+ $raw_list = explode(',', $value);
+ $out_list = self::sanitizeArray($raw_list);
+ return $out_list;
+ }
+
+}
diff --git a/apps/um/lib/Hasher.class.php b/apps/um/lib/Hasher.class.php
new file mode 100644
index 0000000..dc16d68
--- /dev/null
+++ b/apps/um/lib/Hasher.class.php
@@ -0,0 +1,18 @@
+<?php
+require_once('Singleton.class.php');
+require_once('PasswordHash.class.php');
+
+class Hasher extends Singleton {
+ private $pw_hash;
+
+ function __construct() {
+ $this->pw_hash = new PasswordHash(8, false);
+ }
+
+ public function hash($password) {
+ return $this->pw_hash->HashPassword($password);
+ }
+ public function check($password, $hash) {
+ return $this->pw_hash->CheckPassword($password, $hash);
+ }
+}
diff --git a/apps/um/lib/Login.class.php b/apps/um/lib/Login.class.php
new file mode 100644
index 0000000..bb21928
--- /dev/null
+++ b/apps/um/lib/Login.class.php
@@ -0,0 +1,41 @@
+<?php
+require_once('Database.class.php');
+require_once('Hasher.class.php');
+
+class Login {
+ /** Decalare an empty __construct() so that the login function doesn't
+ get mistaken for the costructor. */
+ public function __construct() {}
+
+ public static function login($username, $password) {
+ $db = Database::getInstance();
+ $hasher = Hasher::getInstance();
+
+ $uid = $db->getUID($username);
+ if ($uid!==false && $db->getStatus($uid)>=3)
+ $uid=false;
+ if ($uid===false) {
+ // user does not exist
+ return 2;
+ }
+ $hash = $db->getPasswordHash($uid);
+ if ($hasher->check($password, $hash)) {
+ // success
+ $_SESSION['uid'] = $uid;
+ return 0;
+ } else {
+ // wrong password
+ return 1;
+ }
+ }
+ public static function isLoggedIn() {
+ if ( isset($_SESSION['uid']) && ($_SESSION['uid']!='') ) {
+ return $_SESSION['uid'];
+ } else {
+ return false;
+ }
+ }
+ public static function logout() {
+ $_SESSION['uid'] = '';
+ }
+}
diff --git a/apps/um/lib/Plugin.class.php b/apps/um/lib/Plugin.class.php
new file mode 100644
index 0000000..9d2fc2e
--- /dev/null
+++ b/apps/um/lib/Plugin.class.php
@@ -0,0 +1,25 @@
+<?php
+
+abstract class Plugin {
+ protected $config = Array();
+
+ public abstract static function configList();
+ public abstract static function description();
+
+ public function configSet($param, $value) {
+ if (isset($this->config[$param])) {
+ $this->config[$param]=$value;
+ }
+ }
+
+ public function userConfig() { return array(); }
+ protected function addConfigGroup($arr, $group) {
+ if (!isset($arr[$group]))
+ $arr[$group] = array();
+ }
+
+ public abstract function init();
+
+ public function antispam_html() { return ''; }
+ public function antispam_verify() { return true; }
+}
diff --git a/apps/um/lib/PluginManager.class.php b/apps/um/lib/PluginManager.class.php
new file mode 100644
index 0000000..ce5a3ef
--- /dev/null
+++ b/apps/um/lib/PluginManager.class.php
@@ -0,0 +1,99 @@
+<?php
+require_once('Singleton.class.php');
+require_once('Database.class.php');
+
+class PluginManager extends Singleton {
+ public $plugins = array();
+ private $loaded = false;
+
+ /**
+ * Return an instance of the plugin with $plugin_name
+ */
+ public function loadPlugin($plugin_name) {
+ $db = Database::getInstance();
+
+ require_once("$plugin_name.class.php");
+ $obj = new $plugin_name;
+ $params = call_user_func("$plugin_name::configList");
+ foreach ($params as $param => $type) {
+ $value = $db->getPluginConf($plugin_name, $param);
+ if ($value!==false) {
+ switch ($type) {
+ case 'text':
+ case 'password':
+ $value = "$value";
+ break;
+ case 'int':
+ $value = (int)$value;
+ break;
+ }
+ $obj->configSet($param, $value);
+ }
+ }
+ return $obj;
+ }
+
+ /**
+ * Return an array of available plugin names.
+ */
+ public function listPlugins() {
+ $plugins = array();
+
+ $dirs = explode(PATH_SEPARATOR, PLUGINPATH);
+ foreach ($dirs as $dir) {
+ // Find all files in $dir with the ext `.class.php'
+ $files = glob($dir.'/*.class.php');
+ foreach ($files as $file) {
+ $plugins[] = preg_replace('@\.class\.php$@', '$1', basename($file));
+ }
+ }
+
+ return $plugins;
+ }
+
+ /**
+ * Return an array of enabled plugin names.
+ */
+ public function getActivePlugins() {
+ $db = Database::getInstance();
+ $string = $db->getSysConf('plugins');
+ return $db->valueToArray($string);
+ }
+
+ /**
+ * Set the enabled plugins.
+ */
+ public function setActivePlugins($plugins) {
+ $db = Database::getInstance();
+ $string = $db->arrayToValue($plugins);
+ return $db->setSysConf('plugins', $string);
+ }
+
+ /**
+ * Load the enabled plugins.
+ */
+ public function loadPlugins() {
+ if ($this->loaded) return;
+ $plugin_names = $this->getActivePlugins();
+ foreach ($plugin_names as $name) {
+ $this->plugins[$name] = $this->loadPlugin($name);
+ }
+ $this->loaded = true;
+ }
+
+ public function callHook($hook, $arg=null) {
+ $this->loadPlugins();
+ $ret = array();
+ foreach ($this->plugins as $name => $plugin) {
+ $ret[$name] = call_user_func(array($plugin, $hook),
+ &$arg);
+ }
+ return $ret;
+ }
+
+ public function staticHook($plugin_name, $hook) {
+ require_once("$plugin_name.class.php");
+ return call_user_func("$plugin_name::$hook");
+ }
+
+}
diff --git a/apps/um/lib/Site.class.php b/apps/um/lib/Site.class.php
new file mode 100644
index 0000000..1204089
--- /dev/null
+++ b/apps/um/lib/Site.class.php
@@ -0,0 +1,32 @@
+<?php
+require_once('Singleton.class.php');
+require_once('Database.class.php');
+
+class Site extends Singleton {
+ public function shortUrl($longUrl) {
+ $ch = curl_init('http://ur1.ca');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFILEDS,
+ 'longurl='.urlencode($longUrl));
+ $html = curl_exec();
+ preg_match('/Your ur1 is: <a href="([^"]*)">/',$html,$matches);
+ $shortUrl = $matches[1];
+ curl_close($ch);
+ return $shortUrl;
+ }
+
+ public function baseUrl() {
+ $base = $_SERVER['REQUEST_URI'];
+
+ $db = Database::getInstance();
+ if ($db !== null) {
+ $b = $db->getSysConf('baseurl');
+ if ($b != false) {
+ $base = $b;
+ }
+ }
+
+ return $base;
+ }
+}