diff --git a/cotisations/models.py b/cotisations/models.py index 5ba43452..8d8fb756 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -124,6 +124,8 @@ class Facture(FieldPermissionModelMixin, models.Model): def can_edit(self, user_request, *args, **kwargs): if not user_request.has_perm('cotisations.change_facture'): return False, u"Vous n'avez pas le droit d'éditer les factures" + elif not user_request.has_perm('cotisations.change_all_facture') and not self.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer les factures de cet user protégé" elif not user_request.has_perm('cotisations.change_all_facture') and\ (self.control or not self.valid): return False, u"Vous n'avez pas le droit d'éditer une facture\ @@ -134,6 +136,8 @@ class Facture(FieldPermissionModelMixin, models.Model): def can_delete(self, user_request, *args, **kwargs): if not user_request.has_perm('cotisations.delete_facture'): return False, u"Vous n'avez pas le droit de supprimer une facture" + if not self.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer les factures de cet user protégé" if self.control or not self.valid: return False, u"Vous ne pouvez pas supprimer une facture\ contrôlée ou invalidée par un trésorier" @@ -282,6 +286,8 @@ class Vente(models.Model): def can_edit(self, user_request, *args, **kwargs): if not user_request.has_perm('cotisations.change_vente'): return False, u"Vous n'avez pas le droit d'éditer les ventes" + elif not user_request.has_perm('cotisations.change_all_facture') and not self.facture.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer les factures de cet user protégé" elif not user_request.has_perm('cotisations.change_all_vente') and\ (self.facture.control or not self.facture.valid): return False, u"Vous n'avez pas le droit d'éditer une vente\ @@ -292,6 +298,8 @@ class Vente(models.Model): def can_delete(self, user_request, *args, **kwargs): if not user_request.has_perm('cotisations.delete_vente'): return False, u"Vous n'avez pas le droit de supprimer une vente" + if not self.facture.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer les factures de cet user protégé" if self.facture.control or not self.facture.valid: return False, u"Vous ne pouvez pas supprimer une vente\ contrôlée ou invalidée par un trésorier" diff --git a/machines/models.py b/machines/models.py index f2dedee9..226cd0cc 100644 --- a/machines/models.py +++ b/machines/models.py @@ -112,9 +112,10 @@ class Machine(FieldPermissionModelMixin, models.Model): :param self: instance machine à éditer :param user_request: instance user qui fait l'edition :return: True ou False avec la raison le cas échéant""" - if not user_request.has_perm('machines.change_machine') and self.user != user_request: - return False, u"Vous ne pouvez pas éditer une machine d'un autre user\ - que vous sans droit" + if self.user != user_request: + if not user_request.has_perm('machines.change_interface') or not self.user.can_edit(self.user, user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer une machine\ + d'un autre user que vous sans droit" return True, None def can_delete(self, user_request, *args, **kwargs): @@ -123,9 +124,10 @@ class Machine(FieldPermissionModelMixin, models.Model): :param self: instance machine à supprimer :param user_request: instance user qui fait l'edition :return: True ou False avec la raison de l'échec le cas échéant""" - if not user_request.has_perm('machines.delete_machine') and self.user != user_request: - return False, u"Vous ne pouvez pas éditer une machine d'un autre user\ - que vous sans droit" + if self.user != user_request: + if not user_request.has_perm('machines.change_interface') or not self.user.can_edit(self.user, user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer une machine\ + d'un autre user que vous sans droit" return True, None def can_view_all(user_request, *args, **kwargs): @@ -1287,9 +1289,10 @@ class Interface(models.Model): :param self: Instance interface à editer :param user_request: Utilisateur qui fait la requête :return: soit True, soit False avec la raison de l'échec""" - if not user_request.has_perm('machines.change_interface') and self.machine.user != user_request: - return False, u"Vous ne pouvez pas éditer une machine\ - d'un autre user que vous sans droit" + if self.machine.user != user_request: + if not user_request.has_perm('machines.change_interface') or not self.machine.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer une machine\ + d'un autre user que vous sans droit" return True, None def can_delete(self, user_request, *args, **kwargs): @@ -1298,9 +1301,10 @@ class Interface(models.Model): :param self: Instance interface à del :param user_request: Utilisateur qui fait la requête :return: soit True, soit False avec la raison de l'échec""" - if not user_request.has_perm('machines.delete_interface') and self.machine.user != user_request: - return False, u"Vous ne pouvez pas éditer une machine d'un autre\ - user que vous sans droit" + if self.machine.user != user_request: + if not user_request.has_perm('machines.change_interface') or not self.machine.user.can_edit(user_request, *args, **kwargs)[0]: + return False, u"Vous ne pouvez pas éditer une machine\ + d'un autre user que vous sans droit" return True, None def can_view_all(user_request, *args, **kwargs): diff --git a/users/forms.py b/users/forms.py index ac8e9923..74d6694e 100644 --- a/users/forms.py +++ b/users/forms.py @@ -450,7 +450,7 @@ class ListRightForm(ModelForm): class Meta: model = ListRight - fields = ['name', 'unix_name', 'permissions', 'details'] + fields = ['name', 'unix_name', 'critical', 'permissions', 'details'] def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) diff --git a/users/migrations/0068_auto_20180107_2245.py b/users/migrations/0068_auto_20180107_2245.py new file mode 100644 index 00000000..3ce232dc --- /dev/null +++ b/users/migrations/0068_auto_20180107_2245.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-01-07 21:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0067_serveurpermission'), + ] + + def transfer_permissions(apps, schema_editor): + critical_rights = ['adm', 'admin', 'bureau', 'infra', 'tresorier', 'serveur', 'bofh'] + db_alias = schema_editor.connection.alias + rights = apps.get_model("users", "ListRight") + for right in critical_rights: + rg = rights.objects.using(db_alias).filter(unix_name=right).first() + rg.critical=True + rg.save() + + def untransfer_permissions(apps, schema_editor): + return + + operations = [ + migrations.AlterModelOptions( + name='user', + options={'permissions': (('change_user_password', "Peut changer le mot de passe d'un user"), ('change_user_state', "Peut éditer l'etat d'un user"), ('change_user_force', 'Peut forcer un déménagement'), ('change_user_shell', "Peut éditer le shell d'un user"), ('change_user_groups', "Peut éditer les groupes d'un user ! Permission critique"), ('change_all_users', 'Peut éditer tous les users, y compris ceux dotés de droits. Superdroit'), ('view_user', 'Peut voir un objet user quelquonque'))}, + ), + migrations.AddField( + model_name='listright', + name='critical', + field=models.BooleanField(default=False), + ), + migrations.RunPython(transfer_permissions, untransfer_permissions), + ] diff --git a/users/models.py b/users/models.py index 9761cc20..83fb2788 100644 --- a/users/models.py +++ b/users/models.py @@ -233,6 +233,7 @@ class User(FieldPermissionModelMixin, AbstractBaseUser, PermissionsMixin): ("change_user_force", "Peut forcer un déménagement"), ("change_user_shell", "Peut éditer le shell d'un user"), ("change_user_groups", "Peut éditer les groupes d'un user ! Permission critique"), + ("change_all_users", "Peut éditer tous les users, y compris ceux dotés de droits. Superdroit"), ("view_user", "Peut voir un objet user quelquonque"), ) @@ -712,7 +713,19 @@ class User(FieldPermissionModelMixin, AbstractBaseUser, PermissionsMixin): else: return False, u"Vous n'avez pas le droit d'éditer ce club" else: - if self == user_request or user_request.has_perm('users.change_user'): + options, _created = AssoOption.objects.get_or_create() + if self == user_request: + return True, None + elif user_request.has_perm('users.change_all_users'): + return True, None + elif user_request.has_perm('users.change_user'): + if self.groups.filter(listright__critical=True): + return False, u"Utilisateurs avec droits critiques, ne peut etre édité" + elif self == options.utilisateur_asso: + return False, u"Impossible d'éditer l'utilisateur asso sans droit change_all_users" + else: + return True, None + elif user_request.has_perm('users.change_all_users'): return True, None else: return False, u"Vous ne pouvez éditer un autre utilisateur que vous même" @@ -1112,6 +1125,7 @@ class ListRight(Group): )] ) gid = models.PositiveIntegerField(unique=True, null=True) + critical = models.BooleanField(default=False) details = models.CharField( help_text="Description", max_length=255, diff --git a/users/templates/users/aff_listright.html b/users/templates/users/aff_listright.html index 080a7388..b8a8008c 100644 --- a/users/templates/users/aff_listright.html +++ b/users/templates/users/aff_listright.html @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,