diff options
-rw-r--r-- | app/class/user.class.php | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/app/class/user.class.php b/app/class/user.class.php new file mode 100644 index 0000000..8d7da45 --- /dev/null +++ b/app/class/user.class.php @@ -0,0 +1,183 @@ +<?php + +/* + * SCROTT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to UNLICENSE + */ + +require_once "class/agent.class.php"; + +/* + * This class models Scrott users, including users without valid logins + * (external-users). + */ +class user extends agent +{ + /* + * Constructor + */ + public function __construct(?string $guid = NULL) + { + $this->fields['users'] = array( + "guid", + "auth", + "salt", + "alias", + "email", + "emailVer", + "admin", + "reg", + "emailConf", + ); + + parent::__construct($guid); + } + + /* + * Get the GUID of a user object from a given username, or NULL if + * the username is not in use. Therefore, this function can be + * used to test the existence of a user with the given username. + */ + public static function getGuidByUname(string $uname) : ?string + { + $uname = $this->db->esc($uname); + + $query = "SELECT guid FROM objects WHERE objtype = 'user' AND name = '" . $uname . "'"; + $res = $this->db->query($query); + + if (count($res) == 0) + return NULL; + + return $res[0]['guid']; + } + + /* + * Get a user object from a given username, or NULL if the username + * is not in use. This function can be used to test the existence + * of a user with the given username. + */ + public static function getByUname(string $uname) : ?user + { + if (($guid = self::getGuidByUname($uname))) + return new user($guid); + + return NULL; + } + + /* + * Get an array of all users, sorted by username + */ + public static function getAll_ordByUname() : array + { + $query = "SELECT guid FROM objects WHERE objtype = 'user' ORDER BY name"; + $res = $this->db->query($query); + + $users = array(); + + foreach ($res as $u) + $users[] = new user($u['guid']); + + return $users; + } + + /* + * Get an array of all users, sorted by admin (descending, admins + * first), then by username. + */ + public static function getAll_ordByAdminByUname() : array + { + $query = "SELECT o.guid FROM objects o JOIN users u ON o.guid = u.guid " . + "WHERE o.objtype = 'user' ORDER BY u.admin DESC, o.name"; + $res = $this->db->query($query); + + $users = array(); + + foreach ($res as $u) + $users[] = new user($u['guid']); + + return $users; + } + + /* + * Get an array of all admins, sorted by username + */ + public static function getAllAdmin_ordByUname() : array + { + $query = "SELECT o.guid FROM objects o JOIN users u ON o.guid = u.guid " . + "WHERE o.objtype = 'user' AND u.admin = 1 ORDER BY o.name"; + $res = $this->db->query($query); + + $users = array(); + + foreach ($res as $u) + $users[] = new user($u['guid']); + + return $users; + } + + /* + * Get the currently logged in user, or NULL if logged out. This + * function will throw if unable to aquire a PHP session. This + * function will also forcibly log the current user out if it + * detects any changes in the user-agent or remote IP address. + */ + public static function getCurrent() : ?user + { + if (!session_start()) + throw new Exception("Unable to aquire a PHP session"); + + if (!isset($_SESSION['userguid'])) + return NULL; + + /* detect session hijacking */ + if (($_SESSION['useragent'] != $_SERVER['HTTP_USER_AGENT']) || + ($_SESSION['userip'] != $_SERVER['REMOTE_ADDR'])) + { + self::setCurrent(); + return NULL; + } + + return new user($_SESSION['userguid']); + } + + /* + * Set the currently logged in user. Using NULL will logout any + * current user. This function will throw if unable to aquire a + * PHP session. This function will also cache the user-agent and + * remote IP address of the current request to help validate future + * requests made under the same session. + */ + public static function setCurrent(?user $user = NULL) : void + { + if (!session_start()) + throw new Exception("Unable to aquire a PHP session"); + + unset($_SESSION['userguid']); + unset($_SESSION['useragent']); + unset($_SESSION['userip']); + + if ($user) + { + $_SESSION['userguid'] = $user->guid; + $_SESSION['useragent'] = $_SERVER['HTTP_USER_AGENT']; + $_SESSION['userip'] = $_SERVER['REMOTE_ADDR']; + } + } + + /* + * Get the salted and hashed form of a password + */ + private static function getAuth(string $passwd, string $salt) : string + { + return hash("sha256", $passwd . $salt); + } +} + +?> |