From 63f776746030d3130fa92a77cfb7a272b9f44250 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Mon, 12 Feb 2024 13:14:02 +0100 Subject: [PATCH] =?UTF-8?q?1.5.00=20contr=C3=B4le=20des=20permisison=20g?= =?UTF-8?q?=C3=A9n=C3=A9rale=20spour=20les=20comptes=20=C3=A9diteurs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- core/core.php | 2 +- core/module/course/course.php | 407 ++++++++++++++-------- core/module/course/view/manage/manage.php | 71 ++-- 4 files changed, 299 insertions(+), 183 deletions(-) diff --git a/README.md b/README.md index 954849c..be0ead2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ZwiiCampus 1.4.26 +# ZwiiCampus 1.5.00 ZwiiCampus (Learning Management System) est logiciel auteur destiné à mettre en ligne des tutoriels. Il dispose de plusieurs modalités d'ouverture et d'accès des contenus. Basé sur la version 13 du CMS Zwii, la structure logicielle est solide, le framework de Zwii est éprouvé. diff --git a/core/core.php b/core/core.php index df989f9..1719725 100644 --- a/core/core.php +++ b/core/core.php @@ -51,7 +51,7 @@ class common const ACCESS_TIMER = 1800; // Numéro de version - const ZWII_VERSION = '1.4.26'; + const ZWII_VERSION = '1.5.00'; // URL autoupdate const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/campus-update/raw/branch/master/'; diff --git a/core/module/course/course.php b/core/module/course/course.php index e9a11d5..384d352 100644 --- a/core/module/course/course.php +++ b/core/module/course/course.php @@ -23,12 +23,6 @@ class course extends common 'index' => self::GROUP_EDITOR, 'edit' => self::GROUP_EDITOR, 'manage' => self::GROUP_EDITOR, - 'add' => self::GROUP_ADMIN, - 'delete' => self::GROUP_ADMIN, - 'category' => self::GROUP_ADMIN, - 'categoryAdd' => self::GROUP_ADMIN, - 'categoryEdit' => self::GROUP_ADMIN, - 'categoryDelete' => self::GROUP_ADMIN, 'users' => self::GROUP_EDITOR, 'usersAdd' => self::GROUP_EDITOR, 'userDelete' => self::GROUP_EDITOR, @@ -38,7 +32,13 @@ class course extends common 'userHistoryExport' => self::GROUP_EDITOR, 'backup' => self::GROUP_EDITOR, 'restore' => self::GROUP_EDITOR, - 'clone' => self::GROUP_ADMIN + 'clone' => self::GROUP_ADMIN, + 'add' => self::GROUP_ADMIN, + 'delete' => self::GROUP_ADMIN, + 'category' => self::GROUP_ADMIN, + 'categoryAdd' => self::GROUP_ADMIN, + 'categoryEdit' => self::GROUP_ADMIN, + 'categoryDelete' => self::GROUP_ADMIN, ]; public static $courseAccess = [ @@ -88,41 +88,37 @@ class course extends common && $this->getCoursesByUser() ) { foreach ($this->getCoursesByUser() as $courseId => $courseValue) { - /** * Filtres : * Groupes acceptés : * admin : tous les espaces - * editor : gère son espace + * editor : gère son espace son espace dans lequel il est inscrit */ - - if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $courseId, 'author']) + if ( + $this->permissionControl(__FUNCTION__, $courseId) ) { - continue; - } - $author = $this->getData(['course', $courseId, 'author']) - ? sprintf('%s %s', $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'firstname']), $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'lastname'])) - : ''; - $categorieUrl = helper::baseUrl() . 'course/swap/' . $courseId; - $info = sprintf('%s
Auteur : %s
Id : %s
', $this->getData(['course', $courseId, 'title']), $author, $categorieUrl, $courseId); - $enrolment = sprintf( - 'Accès : %s
Inscription : %s
', - self::$courseAccess[$this->getData(['course', $courseId, 'access'])], - self::$courseEnrolment[$this->getData(['course', $courseId, 'enrolment'])] - ); - self::$courses[] = [ - $info, - $this->getData(['course', $courseId, 'description']), - $enrolment, - template::button('categoryUser' . $courseId, [ - 'href' => helper::baseUrl() . 'course/manage/' . $courseId, - 'value' => template::ico('eye'), - 'help' => 'Gérer' - ]) - ]; + $author = $this->getData(['course', $courseId, 'author']) + ? sprintf('%s %s', $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'firstname']), $this->getData(['user', $this->getData(['course', $courseId, 'author']), 'lastname'])) + : ''; + $categorieUrl = helper::baseUrl() . 'course/swap/' . $courseId; + $info = sprintf('%s
Auteur : %s
Id :
%s
', $this->getData(['course', $courseId, 'title']), $author, $categorieUrl, $courseId); + $enrolment = sprintf( + 'Accès : %s
Inscription : %s
', + self::$courseAccess[$this->getData(['course', $courseId, 'access'])], + self::$courseEnrolment[$this->getData(['course', $courseId, 'enrolment'])] + ); + self::$courses[] = [ + $info, + $this->getData(['course', $courseId, 'description']), + $enrolment, + template::button('categoryUser' . $courseId, [ + 'href' => helper::baseUrl() . 'course/manage/' . $courseId, + 'value' => template::ico('eye'), + 'help' => 'Gérer' + ]) + ]; + } } } @@ -142,9 +138,18 @@ class course extends common public function add() { + // Accès limité aux admins + if ( + $this->getUser('group') !== self::GROUP_ADMIN + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + // Soumission du formulaire if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) === true && $this->isPost() ) { $courseId = uniqid(); @@ -230,10 +235,12 @@ class course extends common public function edit() { - // Profil limité au propriétaire ou admis + // Espace sélectionné + $courseId = $this->getUrl(2); + + // Accès limité aux admins, à l'auteur ou éditeurs inscrits if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ @@ -243,10 +250,10 @@ class course extends common // Soumission du formulaire if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) === true && + //$this->getUser('permission', __CLASS__, __FUNCTION__) === true && $this->isPost() ) { - $courseId = $this->getUrl(2); + $this->setData([ 'course', $courseId, @@ -310,11 +317,12 @@ class course extends common public function manage() { - // Profil limité au propriétaire ou admis + // Espace sélectionné + $courseId = $this->getUrl(2); + + // Accès limité aux admins, à l'auteur ou éditeurs inscrits if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ @@ -358,46 +366,47 @@ class course extends common public function clone () { - // Profil limité au propriétaire ou admis + // Cours à dupliquer + $courseId = $this->getUrl(2); + + // Accès limité aux admins, à l'auteur ou éditeurs inscrits if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->getUser('group') !== self::$actions[__FUNCTION__] ) { // Valeurs en sortie $this->addOutput([ 'access' => false ]); + } else { + // Id du nouveau cours + $target = uniqid(); + + // Créer la structure de données + mkdir(self::DATA_DIR . $target); + + $this->copyDir(self::DATA_DIR . $courseId, self::DATA_DIR . $target); + + $this->setData(['course', $target, $this->getData(['course', $courseId])]); + + // Valeurs en sortie + $this->addOutput([ + 'redirect' => helper::baseUrl() . 'course', + 'notification' => helper::translate('Espace dupliqué'), + 'state' => true + ]); } - - // Cours à dupliquer - $courseId = $this->getUrl(2); - - // Id du nouveau cours - $target = uniqid(); - - // Créer la structure de données - mkdir(self::DATA_DIR . $target); - - $this->copyDir(self::DATA_DIR . $courseId, self::DATA_DIR . $target); - - $this->setData(['course', $target, $this->getData(['course', $courseId])]); - - // Valeurs en sortie - $this->addOutput([ - 'redirect' => helper::baseUrl() . 'course', - 'notification' => helper::translate('Espace dupliqué'), - 'state' => true - ]); } public function delete() { + // Espace sélectionné $courseId = $this->getUrl(2); + if ( - ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true - // Le contenu n'existe pas - || $this->getData(['course', $courseId]) === null) + // Accès limité aux admins + $this->getUser('group') !== self::$actions[__FUNCTION__] + // Le contenu n'existe pas + || $this->getData(['course', $courseId]) === null ) { // Valeurs en sortie $this->addOutput([ @@ -434,40 +443,55 @@ class course extends common */ public function category() { - $categories = $this->getData(['category']); - ksort($categories); - foreach ($categories as $categoryId => $categoryTitle) { - self::$courseCategories[] = [ - $categoryId, - $categoryTitle, - template::button('categoryEdit' . $categoryId, [ - 'href' => helper::baseUrl() . 'course/categoryEdit/' . $categoryId, - 'value' => template::ico('pencil'), - 'help' => 'Éditer' - ]), - template::button('courseDelete' . $categoryId, [ - 'class' => 'categoryDelete buttonRed', - 'href' => helper::baseUrl() . 'course/categoryDelete/' . $categoryId, - 'value' => template::ico('trash'), - 'help' => 'Supprimer' - ]) - ]; + + if ( + // Accès limité aux admins + $this->getUser('group') !== self::$actions[__FUNCTION__] + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } else { + $categories = $this->getData(['category']); + ksort($categories); + foreach ($categories as $categoryId => $categoryTitle) { + self::$courseCategories[] = [ + $categoryId, + $categoryTitle, + template::button('categoryEdit' . $categoryId, [ + 'href' => helper::baseUrl() . 'course/categoryEdit/' . $categoryId, + 'value' => template::ico('pencil'), + 'help' => 'Éditer' + ]), + template::button('courseDelete' . $categoryId, [ + 'class' => 'categoryDelete buttonRed', + 'href' => helper::baseUrl() . 'course/categoryDelete/' . $categoryId, + 'value' => template::ico('trash'), + 'help' => 'Supprimer' + ]) + ]; + } + // Valeurs en sortie + $this->addOutput([ + 'title' => helper::translate('Catégories'), + 'view' => 'category' + ]); } - // Valeurs en sortie - $this->addOutput([ - 'title' => helper::translate('Catégories'), - 'view' => 'category' - ]); } public function categoryAdd() { - // Soumission du formulaire if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) === true && - $this->isPost() + // Accès limité aux admins + $this->getUser('group') !== self::$actions[__FUNCTION__] ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); // Soumission du formulaire + } elseif ($this->isPost()) { $categoryId = $this->getInput('categoryAddTitle', helper::FILTER_ID, true); $this->setData([ 'category', @@ -479,22 +503,27 @@ class course extends common 'redirect' => helper::baseUrl() . 'course/category', 'notification' => helper::translate('Catégorie créée'), 'state' => true - ]); - } + ]); // Valeurs en sortie - // Valeurs en sortie + } $this->addOutput([ 'title' => helper::translate('Ajouter une catégorie'), 'view' => 'categoryAdd' ]); + } public function categoryEdit() { - - // Soumission du formulaire if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) === true && + // Accès limité aux admins + $this->getUser('group') !== self::$actions[__FUNCTION__] + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); // Soumission du formulaire + } elseif ( $this->isPost() ) { $categoryId = $this->getUrl(2); @@ -521,9 +550,9 @@ class course extends common public function categoryDelete() { - // Accès refusé if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + // Accès limité aux admins + $this->getUser('group') !== self::$actions[__FUNCTION__] ) { // Valeurs en sortie $this->addOutput([ @@ -554,11 +583,12 @@ class course extends common public function users() { - // Profil limité au propriétaire ou admis + $courseId = $this->getUrl(2); + + // Accès limité au propriétaire, admin ou éditeurs isncrits + if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ @@ -718,11 +748,12 @@ class course extends common public function usersAdd() { - // Profil limité au propriétaire ou admis + // Contenu sélectionné + $courseId = $this->getUrl(2); + + // Accès limité au propriétaire ou éditeurs inscrits ou admin if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ @@ -730,9 +761,6 @@ class course extends common ]); } - // Contenu sélectionné - $courseId = $this->getUrl(2); - // Inscription des utilisateurs cochés if ( isset($_POST['courseUsersAddSubmit']) @@ -861,12 +889,12 @@ class course extends common */ public function userDelete() { + // Contenu sélectionné + $courseId = $this->getUrl(2); - // Profil limité au propriétaire ou admis + // Accès limité au propriétaire ou admin ou éditeurs inscrits if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ @@ -892,6 +920,16 @@ class course extends common // Contenu sélectionné $courseId = $this->getUrl(2); + // Accès limité aux admins, à l'auteur ou éditeurs inscrits + if ( + $this->permissionControl(__FUNCTION__, $courseId) === false + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + // Inscription des utilisateurs cochés if ( isset($_POST['courseUsersDeleteSubmit']) @@ -1119,7 +1157,19 @@ class course extends common public function userHistory() { + // Espace sélectionné $courseId = $this->getUrl(2); + + // Accès limité au propriétaire ou éditeurs inscrits ou admin + if ( + $this->permissionControl(__FUNCTION__, $courseId) === false + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + $userId = $this->getUrl(3); $h = $this->getData(['enrolment', $courseId, $userId, 'history']); @@ -1196,6 +1246,16 @@ class course extends common $courseId = $this->getUrl(2); + // Accès limité au propriétaire ou éditeurs inscrits ou admin + if ( + $this->permissionControl(__FUNCTION__, $courseId) === false + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + self::$courseUsers = [ 0 => ['UserId', 'Prénom', 'Nom', 'Page Titre', 'Consultation Date', 'Consultation Heure', 'Progression'] ]; @@ -1293,6 +1353,16 @@ class course extends common $courseId = $this->getUrl(2); $userId = $this->getUrl(3); + // Accès limité au propriétaire ou éditeur inscrit ou admin + if ( + $this->permissionControl(__FUNCTION__, $courseId) === false + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + // Traitement de l'historique $h = $this->getData(['enrolment', $courseId, $userId, 'history']); @@ -1487,18 +1557,18 @@ class course extends common public function backup() { - // Profil limité au propriétaire ou admis + // Espace sélectionné + $courseId = $this->getUrl(2); + + // Accès limité aux admins, à l'auteur ou éditeurs inscrits if ( - $this->getUser('group') === self::GROUP_EDITOR - && $this->getUser('id') != $this->getData(['course', $this->getUrl(2), 'author']) - || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true + $this->permissionControl(__FUNCTION__, $courseId) === false ) { // Valeurs en sortie $this->addOutput([ 'access' => false ]); } else { - $courseId = $this->getUrl(2); // Participants avec historiques $enrolment = $this->getData(['enrolment', $courseId]); @@ -1551,9 +1621,22 @@ class course extends common public function restore() { + + // Espace sélectionné + $courseId = $this->getUrl(2); + + // Accès limité aux admins, à l'auteur ou éditeurs inscrits + if ( + $this->permissionControl(__FUNCTION__, $courseId) === false + ) { + // Valeurs en sortie + $this->addOutput([ + 'access' => false + ]); + } + // Soumission du formulaire if ( - $this->getUser('permission', __CLASS__, __FUNCTION__) === true && $this->isPost() ) { @@ -1663,37 +1746,32 @@ class course extends common } + /** - * Autorise l'accès à un contenu - * @param @return bool le user a le droit d'entrée dans le contenu - * @param string $userId identifiant de l'utilisateur - * @param string $courseId identifiant du contenu sollicité + * Retourne false quand l'utilisateur ne dispose pas des droits d'accès à la fonction + * Règles d'accès à un espace : + * Admin : tous les droits + * Editor : Inscrits dans le cours ou propriétaire */ - private function courseIsUserEnroled($courseId) + public function permissionControl($funtion, $courseId) { - $userId = $this->getUser('id'); - $group = $userId ? $this->getData(['user', $userId, 'group']) : null; - switch ($group) { + switch (self::$actions[$funtion]) { case self::GROUP_ADMIN: - $r = true; - break; + return ($this->getUser('group') === self::$actions[$funtion]); case self::GROUP_EDITOR: - $r = in_array($userId, array_keys($this->getData(['enrolment', $courseId]))); - break; - case self::GROUP_MEMBER: - $r = in_array($userId, array_keys($this->getData(['enrolment', $courseId]))); - break; - // Visiteur non connecté - case self::GROUP_VISITOR: - case null: - $r = $this->getData(['course', $courseId, 'enrolment']) === self::COURSE_ENROLMENT_GUEST; - break; + return ( + $this->getUser('group') >= self::$actions[$funtion] + && $this->getData(['enrolment', $courseId]) + && ($this->getUser('id') === $this->getData(['course', $courseId, 'author']) + || array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) ) + ); default: - $r = false; + return false; } - return $r; } + + /** * Autorise l'accès à un contenu * @param @return bool le user a le droit d'entrée dans le contenu @@ -1752,4 +1830,35 @@ class course extends common ]); } + /** + * Autorise l'accès à un contenu + * @param @return bool le user a le droit d'entrée dans le contenu + * @param string $userId identifiant de l'utilisateur + * @param string $courseId identifiant du contenu sollicité + */ + private function courseIsUserEnroled($courseId) + { + $userId = $this->getUser('id'); + $group = $userId ? $this->getData(['user', $userId, 'group']) : null; + switch ($group) { + case self::GROUP_ADMIN: + $r = true; + break; + case self::GROUP_EDITOR: + $r = in_array($userId, array_keys($this->getData(['enrolment', $courseId]))); + break; + case self::GROUP_MEMBER: + $r = in_array($userId, array_keys($this->getData(['enrolment', $courseId]))); + break; + // Visiteur non connecté + case self::GROUP_VISITOR: + case null: + $r = $this->getData(['course', $courseId, 'enrolment']) === self::COURSE_ENROLMENT_GUEST; + break; + default: + $r = false; + } + return $r; + } + } \ No newline at end of file diff --git a/core/module/course/view/manage/manage.php b/core/module/course/view/manage/manage.php index 1ccb676..7c7949a 100644 --- a/core/module/course/view/manage/manage.php +++ b/core/module/course/view/manage/manage.php @@ -7,46 +7,53 @@ ]); ?> -
-
- getUrl(2), [ - 'href' => helper::baseUrl() . 'course/users/' . $this->getUrl(2), - 'value' => 'Participants', - 'ico' => 'users' - ]); ?> -
-
- getUrl(2), [ +
+ permissionControl('users', $this->getUrl(2))): ?> +
+ getUrl(2), [ + 'href' => helper::baseUrl() . 'course/users/' . $this->getUrl(2), + 'value' => 'Participants', + 'ico' => 'users' + ]); ?> +
+ + permissionControl('edit', $this->getUrl(2))): ?> +
+ getUrl(2), [ 'href' => helper::baseUrl() . 'course/edit/' . $this->getUrl(2), 'value' => 'Éditer', 'ico' => 'pencil' ]); ?> -
-
- getUrl(2), [ - 'href' => helper::baseUrl() . 'course/clone/' . $this->getUrl(2), - 'value' => 'Cloner', - 'ico' => 'clone' - ]); ?> -
-
- getUrl(2), [ +
+ + permissionControl('backup', $this->getUrl(2))): ?> +
+ getUrl(2), [ 'href' => helper::baseUrl() . 'course/backup/' . $this->getUrl(2), 'value' => 'Sauvegarder', 'ico' => 'download-cloud' ]); ?> -
-
- getUrl(2), [ +
+ + permissionControl('clone', $this->getUrl(2))): ?> +
+ getUrl(2), [ + 'href' => helper::baseUrl() . 'course/clone/' . $this->getUrl(2), + 'value' => 'Cloner', + 'ico' => 'clone' + ]); ?> +
+ + permissionControl('delete', $this->getUrl(2))): ?> +
+ getUrl(2), [ 'class' => 'courseDelete buttonRed', 'href' => helper::baseUrl() . 'course/delete/' . $this->getUrl(2), 'value' => 'Supprimer', 'ico' => 'trash' ]); ?> -
+
+
@@ -121,11 +128,11 @@
- 'Participation', - 'selected' => $this->getdata(['course', $this->getUrl(2), 'enrolment']), - 'disabled' => true, - ]); ?> + 'Participation', + 'selected' => $this->getdata(['course', $this->getUrl(2), 'enrolment']), + 'disabled' => true, + ]); ?>