225 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
require_once "common_func.php";
 | 
						|
 | 
						|
require_once "AutoStoring.php";
 | 
						|
 | 
						|
class User extends AutoStoring
 | 
						|
{
 | 
						|
    private int $id; // User's ID
 | 
						|
    private string $nickname; // User's nickname
 | 
						|
    private string $password; // User's password in it's encoded form or left empty
 | 
						|
    private string $realname; // User's real name displayed in their profile
 | 
						|
    private array $groups; // User's assigned groups
 | 
						|
    private string $privilege; // User's privilege
 | 
						|
    private UserMgr $userMgr; // UserManager object governing this object.
 | 
						|
 | 
						|
    // -------------------------------------------
 | 
						|
 | 
						|
    // Store modifications to the database.
 | 
						|
    public function storeMods(): void
 | 
						|
    {
 | 
						|
        $this->userMgr->updateUser($this);
 | 
						|
    }
 | 
						|
 | 
						|
    // -------------------------------------------
 | 
						|
 | 
						|
    function __construct(UserMgr &$usrmgr, int $id, string $nickname = null, string $password = null, string $realname = null, array $groups = null, string $privilege = null)
 | 
						|
    {
 | 
						|
        parent::__construct();
 | 
						|
 | 
						|
        $this->id = $id;
 | 
						|
        $this->nickname = $nickname;
 | 
						|
        $this->password = $password;
 | 
						|
        $this->realname = $realname;
 | 
						|
        $this->groups = $groups;
 | 
						|
        $this->privilege = $privilege;
 | 
						|
 | 
						|
        // save reference to user manager
 | 
						|
        $this->userMgr = &$usrmgr;
 | 
						|
    }
 | 
						|
 | 
						|
    // Create user from an array
 | 
						|
    static function fromArray(UserMgr &$usrmgr, array $a): User
 | 
						|
    {
 | 
						|
        $id = $a["_id"] ?? -1;
 | 
						|
        return new User($usrmgr, $id, $a["nickname"], $a["password"], $a["realname"], $a["groups"], $a["privilege"]);
 | 
						|
    }
 | 
						|
 | 
						|
    // Convert user to array
 | 
						|
    function toArray(array $omit = []): array
 | 
						|
    {
 | 
						|
        $a = [
 | 
						|
            "_id" => $this->id,
 | 
						|
            "nickname" => $this->nickname,
 | 
						|
            "password" => $this->password,
 | 
						|
            "realname" => $this->realname,
 | 
						|
            "groups" => $this->groups,
 | 
						|
            "privilege" => $this->privilege
 | 
						|
        ];
 | 
						|
 | 
						|
        // omit specific fields
 | 
						|
        foreach ($omit as $field) {
 | 
						|
            unset($a[$field]);
 | 
						|
        }
 | 
						|
 | 
						|
        return $a;
 | 
						|
    }
 | 
						|
 | 
						|
    // Change user password. If $safe, then $old is checked.
 | 
						|
    function changePassword(string $new, string $old, bool $safe = true): bool
 | 
						|
    {
 | 
						|
        if (!$safe || password_verify($old, $this->password)) {
 | 
						|
            $this->password = password_hash($new, PASSWORD_DEFAULT);
 | 
						|
            $this->storeMods(); // store modifications
 | 
						|
            return true;
 | 
						|
        } else {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Change user groups
 | 
						|
    function changeGroups(array $add, array $remove): void
 | 
						|
    {
 | 
						|
        alter_array_contents($this->groups, $add, $remove);
 | 
						|
        $this->storeMods(); // store modifications
 | 
						|
    }
 | 
						|
 | 
						|
    // Get user's groups
 | 
						|
    function getGroups(): array
 | 
						|
    {
 | 
						|
        return $this->groups;
 | 
						|
    }
 | 
						|
 | 
						|
    // Set user privilege level
 | 
						|
    function setPrivilege(string $privilege): void
 | 
						|
    {
 | 
						|
        $this->privilege = ($this->nickname === QUIZMASTER_NICKNAME) ? PRIVILEGE_QUIZMASTER : $privilege; // quizmaster's privilege mustn't be tampered with
 | 
						|
        $this->storeMods(); // store modifications
 | 
						|
    }
 | 
						|
 | 
						|
    // Get user privilege level
 | 
						|
    function getPrivilege(): string
 | 
						|
    {
 | 
						|
        return $this->privilege;
 | 
						|
    }
 | 
						|
 | 
						|
    // Get user's nickname.
 | 
						|
    function getNickname(): string
 | 
						|
    {
 | 
						|
        return $this->nickname;
 | 
						|
    }
 | 
						|
 | 
						|
    // Set user's real name.
 | 
						|
    function setRealname(string $realname): void
 | 
						|
    {
 | 
						|
        $this->realname = $realname;
 | 
						|
    }
 | 
						|
 | 
						|
    // Get user's real name.
 | 
						|
    function getRealname(): string
 | 
						|
    {
 | 
						|
        return $this->realname;
 | 
						|
    }
 | 
						|
 | 
						|
    // Check against user credentials.
 | 
						|
    function checkPassword(string $password): bool
 | 
						|
    {
 | 
						|
        return password_verify($password, $this->password);
 | 
						|
    }
 | 
						|
 | 
						|
    // Has the user quizmaster privileges?
 | 
						|
    function hasQuizmasterPrivilege(): bool
 | 
						|
    {
 | 
						|
        return $this->privilege == PRIVILEGE_QUIZMASTER;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
class UserMgr
 | 
						|
{
 | 
						|
    public \SleekDB\Store $db;
 | 
						|
 | 
						|
    function __construct()
 | 
						|
    {
 | 
						|
        // create database
 | 
						|
        $this->db = new \SleekDB\Store(USERDB, DATADIR, ["timeout" => false]);
 | 
						|
    }
 | 
						|
 | 
						|
    // Get user by nickname. Returns with a User object if found, null else.
 | 
						|
    function getUser(string $nickname): User|null
 | 
						|
    {
 | 
						|
        $user_data_array = $this->db->findBy(["nickname", "=", $nickname]);
 | 
						|
        return count($user_data_array) != 0 ? User::fromArray($this, $user_data_array[0]) : null;
 | 
						|
    }
 | 
						|
 | 
						|
    // Update user.
 | 
						|
    function updateUser(User $user): void
 | 
						|
    {
 | 
						|
        $a = $user->toArray(); // convert to array
 | 
						|
        $this->db->update($a); // update using the extracted array
 | 
						|
    }
 | 
						|
 | 
						|
    // checks if a nickname is taken
 | 
						|
    function isNicknameTaken(string $nickname): bool
 | 
						|
    {
 | 
						|
        return !($this->db->findOneBy(["nickname", "=", $nickname]) == null);
 | 
						|
    }
 | 
						|
 | 
						|
    // Add new user.
 | 
						|
    function addUser(string $nickname, string $password, string $realname, array $groupids = [], string $privilege = PRIVILEGE_PLAYER): bool
 | 
						|
    {
 | 
						|
        if ($this->isNicknameTaken($nickname)) { // user exists
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        $a = [
 | 
						|
            "nickname" => $nickname,
 | 
						|
            "password" => password_hash($password, PASSWORD_DEFAULT),
 | 
						|
            "realname" => $realname,
 | 
						|
            "groups" => $groupids,
 | 
						|
            "privilege" => $privilege
 | 
						|
        ];
 | 
						|
 | 
						|
        // create user object
 | 
						|
        $user = User::fromArray($this, $a);
 | 
						|
 | 
						|
        // add user to specific groups FIXME!!!!
 | 
						|
        foreach ($groupids as $groupid) {
 | 
						|
            change_group_user_assignments($groupid, $nickname, null);
 | 
						|
        }
 | 
						|
 | 
						|
        $this->db->insert($user->toArray(["_id"]));
 | 
						|
 | 
						|
        return true; // user registration successful
 | 
						|
    }
 | 
						|
 | 
						|
    // Delete user from the storage
 | 
						|
    function deleteUser(string $nickname): void
 | 
						|
    {
 | 
						|
        // cannot delete quizmaster
 | 
						|
        if ($nickname == QUIZMASTER_NICKNAME) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
//        $user = $this->getUser($nickname);
 | 
						|
//        if ($user !== null) {
 | 
						|
//            foreach ($user->getGroups() as $groupid) {
 | 
						|
//                change_group_user_assignments($groupid, null, $nickname);
 | 
						|
//            }
 | 
						|
        $this->db->deleteBy(["nickname", "=", $nickname]);
 | 
						|
        //}
 | 
						|
    }
 | 
						|
 | 
						|
    // Dump all users. Users come wrapped in User objects.
 | 
						|
    function getAllUsers(): array
 | 
						|
    {
 | 
						|
        return array_map(fn($a): User => User::fromArray($this, $a), $this->db->findAll());
 | 
						|
    }
 | 
						|
 | 
						|
    // Get all nicknames.
 | 
						|
    function getAllNicknames(): array
 | 
						|
    {
 | 
						|
        $qb = $this->db->createQueryBuilder();
 | 
						|
        return array_map(fn($c): string => $c["nickname"], $qb->select(["nickname"])->getQuery()->fetch());
 | 
						|
    }
 | 
						|
} |