def update_permissions(sender, instance, **kwargs): """Permissions cleanup.""" request = get_request() # request migth be None (management command context) if request: from_user = request.user if from_user == instance: raise exceptions.PermDeniedException( _("You can't delete your own account") ) if not from_user.can_access(instance): raise exceptions.PermDeniedException # We send an additional signal before permissions are removed core_signals.account_deleted.send( sender="update_permissions", user=instance) owner = permissions.get_object_owner(instance) if owner == instance: # The default admin is being removed... owner = from_user # Change ownership of existing objects for ooentry in instance.objectaccess_set.filter(is_owner=True): if ooentry.content_object is not None: permissions.grant_access_to_object( owner, ooentry.content_object, True) permissions.ungrant_access_to_object( ooentry.content_object, instance) # Remove existing permissions on this user permissions.ungrant_access_to_object(instance)
def fix_owner(self, model, dry_run=False, **options): for obj in model.objects.all(): kw = dict( cls=model.__name__, obj=obj ) if get_object_owner(obj) is None: if dry_run: self.log( " {cls} {obj} has no owner".format(**kw), **options) else: if isinstance(obj, User): admin = User.objects.filter(is_superuser=True, is_active=True).first() elif isinstance(obj, models.Domain): admin = obj.admins.first() elif isinstance(obj, models.DomainAlias): admin = obj.target.admins.first() else: admin = obj.domain.admins.first() if not admin: # domain has no admin. use the first superuser found admin = User.objects.filter(is_superuser=True, is_active=True).first() grant_access_to_object(admin, obj, is_owner=True) kw['admin'] = admin self.log( " {cls} {obj} is now owned by {admin}".format(**kw), **options)
def role(self, role): """Set administrative role for this account :param string role: the role to set """ if role is None or self.role == role: return signals.account_role_changed.send( sender=self.__class__, account=self, role=role) self.groups.clear() if role == "SuperAdmins": self.is_superuser = True else: if self.is_superuser: ObjectAccess.objects.filter(user=self).delete() self.is_superuser = False try: self.groups.add(Group.objects.get(name=role)) except Group.DoesNotExist: self.groups.add(Group.objects.get(name="SimpleUsers")) if role != "SimpleUsers" and not self.can_access(self): from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(self, self) self.save() self._role = role
def account_auto_created(sender, user, **kwargs): """New account has been auto-created, build the rest.""" if not param_tools.get_global_parameter("auto_create_domain_and_mailbox"): return localpart, domname = split_mailbox(user.username) if user.role != "SimpleUsers" and domname is None: return sadmins = core_models.User.objects.filter(is_superuser=True) try: domain = models.Domain.objects.get(name=domname) except models.Domain.DoesNotExist: label = lib.check_if_domain_exists( domname, [(models.DomainAlias, _("domain alias"))]) if label is not None: return domain = models.Domain(name=domname, enabled=True, default_mailbox_quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: permissions.grant_access_to_object(su, domain) qset = models.Mailbox.objects.filter(domain=domain, address=localpart) if not qset.exists(): mb = models.Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) user.email = mb.full_address user.save(update_fields=["email"]) for su in sadmins[1:]: permissions.grant_access_to_object(su, mb)
def fix_owner(qs, dry_run=False, **options): """Fix ownership for orphan objects.""" model = qs.model for obj in qs: kw = {"cls": model.__name__, "obj": obj} if get_object_owner(obj) is not None: continue if dry_run: log(" {cls} {obj} has no owner".format(**kw), **options) continue if isinstance(obj, User): admin = User.objects.filter( is_superuser=True, is_active=True).first() elif isinstance(obj, models.Domain): admin = obj.admins.first() elif isinstance(obj, models.DomainAlias): admin = obj.target.admins.first() else: admin = obj.domain.admins.first() if not admin: # Fallback: use the first superuser found admin = User.objects.filter( is_superuser=True, is_active=True).first() grant_access_to_object(admin, obj, is_owner=True) kw["admin"] = admin log(" {cls} {obj} is now owned by {admin}".format(**kw), **options)
def account_auto_created(user): from modoboa.core.models import User from modoboa.lib.permissions import grant_access_to_object from .lib import check_if_domain_exists if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no": return localpart, domname = split_mailbox(user.username) if user.group != 'SimpleUsers' and domname is None: return sadmins = User.objects.filter(is_superuser=True) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: label = check_if_domain_exists(domname, [(DomainAlias, _('domain alias'))]) if label is not None: return domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def account_auto_created(sender, user, **kwargs): """New account has been auto-created, build the rest.""" if not param_tools.get_global_parameter("auto_create_domain_and_mailbox"): return localpart, domname = split_mailbox(user.username) if user.role != 'SimpleUsers' and domname is None: return sadmins = core_models.User.objects.filter(is_superuser=True) try: domain = models.Domain.objects.get(name=domname) except models.Domain.DoesNotExist: label = lib.check_if_domain_exists( domname, [(models.DomainAlias, _("domain alias"))]) if label is not None: return domain = models.Domain( name=domname, enabled=True, default_mailbox_quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: permissions.grant_access_to_object(su, domain) qset = models.Mailbox.objects.filter(domain=domain, address=localpart) if not qset.exists(): mb = models.Mailbox( address=localpart, domain=domain, user=user, use_domain_quota=True ) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: permissions.grant_access_to_object(su, mb)
def delete(self, fromuser, *args, **kwargs): """Custom delete method To check permissions properly, we need to make a distinction between 2 cases: * If the user owns a mailbox, the check is made on that object (useful for domain admins) * Otherwise, the check is made on the user """ from modoboa.lib.permissions import \ get_object_owner, grant_access_to_object, ungrant_access_to_object if fromuser == self: raise PermDeniedException( _("You can't delete your own account") ) if not fromuser.can_access(self): raise PermDeniedException owner = get_object_owner(self) for ooentry in self.objectaccess_set.filter(is_owner=True): if ooentry.content_object is not None: grant_access_to_object(owner, ooentry.content_object, True) events.raiseEvent("AccountDeleted", self, fromuser, **kwargs) ungrant_access_to_object(self) super(User, self).delete()
def update_permissions(sender, instance, **kwargs): """Permissions cleanup.""" request = get_request() # request migth be None (management command context) if request: from_user = request.user if from_user == instance: raise exceptions.PermDeniedException( _("You can't delete your own account")) if not from_user.can_access(instance): raise exceptions.PermDeniedException # We send an additional signal before permissions are removed core_signals.account_deleted.send(sender="update_permissions", user=instance) owner = permissions.get_object_owner(instance) if owner == instance: # The default admin is being removed... owner = from_user # Change ownership of existing objects for ooentry in instance.objectaccess_set.filter(is_owner=True): if ooentry.content_object is not None: permissions.grant_access_to_object(owner, ooentry.content_object, True) permissions.ungrant_access_to_object(ooentry.content_object, instance) # Remove existing permissions on this user permissions.ungrant_access_to_object(instance)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(creator, self, is_owner=True) events.raiseEvent("MailboxAliasCreated", creator, self) if creator.is_superuser: for admin in self.domain.admins: grant_access_to_object(admin, self)
def role(self, role): """Set administrative role for this account :param string role: the role to set """ if role is None or self.role == role: return signals.account_role_changed.send(sender=self.__class__, account=self, role=role) self.groups.clear() if role == "SuperAdmins": self.is_superuser = True else: if self.is_superuser: ObjectAccess.objects.filter(user=self).delete() self.is_superuser = False try: self.groups.add(Group.objects.get(name=role)) except Group.DoesNotExist: self.groups.add(Group.objects.get(name="SimpleUsers")) if role != "SimpleUsers" and not self.can_access(self): from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(self, self) self.save() self._role = role
def fix_owner(qs, dry_run=False, **options): """Fix ownership for orphan objects.""" model = qs.model for obj in qs: kw = {"cls": model.__name__, "obj": obj} if get_object_owner(obj) is not None: continue if dry_run: log(" {cls} {obj} has no owner".format(**kw), **options) continue if isinstance(obj, User): admin = User.objects.filter(is_superuser=True, is_active=True).first() elif isinstance(obj, models.Domain): admin = obj.admins.first() elif isinstance(obj, models.DomainAlias): admin = obj.target.admins.first() else: admin = obj.domain.admins.first() if not admin: # Fallback: use the first superuser found admin = User.objects.filter(is_superuser=True, is_active=True).first() grant_access_to_object(admin, obj, is_owner=True) kw["admin"] = admin log(" {cls} {obj} is now owned by {admin}".format(**kw), **options)
def account_auto_created(user): from modoboa.core.models import User from modoboa.lib.permissions import grant_access_to_object from .lib import check_if_domain_exists if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no": return localpart, domname = split_mailbox(user.username) if user.group != 'SimpleUsers' and domname is None: return sadmins = User.objects.filter(is_superuser=True) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: label = check_if_domain_exists( domname, [(DomainAlias, _('domain alias'))]) if label is not None: return domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox( address=localpart, domain=domain, user=user, use_domain_quota=True ) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def delete(self, fromuser, *args, **kwargs): """Custom delete method To check permissions properly, we need to make a distinction between 2 cases: * If the user owns a mailbox, the check is made on that object (useful for domain admins) * Otherwise, the check is made on the user """ from modoboa.lib.permissions import \ get_object_owner, grant_access_to_object, ungrant_access_to_object if fromuser == self: raise PermDeniedException(_("You can't delete your own account")) if not fromuser.can_access(self): raise PermDeniedException owner = get_object_owner(self) for ooentry in self.objectaccess_set.filter(is_owner=True): if ooentry.content_object is not None: grant_access_to_object(owner, ooentry.content_object, True) ungrant_access_to_object(ooentry.content_object, self) events.raiseEvent("AccountDeleted", self, fromuser, **kwargs) ungrant_access_to_object(self) super(User, self).delete()
def account_auto_created(user): from modoboa.core.models import User from modoboa.lib.permissions import grant_access_to_object localpart, domname = split_mailbox(user.username) if user.group != 'SimpleUsers' and domname is None: return sadmins = User.objects.filter(is_superuser=True) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox( address=localpart, domain=domain, user=user, use_domain_quota=True ) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def fix_permissions(): from modoboa.admin.models.domain import Domain from modoboa.admin.models.mailbox import Mailbox from modoboa.lib.permissions import grant_access_to_object for d in Domain.objects.all(): print('Fixing %r' % d) mailboxes = Mailbox.objects.filter(domain=d) for admin in d.admins: for mailbox in mailboxes: grant_access_to_object(admin, mailbox) grant_access_to_object(admin, mailbox.user)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object super(Mailbox, self).post_create(creator) if creator.is_superuser and not self.user.has_perm("admin.add_domain"): # A super user is creating a new mailbox. Give # access to that mailbox (and the associated # account) to the appropriate domain admins, # except if the new account has a more important # role (SuperAdmin, Reseller) for admin in self.domain.admins: grant_access_to_object(admin, self) grant_access_to_object(admin, self.user)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object super(Mailbox, self).post_create(creator) conditions = (creator.has_perm("admin.add_mailbox"), not self.user.has_perm("admin.add_domain")) if all(conditions): # An admin is creating a new mailbox. Give # access to that mailbox (and the associated # account) to the appropriate domain admins, # except if the new account has a more important # role (SuperAdmin, Reseller) for admin in self.domain.admins: if admin == creator: continue grant_access_to_object(admin, self) grant_access_to_object(admin, self.user)
def populate_callback(user, group='SimpleUsers'): """Populate callback If the LDAP authentication backend is in use, this callback will be called each time a new user authenticates succesfuly to Modoboa. This function is in charge of creating the mailbox associated to the provided ``User`` object. :param user: a ``User`` instance """ from modoboa.lib.permissions import grant_access_to_object sadmins = User.objects.filter(is_superuser=True) user.set_role(group) user.post_create(sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, user) events.raiseEvent("AccountAutoCreated", user)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object super(Mailbox, self).post_create(creator) conditions = ( creator.has_perm("admin.add_mailbox"), not self.user.has_perm("admin.add_domain") ) if all(conditions): # An admin is creating a new mailbox. Give # access to that mailbox (and the associated # account) to the appropriate domain admins, # except if the new account has a more important # role (SuperAdmin, Reseller) for admin in self.domain.admins: if admin == creator: continue grant_access_to_object(admin, self) grant_access_to_object(admin, self.user)
def add_admin(self, account): """Add a new administrator for this domain :param User account: the administrotor to add """ from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(account, self) for mb in self.mailbox_set.all(): if mb.user.has_perm("admin.add_domain"): continue grant_access_to_object(account, mb) grant_access_to_object(account, mb.user) for al in self.alias_set.all(): grant_access_to_object(account, al)
def populate_callback(user): """Populate callback If the LDAP authentication backend is in use, this callback will be called each time a new user authenticates succesfuly to Modoboa. This function is in charge of creating the mailbox associated to the provided ``User`` object. :param user: a ``User`` instance """ from modoboa.lib.permissions import grant_access_to_object sadmins = User.objects.filter(is_superuser=True) user.set_role("SimpleUsers") user.post_create(sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, user) localpart, domname = split_mailbox(user.username) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def test_update_resources(self): """Update resources.""" url = reverse("api:resources-detail", args=[self.reseller.pk]) response = self.client.get(url) resources = response.data resources.update({"domains": 1000, "mailboxes": 1000}) response = self.client.put(url, resources) self.assertEqual(response.status_code, 200) self.assertEqual( self.reseller.userobjectlimit_set.get(name="domains").max_value, 1000) # As domain admin => fails self.client.credentials( HTTP_AUTHORIZATION="Token {}".format(self.da_token.key)) resources.update({"domains": 2, "mailboxes": 2}) url = reverse("api:resources-detail", args=[self.user.pk]) response = self.client.put(url, resources) self.assertEqual(response.status_code, 404) # As reseller => ok permissions.grant_access_to_object(self.reseller, self.user, True) self.client.credentials( HTTP_AUTHORIZATION="Token {}".format(self.r_token.key)) resources.update({"domains": 500, "mailboxes": 500}) url = reverse("api:resources-detail", args=[self.user.pk]) response = self.client.put(url, resources) self.assertEqual(response.status_code, 200) self.assertEqual( self.user.userobjectlimit_set.get(name="domains").max_value, 500) self.assertEqual( self.reseller.userobjectlimit_set.get(name="domains").max_value, 502) resources.update({"domains": 1003}) response = self.client.put(url, resources) self.assertEqual(response.status_code, 424)
def add_admin(self, account): """Add a new administrator to this domain. :param User account: the administrator """ from modoboa.lib.permissions import grant_access_to_object core_signals.can_create_object.send( sender=self.__class__, context=self, object_type="domain_admins") grant_access_to_object(account, self) for mb in self.mailbox_set.all(): if mb.user.has_perm("admin.add_domain"): continue grant_access_to_object(account, mb) grant_access_to_object(account, mb.user) for al in self.alias_set.all(): grant_access_to_object(account, al)
def post_create(self, creator): grant_access_to_object(creator, self, is_owner=True)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(creator, self, is_owner=True) events.raiseEvent("AccountCreated", self)
def post_create(self, creator): """Grant permission on this user to creator.""" from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(creator, self, is_owner=True)
def post_create(self, creator): grant_access_to_object(creator, self, is_owner=True) events.raiseEvent("%sCreated" % self.objectname, creator, self)
def post_create(self, creator): from modoboa.lib.permissions import grant_access_to_object super(Alias, self).post_create(creator) if creator.is_superuser: for admin in self.domain.admins: grant_access_to_object(admin, self)