From 9ce26b55017a24f3cae5c20958f2d612273c2f60 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Tue, 26 Jan 2016 21:55:43 -0500 Subject: + Added function to User class to fetch all users from DB * Altered Auth MVC deflt action to return false if no users are found. This way, the Auth controller can automatically present user a page to create an admin account --- app/class/user.class.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'app/class') diff --git a/app/class/user.class.php b/app/class/user.class.php index 8ef91ae..6004dc9 100644 --- a/app/class/user.class.php +++ b/app/class/user.class.php @@ -25,6 +25,22 @@ class User extends Object parent::__construct("user", $cols); $this->loadObj($guid); } + + /* + * Get all users -- ordered by name, ascending + */ + function getAllUsers_orderByName() + { + $query = "SELECT guid FROM `object` WHERE `type` = 'user' ORDER BY name"; + $result = $this->db->query($query); + + $users = array(); + + foreach ($result as $u) + $users[] = new User($u['guid']); + + return $users; + } } ?> -- cgit v1.2.3 From 635ceb4808624ad6676d43e83c1ff5a7d4341d36 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Thu, 28 Jan 2016 19:38:28 -0500 Subject: Add admin field to user table User accounts now have a field to denote whether they are site administrators. The first account created during app initial configuration is an admin automatically. --- app/class/user.class.php | 1 + 1 file changed, 1 insertion(+) (limited to 'app/class') diff --git a/app/class/user.class.php b/app/class/user.class.php index 6004dc9..9a87b01 100644 --- a/app/class/user.class.php +++ b/app/class/user.class.php @@ -17,6 +17,7 @@ class User extends Object "key", "salt", "alias", + "admin", "email", "emailConf", "emailConfKey" -- cgit v1.2.3 From bad5036569b3c572f60dae034c42a8129adc29e5 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sat, 30 Jan 2016 18:22:13 -0500 Subject: Handle object timestamps automatically in Object::saveObj() The saveObj() function now initializes and update the timeCreated and timeUpdated fields of objects on its own. A new function, getCurrentTimestamp() (from class Object) is introduced to aid simpler fetching of the date and time --- app/class/object.class.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'app/class') diff --git a/app/class/object.class.php b/app/class/object.class.php index bcd8dfa..93b52f0 100644 --- a/app/class/object.class.php +++ b/app/class/object.class.php @@ -77,6 +77,8 @@ abstract class Object extends Framework { if (isset($this->guid)) { + $this->timeUpdated = $this->getCurrentTimestamp(); + /* Update Base */ $updateStr = ""; @@ -117,6 +119,8 @@ abstract class Object extends Framework else { $this->guid = $this->getNewGUID(); + $this->timeCreated = $this->getCurrentTimestamp(); + $this->timeUpdated = $this->timeCreated; /* Insert Base */ $colsStr = ""; @@ -179,6 +183,16 @@ abstract class Object extends Framework $this->db->query($query); } + /* + * Get current timestamp for object database purposes + */ + function getCurrentTimestamp() + { + $query = "SELECT now() AS stamp"; + $result = $this->db->query($query); + return $result[0]['stamp']; + } + /* * Check whether given GUID exists */ -- cgit v1.2.3 From b6bb1893ad7b4a901a28b0fa2e725141a7b39509 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sat, 30 Jan 2016 20:48:14 -0500 Subject: Update app source of entropy for creating random blobs Removed use of PHP's rand() functon in favor of openssl extension's openssl_random_pseudo_bytes() to create blobs with better entropy. Created function getBlob (from class Object) to get a sha256 hash created from randomness for use as object GUIDs, password salts, application tokens, etc. --- app/class/object.class.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'app/class') diff --git a/app/class/object.class.php b/app/class/object.class.php index 93b52f0..96cc810 100644 --- a/app/class/object.class.php +++ b/app/class/object.class.php @@ -214,13 +214,20 @@ abstract class Object extends Framework { do { - $sha = hash("sha256", rand()); - $guid = substr($sha, 0, 8); + $guid = substr($this->getBlob(), 0, 8); } while ($this->isGUID($guid)); return $guid; } + + /* + * Get a random sha256 blob + */ + function getBlob() + { + return hash("sha256", openssl_random_pseudo_bytes(64)); + } } /* -- cgit v1.2.3 From 2b6afdd9ef767e1e84c4751c72da6be13d9b4402 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sat, 30 Jan 2016 21:20:41 -0500 Subject: Add functionality to create new User objects User class now has a new function which will take a $username and a $password and use it to initialize itself as well as write new object data to the database. This commit introduces a helper function getKey() (from class User) for creating user object keys by hashing the contatenation of its password and salt. This commit introduces a helper function usernameInUse() (from class User) for ensuring the uniqueness of names amongst user-type objects --- app/class/user.class.php | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'app/class') diff --git a/app/class/user.class.php b/app/class/user.class.php index 9a87b01..6bce26c 100644 --- a/app/class/user.class.php +++ b/app/class/user.class.php @@ -42,6 +42,60 @@ class User extends Object return $users; } + + /* + * Check whether a given username is currently in use + */ + function usernameInUse($username) + { + $escd_username = $this->db->esc($username); + + $query = "SELECT name FROM object WHERE type = 'user' AND name = '" . $escd_username . "'"; + $results = $this->db->query($query); + + if (count($results) > 0) + return true; + + return false; + } + + /* + * Generate a key from a user's password and salt + */ + function getKey($password, $salt) + { + return hash("sha256", $salt . $password); + } + + /* + * Create a new User object with the given username and keyed with the given plain-text password + * This function returns false if $username is already being used + * On success, this object should be initialized as the new user (use only on new User() objects) + */ + function createNewUser($username, $password) + { + if ($this->usernameInUse($username)) + return false; + + /* if there exist no users already, make this new one an admin */ + if (count($this->getAllUsers_orderByName()) == 0) + $this->admin = 1; + + $this->perms = 0; + $this->name = $username; + $this->type = "user"; + $this->salt = $this->getBlob(); + $this->key = $this->getKey($password, $this->salt); + $this->emailConf = 0; + $this->emailConfKey = $this->getBlob(); + + $this->saveObj(); + + $this->owner = $this->guid; + $this->saveObj(); + + return true; + } } ?> -- cgit v1.2.3 From e15599108f64bd816eb32f8028a81e3db76c19ff Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sun, 31 Jan 2016 16:52:52 -0500 Subject: Implement PHP session semantics in Framework class Added PHP session handling to core framework. Functions now exist to set the current user, get the current user, and get the IP address used to login (to compare with furure requests on the same session to combat session hijacking). --- app/class/framework.class.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'app/class') diff --git a/app/class/framework.class.php b/app/class/framework.class.php index d1293de..74c4b14 100644 --- a/app/class/framework.class.php +++ b/app/class/framework.class.php @@ -4,7 +4,11 @@ is_file("scrott.conf.php") && require_once "scrott.conf.php"; +/* Init PHP session */ +session_start(); + require_once "class/mysql.class.php"; +require_once "class/user.class.php"; /* * Global functions / operations and access to contextual or session-based information @@ -47,6 +51,43 @@ abstract class Framework exit; } + /* + * Get a user object for the currently logged in user. Returns false if session is logged out. + */ + function getCurrentUser() + { + if (isset($_SESSION['userguid'])) + return new User($_SESSION['userguid']); + + return false; + } + + /* + * Get the IP address the client held when the current session began + */ + function getOriginIP() + { + return $_SESSION['userip']; + } + + /* + * Set the current logged in user + */ + function setCurrentUser($user = null) + { + if ($user != null && isset($user->guid)) + { + $_SESSION['userguid'] = $user->guid; + $_SESSION['userip'] = $_SERVER['REMOTE_ADDR']; + } + + else + { + unset($_SESSION['userguid']); + unset($_SESSION['userip']); + } + } + /* * Get or create the app's database connection object (this is a singleton object and dependent on system-level config) */ -- cgit v1.2.3 From c776b36fd884808435dd1208f0dd9a57216b3927 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Mon, 1 Feb 2016 19:18:55 -0500 Subject: Implement authentication helper functions in User class Added function to initialize a User object by username wrather than GUID. Added function to validate a user-supplied plain-text password for a given user --- app/class/user.class.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'app/class') diff --git a/app/class/user.class.php b/app/class/user.class.php index 6bce26c..bd2e174 100644 --- a/app/class/user.class.php +++ b/app/class/user.class.php @@ -27,6 +27,21 @@ class User extends Object $this->loadObj($guid); } + /* + * Initialize object by username + */ + function initByUsername($username) + { + $query = "SELECT guid FROM object WHERE type = 'user' AND name = '" . $this->db->esc($username) . "'"; + $result = $this->db->query($query); + + if (count($result) == 0) + return false; + + $this->loadObj($result[0]['guid']); + return true; + } + /* * Get all users -- ordered by name, ascending */ @@ -96,6 +111,15 @@ class User extends Object return true; } + + /* + * Validate the password for this user. Returns true if correct, false otherwise + */ + function validatePassword($password) + { + $key = $this->getKey($password, $this->salt); + return $key == $this->key; + } } ?> -- cgit v1.2.3 From 7d484a70f73bd679e0dcf18d23d8124d8edf8f63 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Tue, 2 Feb 2016 19:52:07 -0500 Subject: Add helper function to Setting class Added a static helper function to replacing (or inserting) an option value in the database, longhand. --- app/class/setting.class.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'app/class') diff --git a/app/class/setting.class.php b/app/class/setting.class.php index ea5fac3..b48f241 100644 --- a/app/class/setting.class.php +++ b/app/class/setting.class.php @@ -23,6 +23,23 @@ class Setting extends Framework return $res[0]['value']; } + + /* + * Helper function for setting setting values on the database + */ + static function setValue($key, $value) + { + $db = parent::getDbConnection(); + $escdKey = $db->esc($key); + $escdValue = $db->esc($value); + + if (self::getValue($key) === false) + $query = "INSERT INTO setting (`key`, value) VALUES('" . $escdKey . "', '" . $escdValue . "')"; + else + $query = "UPDATE setting SET value = '" . $escdValue . "' WHERE `key` = '" . $escdKey . "'"; + + $db->query($query); + } } ?> -- cgit v1.2.3 From 4496b56e3392ba8183c0e1764557d51a8633e7ca Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Tue, 2 Feb 2016 20:31:29 -0500 Subject: Add admin setting 'allowPublicSignup' This setting will be used to decide if the app should allow unauthenticated users to create their own user accounts or if an admin must create them. --- app/class/setting.class.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'app/class') diff --git a/app/class/setting.class.php b/app/class/setting.class.php index b48f241..e3ef7f1 100644 --- a/app/class/setting.class.php +++ b/app/class/setting.class.php @@ -40,6 +40,19 @@ class Setting extends Framework $db->query($query); } + + /* + * Should the app allow the public to signup their own accounts with Scrott? + */ + static function allowPublicSignup($value = null) + { + $opt = "allowPublicSignup"; + + if ($value != null) + self::setValue($opt, $value); + + return self::getValue($opt); + } } ?> -- cgit v1.2.3