Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dissocier les droits applicatifs des groupes Sugoi #634

Closed
3 of 12 tasks
EmmanuelDemey opened this issue May 30, 2024 · 9 comments · Fixed by #646
Closed
3 of 12 tasks

Dissocier les droits applicatifs des groupes Sugoi #634

EmmanuelDemey opened this issue May 30, 2024 · 9 comments · Fixed by #646
Assignees

Comments

@EmmanuelDemey
Copy link
Collaborator

EmmanuelDemey commented May 30, 2024

Cette carte vise à mettre en œuvre le résultat des ateliers du séminaire RMéS de juin 2023 sur la gestion des droits.
L'objectif est de dissocier les droits appliqués dans l'application Bauhaus des groupes Sugoi (ie de ne plus avoir les groupes dans le code de l'application) afin de rendre possible d'autres organisation du travail pour les utilisateurs de Bauhaus sans changer le code de l'application.

Le principe de base serait de paramétrer quelque part (dans un fichier de configuration probablement) les droits associés aux groupes Sugoi et par ailleurs de gérer les droits dans l'application suivant des fonctionnalités de base : créer (C), lire (R), modifier (U), supprimer (D), et aussi publier (P) voire valider (V) [actuellement il n'y a pas de différence entre publier et valider]

Pour chaque action de l'utilisateur, le contrôle d'autorisation serait fonction des droits de l'utilisateurs, calculés à partir de son appartenance à différents groupes et des droits indiqués dans le fichier de paramètre pour ces groupes.
Par exemple, pour créer un concept, l'utilisateur devrait appartenir à un groupe autorisé à créer (C) un concept.

La description des droits associés à un groupe Sugoi est une matrice avec en ligne les différents types d'objets (concepts, séries, opérations, nomenclatures...) et en colonne les différents droits (créer, lire, modifier...), Chaque élément de la matrice peut prendre trois valeurs : "autorisé sans restriction", "autorisé selon le timbre de l'utilisateur" et "non autorisé".
Les droits de l'utilisateurs correspondent à la matrice contenant le droit le plus élevé de tous les groupes auxquels il appartient.

La forme du fichier de paramétrage est à définir mais il pourrait être un fichier json, ne contenant pas les "non autorisés" (qui n'ont pas d'intérêt).
Par exemple en reprenant de façon simplifiés quelques groupes actuels (et en se restreignant aux modules concepts et opérations), il pourrait ressembler à :

{
	"Administrateur_RMESGNCS": {
		"concept": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"collection": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"family": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"serie": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"operation": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"indicator": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"sims": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"},
		"classification": {"create": "A", "read": "A", "update": "A", "delete": "A", "publish": "A", "validate": "A"}
	},
	"Utilisateur_RMESGNCS": {
		"concept": {"read": "A"},
		"collection": {"read": "A"},
		"family": {"read": "A"},
		"serie": {"read": "A"},
		"operation": {"read": "A"},
		"indicator": {"read": "A"},
		"sims": {"read": "A"},
		"classification": {"read": "A"}
	},
	"Gestionnaire_concept_RMESGNCS": {
		"concept": {"create": "B", "read": "B", "update": "B", "publish": "B", "validate": "B"}
	},
	"Gestionnaire_ensemble_concepts_RMESGNCS": {
		"concept": {"create": "A", "read": "A", "update": "A", "publish": "A", "validate": "A"}
	},
	"Gestionnaire_serie_RMESGNCS": {
		"serie": {"read": "B", "update": "B", "publish": "B", "validate": "B"},
		"operation": {"create": "B", "read": "B", "update": "B", "publish": "B", "validate": "B"},
		"sims": {"create": "B", "read": "B", "update": "B", "publish": "B", "validate": "B"}
	},
	"Gestionnaire_indicateur_RMESGNCS": {
		"serie": {"read": "B", "update": "B", "publish": "B", "validate": "B"},
		"indicator": {"create": "B", "read": "B", "update": "B", "publish": "B", "validate": "B"},
		"sims": {"create": "B", "read": "B", "update": "B", "publish": "B", "validate": "B"}
	},
}

(toutes les valeurs sont à débattre, en particulier A et B pour les deux niveaux d'autorisation, tenant compte ou non du timbre de l'utilisateur)

Cette modification est probablement assez importante en volume. Il est possible de la découper en plusieurs cartes. Par exemple en commençant par gérer le fichier de paramétrage, puis le calcul des droits de l'utilisateurs, puis en prenant en compte petit à petit ces droits dans les différents modules.

@EmmanuelDemey EmmanuelDemey linked a pull request May 30, 2024 that will close this issue
@FBibonne
Copy link
Member

@ChristopheYon

Dans le cas des droits de création d'une ressource, pour les gestionnaires, il paraît difficile de faire une vérification sur le timbre de la ressource avant l'opération puisqu'elle n'existe pas. Ou bien doit-on s'attendre à trouver le timbre dans le payload du POST ?

A l'issue de l'opérationn, la ressource aura bien le timbre de son créateur.

En partant d'une principe que la création d'une ressource n'est donc pas contingentée à timbre pour les gestionnaires, voici comment nous avons défini les droits d'un rôle gestionnaire (avec notre propre langage) :

    Gestionnaire_jeu_donnees_RMESGNCS:
      dataset:
        delete: STAMP
        update: STAMP
        validate: STAMP
        publish: STAMP
        create: ALL
        read: STAMP

Est-ce que ça te va ?

@FBibonne
Copy link
Member

Question similaire pour des endpoints comme GET /datasets/archivageUnits : je propose de n'autoriser le endpoint que pour les utilisateurs qui ont une stratégie de READ à ALL comme ça renvoie tous les stamps sauf erreur de ma part ? Ceux qui ont une stratégie STAMP se verront refuser l'accès

@ChristopheYon
Copy link

@ChristopheYon

Dans le cas des droits de création d'une ressource, pour les gestionnaires, il paraît difficile de faire une vérification sur le timbre de la ressource avant l'opération puisqu'elle n'existe pas. Ou bien doit-on s'attendre à trouver le timbre dans le payload du POST ?

A l'issue de l'opérationn, la ressource aura bien le timbre de son créateur.

En partant d'une principe que la création d'une ressource n'est donc pas contingentée à timbre pour les gestionnaires, voici comment nous avons défini les droits d'un rôle gestionnaire (avec notre propre langage) :

Gestionnaire_jeu_donnees_RMESGNCS:
  dataset:
    delete: STAMP
    update: STAMP
    validate: STAMP
    publish: STAMP
    create: ALL
    read: STAMP

Est-ce que ça te va ?

@FBibonne

Je pense que ce n'est pas au niveau du paramétrage des droits que se situe la différence entre la création et les autres opérations mais au niveau de la signification des droits en question.

Effectivement, la différence essentielle de l'opération de création avec les autres est qu'on n'a pas de ressource existante. Donc si on peut bien vérifier que l'utilisateur possède ou non le droit pour ce type d'opération et pour le type d'objet (comme pour les autres opérations), on ne peut pas ajouter (pour le type de droits STAMP) de vérification sur l'existant (qui n'existe pas).

Par contre la distinction fonctionnellement utile entre le type de droits ALL et le type de droits STAMP dans le cas de la création, c'est que le premier autorise l'utilisateur à créer pour n'importe quel timbre alors que le second ne l'autorise à créer que pour son propre timbre propre.

Cela correspond au rôle "d'administrateur" de l'équipe RMéS qui peut créer des opérations ou des concepts pour le compte d'autres unités (et qui est même seule à pouvoir le faire pour les concepts). Et cela assure que les "gestionnaires" ne peuvent créer que pour leur propre compte.
Par ailleurs, cela assure la cohérence avec les autres opérations : un utilisateur avec le droit ALL pour la création et pour la modification pourra créer et modifier les mêmes ressources (et n'aura pas besoin de reprendre en modification un ressource pour l'affecter à un autre timbre mais pourra le faire dès la création).

Par contre ce besoin fonctionnel est probablement difficile à mettre en place techniquement, en particulier de façon unifiée alors que la gestion des "timbres propriétaires" ne semble pas cohérente pour les différents types d'objets. Il y a peut-être une mise en cohérence à faire à ce niveau là.

@ChristopheYon
Copy link

Question similaire pour des endpoints comme GET /datasets/archivageUnits : je propose de n'autoriser le endpoint que pour les utilisateurs qui ont une stratégie de READ à ALL comme ça renvoie tous les stamps sauf erreur de ma part ? Ceux qui ont une stratégie STAMP se verront refuser l'accès

J'aurais plutôt pensé qu'avec la stratégie STAMP, on n'afficherait que les ressources appartenant au timbre de l'utilisateur (et toutes les ressources avec la stratégie ALL). Mais outre la question technique, c'est probablement fonctionnellement à débattre.

@FBibonne
Copy link
Member

FBibonne commented Aug 13, 2024

Si je comprends bien, tu proposes d'implémenter les règles suivantes :

  • Un utilisateur avec la stratégie STAMP ne peut créer de ressource que pour son timbre
  • Un utilisateur avec la stratégie ALL peut créer des ressources pour n'importe quel timbre

Pour les GET qui renvoient tous les éléments d'une ressource, tu proposes de limiter aux ressources qui ont le même timbre que l'utilisateur pour la stratégie STAMP. Ca peut avoir du sens pour répondre à un besoin de n'afficher que les entités correspondant au groupe de l'utilisateur. Après il faut que ce besoin soit traduit dans le front et ne pas oublier que l'application part du principe que tout le monde peut lire toutes les données et donc peut-être quand même laisser la possibilité de demander toutes les entités. D'autant plus que si on s'appuie sur les privilèges comme tout le monde a le rôle "Utilisateur_RMESGNCS", tout le monde a le droit de lecture sur tout et ça "écraseé systématiquement le droit READ: STAMP que peut avoir un gestionnaire.

Un éclaircissement pour finir : tu écris :

Cela correspond au rôle "d'administrateur" de l'équipe RMéS qui peut créer des opérations ou des concepts pour le compte d'autres unités (et qui est même seule à pouvoir le faire pour les concepts)

Je comprends seuls les administrateurs peuvent créer des concepts et donc eux seuls possèdent le privilège de CREATE pour le module CONCEPT. Pourtant dans le fichier exemple de configuration, tu as un rôle "Gestionnaire_concept_RMESGNCS" et un rôle "Gestionnaire_ensemble_concepts_RMESGNCS" qui ont un privilège de CREATE pour CONCEPT : il y a quelque chose que j'ai mal compris ?

@ChristopheYon
Copy link

Si je comprends bien, tu proposes d'implémenter les règles suivantes :

  • Un utilisateur avec la stratégie STAMP ne peut créer de ressource que pour son timbre
  • Un utilisateur avec la stratégie ALL peut créer des ressources pour n'importe quel timbre

Oui, exactement

Pour les GET qui renvoient tous les éléments d'une ressource, tu proposes de limiter aux ressources qui ont le même timbre que l'utilisateur pour la stratégie STAMP. Ca peut avoir du sens pour répondre à un besoin de n'afficher que les entités correspondant au groupe de l'utilisateur. Après il faut que ce besoin soit traduit dans le front et ne pas oublier que l'application part du principe que tout le monde peut lire toutes les données et donc peut-être quand même laisser la possibilité de demander toutes les entités. D'autant plus que si on s'appuie sur les privilèges comme tout le monde a le rôle "Utilisateur_RMESGNCS", tout le monde a le droit de lecture sur tout et ça "écraseé systématiquement le droit READ: STAMP que peut avoir un gestionnaire.

Oui, c'est en partie pour ça que je dis que c'est à débattre : comme a priori tout le monde a le rôle d'utilisateur et donc le droit de lecture sur tout, la question de ce qui se passe quand on n'a pas ce droit est probablement assez théorique.

Un éclaircissement pour finir : tu écris :

Cela correspond au rôle "d'administrateur" de l'équipe RMéS qui peut créer des opérations ou des concepts pour le compte d'autres unités (et qui est même seule à pouvoir le faire pour les concepts)

Je comprends seuls les administrateurs peuvent créer des concepts et donc eux seuls possèdent le privilège de CREATE pour le module CONCEPT. Pourtant dans le fichier exemple de configuration, tu as un rôle "Gestionnaire_concept_RMESGNCS" et un rôle "Gestionnaire_ensemble_concepts_RMESGNCS" qui ont un privilège de CREATE pour CONCEPT : il y a quelque chose que j'ai mal compris ?

Ce sont sans doute des exemples mal choisis de ma part : ces deux groupes "Gestionnaire_concept_RMESGNCS" et "Gestionnaire_ensemble_concepts_RMESGNCS" existent déjà dans Sugoi, avec (probablement) des droits de gestion sur les concepts qui correspondent à ce que j'ai mis dans les exemples : "Gestionnaire_concept_RMESGNCS" peut manipuler les concepts de son timbre et "Gestionnaire_ensemble_concepts_RMESGNCS" peut manipuler tous les concepts. Et l'objectif de la présente carte est bien de faire en sorte de pouvoir mettre en place ce genre de rôle (par exemple pour d'autres objets) en modifiant un fichier de paramètre plutôt qu'en modifiant l'application à chaque fois.
Mais dans la réalité, ces groupes sont vides dans Sugoi et les seuls utilisateurs qui manipulent réellement les concepts sont ceux du groupe "Administrateur_RMESGNCS", c'est à dire l'équipe métier RMéS (et quelques guests dont une partie de l'équipe informatique).

@HugoBouttes
Copy link
Contributor

@ChristopheYon une autre petite question:

Que faire des autres modules que nous avons sur Bauhaus et qui ne sont pas actuellement gérés dans RBAC, par exemple DATASET & CODE_LIST, doit-on rajouter des rôles temporaires pour les gérer ? Doit-on compléter le rôle Administrateur_RMESGNCS pour gérer les modules manquants ? Ou bien ce n'est pas d'actualité pour le moment.

@ChristopheYon
Copy link

@ChristopheYon une autre petite question:

Que faire des autres modules que nous avons sur Bauhaus et qui ne sont pas actuellement gérés dans RBAC, par exemple DATASET & CODE_LIST, doit-on rajouter des rôles temporaires pour les gérer ? Doit-on compléter le rôle Administrateur_RMESGNCS pour gérer les modules manquants ? Ou bien ce n'est pas d'actualité pour le moment.

(désolé, je n'avais pas vu la question. Je crois que la messagerie Insee bloque les notifications de GitHub...)
Oui, je pense qu'en attendant la mise en place du RBAC pour tous les modules, il faut avoir des rôles temporaires qui permettent d'accéder aux modules pas encore passés. Mais je pensais que c'était déjà le cas.
Et ensuite, il faudra effectivement compléter la matrice du rôle Administrateur_RMESGNCS pour donner les droits sur tous les modules.

@GtanSndil
Copy link
Contributor

vu avec Christophe à l'occasion de la rédaction du DAT :
Gestionnaire_jeu_donnees_RMESGNCS:
dataset:
delete: STAMP
update: STAMP
validate: STAMP
publish: STAMP
create: STAMP (et non ALL)
read: STAMP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants