From f554be11b03d6c187a25bbf33bf76e30e70c7ebf Mon Sep 17 00:00:00 2001 From: Laurent Panabieres <laurent.panabieres@veremes.com> Date: Wed, 7 Aug 2024 17:35:17 +0200 Subject: [PATCH] =?UTF-8?q?M=C3=A0j=20doc=20gestion=20des=20droits.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Màj doc gestion des droits. --- doc/source/administrator/rights/auth_token.md | 62 +++++++--------- doc/source/administrator/rights/data.md | 62 +++++++++------- doc/source/administrator/rights/privilege.md | 27 ++++--- .../administrator/rights/restriction.md | 69 +++++++++++------- .../auth_token/jeton_connexion_public.png | Bin 0 -> 11591 bytes 5 files changed, 125 insertions(+), 95 deletions(-) create mode 100644 doc/source/images/administrator/rights/auth_token/jeton_connexion_public.png diff --git a/doc/source/administrator/rights/auth_token.md b/doc/source/administrator/rights/auth_token.md index b3b03440..d8d2b4e3 100644 --- a/doc/source/administrator/rights/auth_token.md +++ b/doc/source/administrator/rights/auth_token.md @@ -1,30 +1,33 @@ # Gestion des jetons de connexion -Un jeton de connexion est une manière de permettre un accès à l'application, via le compte de la personne qui possède le jeton, sans avoir à fournir ses identifiants. - -L'avatange d'un jeton est qu'il ne donne aucunes informations sur l'utilisateur à la personne, et peut être désactivé à tout moment. +Un jeton de connexion est une manière d'accéder à l'application, via le compte d'un utilisateur, sans avoir à fournir ses identifiants. +Cette fonctionnalité est communément utilisé pour réaliser des `cartes ou applications publiques` (sans avoir à renseigner des informations de connexion). ## Utilité -Le jeton de connexion permet de faire tout ce que l'utilisateur lié au jeton peut faire, et est au centre de plusieurs fonctionnalités : +Un jeton de connexion permet : -- Il permet l'utilisation de l'API -- Il permet d'utiliser le mode public de vMap2, en étant connecté à l'application via cet utilisateur. -- Il permet d'utiliser les widgets. +- D'utiliser l'API +- D'utiliser vMap comme un utilisateur normal mais sans que ce dernier ait la nécessité de se loguer à l'application (carte publique) +- D'utiliser vMap sous forme de widget (intégrer vMap dans un site web). -## Création +## Création d'un jeton -Il est possible de créer un token dans l'interface prévue à cet effet, à l'emplacement "Utilisateurs" > "Jetons de connexion", puis de cliquer sur le bouton "Ajouter" pour ajouter un nouveau jeton de connexion. +Il est possible de créer un jeton de connexion depuis le bouton `Ajouter` présent dans le mode "Utilisateurs" > "Jetons de connexion".  -Il suffit ensuite de remplir les différents champs du formulaire pour créer le token : +Les informations demandées permettent ainsi de définir : + - Le nom du jeton de connexion + - S'il possède une date limite de fonctionnement + - Un login et mot de passe utilisateur permettant à l'application de se connecter `en tant que` l'utilisateur renseigné + - Et enfin une restriction de ce jeton sur une IP précise.  -## Utilisation +## Exemples d'utilisation -### Utilisation de l'API avec un jeton +### Utilisation d'un jeton dans l'API de vMap Il est possible, via un jeton utilisateur, de récupérer un jeton de connexion, permettant d'utiliser l'API de vMap2. @@ -40,20 +43,16 @@ Celui-ci peut ensuite être utilisé dans le reste des routes de l'API, dans le  -### Connexion au mode publique +### Utilisation d'un jeton pour faire une carte publique dans vMap + +Pour réaliser une connexion publique (sans couple login / mot de passe à renseigner) dans vMap, il est nécessaire de mettre en place un jeton de connexion et de renseigner ce jeton -Une autre des utilités des jetons est la mise en place du mode publique. -En effet, le mode public nécessite un jeton de connexion afin de pouvoir connecter l'utilisateur invité à l'application. -Pour ce faire, il suffit de paramétrer deux propriétés, dont une nécessitant le jeton de connexion : +Pour ce faire, 2 propriétés sont à paramétrer dans la section `Authetification` du mode `Configuration > Général.`. -```js -{ -... -"public_connect_enabled": false, -"public_connect_token": "", -... -} +```{figure} ../../images/administrator/rights/auth_token/jeton_connexion_public.png +:alt: Paramètre du mode public +:align: center ``` Une fois ces informations mises en place, il est possible d'accéder à l'application sans connexion de l'utilisateur. @@ -62,29 +61,24 @@ Une fois ces informations mises en place, il est possible d'accéder à l'applic :alt: mode_publique :align: center -Exemple d'application avec le mode publique +Exemple d'application avec le mode public ``` ### Création d'un widget carte -Dans vMap2, il est également possible de créer un widget carte qui permet d'intégrer des cartes dans d'autres sites WEB. - -Pour ce faire, il est absolument nécessaire d'avoir un jeton de connexion existant. +Dans vMap2, il est également possible de créer un `widget de type carte` permettant d'intégrer des cartes dans d'autres applications WEB. +Pour fonctionner, les widgets nécessitent un jeton de connexion existant. -Pour créer un widget, il faut se rendre dans "Cartes et Couches" > "Cartes". +Pour créer un widget, éditer une carte depuis le mode `Cartes et Couches` > `Cartes` de l'application :  -Il faut ensuite appuyer sur le crayon au niveau de la carte choisie, puis sur le formulaire. - -Une fois sur le formulaire d'édition de la carte, il faut se rendre dans le sous-menu "appel externe" et ajouter un nouvel enregistrement : +Se rendre dans la section `Appel externe`, y ajouter un nouvel enregistrement et y renseigner les informations demandées, notamment le jeton de connexion (indirectement le login de l'utilisateur) qui sera utilisé lors de chaque utilisation du widget :  -Une fois dans l'interface d'ajout, il suffit de remplir les différentes informations, en choisissant le bon token dans la liste déroulante. -  -Une fois le formulaire validé, le code pour intégrer la carte est disponible dans une nouvelle fenêtre dans le formulaire : +Une fois créé, l'application génère un code HTML qu'il suffit de copier / coller à l'endroit souhaité sur le site web :  \ No newline at end of file diff --git a/doc/source/administrator/rights/data.md b/doc/source/administrator/rights/data.md index 5eaa7a6a..3d75d924 100644 --- a/doc/source/administrator/rights/data.md +++ b/doc/source/administrator/rights/data.md @@ -1,26 +1,31 @@ # Les droits portant sur les données -La gestion des droits sur la donnée est une responsabilité administrateur, sa gestion revient donc à ceux-ci. - ## Introduction -Bien que les privilèges permettent l'accès à certaines fonctionnalités de l'application, et les groupes à certaines cartes et modèles d'impression, une autre notion importante à considérer quant à la gestion des droits, est la gestion des droits PostgreSQL. - -En effet, les droits PostgreSQL permettent à l'administrateur de définir quels sont les droits dont les utilisateurs disposent sur une donnée (une table/vue). +Bien que les privilèges et les groupes permettent d'accéder à certaines fonctionnalités de l'application, ces deux notions ne permettent pas de gérer l'accéssibilité à la données (lecture, saisie, modification, suppression). Cette notion là est gérée par le SGBD (Postgresql pour vMap) sur la donnée (table, vue, vue matérialisée...). Cela peut être réalisé en ligne de commande ou plus communément par l'intermédiaire d'un client de base de données (exemple : PgAdmin, Dbeaver...) -Rajouter des droits à ces éléments permet notamment à l’utilisateur final de pouvoir réaliser des actions différentes sur une donnée visualisée dans vMap2 (consultation, saisie, édition ou suppression d’une donnée géographique et attributaire). +Rajouter des droits à ces éléments permet ainsi à l’utilisateur final de pouvoir réaliser des actions différentes sur une donnée dans vMap2 (consultation, saisie, édition, suppression, d’une donnée géographique et / ou attributaire). -Une mauvaise gestion, ou un oubli de ceux-ci pourraient entraîner l'impossibilité pour un utilisateur d'exploiter certaines données dans vMap2. +Une mauvaise gestion, ou un oubli de ces droits pourraient entraîner l'impossibilité pour un utilisateur de visualiser, d'éditer, de saisir ou de supprimer une donnée. -## Fonctionnement +## Exemple -```{info} +```{note} Le tutoriel suivant est illustré avec le client SQL pgadmin. -Le fonctionnement peut différer légèrement pour d'autres clients (DBeaver, phpMyAdmin, ...). -Le principe est que le code SQL reste cependant le même. +Le principe est que quelque soit le client utilisé, le code SQL pour Postgresql reste le même. ``` -Pour cet exemple, j'aimerais rajouter le privilège `exploitant_ville` sur ma table `data_demo_vmap`.`f_villes_l93`, afin qu'un utilisateur ayant ce privilège puisse utiliser/mettre à jour/supprimer les données de ma couche `ville` utilisant cette table. +Pour cet exemple, nous souhaitons qu'un utilisateur ou groupe d'utilisateurs (appartenant au groupe `exploitant_ville`) puisse consulter, mettre à jour ou supprimer les données de la table `data_demo_vmap`.`f_villes_l93`. Pour cela voici les étapes : + + 1- Créer un rôle groupe (soit directement en base de données, soit via les privilèges de vMap) + 2- Associer l'utilisateur à ce rôle groupe + 3- Affecter les droits sur la table à ce rôle groupe + + + +j'aimerais rajouter le privilège `exploitant_ville` sur ma table `data_demo_vmap`.`f_villes_l93`, afin qu'un utilisateur ayant ce privilège puisse consulter, saisir/mettre à jour/supprimer les données de ma couche `ville` utilisant cette table. + +### 1- Créer un rôle groupe ```{note} Le fonctionnement et la création d'un privilège sont expliqués dans la [section suivante](./privilege.md). @@ -28,38 +33,45 @@ Le fonctionnement et la création d'un privilège sont expliqués dans la [secti  -Pour ajouter des droits sur une table, il faut tout d'abord ouvrir un client SQL. +### 2- Associer l'utilisateur à ce rôle groupe + +```{note} +La gestion d'un utilisateur ainsi que ses droits sont expliqués dans la [section suivante](../authentification/local_user.md). +``` -Il faut ensuite effectuer une connexion à la base de données contenant la structure de vMap2. +### 3- Affecter les droits sur la table à ce rôle groupe + + +Pour ajouter des droits sur une table, il faut tout d'abord ouvrir un client de base de données (exemple pgAdmin) et se connecter à la base de données.  -Une fois connecté, je navigue dans ma base via le menu latéral jusqu'à trouver la table concernée : +Une fois connecté, naviguer dans la base via le menu latéral jusqu'à trouver la table concernée :  -Une fois la table trouvée, il faut faire un clique droit dessus, option "properties...", dans la nouvelle fenêtre qui s'ouvre, cliquer sur l'onglet "Security". +Clic droit > Propriété, et se rendre dans l'onglet "Security" de la fenêtre qui s'ouvre.  -En cliquant sur le signe "+" de la ligne "Privileges", il m'est possible d'ajouter un nouvel utilisateur/groupe à ma table, je vais donc rajouter mon privilège `exploitant_ville`, avec les droits `SELECT`, `INSERT`, `UPDATE`, `DELETE` afin qu'il puisse gérer les données de la table. +Cliquer sur le signe "+" de la ligne "Privileges", sélectionner `exploitant_ville` dans la colonne `Grantee` afin de donner des droits au rôle groupe (et donc à l'ensemble des utilisateurs associés à ce rôle groupe) sur la table `data_demo_vmap`.`f_villes_l93`. - +```{note} +Il est possible d'ajouter des droits pour un utilisateur simple ou un groupe d'utilisateur. +``` -Une fois ceci fait, il me suffit de sauvegarder, et l'utilisateur ayant le privilège `exploitant_ville` pourra maintenant consulter, ajouter, mettre à jour et supprimer des données dans cette table. +Sélectionner les droits `SELECT`, `INSERT`, `UPDATE` et `DELETE` dans la colonne `Privilèges` pour donner les droits en consultation, création, mise à jour et suppression. Enregistrer. + + :::{admonition} **Gérer les droits en SQL** :class: dropdown important -Il est également possible d'atteindre le même résultat en pur SQL. - -En utilisant l'éditeur de requêtes, par exemple via ce bouton sur pgadmin: +Il est également possible d'atteindre le même résultat en SQL en utilisant l'éditeur de requêtes, par exemple via le bouton `Query Tool` sur pgadmin:  -Il est possible de rajouter les droits `SELECT`, `INSERT`, `UPDATE`, `DELETE` à la table `data_demo_vmap`.`f_villes_l93` pour le groupe `exploitant_ville` avec la requête suivante : - +La requête serait la suivante : ```sql GRANT SELECT, INSERT, UPDATE, DELETE ON data_demo_vmap.f_villes_l93 TO exploitant_ville; ``` -Cette requête aboutit au même résultat que les étapes au-dessus. ::: \ No newline at end of file diff --git a/doc/source/administrator/rights/privilege.md b/doc/source/administrator/rights/privilege.md index b61e7a16..3d419b00 100644 --- a/doc/source/administrator/rights/privilege.md +++ b/doc/source/administrator/rights/privilege.md @@ -1,7 +1,5 @@ # Les privilèges -Les privilèges sont une notion administrateur, leur gestion revient donc à ceux-ci. - ## Fonctionnement Les privilèges sont l'essence de l'application, ce sont ceux-ci qui permettent l'accès aux différentes fonctionnalités dans l'application. @@ -11,23 +9,32 @@ Il existe deux types de privilèges : - Les privilèges propres à l'application, ceux-ci ne doivent pas être modifiés, édités, ou supprimés, sous peine d'une impossibilité d'utiliser l'application par la suite. - Les privilèges créés par l'administrateur de l'application, qui servent souvent à limiter l'accès aux données. -## Privilèges de vMap +## Privilèges de l'application vMap vMap contient une liste de privilèges permettant d'autoriser l'accès à différentes parties de l'application : -- `vmap_user:` Il s'agit du droit le plus basique pour utiliser vMap, il permet l'accès à la cartographie, ainsi qu'à toutes les fonctionnalités associées à celle-ci (requêteur, filtre, sélection, ...). -- `vmap_admin:` Il permet d'accéder à la partie administration de l'application, c'est-à-dire l'ajout de couches/flux, la gestion de ceux-ci, la gestion des thèmes, des sources de données, des systèmes de coordonnées et des symboles et polices d'écriture. +- `vitis_user :` permet de se connecter à l'application et de configurer son utilisateur. -- `vmap_data_manager:` permet à l'utilisateur d'avoir accès au mode "tableau", et ses différentes fonctionnalités, à savoir ajouter, supprimer ou modifier de la donnée. +- `vitis_admin :` permet d'accéder à différents modes "super administrateur" de vMap permettant : + - de gérer les utilisateurs, domaines, groupes ou jetons de connexions + - de consulter les logs + - de consulter l'API + - et de configurer l'application de manière générale (propriétés générales sur l'authentification, l'interface, les traductions...) -En plus des privilèges vMap2, certains autres privilèges sont disponibles pour les accès aux fonctionnalités du noyau : +- `vmap_user :` permet d'accéder au mode "Carte" (à la cartographie) et donc à l'ensemble des fonctionnalités qui y sont disponibles (requêteur, filtre, sélection, ...). -- `vitis_user` : permet de se connecter à l'application et de configurer son utilisateur. +- `vmap_admin :` permet d'accéder à l'administration de vMap au sens "cartographie" c'est-à-dire + - la gestion des couches, cartes, thèmes, sources + - la gestion des flux (WMS et WFS) + - la gestion des symboles et polices d'écriture + - la gestion des sources de données + - la gestion des formulaires métier + - et enfin la gestion des impressions (modèles et styles) et rapports -- `vitis_admin` : permet l'accès aux modes pour gérer les utilisateurs, domaines, groupes, jetons de connexions, logs, modèles d'email, interface et configuration de l'application. Il a en charge la gestion des paramètres système et de la configuration de vMap2. Il accède également dans le mode API à la documentation relative à l'API de vMap2. +- `vmap_data_manager :` permet à l'utilisateur d'avoir accès au mode "tableau" et à ses différentes fonctionnalités. -- `vitis_shared` : permet de gérer l'arborescence du dossier shared, qui est un dossier partagé entre plusieurs utilisateurs pour partager des ressources. +- `vitis_shared :` permet de gérer l'arborescence du dossier shared, dossier partagé entre plusieurs utilisateurs pour s'échanger des ressources. ## Gestion des privilèges diff --git a/doc/source/administrator/rights/restriction.md b/doc/source/administrator/rights/restriction.md index d75fa343..5d2594d9 100644 --- a/doc/source/administrator/rights/restriction.md +++ b/doc/source/administrator/rights/restriction.md @@ -2,52 +2,54 @@ Les restrictions sont un principe qui permet à un adminstrateur de restreindre l'accès à un utilisateur, à certaines données uniquement, contre un peu de configuration côté application et base de données. -Ce principe est par exemple très utilisé au niveau des données cadastrales, afin de mettre en place des restrictions communale sur les données cadastrales, en renseignant par exemple le code INSEE d'une ou plusieurs communes, afin que l'utilisateur n'ait accès qu'aux données cadastrales nécessaires à son travail sur l'application. +Ce principe est par exemple très utilisé au niveau des données cadastrales, afin de mettre en place des restrictions communale en renseignant, par exemple, le code INSEE d'une ou plusieurs communes, afin que l'utilisateur ait seulement accès (en consultation et interrogation) aux données cadastrales de son territoire. ## Configuration -Pour saisir une restriction, il faut se rendre sur un utilisateur, dans la section "Utilisateurs" > "Utilisateurs" du menu latéral, puis de cliquer sur le bouton en forme de crayon à côté de l'utilisateur pour lequel il faut définir les restrictions. +Pour saisir une restriction, il faut se rendre dans la section "Utilisateurs" > "Utilisateurs" du menu latéral, puis éditer l'utilisateur sur lequel il faut définir une restruction (cliquer sur le bouton en forme de crayon à côté de l'utilisateur).  -Une fois dans l'interface de modifications, dans la section "Droits et restrictions", une section "restrictions" permet de définir les différentes restrictions qui seront appliquées sur les données. +Une fois dans l'interface de modifications, renseigner la restriction dans le champ `Restriction` de la section "Droits et restrictions".  +```{note} La bonne syntaxe pour la chaîne de caractères est un ensemble de chaînes de caractères, séparés par un séparateur (le caractère `|`). - -Par exemple, pour des restrictions communales, la bonne syntaxe serait un ensemble de code INSEE, séparés par le caractère `|`. +Par exemple, pour réaliser une restriction communales sur plusieurs communes, inscrire les Code INSEE séparés par le caractère `|`. ```sql 66106|66125|07324 ``` -Une fois cela fait, la restriction est en place, il reste maintenant à voir le paramétrage côté données (donc en base de données). +Une fois la restriction côté utilisateur réalisée, il reste désormais à configurer la base de données afin que cette dernière utilise la restriction. ## Paramétrage côté base de données -```{tip} -Les restrictions sur les données du cadastre sont déjà appliquées par défaut, étant une structure de données de Veremes. -L'ajout n'est nécessaire que dans le cas où vous voudriez appliquer la restriction à des données autres que le modèle de données du cadastre. -``` - -Maintenant que les restrictions sont mises en place côté utilisateur, il faut également s'assurer que la restriction est appliquée à la table, afin de bien filtrer les données retournées. +Côté base de données, les restrictions sont réalisées par l'intermédiaire de vues en utilisant une clause `WHERE`. -Pour ce faire, il va être nécessaire de faire une vue, avec un filtre en fonction de cette restriction. +#### Exemple -Pour cet exemple, je vais prendre une table des villes (`data_demo_vmap`.`f_villes_f93`) constituée des colonnes suivantes : +Dans cet exemple, nous allons travailler avec la table des villes (`data_demo_vmap`.`f_villes_f93`) constituée des colonnes suivantes :  -Je crée donc ensuite une vue, en cliquant droit sur "views" > "Create" > "View..." +Voici les étapes à réaliser : + + 1- Création de la vue + 2- Ajouter la clause `WHERE` en faisant référence à la restriction de l'utilisateur. + + +Pour créer la vue, cliquer droit sur "views" > "Create" > "View..."  -Il faut rentrer un nom, puis ensuite se rendre dans l'onglet "code" : +Entrer un nom, et se rendre dans l'onglet "code" :  -Puis il faut ensuite rentrer le code de la vue, en ajoutant le code suivant en tant que condition `WHERE` : +Dans l'onglet "Code", ajouter le code SQL suivant en adaptant le paramètre `[nom de la colonne]` : + ```sql WHERE [nom de la colonne] ~ similar_escape(( SELECT "user".restriction @@ -55,34 +57,49 @@ FROM s_vitis."user" WHERE "user".login::name = "current_user"()), NULL::text); ``` -Pour ma vue, le code suivant me permet de filtrer les villes : +```{note} +`[nom de la colonne]` correspond au nom du champ référencé dans le champ `Restriction` de l'utilisateur. +Exemple : `code_insee`, `code_com`, `code_dep`. +``` + +Dans notre exemple, le code suivant permet de filtrer les villes en fonction du champ `code` correspondant au `Code INSEE` de la commune: + ```sql -SELECT * FROM data_demo_vmap.f_villes_93 WHERE f_villes_93.code ~ similar_escape(( SELECT "user".restriction FROM s_vitis."user" WHERE "user".login::name = "current_user"()), NULL::text); ``` +Ce code SQL rajoute une condition WHERE à la vue dont l'aspect final est celui-ci : +  -Une fois cette vue créée, on peut voir que je ne récupère que les données filtrées par la restriction de mon utilisateur : + +#### Test + +Afin de tester si la restriction fonctionne, se connecter à la base de données et exécuter une requête `SELECT` sur la vue en changeant d'utilisateur (exemple ci-dessous avec l'utilisateur `kyllian`) :  -## Exemple dans le module Cadastre +## Les restrictions dans le module Cadastre. + +Tout le module cadastre de vMap utilise nativement les restrictions expliquées ci-dessous. Excepté le champ `Restriction` qui doit être paramétré par l'administrateur, aucune vue ne doit être configurée car tout est déjà réalisé par Veremes. + + +Pour le module cadastre, l'utilisation la plus commune est de restreindre, pour un utilisateur donné, l'accessibilité à une ou plusieurs communes du territoire chargé en base de données. -L'application la plus commune des restrictions est la limitation des données dans le module cadastre. +Les données du cadastre étant sensibles, il est indispensable qu'un utilisateur puisse consulter et surtout interroger uniquement les données dont il doit avoir l'accès. -Les données du cadastre étant sensibles, il est d'usage de limiter les données retournées à l'utilisateur au strict nécessaire. +#### Exemple -Voici un exemple avec le module cadastre sur les Pyrénées-Orientales. +Dans l'exemple ci-dessous, nous avons chargé les données cadastrales de l'ensemble des Pyrénées-Orientales. -Par défaut, sans restrictions, mon utilisateur a accès à la totalité des Pyrénées-Orientales. +Sans restriction (valeur `%` dans le champ `restriction` de l'utilisateur), un utilisateur a accès à la totalité des données des Pyrénées-Orientales.  -Une fois la restriction en place (pour celle-ci, `661316|66210`), seules les communes filtrées sont accessibles à l'utilisateur. +Une fois la restriction mise en place (pour celle-ci, `66136|66210`), seules les communes filtrées sont accessibles à l'utilisateur.  diff --git a/doc/source/images/administrator/rights/auth_token/jeton_connexion_public.png b/doc/source/images/administrator/rights/auth_token/jeton_connexion_public.png new file mode 100644 index 0000000000000000000000000000000000000000..58cfdf247bcd1a49bae0692644f59c7c57a35f11 GIT binary patch literal 11591 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 UK1#HMfq{X+)78&qol`;+0F!!Ih5!Hn literal 0 HcmV?d00001 -- GitLab