def test_management_command_with_dry_run(self): """Check that command works fine.""" ObjectAccess.objects.all().delete() mbox = models.Mailbox.objects.all()[0] # assert mbox has no owner self.assertIs(get_object_owner(mbox), None) # show problems. run in quiet mode because we dont want output in tests management.call_command("modo", "repair", "--quiet", "--dry-run") # assert its not fixed self.assertIs(get_object_owner(mbox), None)
def test_management_command(self): """Check that command works fine.""" ObjectAccess.objects.all().delete() mbox = models.Mailbox.objects.first() alias = models.Alias.objects.first() # assert mbox has no owner self.assertIs(get_object_owner(mbox), None) # fix it. run in quiet mode because we dont want output in tests ret = management.call_command("modo", "repair", "--quiet") assert ret is None # assert it's fixed self.assertIsNot(get_object_owner(mbox), None) self.assertIsNot(get_object_owner(alias), None)
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 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 on_account_modified(old, new): """Update limits when roles are updated""" owner = get_object_owner(old) if owner.group not in ["SuperAdmins", "Resellers"]: # Domain admins can't change the role so nothing to check. return if new.group != "SuperAdmins": # Check if account needs a pool (case: a superadmin is # downgraded) try: pool = new.limitspool except LimitsPool.DoesNotExist: p = LimitsPool(user=new) p.save() p.create_limits() if not new.group in ["DomainAdmins", "Resellers"]: move_pool_resource(owner, new) if old.oldgroup == "DomainAdmins": if new.group != "DomainAdmins": dec_limit(owner, 'domain_admins_limit') return if new.group == "DomainAdmins": check_limit(owner, 'domain_admins_limit') inc_limit(owner, 'domain_admins_limit')
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 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 on_account_modified(old, new): """Update limits when roles are updated""" owner = get_object_owner(old) if owner.group not in ["SuperAdmins", "Resellers"]: # Domain admins can't change the role so nothing to check. return if new.group != "SuperAdmins": # Check if account needs a pool (case: a superadmin is # downgraded) try: pool = new.limitspool except LimitsPool.DoesNotExist: p = LimitsPool(user=new) p.save() p.create_limits(owner) if new.group not in ["DomainAdmins", "Resellers"]: move_pool_resource(owner, new) if old.oldgroup == "DomainAdmins": if new.group != "DomainAdmins": dec_limit_usage(owner, 'domain_admins_limit') return if new.group == "DomainAdmins": check_limit(owner, 'domain_admins_limit') inc_limit_usage(owner, 'domain_admins_limit')
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 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(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 dec_nb_mailboxes(mailboxes): from modoboa.extensions.admin.models import Mailbox if isinstance(mailboxes, Mailbox): mailboxes = [mailboxes] for mailbox in mailboxes: owner = get_object_owner(mailbox) dec_limit_usage(owner, 'mailboxes_limit')
def dec_nb_domaliases(domainaliases): from modoboa.extensions.admin.models import DomainAlias if isinstance(domainaliases, DomainAlias): domainaliases = [domainaliases] for domainalias in domainaliases: owner = get_object_owner(domainalias) dec_limit_usage(owner, 'domain_aliases_limit')
def dec_nb_mbaliases(mailboxaliases): from modoboa.extensions.admin.models import Alias if isinstance(mailboxaliases, Alias): mailboxaliases = [mailboxaliases] for alias in mailboxaliases: owner = get_object_owner(alias) dec_limit_usage(owner, 'mailbox_aliases_limit')
def dec_nb_domaliases(domainaliases): from modoboa.admin.models import DomainAlias if isinstance(domainaliases, DomainAlias): domainaliases = [domainaliases] for domainalias in domainaliases: owner = get_object_owner(domainalias) dec_limit(owner, 'domain_aliases_limit')
def dec_nb_mailboxes(mailboxes): from modoboa.admin.models import Mailbox if isinstance(mailboxes, Mailbox): mailboxes = [mailboxes] for mailbox in mailboxes: owner = get_object_owner(mailbox) dec_limit(owner, 'mailboxes_limit')
def on_account_modified(old, new): """Update limits when roles are updated""" owner = get_object_owner(old) if owner.role not in ["SuperAdmins", "Resellers"]: # Domain admins can't change the role so nothing to check. return if new.role not in ["DomainAdmins", "Resellers"]: move_pool_resource(owner, new)
def move_pool_resource(sender, account, role, **kwargs): """Move remaining resource to owner if needed.""" owner = permissions.get_object_owner(account) if not owner or owner.is_superuser or owner.role != "Resellers": # Domain admins can't change the role so nothing to check. return if role not in ["DomainAdmins", "Resellers"]: utils.move_pool_resource(owner, account)
def on_account_deleted(account): owner = get_object_owner(account) if not owner.group in ["SuperAdmins", "Resellers"]: return move_pool_resource(owner, account) if account.group == "DomainAdmins": dec_limit(owner, 'domain_admins_limit')
def on_account_deleted(account, byuser, **kwargs): owner = get_object_owner(account) if owner.group not in ["SuperAdmins", "Resellers"]: return move_pool_resource(owner, account) if account.group == "DomainAdmins": dec_limit_usage(owner, 'domain_admins_limit')
def dec_nb_domains(domain): owner = get_object_owner(domain) dec_limit(owner, 'domains_limit') for domalias in domain.domainalias_set.all(): dec_nb_domaliases(domalias) for mailbox in domain.mailbox_set.all(): dec_nb_mailboxes(mailbox) for mbalias in domain.alias_set.all(): dec_nb_mbaliases(mbalias)
def on_account_modified(old, new): """Update limits when roles are updated""" owner = get_object_owner(old) if owner.group not in ["SuperAdmins", "Resellers"]: # Domain admins can't change the role so nothing to check. return if new.group not in ["DomainAdmins", "Resellers"]: move_pool_resource(owner, new)
def save(self): owner = get_object_owner(self.account) for ltpl in LimitTemplates().templates: if ltpl[0] not in self.cleaned_data: continue l = self.account.limitspool.limit_set.get(name=ltpl[0]) if not owner.is_superuser: self.allocate_from_pool(l, owner.limitspool) l.maxvalue = self.cleaned_data[ltpl[0]] l.save()
def dec_nb_domains(domain, owner=None): if owner is None: owner = get_object_owner(domain) dec_limit_usage(owner, 'domains_limit') for domalias in domain.domainalias_set.all(): dec_nb_domaliases(domalias) for mailbox in domain.mailbox_set.all(): dec_nb_mailboxes(mailbox) for mbalias in domain.alias_set.all(): dec_nb_mbaliases(mbalias)
def save(self): owner = get_object_owner(self.account) for name, ltpl in utils.get_user_limit_templates(): fieldname = "{}_limit".format(name) if fieldname not in self.cleaned_data: continue l = self.account.userobjectlimit_set.get(name=name) if not owner.is_superuser: self.allocate_from_user(l, owner) l.max_value = self.cleaned_data[fieldname] l.save()
def save(self): owner = get_object_owner(self.account) for name, ltpl in utils.get_limit_templates(): fieldname = "{}_limit".format(name) if fieldname not in self.cleaned_data: continue l = self.account.objectlimit_set.get(name=name) if not owner.is_superuser: self.allocate_from_user(l, owner) l.max_value = self.cleaned_data[fieldname] l.save()
def create_pool(user): owner = get_object_owner(user) if owner.group not in ['SuperAdmins', 'Resellers']: return if user.group == 'DomainAdmins': check_limit(owner, 'domain_admins_limit') inc_limit_usage(owner, 'domain_admins_limit') if user.group in ['DomainAdmins', 'Resellers']: p, created = LimitsPool.objects.get_or_create(user=user) p.create_limits(owner)
def save(self): from modoboa.lib.permissions import get_object_owner owner = get_object_owner(self.account) for ltpl in limits_tpl: if not ltpl[0] in self.cleaned_data: continue l = self.account.limitspool.limit_set.get(name=ltpl[0]) if not owner.is_superuser: self.allocate_from_pool(l, owner.limitspool) l.maxvalue = self.cleaned_data[ltpl[0]] l.save()
def create_pool_when_account_is_imported(user, account, row): owner = get_object_owner(account) if owner.group not in ['SuperAdmins', 'Resellers']: return if account.group == 'DomainAdmins': check_limit(owner, 'domain_admins_limit') inc_limit_usage(owner, 'domain_admins_limit') if account.group in ['DomainAdmins', 'Resellers']: p, created = LimitsPool.objects.get_or_create(user=account) p.create_limits(owner)
def save(self): owner = get_object_owner(self.account) for name, _definition in utils.get_user_limit_templates(): fieldname = "{}_limit".format(name) if fieldname not in self.cleaned_data: continue limit = self.account.userobjectlimit_set.get(name=name) if not owner.is_superuser: allocate_resources_from_user( limit, owner, self.cleaned_data[fieldname]) limit.max_value = self.cleaned_data[fieldname] limit.save(update_fields=["max_value"])
def create_pool(user): owner = get_object_owner(user) if not owner.is_superuser and \ not owner.belongs_to_group("Resellers"): return if user.belongs_to_group("DomainAdmins"): check_limit(owner, 'domain_admins_limit') inc_limit(owner, 'domain_admins_limit') if user.group in ["DomainAdmins", "Resellers"]: p = LimitsPool(user=user) p.save() p.create_limits()
def remove_admin(self, account): """Remove an administrator of this domain. :param User account: administrator to remove """ from modoboa.lib.permissions import \ ungrant_access_to_object, get_object_owner if get_object_owner(self) == account: events.raiseEvent('DomainOwnershipRemoved', account, self) ungrant_access_to_object(self, account) for mb in self.mailbox_set.all(): if mb.user.has_perm("admin.add_domain"): continue ungrant_access_to_object(mb, account) ungrant_access_to_object(mb.user, account) for al in self.alias_set.all(): ungrant_access_to_object(al, account)
def on_account_modified(old, new): owner = get_object_owner(old) if owner.group not in ["SuperAdmins", "Resellers"]: return if not new.group in ["DomainAdmins", "Resellers"]: move_pool_resource(owner, new) try: pool = new.limitspool except LimitsPool.DoesNotExist: p = LimitsPool(user=new) p.save() p.create_limits() if old.oldgroup == "DomainAdmins": if new.group != "DomainAdmins": dec_limit(owner, 'domain_admins_limit') return if new.group == "DomainAdmins": check_limit(owner, 'domain_admins_limit') inc_limit(owner, 'domain_admins_limit')
def dec_rdomaliases_count(rdomainaliases): if isinstance(rdomainaliases, RelayDomainAlias): rdomainaliases = [rdomainaliases] for rdomainalias in rdomainaliases: owner = get_object_owner(rdomainalias) dec_limit_usage(owner, 'relay_domain_aliases_limit')
def dec_relaydomains_count(rdomain): owner = get_object_owner(rdomain) dec_limit_usage(owner, 'relay_domains_limit') for rdomalias in rdomain.relaydomainalias_set.all(): dec_rdomaliases_count(rdomalias)
def move_resource(sender, user, **kwargs): """Move remaining resource to another user.""" owner = permissions.get_object_owner(user) if owner.is_superuser or owner.role != "Resellers": return utils.move_pool_resource(owner, user)
def dec_nb_mbaliases(mailboxaliases): if isinstance(mailboxaliases, Alias): mailboxaliases = [mailboxaliases] for alias in mailboxaliases: owner = get_object_owner(alias) dec_limit_usage(owner, 'mailbox_aliases_limit')
def dec_nb_mbaliases(mailboxalias): owner = get_object_owner(mailboxalias) dec_limit(owner, 'mailbox_aliases_limit')
def dec_nb_mailboxes(mailboxes): if isinstance(mailboxes, admin_models.Mailbox): mailboxes = [mailboxes] for mailbox in mailboxes: owner = get_object_owner(mailbox) dec_limit_usage(owner, 'mailboxes_limit')
def dec_nb_domaliases(domainaliases): if isinstance(domainaliases, DomainAlias): domainaliases = [domainaliases] for domainalias in domainaliases: owner = get_object_owner(domainalias) dec_limit_usage(owner, 'domain_aliases_limit')
def on_account_deleted(account, byuser, **kwargs): owner = get_object_owner(account) if owner.role not in ["SuperAdmins", "Resellers"]: return move_pool_resource(owner, account)
def dec_nb_mailboxes(mailboxes): if isinstance(mailboxes, Mailbox): mailboxes = [mailboxes] for mailbox in mailboxes: owner = get_object_owner(mailbox) dec_limit_usage(owner, 'mailboxes_limit')