diff --git a/class/GameMgr.php b/class/GameMgr.php index efd5d19..2a56395 100644 --- a/class/GameMgr.php +++ b/class/GameMgr.php @@ -102,7 +102,7 @@ class Game extends AutoStoring $a["game_file_present"], $a["properties"], $a["public"], $a["public_id"], $a["version"]); } - const OMIT_ADVANCED_FIELDS = ["contributors", "game_file_is_present", "properties", "groups", "public", "public_id", "version"]; + const OMIT_ADVANCED_FIELDS = ["contributors", "game_file_is_present", "properties", "public", "public_id", "version"]; // Convert game to array representation. function toArray(array $omit = []): array @@ -383,7 +383,6 @@ class GameMgr "description" => $description, "game_file_present" => false, "properties" => $properties, - "groups" => [], "public" => false, "public_id" => self::genPublicId(), "version" => Game::CURRENT_GAME_VERSION diff --git a/class/GroupMgr.php b/class/GroupMgr.php index f3a5020..b593a6c 100644 --- a/class/GroupMgr.php +++ b/class/GroupMgr.php @@ -359,7 +359,7 @@ class GroupMgr function resolveGroupIds(array &$groupids): void { foreach ($groupids as &$groupid) { - if (array_key_exists($groupid, $this->groupid_cache)) { + if (!array_key_exists($groupid, $this->groupid_cache)) { $group = $this->getGroup($groupid); // fetch group $unique_name = $group->getUniqueName(); // get group's unique name $this->groupid_cache[$groupid] = $unique_name; // store into the cache so that subsequent queries will be somewhat faster @@ -368,4 +368,24 @@ class GroupMgr $groupid = $this->groupid_cache[$groupid]; // replace with the unique name } } + + // Check if a user has access to a game, i.e. there's at least a single group that contains both the user and the game. + function doesUserAccessGame(string $gameid, string $nickname): bool { + $intersection = $this->db->findOneBy([["games", "CONTAINS", $gameid], "AND", ["users", "CONTAINS", $nickname]]); + return $intersection !== null; + } + + // Get user's groups IDs. + function getUserGroupIDs(string $nickname) : array { + $qb = $this->db->createQueryBuilder(); + $a = $qb->where(["users", "CONTAINS", $nickname])->select(["_id"])->getQuery()->fetch(); + return array_map(fn($r) => $r["_id"], $a); + } + + // Get game's group IDs. + function getGameGroupIDs(string $gameid) : array { + $qb = $this->db->createQueryBuilder(); + $a = $qb->where(["games", "CONTAINS", (int)$gameid])->select(["_id"])->getQuery()->fetch(); + return array_map(fn($r) => $r["_id"], $a); + } } \ No newline at end of file diff --git a/class/TestMgr.php b/class/TestMgr.php index 2758edc..8859baa 100644 --- a/class/TestMgr.php +++ b/class/TestMgr.php @@ -114,7 +114,7 @@ class Test extends AutoStoring $this->timeLimited = $a["time_limited"]; $this->startTime = $a["start_time"]; $this->endTime = $a["end_time"] ?? 0; - $this->endLimitTime = $a["end_limit_time"]; + $this->endLimitTime = $a["end_limit_time"] ?? 0; $this->repeatable = $a["repeatable"]; $this->challenges = $a["challenges"]; if (isset($a["summary"])) { diff --git a/class/UserMgr.php b/class/UserMgr.php index 7f2baee..2886b38 100644 --- a/class/UserMgr.php +++ b/class/UserMgr.php @@ -10,7 +10,7 @@ class User extends AutoStoring 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 array $groups; // User's assigned groups private string $privilege; // User's privilege private UserMgr $userMgr; // UserManager object governing this object. @@ -24,7 +24,7 @@ class User extends AutoStoring // ------------------------------------------- - function __construct(UserMgr &$usrmgr, int $id, string $nickname = null, string $password = null, string $realname = null, array $groups = null, string $privilege = null) + function __construct(UserMgr &$usrmgr, int $id, string $nickname = null, string $password = null, string $realname = null, string $privilege = null) { parent::__construct(); @@ -32,7 +32,7 @@ class User extends AutoStoring $this->nickname = $nickname; $this->password = $password; $this->realname = $realname; - $this->groups = $groups; +// $this->groups = $groups; $this->privilege = $privilege; // save reference to user manager @@ -43,7 +43,7 @@ class User extends AutoStoring 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"]); + return new User($usrmgr, $id, $a["nickname"], $a["password"], $a["realname"], $a["privilege"]); } // Convert user to array @@ -54,7 +54,7 @@ class User extends AutoStoring "nickname" => $this->nickname, "password" => $this->password, "realname" => $this->realname, - "groups" => $this->groups, +// "groups" => $this->groups, "privilege" => $this->privilege ]; @@ -78,18 +78,18 @@ class User extends AutoStoring } } - // Change user groups - function changeGroups(array $add, array $remove): void - { - alter_array_contents($this->groups, $add, $remove); - $this->storeMods(); // store modifications - } +// // 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; - } +// // Get user's groups +// function getGroups(): array +// { +// return $this->groups; +// } // Set user privilege level function setPrivilege(string $privilege): void @@ -166,7 +166,7 @@ class UserMgr } // Add new user. - function addUser(string $nickname, string $password, string $realname, array $groupids = [], string $privilege = PRIVILEGE_PLAYER): bool + function addUser(string $nickname, string $password, string $realname, string $privilege = PRIVILEGE_PLAYER): bool { if ($this->isNicknameTaken($nickname)) { // user exists return false; @@ -176,17 +176,16 @@ class UserMgr "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); - } +// // add user to specific groups FIXME!!!! +// foreach ($groupids as $groupid) { +// change_group_user_assignments($groupid, $nickname, null); +// } $this->db->insert($user->toArray(["_id"])); diff --git a/interface.php b/interface.php index f62e5de..5c03e4b 100644 --- a/interface.php +++ b/interface.php @@ -121,7 +121,7 @@ function get_available_games(ReqHandler &$rh, array $params): array global $gameMgr; $games_by_groups = []; - $groupids = $user->getGroups(); + $groupids = $groupMgr->getUserGroupIDs($user->getNickname()); foreach ($groupids as $groupid) { $group = $groupMgr->getGroup($groupid); $game_collection = [ @@ -148,10 +148,15 @@ function start_or_continue_test(ReqHandler &$rh, array $params): string global $user; global $gameMgr; global $testMgr; + global $groupMgr; - $game = $gameMgr->getGame($params["gameid"]); - $test = $testMgr->addOrContinueTest($game, $user); - return $test->getId(); + if ($groupMgr->doesUserAccessGame($params["gameid"], $user->getNickname())) { + $game = $gameMgr->getGame($params["gameid"]); + $test = $testMgr->addOrContinueTest($game, $user); + return $test->getId(); + } else { + return -1; + } } function get_results_overview(ReqHandler &$rh, array $params): array @@ -626,7 +631,6 @@ function create_update_user(ReqHandler &$rh, array $params): string $update = $params[ReqHandler::ACTION_KEY] === "update_user"; $target_nickname = trim($params["nickname"]); $password = trim($params["password"]); - $groups = explode_list($params["groups"]); $realname = trim($params["realname"]); $privilege = trim($params["privilege"]); @@ -635,7 +639,7 @@ function create_update_user(ReqHandler &$rh, array $params): string $success = false; if (($target_nickname !== "")) { if ((!$update) && ($password !== "")) { // CREATE - $success = $userMgr->addUser($target_nickname, $password, $realname, [], $privilege); // FIXME!!! + $success = $userMgr->addUser($target_nickname, $password, $realname, $privilege); // FIXME!!! } else if ($update) { // UPDATE $tuser = $userMgr->getUser($target_nickname); // load user data if ($tuser !== null) { @@ -694,12 +698,25 @@ function get_all_game_users(ReqHandler &$rh, array $params): array for ($i = 0; $i < count($all_users); $i++) { $a = $all_users[$i]->toArray(); // convert user to array unset($a["password"]); // remove password from records - resolve_groupids($a["groups"]); // resolve group IDs FIXME!!!! $user_data_filtered[] = $a; } return $user_data_filtered; } +function get_user_groups(ReqHandler &$rh, array $params): array { + global $groupMgr; + $groups = $groupMgr->getUserGroupIDs($params["nickname"]); + $groupMgr->resolveGroupIds($groups); + return $groups; +} + +function get_game_groups(ReqHandler &$rh, array $params): array { + global $groupMgr; + $groups = $groupMgr->getGameGroupIDs($params["gameid"]); + $groupMgr->resolveGroupIds($groups); + return $groups; +} + function import_users_from_csv(ReqHandler &$rh, array $params): string { if (!isset($_FILES["users_table"])) { @@ -714,9 +731,11 @@ $rh->add("delete_groups", ["ids"], PRIVILEGE_QUIZMASTER, "delete_groups", RESP_P $rh->add("get_all_groups", [], PRIVILEGE_QUIZMASTER, "get_all_player_groups", RESP_JSON, "Get all player groups."); $rh->add("search_groups", ["needle"], PRIVILEGE_QUIZMASTER, "search_player_groups", RESP_JSON, "Serach and fetch player groups."); -$rh->add(["create_user", "update_user"], ["nickname", "password", "groups", "realname", "privilege"], PRIVILEGE_QUIZMASTER, "create_update_user", RESP_PLAIN, "Create or update user."); +$rh->add(["create_user", "update_user"], ["nickname", "password", "realname", "privilege"], PRIVILEGE_QUIZMASTER, "create_update_user", RESP_PLAIN, "Create or update user."); $rh->add("delete_users", ["users"], PRIVILEGE_QUIZMASTER, "delete_users", RESP_PLAIN, "Delete users."); $rh->add("get_all_users", [], PRIVILEGE_QUIZMASTER, "get_all_game_users", RESP_JSON, "Get all users."); +$rh->add("get_user_groups", ["nickname"], PRIVILEGE_QUIZMASTER, "get_user_groups", RESP_JSON, "Get user's groups."); +$rh->add("get_game_groups", ["gameid"], PRIVILEGE_QUIZMASTER, "get_game_groups", RESP_JSON, "Get game's groups."); $rh->add("import_users_from_csv", [], PRIVILEGE_QUIZMASTER, "import_users_from_csv", RESP_JSON, "Get all users."); //function test(ReqHandler &$rh, array $params): string diff --git a/js/gamemgr.js b/js/gamemgr.js index 4521772..7ddf486 100644 --- a/js/gamemgr.js +++ b/js/gamemgr.js @@ -1,3 +1,15 @@ +function fetch_game_groups(gameid, cb) { + let req = { + action: "get_game_groups", + gameid: gameid + }; + request(req).then(resp => { + let groups = JSON.parse(resp); + let groupsJoined = groups.join(", "); + cb(groupsJoined); + }); +} + function list_all_games() { let req = {action: "get_all_game_headers"}; let tbody = document.getElementById("game_manager_table"); @@ -94,7 +106,10 @@ function create_edit_game(game = null) { ownerF.value = game["owner"]; ownerF.readOnly = false; contributorsF.value = game["contributors"].join(", "); - // groupF.value = game["groups"].join(", "); FIXME + + fetch_game_groups(game["_id"], (groups) => { + groupF.value = groups; + }); publicChk.addEventListener("change", hide_public_url_field); publicChk.checked = game["public"]; diff --git a/js/quizmaster_common.js b/js/quizmaster_common.js index 1aefc03..9424d88 100644 --- a/js/quizmaster_common.js +++ b/js/quizmaster_common.js @@ -1,5 +1,5 @@ function create_table_cell(content, styleClass = "") { - if (content.trim() === "") { + if ((content !== null) && (content.trim() === "")) { content = "(üres)"; } let td = document.createElement("td"); diff --git a/js/usermgr.js b/js/usermgr.js index 5d91850..f78ded3 100644 --- a/js/usermgr.js +++ b/js/usermgr.js @@ -1,3 +1,15 @@ +function fetch_user_groups(nickname, cb) { + let req = { + action: "get_user_groups", + nickname: nickname + }; + request(req).then(resp => { + let groups = JSON.parse(resp); + let groupsJoined = groups.join(", "); + cb(groupsJoined); + }); +} + function list_all_users() { let tbody = document.getElementById("user_manager_table_body"); tbody.innerHTML = ""; @@ -21,7 +33,20 @@ function list_all_users() { tdChkBox.classList.add("checkbox"); let tdNickName = create_table_cell(u["nickname"]); let tdRealName = create_table_cell(u["realname"]); - let tdGroups = create_table_cell(u["groups"].join(", ")); + let tdGroups = create_table_cell(null); + let fetchGroupsS = document.createElement("span"); + fetchGroupsS.innerHTML = "📥"; + fetchGroupsS.style.cursor = "pointer"; + fetchGroupsS.addEventListener("click", (evt) => { + let nickname = u["nickname"]; + fetch_user_groups(nickname, (groups) => { + tdGroups.innerText = groups; + }); + + evt.stopPropagation(); + }); + tdGroups.append(fetchGroupsS); + let tdPrivilege = create_table_cell(u["privilege"]); row.append(tdChkBox, tdNickName, tdRealName, tdGroups, tdPrivilege); tbody.appendChild(row); @@ -61,9 +86,13 @@ function create_edit_user(user = null) { passwordF.type = "password"; passwordF.value = ""; passwordF.readOnly = false; - groupsF.value = user["groups"].join(", "); + groupsF.value = ""; privilegeF.value = user["privilege"]; submit_btn.value = "Mentés" + + fetch_user_groups(user["nickname"], (groups) => { + groupsF.value = groups; + }); } else { nicknameF.value = ""; nicknameF.readOnly = false;