Exemple #1
0
class AccountPermissionsForm(forms.Form, DynamicForm):
    domains = DomainNameField(
        label=ugettext_lazy("Domain(s)"),
        required=False,
        help_text=ugettext_lazy("Domain(s) that user administrates"))

    def __init__(self, *args, **kwargs):
        if "instance" in kwargs:
            self.account = kwargs["instance"]
            del kwargs["instance"]

        super(AccountPermissionsForm, self).__init__(*args, **kwargs)

        if not hasattr(self, "account") or self.account is None:
            return
        for pos, dom in enumerate(Domain.objects.get_for_admin(self.account)):
            name = "domains_%d" % (pos + 1)
            self._create_field(DomainNameField, name, dom.name)
        if len(args) and isinstance(args[0], QueryDict):
            self._load_from_qdict(args[0], "domains", DomainNameField)

    def save(self):
        current_domains = [
            dom.name for dom in Domain.objects.get_for_admin(self.account)
        ]
        for name, value in self.cleaned_data.items():
            if not name.startswith("domains"):
                continue
            if value in ["", None]:
                continue
            if value not in current_domains:
                domain = Domain.objects.get(name=value)
                domain.add_admin(self.account)

        for domain in Domain.objects.get_for_admin(self.account):
            if not filter(lambda name: self.cleaned_data[name] == domain.name,
                          self.cleaned_data.keys()):
                domain.remove_admin(self.account)
Exemple #2
0
class RelayDomainFormGeneral(forms.ModelForm):
    """RelayDomain form."""

    name = DomainNameField(label=ugettext_lazy("Name"),
                           help_text=ugettext_lazy("The relay domain name"))

    class Meta:
        model = RelayDomain
        exclude = ["domain", "dates"]
        widgets = {"service": forms.Select(attrs={"class": "form-control"})}

    def __init__(self, *args, **kwargs):
        super(RelayDomainFormGeneral, self).__init__(*args, **kwargs)
        self.field_widths = {"service": 3}

    def save(self, *args, **kwargs):
        """Custom save method."""
        domain = kwargs.get("domain")
        instance = super(RelayDomainFormGeneral, self).save(commit=False)
        if domain:
            instance.domain = domain
        instance.save()
        return instance
Exemple #3
0
class RelayDomainFormGeneral(forms.ModelForm, DynamicForm):
    aliases = DomainNameField(
        label=ugettext_lazy("Alias(es)"),
        required=False,
        help_text=ugettext_lazy(
            "Alias(es) of this relay domain. Indicate only one name per input"
            ", press ENTER to add a new input."))

    class Meta:
        model = RelayDomain
        exclude = ['dates']
        widgets = {"service": forms.Select(attrs={"class": "form-control"})}

    def __init__(self, *args, **kwargs):
        self.oldname = None
        if "instance" in kwargs:
            self.oldname = kwargs["instance"].name
        super(RelayDomainFormGeneral, self).__init__(*args, **kwargs)
        self.field_widths = {"service": 3}
        if args and isinstance(args[0], QueryDict):
            self._load_from_qdict(args[0], "aliases", DomainNameField)
        elif 'instance' in kwargs:
            rd = kwargs['instance']
            for pos, rdalias in enumerate(rd.relaydomainalias_set.all()):
                name = "aliases_%d" % (pos + 1)
                self._create_field(forms.CharField, name, rdalias.name, 3)

    def clean(self):
        """Custom fields validaton.

        We want to prevent duplicate names between domains, relay
        domains, domain aliases and relay domain aliases.

        The validation way is not very smart...
        """
        super(RelayDomainFormGeneral, self).clean()
        cleaned_data = self.cleaned_data
        for dtype, label in [(Domain, _('domain')),
                             (DomainAlias, _('domain alias')),
                             (RelayDomainAlias, _('relay domain alias'))]:
            try:
                dtype.objects.get(name=cleaned_data['name'])
            except dtype.DoesNotExist:
                pass
            else:
                self.add_error("name",
                               _("A %s with this name already exists") % label)
                break

        for k in cleaned_data.keys():
            if not k.startswith("aliases"):
                continue
            if not cleaned_data[k]:
                del cleaned_data[k]
                continue
            for dtype, name in [(RelayDomain, _('relay domain')),
                                (DomainAlias, _('domain alias')),
                                (Domain, _('domain'))]:
                try:
                    dtype.objects.get(name=cleaned_data[k])
                except dtype.DoesNotExist:
                    pass
                else:
                    self.add_error(
                        k,
                        _("A %s with this name already exists") % name)
                    break

        return cleaned_data

    def save(self, user, commit=True, rdomalias_post_create=False):
        """Custom save method.

        As relay domain aliases are defined using the same form as
        relay domains, we need to save them manually.

        :param ``User`` user: connected user
        """
        rd = super(RelayDomainFormGeneral, self).save(commit=False)
        if commit:
            rd.oldname = self.oldname
            rd.save()
            aliases = []
            for k, v in self.cleaned_data.iteritems():
                if not k.startswith("aliases"):
                    continue
                if v in ["", None]:
                    continue
                aliases.append(v)
            for rdalias in rd.relaydomainalias_set.all():
                if rdalias.name not in aliases:
                    rdalias.delete()
                else:
                    aliases.remove(rdalias.name)
            if aliases:
                events.raiseEvent("CanCreate", user, "relay_domain_aliases",
                                  len(aliases))
                for alias in aliases:
                    try:
                        rd.relaydomainalias_set.get(name=alias)
                    except RelayDomainAlias.DoesNotExist:
                        pass
                    else:
                        continue
                    al = RelayDomainAlias(name=alias,
                                          target=rd,
                                          enabled=rd.enabled)
                    al.save(creator=user) \
                        if rdomalias_post_create else al.save()
        return rd
Exemple #4
0
class DomainFormGeneral(forms.ModelForm, DynamicForm):
    quota = forms.IntegerField(
        label=ugettext_lazy("Quota"),
        required=False,
        help_text=ugettext_lazy(
            "Default quota in MB applied to mailboxes. Leave empty to use the "
            "default value."))
    aliases = DomainNameField(
        label=ugettext_lazy("Alias(es)"),
        required=False,
        help_text=ugettext_lazy(
            "Alias(es) of this domain. Indicate only one name per input, "
            "press ENTER to add a new input."))
    name = DomainNameField(widget=forms.TextInput())

    class Meta:
        model = Domain
        fields = ("name", "quota", "aliases", "enabled")

    def __init__(self, *args, **kwargs):
        self.oldname = None
        if "instance" in kwargs:
            self.oldname = kwargs["instance"].name
        super(DomainFormGeneral, self).__init__(*args, **kwargs)

        self.field_widths = {"quota": 3}

        if len(args) and isinstance(args[0], QueryDict):
            self._load_from_qdict(args[0], "aliases", DomainNameField)
        elif "instance" in kwargs:
            d = kwargs["instance"]
            for pos, dalias in enumerate(d.domainalias_set.all()):
                name = "aliases_%d" % (pos + 1)
                self._create_field(forms.CharField, name, dalias.name, 3)

    def clean_quota(self):
        if self.cleaned_data['quota'] is None:
            return int(parameters.get_admin('DEFAULT_DOMAIN_QUOTA'))
        if self.cleaned_data['quota'] < 0:
            raise forms.ValidationError(_("Must be a positive integer"))
        return self.cleaned_data['quota']

    def clean(self):
        """Custom fields validation.

        We want to prevent duplicate names between domains and domain
        aliases. Extensions have the possibility to declare other
        objects (see *CheckDomainName* event).

        The validation way is not very smart...
        """
        super(DomainFormGeneral, self).clean()
        if self._errors:
            raise forms.ValidationError(self._errors)

        cleaned_data = self.cleaned_data
        name = cleaned_data["name"]
        label = check_if_domain_exists(name,
                                       [(DomainAlias, _('domain alias'))])
        if label is not None:
            self._errors["name"] = self.error_class(
                [_("A %s with this name already exists" % unicode(label))])
            del cleaned_data["name"]

        for k in cleaned_data.keys():
            if not k.startswith("aliases"):
                continue
            if cleaned_data[k] == "":
                del cleaned_data[k]
                continue
            if cleaned_data[k] == name:
                self._errors[k] = self.error_class(
                    [_("A %s with this name already exists") % _("domain")])
                del cleaned_data[k]
                continue
            label = check_if_domain_exists(cleaned_data[k],
                                           [(Domain, _("domain"))])
            if label is not None:
                self._errors[k] = self.error_class(
                    [_("A %s with this name already exists" % unicode(label))])
                del cleaned_data[k]

        return cleaned_data

    def update_mailbox_quotas(self, domain):
        """Update all quota records associated to this domain.

        This method must be called only when a domain gets renamed. As
        the primary key used for a quota is an email address, rename a
        domain will change all associated email addresses, so it will
        change the primary keys used for quotas. The consequence is we
        can't issue regular UPDATE queries using the .save() method of
        a Quota instance (it will trigger an INSERT as the primary key
        has changed).

        So, we use this ugly hack to bypass this behaviour. It is not
        perfomant at all as it will generate one query per quota
        record to update.
        """
        for q in Quota.objects.filter(username__contains="@%s" % self.oldname):
            username = q.username.replace('@%s' % self.oldname,
                                          '@%s' % domain.name)
            newq = Quota.objects.create(username=username,
                                        bytes=q.bytes,
                                        messages=q.messages)
            q.delete()

    def save(self, user, commit=True, domalias_post_create=False):
        """Custom save method

        Updating a domain may have consequences on other objects
        (domain alias, mailbox, quota). The most tricky part concerns
        quotas update.

        """
        d = super(DomainFormGeneral, self).save(commit=False)
        if commit:
            old_mail_homes = None
            if self.oldname is not None and d.name != self.oldname:
                d.name = self.oldname
                old_mail_homes = \
                    dict((mb.id, mb.mail_home) for mb in d.mailbox_set.all())
                d.name = self.cleaned_data['name']
            d.save()
            Mailbox.objects.filter(domain=d, use_domain_quota=True) \
                .update(quota=d.quota)
            aliases = []
            for k, v in self.cleaned_data.iteritems():
                if not k.startswith("aliases"):
                    continue
                if v in ["", None]:
                    continue
                aliases.append(v)
            for dalias in d.domainalias_set.all():
                if dalias.name not in aliases:
                    dalias.delete()
                else:
                    aliases.remove(dalias.name)
            if aliases:
                events.raiseEvent("CanCreate", user, "domain_aliases",
                                  len(aliases))
                for alias in aliases:
                    try:
                        d.domainalias_set.get(name=alias)
                    except DomainAlias.DoesNotExist:
                        pass
                    else:
                        continue
                    al = DomainAlias(name=alias, target=d, enabled=d.enabled)
                    al.save(
                        creator=user) if domalias_post_create else al.save()

            if old_mail_homes is not None:
                self.update_mailbox_quotas(d)
                for mb in d.mailbox_set.all():
                    mb.rename_dir(old_mail_homes[mb.id])

        return d