From: Banana Date: Sun, 10 Jan 2021 11:11:15 +0000 (+0100) Subject: group management now available X-Git-Tag: 1.1~28 X-Git-Url: http://91.132.146.200/gitweb/?a=commitdiff_plain;h=5056d18917b611cd0a0c030bf20fb9f57ccb63fa;p=bibliotheca-php.git group management now available --- diff --git a/CHANGELOG b/CHANGELOG index 646be51..0534559 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ * User profile for editing own settings. * Collection management has the option to update entry rights with the collection ones. * Entry rights can now be managed. More info about user and rights can be found in documentation. + * User management: Honor rights from current logged in user + * Group management now available. But no relation check yet. 1.0 - Castle 20210106 * First usable version diff --git a/TODO b/TODO index 6788105..e5a9a96 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,6 @@ -* rights example setup and also check if it matches the menu and actions - + admin - + Management - + User (only its data) * sort by filter for collection display * Mass edit of entries +* User and groupmanagement: Check where a user or group is used! * Better error handling and display while adding / update and delete * responsive and breakpoints diff --git a/documentation/usermanagement-and-rights.txt b/documentation/usermanagement-and-rights.txt index aba4b04..c8cdbc5 100644 --- a/documentation/usermanagement-and-rights.txt +++ b/documentation/usermanagement-and-rights.txt @@ -1,4 +1,4 @@ -Currently there is only a user management. Groups or default users can not be changed. +Groups or default users can not be changed. Default users are: diff --git a/upgrade/from-version-1.0.txt b/upgrade/from-version-1.0.txt index c3d96be..bdde49f 100644 --- a/upgrade/from-version-1.0.txt +++ b/upgrade/from-version-1.0.txt @@ -10,3 +10,5 @@ UPDATE `bib_menu` SET `rights` = 'rw-rw----' WHERE `bib_menu`.`id` = 10; UPDATE `bib_menu` SET `group` = '2' WHERE `bib_menu`.`id` = 10; INSERT INTO `bib_menu` (`id`, `text`, `action`, `icon`, `owner`, `group`, `rights`, `position`, `category`) VALUES (NULL, 'Profile', 'profile', 'user', '1', '2', 'rw-rw----', '5', 'manage'); DELETE FROM `bib_menu` WHERE `bib_menu`.`id` = 13; +INSERT INTO `bib_menu` (`id`, `text`, `action`, `icon`, `owner`, `group`, `rights`, `position`, `category`) VALUES (NULL, 'Groups', 'managegroups', 'users', '1', '1', 'rw-------', '5', 'manage'); +UPDATE `bib_menu` SET `position` = '6' WHERE `bib_menu`.`id` = 16; diff --git a/webclient/lib/mancubus.class.php b/webclient/lib/mancubus.class.php index 890fb6a..696779b 100644 --- a/webclient/lib/mancubus.class.php +++ b/webclient/lib/mancubus.class.php @@ -242,12 +242,14 @@ class Mancubus { $queryOrder = " ORDER BY"; if (!empty($this->_queryOptions['sort'])) { $queryOrder .= ' t.' . $this->_queryOptions['sort']; - } else { + } + else { $queryOrder .= " t.created"; } if (!empty($this->_queryOptions['sortDirection'])) { $queryOrder .= ' ' . $this->_queryOptions['sortDirection']; - } else { + } + else { $queryOrder .= " DESC"; } } diff --git a/webclient/lib/possessed.class.php b/webclient/lib/possessed.class.php index 6af1e9b..3d7eb31 100644 --- a/webclient/lib/possessed.class.php +++ b/webclient/lib/possessed.class.php @@ -18,9 +18,8 @@ /** * Class Possessed - * User management - * There is no group management yet. It uses the defined groups - * from the initial setup. Don't change em, could break something. + * User and group management + * Some groups are protected and should not be removed. * * passwords used here: password_hash("somePassword", PASSWORD_DEFAULT); * @@ -33,12 +32,22 @@ class Possessed { */ private $_DB; + /** + * The user object to query with + * + * @var Doomguy + */ + private $_User; + /** * Possessed constructor. - * @param mysqli $db + * + * @param mysqli $databaseConnectionObject + * @param Doomguy $userObj */ - public function __construct($db) { - $this->_DB = $db; + public function __construct($databaseConnectionObject, $userObj) { + $this->_DB = $databaseConnectionObject; + $this->_User = $userObj; } /** @@ -49,7 +58,10 @@ class Possessed { public function getGroups() { $ret = array(); - $queryStr = "SELECT `id`, `name`, `description` FROM `".DB_PREFIX."_group` ORDER BY `name`"; + $queryStr = "SELECT `id`, `name`, `description`, `created`, `protected` + FROM `".DB_PREFIX."_group` + WHERE ".$this->_User->getSQLRightsString("delete")." + ORDER BY `name`"; if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); try { $query = $this->_DB->query($queryStr); @@ -75,7 +87,8 @@ class Possessed { $ret = array(); $queryStr = "SELECT `id`, `login`, `name`, `active`, `baseGroupId`, `protected`, `created` - FROM `".DB_PREFIX."_user`"; + FROM `".DB_PREFIX."_user` + WHERE ".$this->_User->getSQLRightsString("delete").""; if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); try { $query = $this->_DB->query($queryStr); @@ -106,11 +119,7 @@ class Possessed { public function createUser($username, $login, $password, $group, $active=false) { $ret = false; - if(!empty($login) === true - && $this->_validNewLogin($login) == true - && $this->_validUsergroup($group) == true - &&(!empty($password)) - ) { + if($this->_validNewLogin($login) && $this->_validUsergroup($group)) { if ($active === true) { $active = "1"; } else { @@ -176,11 +185,7 @@ class Possessed { public function updateUser($id, $username, $login, $password, $group, $active=false, $refreshApiToken=false) { $ret = false; - if(!empty($login) === true - && $this->_validUpdateLogin($login,$id) == true - && $this->_validUsergroup($group) == true - && !empty($id) - ) { + if($this->_validUpdateLogin($login,$id) && $this->_validUsergroup($group)) { if ($active === true) { $active = "1"; } else { @@ -201,7 +206,7 @@ class Possessed { $queryStr .= ", `apiTokenValidDate` = CURRENT_TIMESTAMP() + INTERVAL 1 DAY"; } $queryStr .= " WHERE `id` = '".$this->_DB->real_escape_string($id)."' - AND `protected` = '0'"; + AND ".$this->_User->getSQLRightsString("delete").""; if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); try { $this->_DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); @@ -238,9 +243,10 @@ class Possessed { $ret = array(); if(Summoner::validate($userId,'digit')) { - $queryStr = "SELECT `id`, `login`, `name`, `active`, `baseGroupId`, `created`,`apiToken`,`apiTokenValidDate` + $queryStr = "SELECT `id`, `login`, `name`, `active`, `baseGroupId`, + `created`,`apiToken`,`apiTokenValidDate`, `protected` FROM `".DB_PREFIX."_user` - WHERE `protected` = '0' + WHERE ".$this->_User->getSQLRightsString("delete")." AND `id` = '".$this->_DB->real_escape_string($userId)."'"; if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); try { @@ -267,11 +273,12 @@ class Possessed { public function deleteUser($id) { $ret = false; - if(!empty($id)) { + if(Summoner::validate($id,'digit')) { try { $this->_DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); $d1 = $this->_DB->query("DELETE FROM `".DB_PREFIX."_user` WHERE `id` = '".$this->_DB->real_escape_string($id)."' + AND ".$this->_User->getSQLRightsString("delete")." AND `protected` = '0'"); $d2 = $this->_DB->query("DELETE FROM `".DB_PREFIX."_user2group` WHERE `fk_user_id` = '".$this->_DB->real_escape_string($id)."'"); $d3 = $this->_DB->query("DELETE FROM `".DB_PREFIX."_userSession` WHERE `fk_user_id` = '".$this->_DB->real_escape_string($id)."'"); @@ -291,6 +298,181 @@ class Possessed { return $ret; } + /** + * Create group with given data. Validates duplicates based on name + * + * @param string $name + * @param string $description + * @return bool + */ + public function createGroup($name, $description) { + $ret = false; + + if($this->_validNewGroup($name)) { + $queryStr = "INSERT INTO `".DB_PREFIX."_group` SET + `name` = '".$this->_DB->real_escape_string($name)."', + `description` = '".$this->_DB->real_escape_string($description)."', + `modificationuser` = '".$this->_DB->real_escape_string($this->_User->param('id'))."', + `owner` = '".$this->_DB->real_escape_string($this->_User->param('id'))."', + `group` = '".ADMIN_GROUP_ID."', + `rights` = 'rwxr--r--'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $this->_DB->query($queryStr); + $ret = true; + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + + /** + * Update given group identified by id with given name and description + * Checks for duplicate + * + * @param string $id Number + * @param string $name + * @param string $description + * @return bool + */ + public function updateGroup($id, $name, $description) { + $ret = false; + + if($this->_validUpdateGroup($name, $id)) { + $queryStr = "UPDATE `".DB_PREFIX."_group` SET + `name` = '".$this->_DB->real_escape_string($name)."', + `description` = '".$this->_DB->real_escape_string($description)."', + `modificationuser` = '".$this->_DB->real_escape_string($this->_User->param('id'))."' + WHERE `id` = '".$this->_DB->real_escape_string($id)."' + AND ".$this->_User->getSQLRightsString("delete").""; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $this->_DB->query($queryStr); + $ret = true; + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + + /** + * Delete given group identified by id from group table. No relation check yet. + * + * @param string $id Number + * @return bool + */ + public function deleteGroup($id) { + $ret = false; + + if(Summoner::validate($id,'digit')) { + $queryStr = "DELETE FROM `".DB_PREFIX."_group` + WHERE ".$this->_User->getSQLRightsString("delete")." + AND `protected` = '0' + AND `id` = '".$this->_DB->real_escape_string($id)."'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $this->_DB->query($queryStr); + $ret = true; + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + + /** + * Load groupd data from group table fo edit + * + * @param string $id Number + * @return array + */ + public function getEditGroupData($id) { + $ret = array(); + + if(Summoner::validate($id,'digit')) { + $queryStr = "SELECT `id`, `name`, `description`, `created`, `protected` + FROM `".DB_PREFIX."_group` + WHERE ".$this->_User->getSQLRightsString("delete")." + AND `id` = '".$this->_DB->real_escape_string($id)."'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $query = $this->_DB->query($queryStr); + if($query !== false && $query->num_rows > 0) { + $ret = $query->fetch_assoc(); + } + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + + /** + * Check if given group name can be used as a new one + * + * @param string $name + * @return bool + */ + private function _validNewGroup($name) { + $ret = false; + + if (Summoner::validate($name, 'nospace')) { + $queryStr = "SELECT `id` FROM `".DB_PREFIX."_group` + WHERE `name` = '".$this->_DB->real_escape_string($name)."'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $query = $this->_DB->query($queryStr); + if ($query !== false && $query->num_rows < 1) { + $ret = true; + } + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + + /** + * Check if given group name can be used as an update to given group id + * + * @param string $name + * @param string $id Number + * @return bool + */ + private function _validUpdateGroup($name,$id) { + $ret = false; + + if (Summoner::validate($name, 'nospace') && Summoner::validate($id,"digit")) { + $queryStr = "SELECT `id` FROM `" . DB_PREFIX . "_group` + WHERE `name` = '".$this->_DB->real_escape_string($name)."' + AND `id` != '".$this->_DB->real_escape_string($id)."'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $query = $this->_DB->query($queryStr); + if ($query !== false && $query->num_rows < 1) { + $ret = true; + } + } + catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + + return $ret; + } + /** * Check if given login can be used as a new one * @@ -299,6 +481,7 @@ class Possessed { */ private function _validNewLogin($login) { $ret = false; + if (Summoner::validate($login, 'nospace')) { $queryStr = "SELECT `id` FROM `".DB_PREFIX."_user` WHERE `login` = '".$this->_DB->real_escape_string($login)."'"; @@ -326,7 +509,8 @@ class Possessed { */ private function _validUpdateLogin($login,$id) { $ret = false; - if (Summoner::validate($login, 'nospace')) { + + if (Summoner::validate($login, 'nospace') && Summoner::validate($id,"digit")) { $queryStr = "SELECT `id` FROM `" . DB_PREFIX . "_user` WHERE `login` = '".$this->_DB->real_escape_string($login)."' AND `id` != '".$this->_DB->real_escape_string($id)."'"; diff --git a/webclient/lib/summoner.class.php b/webclient/lib/summoner.class.php index cf24eca..8e00afa 100644 --- a/webclient/lib/summoner.class.php +++ b/webclient/lib/summoner.class.php @@ -621,13 +621,13 @@ class Summoner { /** * based on self::ifset check also the value * - * @param array $array - * @param string $key - * @param string $value + * @param array $array The array to use + * @param string $key The key to check + * @param string $value The value to compare * @return bool */ static function ifsetValue($array,$key,$value) { - if(self::ifset($array,$key)) { + if(self::ifset($array,$key) !== false) { return $array[$key] == $value; } return false; diff --git a/webclient/view/default/managegroups/managegroups.html b/webclient/view/default/managegroups/managegroups.html new file mode 100644 index 0000000..d4e349b --- /dev/null +++ b/webclient/view/default/managegroups/managegroups.html @@ -0,0 +1,68 @@ +

Group management

+
+
+

Add or modify a group

+
+
+ +
+ +
+
+
+ +
+ +
+
+ + +
+
Delete
+
+ +
+
+ +
+ +
+
+
+
+

Available groups

+ + + + + + + + + + $v) { ?> + + + + + + + +
NameDescription
+
+ +
+ +
+ + +
+
diff --git a/webclient/view/default/managegroups/managegroups.php b/webclient/view/default/managegroups/managegroups.php new file mode 100644 index 0000000..4220091 --- /dev/null +++ b/webclient/view/default/managegroups/managegroups.php @@ -0,0 +1,86 @@ +getGroups(); +$TemplateData['editData'] = false; + +$_id = false; +if(isset($_GET['id']) && !empty($_GET['id'])) { + $_id = trim($_GET['id']); + $_id = Summoner::validate($_id,'digit') ? $_id : false; +} + +if(!empty($_id)) { + $TemplateData['editData'] = $Possessed->getEditGroupData($_id); + if(!isset($TemplateData['editData']['name'])) { + $TemplateData['refresh'] = 'index.php?p=managegroups'; + } +} + +if(isset($_POST['submitForm'])) { + $fdata = $_POST['fdata']; + if(!empty($fdata)) { + $_name = trim($fdata['name']); + $_description = trim($fdata['description']); + + if(!empty($TemplateData['editData'])) { + if(isset($fdata['doDelete'])) { + $do = $Possessed->deleteGroup($_id); + if ($do === true) { + $TemplateData['refresh'] = 'index.php?p=managegroups'; + } + else { + $TemplateData['message']['content'] = "Group could not be deleted."; + $TemplateData['message']['status'] = "error"; + } + } + elseif (Summoner::validate($_name,'nospace') && Summoner::validate($_description)) { + $do = $Possessed->updateGroup($_id, $_name, $_description); + if ($do === true) { + $TemplateData['refresh'] = 'index.php?p=managegroups'; + } + else { + $TemplateData['message']['content'] = "Group could not be updated. Either wrong input or duplicate group name"; + $TemplateData['message']['status'] = "error"; + } + } + else { + $TemplateData['message']['content'] = "Provide name and description."; + $TemplateData['message']['status'] = "error"; + } + } + else { // adding mode + if (Summoner::validate($_name,'nospace') && Summoner::validate($_description)) { + $do = $Possessed->createGroup($_name, $_description); + if ($do === true) { + $TemplateData['refresh'] = 'index.php?p=managegroups'; + } + else { + $TemplateData['message']['content'] = "Group could not be created."; + $TemplateData['message']['status'] = "error"; + } + } + else { + $TemplateData['message']['content'] = "Provide name and description."; + $TemplateData['message']['status'] = "error"; + } + } + + } +} diff --git a/webclient/view/default/manageusers/manageusers.html b/webclient/view/default/manageusers/manageusers.html index ef01b58..b358d4d 100644 --- a/webclient/view/default/manageusers/manageusers.html +++ b/webclient/view/default/manageusers/manageusers.html @@ -53,7 +53,7 @@ - +
Delete
@@ -113,9 +113,7 @@ - - - + diff --git a/webclient/view/default/manageusers/manageusers.php b/webclient/view/default/manageusers/manageusers.php index 64adbb6..c9a201b 100644 --- a/webclient/view/default/manageusers/manageusers.php +++ b/webclient/view/default/manageusers/manageusers.php @@ -16,25 +16,18 @@ * limitations under the License. */ require_once 'lib/possessed.class.php'; -$Possessed = new Possessed($DB); +$Possessed = new Possessed($DB, $Doomguy); $TemplateData['existingGroups'] = $Possessed->getGroups(); $TemplateData['existingUsers'] = $Possessed->getUsers(); $TemplateData['editData'] = false; -$_editMode = false; -if(isset($_GET['m']) && !empty($_GET['m'])) { - if($_GET['m'] == "edit") { - $_editMode = true; - } -} - $_id = false; if(isset($_GET['id']) && !empty($_GET['id'])) { $_id = trim($_GET['id']); $_id = Summoner::validate($_id,'digit') ? $_id : false; } -if($_editMode === true && !empty($_id)) { +if(!empty($_id)) { $TemplateData['editData'] = $Possessed->getEditData($_id); if(!isset($TemplateData['editData']['name'])) { $TemplateData['refresh'] = 'index.php?p=manageusers'; @@ -60,13 +53,14 @@ if(isset($_POST['submitForm'])) { $do = $Possessed->deleteUser($_id); if ($do === true) { $TemplateData['refresh'] = 'index.php?p=manageusers'; - } else { + } + else { $TemplateData['message']['content'] = "User could not be deleted."; $TemplateData['message']['status'] = "error"; } } elseif (!empty($_username) && !empty($_group) && !empty($_login)) { - if (Summoner::validate($_username, 'text') === true + if (Summoner::validate($_username) === true && Summoner::validate($_login, 'nospace') === true && isset($TemplateData['existingGroups'][$_group]) ) { @@ -77,11 +71,13 @@ if(isset($_POST['submitForm'])) { $do = $Possessed->updateUser($_id, $_username, $_login, $_password, $_group, $_active, $refreshApi); if ($do === true) { $TemplateData['refresh'] = 'index.php?p=manageusers'; - } else { - $TemplateData['message']['content'] = "User could not be updated."; + } + else { + $TemplateData['message']['content'] = "User could not be updated. Either wrong input or duplicate user name"; $TemplateData['message']['status'] = "error"; } - } else { + } + else { $TemplateData['message']['content'] = "Provide username, login and a valid user group."; $TemplateData['message']['status'] = "error"; } @@ -97,11 +93,13 @@ if(isset($_POST['submitForm'])) { $do = $Possessed->createUser($_username, $_login, $_password, $_group, $_active); if ($do === true) { $TemplateData['refresh'] = 'index.php?p=manageusers'; - } else { + } + else { $TemplateData['message']['content'] = "User could not be created."; $TemplateData['message']['status'] = "error"; } - } else { + } + else { $TemplateData['message']['content'] = "Provide username, login, password and a valid user group."; $TemplateData['message']['status'] = "error"; } diff --git a/webclient/view/default/profile/profile.php b/webclient/view/default/profile/profile.php index f061185..7d6397e 100644 --- a/webclient/view/default/profile/profile.php +++ b/webclient/view/default/profile/profile.php @@ -16,7 +16,7 @@ * limitations under the License. */ require_once 'lib/possessed.class.php'; -$Possessed = new Possessed($DB); +$Possessed = new Possessed($DB, $Doomguy); $TemplateData['editData'] = $Doomguy->getAllUserData();