cancel
Showing results for 
Search instead for 
Did you mean: 

Conditionner les actions possibles via CIFS ou Webdav

mlagneaux
Champ on-the-rise
Champ on-the-rise
Bonjour,

Je travaille actuellement sur une application basée sur Alfresco 3.2r Community. Dans cette application, j'ai modifié le modèle de telle manière qu'un statut est associé à chaque document : il s'agit d'une propriété pouvant prendre différentes valeurs (Brouillon, Approuvé, Obsolète, …).

Dans l'application, j'ai conditionné la possibilité de réaliser différentes actions en fonction de la valeur du statut (via l'utilisation de classes héritant de BaseActionEvaluator). Ainsi, un document au statut Approuvé ou Obsolète n'est pas modifiable à moins d'en créer une nouvelle version (le versioning est activé sur tous les documents) : les actions permettant de modifier un document sont donc masquées dans ce cas.

Mon problème est que les utilisateurs peuvent également utiliser CIFS et Webdav pour éditer les documents.

Est-il possible de conditionner les actions réalisées via CIFS ou Webdav ?

Plus précisément et en prenant un exemple concret :
J'ai un document à l'état Approuvé dans mon application : les actions permettant de modifier ce document (par exemple "Mettre à jour") n'apparaissent pas grâce au evaluators. Seule l'action "Editer hors ligne" apparaît et va obliger mon utilisateur à créer une nouvelle version.
Le problème est que, si je passe par CIFS, rien ne m'empêche d'ouvrir ce document, de le modifier et de le sauvegarder alors que cela ne devrait pas être possible compte-tenu de son statut.

Dans ce cas précis, lors de l'ouverture d'un document via CIFS ou Webdav, une solution pourrait être par exemple d'ouvrir le document en lecture seule s'il présente un statut Approuvé ou Obsolète et de l'ouvrir en écriture s'il est au statut Brouillon. Cela est-il possible ? Si oui, comment peut-on s'y prendre pour le développer ?

Une autre piste : peut-on configurer CIFS pour que tous les documents soient ouverts en lecture seule par défaut et développer une nouvelle "action" (semblables au fichier .exe disponibles dans les répertoires lors d'un accès par CIFS) permettant d'ouvrir un document en écriture ?

Merci d'avance pour votre aide.
4 REPLIES 4

rguinot
Confirmed Champ
Confirmed Champ
Pour rendre les documents en lecture seule par défaut, c'est possible, voir ici : http://wiki.alfresco.com/wiki/File_Server_ACLs
Pour le reste, ce sera probablement du développement, peut être via les DynamicAuthority, ou les PolicyComponent qui vous permettra de binder des comportements particuliers pour certains types d'évenement (voir NodeServicePolicies, ContentServicePolicies, ..), et sur certains QName.

mlagneaux
Champ on-the-rise
Champ on-the-rise
Tout d'abord merci pour ces pistes. Je ne connaissais pas les dynamicAuthority.

Dans un premier temps, j'ai pu effectuer le test suivant :
- J'ai mis en commentaires le permissionGroup WriteContent dans le permissionGroup Write. Ainsi, les collaborateurs ne peuvent plus modifier le contenu d'un noeud par défaut ;

      <permissionGroup name="Write" expose="true" allowFullControl="false">
           <includePermissionGroup type="sys:base" permissionGroup="WriteProperties"/>
           <!–
           <includePermissionGroup type="sys:base" permissionGroup="WriteContent"/>
            –>
      </permissionGroup> 
- J'ai créé une dynamicAuthority qui donne l'authority ROLE_WRITER_ACCORDING_STATUS en fonction du statut du document. Cette authority dispose du permissionGroup WriteContent
<globalPermission permission="WriteContent" authority="ROLE_WRITER_ACCORDING_STATUS" />

Ci-dessous le code de la méthode hasAuthority de ma classe :

   public boolean hasAuthority(final NodeRef nodeRef, String userName) {
      System.out.println("WriterAccordingStatusDynamicAuthority#hasAuthority("+nodeRef+", "+userName+")");
        return AuthenticationUtil.runAs(new RunAsWork<Boolean>(){

            public Boolean doWork() throws Exception
            {
                boolean hasAuthority = true;
               
               // find its type so we can see if it's a node we are interested in
                QName type = nodeService.getType(nodeRef);
               
              // make sure the type is defined in the data dictionary
              TypeDefinition typeDef = dictionaryService.getType(type);

              if (typeDef != null)
              {
                 // Look for Content node
                 if (dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT)){
                    String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
                    System.out.println("WriterAccordingStatusDynamicAuthority#hasAuthority => Type CONTENT : "+name);
                    // Get the status of the node
                    String status = (String)nodeService.getProperty(nodeRef, CeaModel.PROP_STATUS);
                    
                    // If the status is different from draft or approval in progress, the authority is denied
                    if(!CeaModel.STATUS_DRAFT.equals(status) && !CeaModel.STATUS_APPROVAL_IN_PROGRESS.equals(status)){
                       hasAuthority = false;
                    }
                 }
              }
              System.out.println("WriterAccordingStatusDynamicAuthority#hasAuthority => "+hasAuthority);
              return hasAuthority;
               
            }}, AuthenticationUtil.getSystemUserName());
   }

Cela fonctionne bien comme je voulais. Cela me permet en effet de donner le droit de modifier le contenu d'un noeud uniquement si le statut du noeud le permet.

Je bloque maintenant sur le point suivant : cette solution donne la permission WriteContent à l'utilisateur même si celui-ci n'est que Lecteur du noeud.

J'ai essayé de solutionner ce problème de la façon suivante :
- J'ai décommenté le permissionGroup WriteContent dans le permissionGroup Write.
- J'ai créé une nouvelle permission et le permissionGroup associé :

      <permissionGroup name="WriteAccordingStatus" expose="false" allowFullControl="false" />

      <permission name="_WriteAccordingStatus" expose="false">
         <grantedToGroup permissionGroup="WriteAccordingStatus" />
      </permission>
- J'ai modifié la permission _WriteContent. J'ai ajouté un tag requiredPermission :

      <permission name="_WriteContent" expose="false">
         <grantedToGroup permissionGroup="WriteContent" />
         <!– Commented out parent permission check …
         <requiredPermission on="parent" name="_ReadChildren" implies="false"/>
         –>
         <requiredPermission on="node" name="_WriteAccordingStatus" implies="false"/>
      </permission>
- J'ai mis en commentaires ma globalPermission sur l'authority ROLE_WRITER_ACCORDING_STATUS.

Avec ce paramétrage, ma permission _WriteAccordingStatus n'étant jamais accordée, je pensais qu'aucun de mes users n'aurait la permission WriteContent (du fait de la requiredPermission). Or, ce n'est pas le cas.
Je pense avoir raté quelque chose concernant le paramétrage des permissions.

Comment faut-il procéder pour donner le droit WriteContent uniquement aux utilisateurs Collaborateurs ayant un permissionGroup que j'affecte avec ma dynamicAuthority ?

D'autre part, je me pose une question concernant les administrateurs, les coordinateurs et le propriétaire d'un noeud. Dans la configuration, ils disposent tous les 3 de la permission FullControl. A terme, j'aurais besoin de leur enlever le droit WriteContent. La 1ère solution qui me vient à l'esprit est de définir un permissionGroup FullControlWithoutWriteContent où je reprends le permissionGroup Collaborator (que j'aurais modifié suite à ma 1ère question) et j'y ajoute tous les permissions restantes.
Y a-t-il une façon plus simple de faire ?


Merci d'avance pour votre aide sur ce sujet.

mlagneaux
Champ on-the-rise
Champ on-the-rise
Tout d'abord, via CIFS, un document est ouvert en écriture si l'utilisateur dispose de la permission Write (et non simplement WriteContent comme je le pensais).

J'ai pu répondre à mon problème de la façon suivante :
- J'ai modifié ma dynamicAuthority : en plus de contrôler le statut du document, elle vérifie également que l'utilisateur est soit Collaborateur, soit Coordinateur soit Propriétaire. Je me suis basé pour cela sur l'exemple fourni dans le post suivant du forum Alfresco anglais.
http://forums.alfresco.com/en/viewtopic.php?f=47&t=17436&p=60903&hilit=dynamicAuthority#p60903

- Au niveau de la définition des permissions:
L'authority donnée par ma classe dynamicAuthority donne la permissions Write à l'utilisateur.
Cette permission Write n'inclut plus que la permission WriteContent et ne fait plus partie de la permission Collaborateur. J'ai par contre inclus la permission WriteProperties dans la permission Collaborateur.
D'autre part, j'ai défini une nouvelle permissions CustomFullControl qui inclut Collborateur et toutes les autres permissions restantes (Delete, Execute, ChangePermissions, …).
J'ai également modifié la permission Coordinateur : celle-ci inclut maintenant la permission CustomFullControl et j'ai passé allowFullControl à false.
Pour finir, la globalPermission associée à ROLE_OWNER donne maintenant la permission CustomFullControl.

- Au niveau de certaines JSP et certaines actions, j'ai remplacé le permissionEvaluator sur Write par un permissionEvaluator sur WriteProperties.

Après pas mal de tests, cela semble fonctionner correctement. Je pense n'avoir rien cassé avec toutes mes modifs.
Merci à rguinot de m'avoir orienté sur les dynamicAuthority.

rguinot
Confirmed Champ
Confirmed Champ
Cool !  Si vous souhaitez packager et contribuer votre code pour la communauté, n'hésitez pas à créer un projet sur la forge Smiley Happy (forge.alfresco.com)