diff --git a/includes/controllers/GroupController.php.tmp b/includes/controllers/GroupController.php similarity index 50% rename from includes/controllers/GroupController.php.tmp rename to includes/controllers/GroupController.php index 93bf066c0..c7f11c44c 100644 --- a/includes/controllers/GroupController.php.tmp +++ b/includes/controllers/GroupController.php @@ -6,8 +6,8 @@ use YesWiki\Core\Exception\InvalidGroupNameException; use YesWiki\Core\Exception\GroupNameDoesNotExistException; use YesWiki\Core\Exception\GroupNameAlreadyUsedException; -use YesWiki\Core\Exception\UserNameAlreadyUsedException; use YesWiki\Core\Exception\UserNameDoesNotExistException; +use YesWiki\Core\Exception\InvalidInputException; use YesWiki\Core\Service\GroupManager; use YesWiki\Core\Service\UserManager; use YesWiki\Core\YesWikiController; @@ -31,19 +31,19 @@ public function __construct( */ private function isNameValid(string $name):bool { if ( str_starts_with($name, "@")) { - $name = substr($name, 1) + $name = substr($name, 1); } return preg_match('/[^A-Za-z0-9]/', $name); } /** - * @return string the ACL associated with the current group - * @see HasUser to check if a user belongs to some group + * @param string $groupName + * @return array the ACL associated with the current group */ - public function getACL(string $groupName) + public function getMembers(string $groupName) : array { - return $this->tripleStore->getOne($groupName, WIKINI_VOC_ACLS, GROUP_PREFIX); + return $this->groupManager->getMembers($groupName); } /** @@ -70,7 +70,7 @@ public function create(string $name, ?array $members): void * delete group * @return void */ - public function delete(string $name) + public function delete(string $name): void { if ($this->groupManager->groupExists($name)) { $this->groupManager->delete($name); @@ -78,65 +78,92 @@ public function delete(string $name) } /** - * add user or group to group - * @param string $group_name - * @param string $name user or group to add - * @return bool + * add users and/or groups to group + * @param string $group_name + * @param array $names users and/or groups to add * @throws UserDoesNotExistException * @throws GroupDoesNotExistException + * @return void */ - public function addOne(string $group_name, string $name) + public function add(string $group_name, array $names): void { if(!$this->groupManager->groupExists($group_name)) { throw new GroupNameDoesNotExistException(); } - if(str_starts_with($name, "@") { - if(!$this->groupManager->groupExists($name)) { - throw new GroupNameDoesNotExistException(_t('GROUP_NAME_DOES_NOT_EXIST')); // FIXME voir GROUP_NAME_DOES_NOT_EXIST + foreach ($names as $name) { + if(str_starts_with($name, "!")) { + $name = substr($name, 1); + } + if(str_starts_with($name, "@")) { + + if(!$this->groupManager->groupExists($name)) { + throw new GroupNameDoesNotExistException(_t('GROUP_NAME_DOES_NOT_EXIST')); + } + if(!this->CheckGroupRecursive($name,$group_name)) { + throw new InvalidInputException(_t('RECURSIVE_GROUP_ERROR')); //FIXME + } + } else { + if(!$this->userManager->userExist($name)) { + throw new UserNameDoesNotExistException(_t('USER_NAME_DOES_NOT_EXIST')); + } } - } else { - if(!$this->userManager->userExist($name)) { - throw new UserNameDoesNotExistException(_t('USER_NAME_DOES_NOT_EXIST')); // FIXME voir USER_NAME_DOES_NOT_EXIST } - } $this->groupManager->add($group_name, $name); } - /** - * remove user or group from group - * @param string $$group_name group to remove from - * @param string $name user or group to remove - * @return bool - * @throws UserDoesNotExistException - * @throws GroupDoesNotExistException - */ - public function removeOne(string $group_name, string $name) - { - - } - - /** - * add users and/or groups to group - * @param string $names users and/or groups to add - * @return bool - * @throws UserDoesNotExistException - * @throws GroupDoesNotExistException + /** + * Checks if a new group acl is not defined recursively + * (this method expects that groups that are already defined are not themselves defined recursively...) + * + * @param string $group_name + * The name of the group to test against origin + * @param string $origin group name to save test recursivity + * @return bool True if the new acl defines the group recursively */ - public function add(array $names) + private function CheckGroupRecursive($group_name, $origin, $checked = array()): bool { - //TODO + $group_name = strtolower(trim($group_name)); + if ($group_name === $origin) { + return true; + } + $members = this->get_members($group_name); + $recursive_members = str_replace(["\r\n", "\r"], "\n", $recursive_members); + foreach (explode("\n", $recursive_members) as $line) { + $line = trim($line); + if (!$line) { + continue; + } + + if ($line[0] == '!') { + $line = substr($line, 1); + } + if (!$line) { + continue; + } + + if ($line[0] == '@') { + $line = substr($line, 1); + if (!in_array($line, $checked)) { + if ($this->CheckGroupRecursive($line, $origin, $checked)) { + return true; + } + } + } + } + $checked[] = $group_name; + return false; } - /** + /** * remove users and/or groups from group * @param array $names users and/or groups to add * @return bool * @throws UserDoesNotExistException * @throws GroupDoesNotExistException */ - public function remove(array $names) + public function remove(array $names): void { - // TODO + $this->groupManager->removeMembers($names); } /** @@ -148,6 +175,6 @@ public function remove(array $names) * @throws GroupDoesNotExistException */ public function update(string $groupName, array $names) { - //TODO + } } diff --git a/includes/services/GroupManager.php b/includes/services/GroupManager.php index dca6d024e..95a557b8d 100644 --- a/includes/services/GroupManager.php +++ b/includes/services/GroupManager.php @@ -37,6 +37,22 @@ public function create(string $group_name, array $members): void { $this->tripleStore->create($group_name, WIKINI_VOC_ACLS, $member_str, GROUP_PREFIX); } + public function delete(string $group_name): void { + $this->tripleStore->delete($group_name, WIKINI_VOC_ACLS, null, GROUP_PREFIX); + } + + + /** + * get list of all groups + * @return string[] + * + */ + public function getall(): array { + $group_list = $this->tripleStore->getMatching(GROUP_PREFIX . '%', WIKINI_VOC_ACLS_URI); + $prefix_len = strlen(GROUP_PREFIX); + return array_map(fn($value): string => substr($value['resource'], $prefix_len),$group_list); + } + /** * get direct members of group. Do not list member of child groups. * @param string group_name @@ -49,12 +65,11 @@ public function getMembers(string $group_name) :array { /** * @param string $group_name - * @param string $members - * + * @param array $members + * @return void */ - public function add(string $group_name, array $members):void { + public function addMembers(string $group_name, array $members):void { $old_members = $this->getMembers($group_name); - if (!in_array($group_name, $members) ) { $new_members = array_merge($old_members, $members); $new_members = array_unique($$new_members); $new_members = implode("\n", $new_members); @@ -63,12 +78,36 @@ public function add(string $group_name, array $members):void { } else { $this->tripleStore->update($group_name, WIKINI_VOC_ACLS, $old_members, $new_members , GROUP_PREFIX); } - } } - public function remove(string $group_name, string $member): void { - $old_members = $this->getMembers($group_name); - + + /** + * @param string $group_name + * @param array $members + * @return void + */ + public function removeMembers(string $group_name, array $members): void { + $old_members = $this->getMembers($group_name); + $new_members = array_diff($$old_members, $members); + $new_members = implode("\n", $new_members); + if($this->tripleStore->delete($group_name, WIKINI_VOC_ACLS, $old_members, GROUP_PREFIX)) { + $this->tripleStore->create($group_name, WIKINI_VOC_ACLS, $new_members, GROUP_PREFIX); + } else { + $this->tripleStore->update($group_name, WIKINI_VOC_ACLS, $old_members, $new_members , GROUP_PREFIX); + } + } + + /** + * @param string $group_name + * @param array $members + * @return void + */ + public function updateMembers(string $group_name, array $members): void { + if($this->tripleStore->delete($group_name, WIKINI_VOC_ACLS, null, GROUP_PREFIX)) { + $this->tripleStore->create($group_name, WIKINI_VOC_ACLS, $members, GROUP_PREFIX); + } else { + $this->tripleStore->update($group_name, WIKINI_VOC_ACLS, null, $members , GROUP_PREFIX); + } } } diff --git a/lang/yeswiki_en.php b/lang/yeswiki_en.php index 892f63903..27e78050c 100644 --- a/lang/yeswiki_en.php +++ b/lang/yeswiki_en.php @@ -678,4 +678,8 @@ 'STYLE_SHEET' => 'Stylesheet', 'TABLE_PREFIX_ALREADY_USED' => 'This table prefix is already in use. Choose another one.', 'DENY_DELETE' => 'You are not allowed to delete this page', + 'GROUP_NAME_ALREADY_USED' => 'group name already used', + 'USER_NAME_DOES_NOT_EXIST' => 'user does not exist', + 'GROUP_NAME_DOES_NOT_EXIST' => 'group does not exist', + 'INVALID_GROUP_NAME' => 'group name is invalid', ]; diff --git a/lang/yeswiki_fr.php b/lang/yeswiki_fr.php index a5cd9f898..c8b7fe395 100755 --- a/lang/yeswiki_fr.php +++ b/lang/yeswiki_fr.php @@ -686,4 +686,8 @@ 'REACTION_TITLE_PARAM_NEEDED' => 'Le paramètre \'titre\' est obligatoire', 'REACTION_BAD_IMAGE_FORMAT' => 'Mauvais format d\'image : doit être un fichier, un icône utf8 ou une classe Fontawesome', 'REACTION_NO_IMAGE' => 'Image manquante', + 'GROUP_NAME_ALREADY_USED' => 'le groupe existe déjà', + 'USER_NAME_DOES_NOT_EXIST' => 'l\'utlisateur n\'existe pas', + 'GROUP_NAME_DOES_NOT_EXIST' => 'le groupe n\'existe pas', + 'INVALID_GROUP_NAME' => 'le nom du groupe n\'est pas valide', ];