Mapper des listes de contrôle d'accès

Bien que cela ne soit pas une exigence absolue, il est vivement recommandé d'indexer les éléments du dépôt d'entreprise en se basant sur leurs listes de contrôle d'accès (LCA). Cela permet de s'assurer que les utilisateurs ayant accès à un élément seront les seuls à pouvoir le voir dans un résultat de recherche. Le principe consiste à modéliser les LCA de votre dépôt et à les inclure lors de l'indexation des éléments de ce dernier. Le SDK Content Connector propose un vaste choix de méthodes suffisamment performantes pour modéliser les LCA de la plupart des dépôts.

Créer une LCA

La procédure de création d'une LCA comprend deux étapes :

  1. Créer un objet Principal à l'aide des méthodes statiques de la classe Acl
  2. Utiliser la classe Acl.Builder pour créer la LCA à partir du compte principal

Pour modéliser et créer des LCA, vous avez besoin de maîtriser d'autres notions comme l'héritage et les conteneurs. Celles-ci sont abordées dans la suite de ce document.

Créer un compte principal à l'aide d'un ID externe

Dans Google Cloud Search, les utilisateurs et les groupes doivent être associés à des adresses e-mail Google. Or, lors de l'indexation des éléments du dépôt, il se peut que des connecteurs de contenu soient associés à des adresses autres que Google. Le SDK Content Connector vous permet d'indexer un élément à l'aide d'un ID externe (autorisant l'accès d'un utilisateur ou d'un groupe aux éléments du dépôt), au lieu d'une adresse e-mail. Pour créer des comptes principaux à l'aide d'ID externes, servez-vous de la méthode getUserPrincipal() ou getGroupPrincpal(). La classe ACL propose d'autres méthodes statiques pour créer des objets Principal.

Héritage des LCA

La notion d'héritage des LCA renvoie au fait d'accorder une autorisation, pour un élément et un utilisateur donnés, après avoir combiné les LCA de l'élément et celles de sa chaîne d'héritage. Cette décision repose sur des règles qui varient en fonction du dépôt et des propriétés de l'élément.

Définir l'héritage

Chaque élément peut être associé à des comptes principaux autorisés directs et à des comptes principaux refusés directs, définis via les méthodes setReaders() et setDeniedReaders(). Le terme "compte principal autorisé direct" désigne un utilisateur identifié dans une LCA lui accordant un accès direct à un élément spécifique. À l'inverse, un compte principal refusé direct fait référence à un utilisateur identifié dans une LCA qui lui refuse cet accès.

Un élément peut également hériter de comptes principaux autorisés indirects et de comptes principaux refusés indirects via la méthode setInheritFrom(). Le terme "compte principal autorisé indirect" désigne un utilisateur disposant d'un accès indirect à un élément spécifique grâce à l'héritage de la LCA. Un compte principal refusé indirect est un utilisateur qui se voit refuser cet accès par ce même mécanisme d'héritage.

La figure 1 explique le mécanisme d'héritage des comptes principaux autorisés et refusés indirects via la méthode setInheritFrom().

Représentation des connexions entre les éléments
Figure 1. Méthode setInheritFrom().

Les contrôles d'accès suivants sont représentés sur la figure 1 :

  • L'utilisateur 1 est un compte principal autorisé direct de l'élément A.
  • L'utilisateur 2 est un compte principal autorisé direct de l'élément B.
  • L'élément B hérite de la LCA de l'élément A.

Voici les règles qui découlent des contrôles d'accès :

  • L'utilisateur 1 n'a pas besoin d'être défini explicitement comme compte principal de l'élément B pour être un compte principal autorisé indirect de cet élément. Il hérite en effet de l'accès pour les raisons suivantes : il a été désigné comme compte principal autorisé direct de l'élément A et l'élément B hérite de la LCA de l'élément A.
  • Par contre, l'utilisateur 2 n'est pas un compte principal autorisé indirect de l'élément A.

Définir le type d'héritage

Si vous définissez l'héritage à l'aide de la méthode setInheritFrom(), vous devez indiquer le type d'héritage via la méthode setInheritanceType(). Le type d'héritage fait référence à la règle qui détermine comment la LCA d'un élément enfant est combinée avec celle de l'élément parent. L'énumération Acl.InheritanceType met en œuvre trois types d'héritage :

  • BOTH_PERMIT : définissez le type d'héritage sur BOTH_PERMIT pour permettre à un utilisateur d'accéder à l'élément uniquement lorsque la LCA de l'élément enfant et la LCA héritée de l'élément parent lui accordent cet accès.

  • CHILD_OVERRIDE : définissez le type d'héritage sur CHILD_OVERRIDE pour que la LCA de l'élément enfant prévale sur la LCA héritée de l'élément parent en cas de conflit entre les deux listes. En supposant que la LCA de l'élément parent refuse l'accès à l'utilisateur (lecteur refusé) et que celui-ci dispose d'un accès à l'élément enfant comme lecteur, l'utilisateur peut encore accéder à l'élément. À l'inverse, s'il est un lecteur refusé de l'élément enfant, il n'a pas d'autorisation d'accès même si la LCA de l'élément parent la lui accorde.

  • PARENT_OVERRIDE : définissez le type d'héritage sur PARENT_OVERRIDE pour que la LCA de l'élément parent prévale sur celle de l'élément enfant en cas de conflit entre les deux listes. En supposant que la LCA de l'élément enfant refuse l'accès à l'utilisateur (lecteur refusé) et que celui-ci dispose d'un accès à l'élément parent comme lecteur, l'utilisateur peut encore accéder à l'élément. À l'inverse, s'il est un lecteur refusé de l'élément parent, il n'a pas d'autorisation d'accès même si la LCA de l'élément enfant la lui accorde.

L'ordre dans lequel une chaîne d'héritage de LCA est évaluée influe sur la décision finale (autorisation ou refus). Dans Cloud Search, l'évaluation de la chaîne s'effectue de la feuille vers la racine. Une feuille est d'abord évaluée, puis son parent, et ainsi de suite jusqu'à la racine.

Conteneurs et suppression d'éléments

Il est possible de désigner comme conteneur un élément à indexer en utilisant la méthode setContainer() de la classe IndexingItemBuilder. La relation conteneur/contenu permet de hiérarchiser physiquement les éléments, en particulier afin de gérer correctement leur suppression. Lorsqu'un conteneur est supprimé, les éléments qu'il contient le sont également.

Les relations de conteneur sont totalement indépendantes des règles d'héritage des LCA. Par exemple, un fichier d'un système de fichiers peut se trouver dans un dossier à supprimer, mais hériter de la LCA d'un autre dossier. La suppression d'un dossier ne supprime pas les éléments qui héritent de la LCA de ce dossier, sauf si ce dernier figure également dans l'arborescence de conteneurs.

Les contrôles d'accès suivants sont représentés sur la figure 2 :

  • L'utilisateur 1 est un compte principal autorisé direct de l'élément A.
  • L'utilisateur 2 est un compte principal autorisé direct de l'élément B.
  • L'utilisateur 3 est un compte principal autorisé direct de l'élément C.
  • L'élément C hérite de la LCA de l'élément A.
  • L'élément B désigne l'élément A comme son conteneur.
  • L'élément C désigne l'élément B comme son conteneur.

Voici les règles qui découlent des contrôles d'accès :

  • L'accès indirect est accordé par la méthode setInheritFrom(). Par conséquent, l'utilisateur 1 peut accéder à l'élément C, car ce dernier hérite de la LCA de l'élément A.
  • L'accès indirect ne découle pas du fait que l'élément C soit contenu dans l'élément B. Par conséquent, l'utilisateur 2 n'a pas accès à l'élément C.
Représentation des connexions entre les éléments
Figure 2. Méthode setInheritFrom()

S'il vous est possible de modéliser un tel éventail de structures, c'est précisément grâce à cette séparation entre l'héritage des LCA et l'arborescence de conteneurs.

Après la suppression d'un élément :

  • tout élément ayant désigné l'élément supprimé comme son conteneur est exclu de l'index de recherche (sa suppression de la source de données de Google est alors programmée) ;
  • tout élément ayant désigné l'élément supprimé via la méthode setInheritFrom() est exclu de l'index de recherche.

Si une ressource est liée à un élément supprimé via la méthode setInheritFrom(), mais à aucun conteneur défini par setContainer(), ou si son arborescence de conteneurs n'inclut aucun élément supprimé, cet élément et ses données sont toujours présents dans la source de données de Google. C'est alors à vous de supprimer l'élément.

La figure 3 illustre la procédure de suppression pour une arborescence d'éléments.

Représentation des connexions entre les éléments
Figure 3. Suppression d'un élément et héritage des LCA

Les contrôles d'accès suivants sont représentés sur la figure 3 :

  • L'utilisateur 1 est un compte principal autorisé direct de l'élément A.
  • L'utilisateur 2 est un compte principal autorisé direct de l'élément D.
  • Les éléments D et E héritent tous deux de la LCA de l'élément A.
  • L'élément D désigne l'élément A comme son conteneur.
  • Les éléments A et E sont des éléments de niveau racine, car ils n'ont pas d'élément conteneur.

L'opération de suppression est répercutée en cascade au niveau des références de conteneur. Ainsi, en cas de suppression de l'élément A :

  • plus aucun descendant de la référence setInheritFrom() n'est accessible, et ce pour tous les utilisateurs ;
  • aucun utilisateur ne peut accéder à l'élément A ;
  • l'élément D est implicitement supprimé (aucun utilisateur ne peut y accéder) ;
  • l'élément E n'est pas supprimé, car l'opération de suppression n'est répercutée qu'au niveau des références de conteneur ;
  • l'élément E est exclu de l'index de recherche (aucun utilisateur ne peut lancer une recherche sur cet élément).