localroles [How-To]
- les permissions affectées au profil sont modifiées par le Manager depuis
le Folder constituant le point de départ de la hiérarchie à impacter ;
cela a un effet sur tous les utilisateurs bénéficiant du même rôle ... cela peut augmenter les risques d'erreur de manipulation ... - tous les utilisateurs ne devant pas être impactés, le Manager crée localement
des "acl_users" où il redéclare quelques utilisateurs en leur affectant un rôle
supplémentaire ...
mais cela va compliquer sa gestion des utilisateurs, et rendre délicat la réalisation de fonctions de personnalisation (changement de password par exemple ...).
La gestion de "local roles" permet de s'affranchir de ces problèmes :
- on ne gère qu'un seul "acl_users", à la racine du site ;
- on envisage 2 sortes de "user defined roles" :
- les rôles fonctionnels locaux : "reviewer", "writer", etc.
- les catégories d'utilisateurs : "GroupA", "GroupB", etc.
Les "catégories" sont affectées dans l'"acl_users" ; elles s'appliquent à tout le site ; les "rôles fonctionnels" sont affectés depuis le Folder à partir duquel l'utilisateur doit jouir de ses privilèges étendus.
La catégorie et les privilèges locaux de l'utilisateur sont toujours disponibles :
Si l'utilisateur s'est identifié :
"_.SecurityGetUser().getUserName() != 'Anonymous User'"
Si l'utilisateur appartient à la catégorie "GroupA" :
"'GroupA' in _.SecurityGetUser().getRoles()"
ou encore :
"_.SecurityGetUser().has_role('GroupA')"
Et l'on peut évaluer les privilèges locaux, en faisant explicitement référence à l'objet (Folder ou DTMLDocument, ou autre) :
"_.SecurityGetUser().has_role('reviewer', mon_objet)"
Il est donc aisé de proposer des contenus, des liens ... en fonction de la configuration utilisateur.
Mais allons plus loin dans la manipulation conjointe des "groupes" et des "privilèges" locaux : il facile d'imaginer qu'au sein d'un groupe donné une personne joue un rôle d'animateur ; il pourrait être interessant de lui permettre de modifier la composition de son groupe, et d'attribuer à quelques membres des privilèges intermédiaires (mettre à jour ... ).
Voic quelques indications, fortement teintée DTML/PythonScript (que les fans de ZPT me pardonnent ...) :
Pour lister les membres d'un groupe :
""""
listUserGroup(Group)
Script Python pour récupérer la liste des utilisateurs bénéficiants du rôle ("user defined") 'Group'
paramètre : 'Group' (string)
""""
groupusers = []
users = context.acl_users.getUserNames()
for user in users:
if Group in context.acl_users.getUser(user).getRoles():
groupusers.append(user)
return groupusers
Affecter ou retirer le rôle 'GroupA' à un nouvel utilisateur ;
cette fonction est un "toggle" :
si le rôle est affecté, on aura appelé ce script pour retirer le rôle
sinon, on veut ajouter ce rôle
""""
Script Python pour affecter/retirer un rôle ("user defined") 'Group' à un utilisateur donné
paramètres : 'Group' (string), 'user'(string)
""""
def deleterole(roles, role):
newroles = []
for keep in roles:
if keep != role:
newroles.append(keep)
return newroles
newroles = []
roles = context.acl_users.getUser(user).getRoles():
if Group in roles
newroles = deleterole(roles, Group)
else:
newroles = roles.append(Group)
return newroles
Pour affecter le rôle local "writer" à l'un des utilisateurs :
"getattr(context, objet).manage_addLocalRoles(user, ('writer',))"
Pour retirer le privilège "writer", mais en conservant éventuellement d'autres rôles (en particulier 'Owner' ...) :
""""
Script Python pour retirer le "local role" 'Group' à un utilisateur donné sur un objet donné
paramètres : 'Group' (string), 'user'(string)
"""
def deleterole(roles, role):
newroles = []
for keep in roles:
if keep != role:
newroles.append(keep)
return newroles
newroles = []
roles = list(getattr(context, objet).get_local_roles_for_userid(user))
if 'writer' in roles
newroles = deleterole(roles, 'writer')
if len(newroles) == 0:
getattr(context, objet).manage_delLocalRoles((user,))
else:
getattr(context, objet).manage_setLocalRoles(user, newroles)
Ces deux derniers codes doivent être utilisés dans un script Python doté d'un "proxy role" 'Manager' ; seront déclarés en paramètres l'objet à impacter et le nom de l'utilisateur concerné.
Nota technique :
- la fonction "manage_delLocalRoles" demande une liste d'utilisateurs !
- l'utilisation de "getattr(obj, attr)" permet de s'assurer que l'objet impacté est bien transmis ...
Commentaires
Re: localroles
Posted by:
zopera
at
10/09/01
WAAAOOOUUU !!! Ca c'est de la contribution !!
MMEERRCCII !!!
Des petites précisions :
Concernant les conversions en ZPT, "_.SecurityGetUser()" est spécifique au DTML (et remplace l'ancien REQUEST/AUTHENTICATED_USER pour des questions de sécurité). En ZPT, on utilisera le nom "user". Par exemple : tal:condition="python:user.has_role(monRole)"
Concernant les local roles, pour éviter toute confusion, ils ne sont pas considérés si on ne précise pas un context. Il vaut mieux donc toujours donner un context pour ne pas les oublier. Par exemple :
- l'expression tal:condition="python:user.has_role(
monRole)" considère uniquement les roles fixés dans les acl_users. - l'expression tal:condition="python:user.has_role(
monRole,here)" considère tous les roles (ceux fixés dans les acl_users et ceux donnés en local role).

Log in
PloneArticle
Restreindre les meta_types d'un ObjectManager