class ParametersForm(AdminParametersForm):
    """Admin parameters form."""

    app = "modoboa_pdfcredentials"

    docstore = SeparatorField(label=_("Documents storage"))

    storage_dir = forms.CharField(
        label=_("Directory to save documents into"),
        initial="/var/lib/modoboa/pdf_credentials",
        help_text=_("Path to a directory where PDF documents will be saved"),
    )

    security = SeparatorField(label=_("Security options"))

    delete_first_dl = YesNoField(
        label=_("Delete documents after the first download"),
        initial="yes",
        help_text=_(
            "Automatically delete a document just after its first download "
            "from this interface"))

    generate_at_creation = YesNoField(
        label=_("Generate documents only at account creation"),
        initial="yes",
        help_text=_(
            "Generate a new document only when a new account is created. "
            "If set to no, a new document will be created each time a "
            "password is updated."))
Exemplo n.º 2
0
class ParametersForm(AdminParametersForm):
    app = "webmail"

    sep3 = SeparatorField(label=_("General"))

    max_attachment_size = forms.CharField(
        label=_("Maximum attachment size"),
        initial="2048",
        help_text=_(
            "Maximum attachment size in bytes (or KB, MB, GB if specified)"))

    sep1 = SeparatorField(label=_("IMAP settings"))

    imap_server = forms.CharField(label=_("Server address"),
                                  initial="127.0.0.1",
                                  help_text=_("Address of your IMAP server"))

    imap_secured = YesNoField(
        label=_("Use a secured connection"),
        initial="no",
        help_text=_("Use a secured connection to access IMAP server"))

    imap_port = forms.IntegerField(
        label=_("Server port"),
        initial=143,
        help_text=_("Listening port of your IMAP server"))

    sep2 = SeparatorField(label=_("SMTP settings"))

    smtp_server = forms.CharField(label=_("Server address"),
                                  initial="127.0.0.1",
                                  help_text=_("Address of your SMTP server"))

    smtp_secured_mode = forms.ChoiceField(
        label=_("Secured connection mode"),
        choices=[("none", _("None")), ("starttls", "STARTTLS"),
                 ("ssl", "SSL/TLS")],
        initial="none",
        help_text=_("Use a secured connection to access SMTP server"),
        widget=InlineRadioSelect)

    smtp_port = forms.IntegerField(
        label=_("Server port"),
        initial=25,
        help_text=_("Listening port of your SMTP server"))

    smtp_authentication = YesNoField(
        label=_("Authentication required"),
        initial="no",
        help_text=_("Server needs authentication"))
Exemplo n.º 3
0
class ParametersForm(AdminParametersForm):
    app = "modoboa_sievefilters"

    sep1 = SeparatorField(label=_("ManageSieve settings"))

    server = forms.CharField(
        label=_("Server address"),
        initial="127.0.0.1",
        help_text=_("Address of your MANAGESIEVE server"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    port = forms.IntegerField(
        label=_("Server port"),
        initial=4190,
        help_text=_("Listening port of your MANAGESIEVE server"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    starttls = YesNoField(label=_("Connect using STARTTLS"),
                          initial="no",
                          help_text=_("Use the STARTTLS extension"))

    authentication_mech = forms.ChoiceField(
        label=_("Authentication mechanism"),
        choices=supported_auth_mechs(),
        initial="auto",
        help_text=_("Prefered authentication mechanism"),
        widget=forms.Select(attrs={"class": "form-control"}))
Exemplo n.º 4
0
class ParametersForm(AdminParametersForm):
    app = "radicale"

    server_settings = SeparatorField(label=ugettext_lazy("Server settings"))

    server_location = forms.CharField(
        label=ugettext_lazy("Server URL"),
        help_text=ugettext_lazy("The URL of your Radicale server. "
                                "It will be used to construct calendar URLs."),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    rights_management_sep = SeparatorField(
        label=ugettext_lazy("Rights management"))

    rights_file_path = forms.CharField(
        label=ugettext_lazy("Rights file's path"),
        initial="/etc/radicale/rights",
        help_text=ugettext_lazy(
            "Path to the file that contains rights definition"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    allow_calendars_administration = YesNoField(
        label=ugettext_lazy("Allow calendars administration"),
        initial="no",
        help_text=ugettext_lazy(
            "Allow domain administrators to manage user calendars "
            "(read and write)"))
def extra_mailform_fields(form_name, mailbox=None):
    """Define extra fields to include in mail forms.

    For now, only the auto-reply state can be modified.

    :param str form_name: form name (must be 'mailform')
    :param Mailbox mailbox: mailbox
    """
    if form_name != "mailform":
        return []
    status = False
    if mailbox is not None and mailbox.armessage_set.count():
        status = mailbox.armessage_set.all()[0].enabled
    return [
        ('autoreply',
         YesNoField(
             label=ugettext_lazy("Enable auto-reply"),
             initial="yes" if status else "no",
             required=False,
             help_text=ugettext_lazy("Enable or disable Postfix auto-reply")))
    ]
Exemplo n.º 6
0
class GeneralParametersForm(param_forms.AdminParametersForm):
    """General parameters."""

    app = "core"

    sep1 = SeparatorField(label=ugettext_lazy("Authentication"))

    authentication_type = forms.ChoiceField(
        label=ugettext_lazy("Authentication type"),
        choices=[('local', ugettext_lazy("Local")), ('ldap', "LDAP")],
        initial="local",
        help_text=ugettext_lazy("The backend used for authentication"),
        widget=InlineRadioSelect)

    password_scheme = forms.ChoiceField(
        label=ugettext_lazy("Default password scheme"),
        choices=[("sha512crypt", "sha512crypt"),
                 ("sha256crypt", "sha256crypt"), ("blfcrypt", "bcrypt"),
                 ("md5crypt", ugettext_lazy("md5crypt (weak)")),
                 ("sha256", ugettext_lazy("sha256 (weak)")),
                 ("md5", ugettext_lazy("md5 (weak)")),
                 ("crypt", ugettext_lazy("crypt (weak)")),
                 ("plain", ugettext_lazy("plain (weak)"))],
        initial="sha512crypt",
        help_text=ugettext_lazy("Scheme used to crypt mailbox passwords"),
        widget=forms.Select(attrs={"class": "form-control"}))

    rounds_number = forms.IntegerField(
        label=ugettext_lazy("Rounds"),
        initial=70000,
        help_text=ugettext_lazy(
            "Number of rounds to use (only used by sha256crypt and "
            "sha512crypt). Must be between 1000 and 999999999, inclusive."),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    secret_key = forms.CharField(
        label=ugettext_lazy("Secret key"),
        initial=random_key(),
        help_text=ugettext_lazy("Key used to encrypt/decrypt passwords"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    default_password = forms.CharField(
        label=ugettext_lazy("Default password"),
        initial="password",
        help_text=ugettext_lazy(
            "Default password for automatically created accounts."))

    random_password_length = forms.IntegerField(
        label=ugettext_lazy("Random password length"),
        min_value=8,
        initial=8,
        help_text=ugettext_lazy("Length of randomly generated passwords."))

    # LDAP specific settings
    ldap_sep = SeparatorField(label=ugettext_lazy("LDAP settings"))

    ldap_server_address = forms.CharField(
        label=ugettext_lazy("Server address"),
        initial="localhost",
        help_text=ugettext_lazy(
            "The IP address or the DNS name of the LDAP server"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_server_port = forms.IntegerField(
        label=ugettext_lazy("Server port"),
        initial=389,
        help_text=ugettext_lazy("The TCP port number used by the LDAP server"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_secured = YesNoField(
        label=ugettext_lazy("Use a secured connection"),
        initial=False,
        help_text=ugettext_lazy(
            "Use an SSL/TLS connection to access the LDAP server"))

    ldap_auth_method = forms.ChoiceField(
        label=ugettext_lazy("Authentication method"),
        choices=[('searchbind', ugettext_lazy("Search and bind")),
                 ('directbind', ugettext_lazy("Direct bind"))],
        initial='searchbind',
        help_text=ugettext_lazy("Choose the authentication method to use"),
        widget=forms.Select(attrs={"class": "form-control"}))

    ldap_bind_dn = forms.CharField(
        label=ugettext_lazy("Bind DN"),
        initial='',
        help_text=ugettext_lazy(
            "The distinguished name to use when binding to the LDAP server. "
            "Leave empty for an anonymous bind"),
        required=False,
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_bind_password = forms.CharField(
        label=ugettext_lazy("Bind password"),
        initial='',
        help_text=ugettext_lazy(
            "The password to use when binding to the LDAP server "
            "(with 'Bind DN')"),
        widget=forms.PasswordInput(attrs={"class": "form-control"},
                                   render_value=True),
        required=False)

    ldap_search_base = forms.CharField(
        label=ugettext_lazy("Users search base"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name of the search base used to find users"),
        required=False,
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_search_filter = forms.CharField(
        label=ugettext_lazy("Search filter"),
        initial="(mail=%(user)s)",
        help_text=ugettext_lazy(
            "An optional filter string (e.g. '(objectClass=person)'). "
            "In order to be valid, it must be enclosed in parentheses."),
        required=False,
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_user_dn_template = forms.CharField(
        label=ugettext_lazy("User DN template"),
        initial="",
        help_text=ugettext_lazy(
            "The template used to construct a user's DN. It should contain "
            "one placeholder (ie. %(user)s)"),
        required=False,
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_password_attribute = forms.CharField(
        label=ugettext_lazy("Password attribute"),
        initial="userPassword",
        help_text=ugettext_lazy("The attribute used to store user passwords"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    ldap_is_active_directory = YesNoField(
        label=ugettext_lazy("Active Directory"),
        initial=False,
        help_text=ugettext_lazy(
            "Tell if the LDAP server is an Active Directory one"))

    ldap_admin_groups = forms.CharField(
        label=ugettext_lazy("Administrator groups"),
        initial="",
        help_text=ugettext_lazy(
            "Members of those LDAP Posix groups will be created as domain "
            "administrators. Use ';' characters to separate groups."),
        required=False)

    ldap_group_type = forms.ChoiceField(
        label=ugettext_lazy("Group type"),
        initial="posixgroup",
        choices=constants.LDAP_GROUP_TYPES,
        help_text=ugettext_lazy(
            "The LDAP group type to use with your directory."))

    ldap_groups_search_base = forms.CharField(
        label=ugettext_lazy("Groups search base"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name of the search base used to find groups"),
        required=False)

    dash_sep = SeparatorField(label=ugettext_lazy("Dashboard"))

    rss_feed_url = forms.URLField(
        label=ugettext_lazy("Custom RSS feed"),
        required=False,
        help_text=ugettext_lazy(
            "Display custom RSS feed to resellers and domain administrators"))

    hide_features_widget = YesNoField(
        label=ugettext_lazy("Hide features widget"),
        initial=False,
        help_text=ugettext_lazy(
            "Hide features widget for resellers and domain administrators"))

    notif_sep = SeparatorField(label=ugettext_lazy("Notifications"))

    sender_address = lib_fields.UTF8EmailField(
        label=_("Sender address"),
        initial="*****@*****.**",
        help_text=_("Email address used to send notifications."))

    api_sep = SeparatorField(label=ugettext_lazy("Public API"))

    enable_api_communication = YesNoField(
        label=ugettext_lazy("Enable communication"),
        initial=True,
        help_text=ugettext_lazy(
            "Enable communication with Modoboa public API"))

    check_new_versions = YesNoField(
        label=ugettext_lazy("Check new versions"),
        initial=True,
        help_text=ugettext_lazy(
            "Automatically checks if a newer version is available"))

    send_statistics = YesNoField(label=ugettext_lazy("Send statistics"),
                                 initial=True,
                                 help_text=ugettext_lazy(
                                     "Send statistics to Modoboa public API "
                                     "(counters and used extensions)"))

    sep3 = SeparatorField(label=ugettext_lazy("Miscellaneous"))

    inactive_account_threshold = forms.IntegerField(
        label=_("Inactive account threshold"),
        initial=30,
        help_text=_(
            "An account with a last login date greater than this threshold "
            "(in days) will be considered as inactive"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    top_notifications_check_interval = forms.IntegerField(
        label=_("Top notifications check interval"),
        initial=30,
        help_text=_(
            "Interval between two top notification checks (in seconds)"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    log_maximum_age = forms.IntegerField(
        label=ugettext_lazy("Maximum log record age"),
        initial=365,
        help_text=ugettext_lazy("The maximum age in days of a log record"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    items_per_page = forms.IntegerField(
        label=ugettext_lazy("Items per page"),
        initial=30,
        help_text=ugettext_lazy("Number of displayed items per page"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    default_top_redirection = forms.ChoiceField(
        label=ugettext_lazy("Default top redirection"),
        choices=[],
        initial="user",
        help_text=ugettext_lazy(
            "The default redirection used when no application is specified"),
        widget=forms.Select(attrs={"class": "form-control"}))

    # Visibility rules
    visibility_rules = {
        "ldap_sep": "authentication_type=ldap",
        "ldap_server_address": "authentication_type=ldap",
        "ldap_server_port": "authentication_type=ldap",
        "ldap_secured": "authentication_type=ldap",
        "ldap_auth_method": "authentication_type=ldap",
        "ldap_bind_dn": "ldap_auth_method=searchbind",
        "ldap_bind_password": "******",
        "ldap_search_base": "ldap_auth_method=searchbind",
        "ldap_search_filter": "ldap_auth_method=searchbind",
        "ldap_user_dn_template": "ldap_auth_method=directbind",
        "ldap_password_attribute": "authentication_type=ldap",
        "ldap_is_active_directory": "authentication_type=ldap",
        "ldap_admin_groups": "authentication_type=ldap",
        "ldap_group_type": "authentication_type=ldap",
        "ldap_groups_search_base": "authentication_type=ldap",
        "check_new_versions": "enable_api_communication=True",
        "send_statistics": "enable_api_communication=True",
    }

    def __init__(self, *args, **kwargs):
        super(GeneralParametersForm, self).__init__(*args, **kwargs)
        self.fields["default_top_redirection"].choices = enabled_applications()

    def clean_secret_key(self):
        if len(self.cleaned_data["secret_key"]) not in [16, 24, 32]:
            raise forms.ValidationError(
                _("Key must be either 16, 24, or 32 bytes long"))
        return self.cleaned_data["secret_key"]

    def clean_ldap_user_dn_template(self):
        tpl = self.cleaned_data["ldap_user_dn_template"]
        try:
            test = tpl % {"user": "******"}
        except (KeyError, ValueError):
            raise forms.ValidationError(_("Invalid syntax"))
        return tpl

    def clean_rounds_number(self):
        value = self.cleaned_data["rounds_number"]
        if value < 1000 or value > 999999999:
            raise forms.ValidationError(_("Invalid rounds number"))
        return value

    def clean_default_password(self):
        """Check password complexity."""
        value = self.cleaned_data["default_password"]
        password_validation.validate_password(value)
        return value

    def clean(self):
        """Custom validation method

        Depending on 'ldap_auth_method' value, we check for different
        required parameters.
        """
        super(GeneralParametersForm, self).clean()
        cleaned_data = self.cleaned_data
        if cleaned_data["authentication_type"] != "ldap":
            return cleaned_data

        if cleaned_data["ldap_auth_method"] == "searchbind":
            required_fields = ["ldap_search_base", "ldap_search_filter"]
        else:
            required_fields = ["ldap_user_dn_template"]

        for f in required_fields:
            if f not in cleaned_data or cleaned_data[f] == u'':
                self.add_error(f, _("This field is required"))

        return cleaned_data

    def to_django_settings(self):
        """Apply LDAP related parameters to Django settings.

        Doing so, we can use the django_auth_ldap module.
        """
        try:
            import ldap
            from django_auth_ldap.config import (LDAPSearch, PosixGroupType,
                                                 GroupOfNamesType)
            ldap_available = True
        except ImportError:
            ldap_available = False

        values = dict(param_tools.get_global_parameters("core"))
        if not ldap_available or values["authentication_type"] != "ldap":
            return
        if not hasattr(settings, "AUTH_LDAP_USER_ATTR_MAP"):
            setattr(settings, "AUTH_LDAP_USER_ATTR_MAP", {
                "first_name": "givenName",
                "email": "mail",
                "last_name": "sn"
            })
        ldap_uri = "ldaps://" if values["ldap_secured"] else "ldap://"
        ldap_uri += "%s:%s" % (values["ldap_server_address"],
                               values["ldap_server_port"])
        setattr(settings, "AUTH_LDAP_SERVER_URI", ldap_uri)

        if values["ldap_group_type"] == "groupofnames":
            setattr(settings, "AUTH_LDAP_GROUP_TYPE", GroupOfNamesType())
            searchfilter = "(objectClass=groupOfNames)"
        else:
            setattr(settings, "AUTH_LDAP_GROUP_TYPE", PosixGroupType())
            searchfilter = "(objectClass=posixGroup)"
        setattr(
            settings, "AUTH_LDAP_GROUP_SEARCH",
            LDAPSearch(values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE,
                       searchfilter))
        if values["ldap_auth_method"] == "searchbind":
            setattr(settings, "AUTH_LDAP_BIND_DN", values["ldap_bind_dn"])
            setattr(settings, "AUTH_LDAP_BIND_PASSWORD",
                    values["ldap_bind_password"])
            search = LDAPSearch(values["ldap_search_base"], ldap.SCOPE_SUBTREE,
                                values["ldap_search_filter"])
            setattr(settings, "AUTH_LDAP_USER_SEARCH", search)
        else:
            setattr(settings, "AUTH_LDAP_USER_DN_TEMPLATE",
                    values["ldap_user_dn_template"])
        if values["ldap_is_active_directory"]:
            if not hasattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS"):
                setattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS",
                        {ldap.OPT_REFERRALS: False})
            else:
                settings.AUTH_LDAP_GLOBAL_OPTIONS[ldap.OPT_REFERRALS] = False
Exemplo n.º 7
0
class DomainFormOptions(forms.Form):
    """A form containing options for domain creation."""

    create_dom_admin = YesNoField(
        label=ugettext_lazy("Create a domain administrator"),
        initial="no",
        help_text=ugettext_lazy(
            "Automatically create an administrator for this domain"))

    dom_admin_username = forms.CharField(
        label=ugettext_lazy("Name"),
        initial="admin",
        help_text=ugettext_lazy(
            "The administrator's name. Don't include the domain's name here, "
            "it will be automatically appended."),
        required=False)

    create_aliases = YesNoField(
        label=ugettext_lazy("Create aliases"),
        initial="yes",
        help_text=ugettext_lazy(
            "Automatically create standard aliases for this domain"),
        required=False)

    def __init__(self, user, *args, **kwargs):
        super(DomainFormOptions, self).__init__(*args, **kwargs)
        result = events.raiseQueryEvent('UserCanSetRole', user, 'DomainAdmins')
        if False in result:
            self.fields = {}
            return
        if args:
            if args[0].get("create_dom_admin", "no") == "yes":
                self.fields["dom_admin_username"].required = True
                self.fields["create_aliases"].required = True

    def clean_dom_admin_username(self):
        """Ensure admin username is an email address."""
        if '@' in self.cleaned_data["dom_admin_username"]:
            raise forms.ValidationError(_("Invalid format"))
        return self.cleaned_data["dom_admin_username"]

    def save(self, *args, **kwargs):
        if not self.fields:
            return
        if self.cleaned_data["create_dom_admin"] == "no":
            return
        user = kwargs.pop("user")
        domain = kwargs.pop("domain")
        username = "******" % (self.cleaned_data["dom_admin_username"],
                              domain.name)
        try:
            da = User.objects.get(username=username)
        except User.DoesNotExist:
            pass
        else:
            raise Conflict(_("User '%s' already exists") % username)
        core_signals.can_create_object.send(self.__class__,
                                            context=user,
                                            object_type="mailboxes")
        da = User(username=username, email=username, is_active=True)
        da.set_password("password")
        da.save()
        da.role = "DomainAdmins"
        da.post_create(user)

        mb = Mailbox(address=self.cleaned_data["dom_admin_username"],
                     domain=domain,
                     user=da,
                     use_domain_quota=True)
        mb.set_quota(override_rules=user.has_perm("admin.change_domain"))
        mb.save(creator=user)

        if domain.type == "domain" and \
           self.cleaned_data["create_aliases"] == "yes":
            core_signals.can_create_object.send(self.__class__,
                                                context=user,
                                                object_type="mailbox_aliases")
            alias = Alias(address=u"postmaster@{}".format(domain.name),
                          domain=domain,
                          enabled=True)
            alias.save()
            alias.set_recipients([mb.full_address])
            alias.post_create(user)

        domain.add_admin(da)
Exemplo n.º 8
0
class GeneralParametersForm(param_forms.AdminParametersForm):
    """General parameters."""

    app = "core"

    sep1 = SeparatorField(label=ugettext_lazy("Authentication"))

    authentication_type = forms.ChoiceField(
        label=ugettext_lazy("Authentication type"),
        choices=[("local", ugettext_lazy("Local")), ("ldap", "LDAP")],
        initial="local",
        help_text=ugettext_lazy("The backend used for authentication"),
        widget=HorizontalRadioSelect())

    password_scheme = forms.ChoiceField(
        label=ugettext_lazy("Default password scheme"),
        choices=[(hasher.name, ugettext_lazy(hasher.label))
                 for hasher in PasswordHasher.get_password_hashers()
                 if hasher().scheme in get_dovecot_schemes()],
        initial="sha512crypt",
        help_text=ugettext_lazy("Scheme used to crypt mailbox passwords"),
    )

    rounds_number = forms.IntegerField(
        label=ugettext_lazy("Rounds"),
        initial=70000,
        help_text=ugettext_lazy(
            "Number of rounds to use (only used by sha256crypt and "
            "sha512crypt). Must be between 1000 and 999999999, inclusive."),
    )

    update_scheme = YesNoField(
        label=ugettext_lazy("Update password scheme at login"),
        initial=True,
        help_text=ugettext_lazy(
            "Update user password at login to use the default password scheme")
    )

    default_password = forms.CharField(
        label=ugettext_lazy("Default password"),
        initial="password",
        help_text=ugettext_lazy(
            "Default password for automatically created accounts."))

    random_password_length = forms.IntegerField(
        label=ugettext_lazy("Random password length"),
        min_value=8,
        initial=8,
        help_text=ugettext_lazy("Length of randomly generated passwords."))

    update_password_url = forms.URLField(
        label=ugettext_lazy("Update password service URL"),
        initial="",
        required=False,
        help_text=ugettext_lazy(
            "The URL of an external page where users will be able"
            " to update their password. It applies only to non local"
            " users, ie. those automatically created after a successful"
            " external authentication (LDAP, SMTP)."))

    # LDAP specific settings
    ldap_sep = SeparatorField(label=ugettext_lazy("LDAP settings"))

    ldap_server_address = forms.CharField(
        label=ugettext_lazy("Server address"),
        initial="localhost",
        help_text=ugettext_lazy(
            "The IP address or the DNS name of the LDAP server"),
    )

    ldap_server_port = forms.IntegerField(
        label=ugettext_lazy("Server port"),
        initial=389,
        help_text=ugettext_lazy("The TCP port number used by the LDAP server"),
    )

    ldap_enable_secondary_server = YesNoField(
        label=ugettext_lazy("Enable secondary server (fallback)"),
        initial=False,
        help_text=ugettext_lazy(
            "Enable a secondary LDAP server which will be used "
            "if the primary one fails"))

    ldap_secondary_server_address = forms.CharField(
        label=ugettext_lazy("Secondary server address"),
        initial="localhost",
        help_text=ugettext_lazy(
            "The IP address or the DNS name of the seondary LDAP server"),
    )

    ldap_secondary_server_port = forms.IntegerField(
        label=ugettext_lazy("Secondary server port"),
        initial=389,
        help_text=ugettext_lazy(
            "The TCP port number used by the LDAP secondary server"),
    )

    ldap_secured = forms.ChoiceField(
        label=ugettext_lazy("Use a secured connection"),
        choices=constants.LDAP_SECURE_MODES,
        initial="none",
        help_text=ugettext_lazy(
            "Use an SSL/STARTTLS connection to access the LDAP server"))

    ldap_is_active_directory = YesNoField(
        label=ugettext_lazy("Active Directory"),
        initial=False,
        help_text=ugettext_lazy(
            "Tell if the LDAP server is an Active Directory one"))

    ldap_admin_groups = forms.CharField(
        label=ugettext_lazy("Administrator groups"),
        initial="",
        help_text=ugettext_lazy(
            "Members of those LDAP Posix groups will be created as domain "
            "administrators. Use ';' characters to separate groups."),
        required=False)

    ldap_group_type = forms.ChoiceField(
        label=ugettext_lazy("Group type"),
        initial="posixgroup",
        choices=constants.LDAP_GROUP_TYPES,
        help_text=ugettext_lazy(
            "The LDAP group type to use with your directory."))

    ldap_groups_search_base = forms.CharField(
        label=ugettext_lazy("Groups search base"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name of the search base used to find groups"),
        required=False)

    ldap_password_attribute = forms.CharField(
        label=ugettext_lazy("Password attribute"),
        initial="userPassword",
        help_text=ugettext_lazy("The attribute used to store user passwords"),
    )

    # LDAP authentication settings
    ldap_auth_sep = SeparatorField(
        label=ugettext_lazy("LDAP authentication settings"))

    ldap_auth_method = forms.ChoiceField(
        label=ugettext_lazy("Authentication method"),
        choices=[("searchbind", ugettext_lazy("Search and bind")),
                 ("directbind", ugettext_lazy("Direct bind"))],
        initial="searchbind",
        help_text=ugettext_lazy("Choose the authentication method to use"),
    )

    ldap_bind_dn = forms.CharField(
        label=ugettext_lazy("Bind DN"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name to use when binding to the LDAP server. "
            "Leave empty for an anonymous bind"),
        required=False,
    )

    ldap_bind_password = forms.CharField(
        label=ugettext_lazy("Bind password"),
        initial="",
        help_text=ugettext_lazy(
            "The password to use when binding to the LDAP server "
            "(with 'Bind DN')"),
        widget=forms.PasswordInput(render_value=True),
        required=False)

    ldap_search_base = forms.CharField(
        label=ugettext_lazy("Users search base"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name of the search base used to find users"),
        required=False,
    )

    ldap_search_filter = forms.CharField(
        label=ugettext_lazy("Search filter"),
        initial="(mail=%(user)s)",
        help_text=ugettext_lazy(
            "An optional filter string (e.g. '(objectClass=person)'). "
            "In order to be valid, it must be enclosed in parentheses."),
        required=False,
    )

    ldap_user_dn_template = forms.CharField(
        label=ugettext_lazy("User DN template"),
        initial="",
        help_text=ugettext_lazy(
            "The template used to construct a user's DN. It should contain "
            "one placeholder (ie. %(user)s)"),
        required=False,
    )

    # LDAP sync. settings
    ldap_sync_sep = SeparatorField(
        label=ugettext_lazy("LDAP synchronization settings"))

    ldap_sync_bind_dn = forms.CharField(
        label=ugettext_lazy("Bind DN"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name to use when binding to the LDAP server. "
            "Leave empty for an anonymous bind"),
        required=False,
    )

    ldap_sync_bind_password = forms.CharField(
        label=ugettext_lazy("Bind password"),
        initial="",
        help_text=ugettext_lazy(
            "The password to use when binding to the LDAP server "
            "(with 'Bind DN')"),
        widget=forms.PasswordInput(render_value=True),
        required=False)

    ldap_enable_sync = YesNoField(
        label=ugettext_lazy("Enable export to LDAP"),
        initial=False,
        help_text=ugettext_lazy(
            "Enable automatic synchronization between local database and "
            "LDAP directory"))

    ldap_sync_delete_remote_account = YesNoField(
        label=ugettext_lazy(
            "Delete remote LDAP account when local account is deleted"),
        initial=False,
        help_text=ugettext_lazy(
            "Delete remote LDAP account when local account is deleted, "
            "otherwise it will be disabled."))

    ldap_sync_account_dn_template = forms.CharField(
        label=ugettext_lazy("Account DN template"),
        initial="",
        help_text=ugettext_lazy(
            "The template used to construct an account's DN. It should contain "
            "one placeholder (ie. %(user)s)"),
        required=False)

    ldap_enable_import = YesNoField(
        label=ugettext_lazy("Enable import from LDAP"),
        initial=False,
        help_text=ugettext_lazy(
            "Enable account synchronization from LDAP directory to local "
            "database"))

    ldap_import_search_base = forms.CharField(
        label=ugettext_lazy("Users search base"),
        initial="",
        help_text=ugettext_lazy(
            "The distinguished name of the search base used to find users"),
        required=False,
    )

    ldap_import_search_filter = forms.CharField(
        label=ugettext_lazy("Search filter"),
        initial="(cn=*)",
        help_text=ugettext_lazy(
            "An optional filter string (e.g. '(objectClass=person)'). "
            "In order to be valid, it must be enclosed in parentheses."),
        required=False,
    )

    ldap_import_username_attr = forms.CharField(
        label=ugettext_lazy("Username attribute"),
        initial="cn",
        help_text=ugettext_lazy(
            "The name of the LDAP attribute where the username can be found."),
    )

    dash_sep = SeparatorField(label=ugettext_lazy("Dashboard"))

    rss_feed_url = forms.URLField(
        label=ugettext_lazy("Custom RSS feed"),
        required=False,
        help_text=ugettext_lazy(
            "Display custom RSS feed to resellers and domain administrators"))

    hide_features_widget = YesNoField(
        label=ugettext_lazy("Hide features widget"),
        initial=False,
        help_text=ugettext_lazy(
            "Hide features widget for resellers and domain administrators"))

    notif_sep = SeparatorField(label=ugettext_lazy("Notifications"))

    sender_address = lib_fields.UTF8EmailField(
        label=_("Sender address"),
        initial="*****@*****.**",
        help_text=_("Email address used to send notifications."))

    api_sep = SeparatorField(label=ugettext_lazy("Public API"))

    enable_api_communication = YesNoField(
        label=ugettext_lazy("Enable communication"),
        initial=True,
        help_text=ugettext_lazy(
            "Enable communication with Modoboa public API"))

    check_new_versions = YesNoField(
        label=ugettext_lazy("Check new versions"),
        initial=True,
        help_text=ugettext_lazy(
            "Automatically checks if a newer version is available"))

    send_new_versions_email = YesNoField(
        label=ugettext_lazy("Send an email when new versions are found"),
        initial=False,
        help_text=ugettext_lazy(
            "Send an email to notify admins about new versions"))
    new_versions_email_rcpt = lib_fields.UTF8EmailField(
        label=_("Recipient"),
        initial="*****@*****.**",
        help_text=_("Recipient of new versions notification emails."))

    send_statistics = YesNoField(label=ugettext_lazy("Send statistics"),
                                 initial=True,
                                 help_text=ugettext_lazy(
                                     "Send statistics to Modoboa public API "
                                     "(counters and used extensions)"))

    sep3 = SeparatorField(label=ugettext_lazy("Miscellaneous"))

    inactive_account_threshold = forms.IntegerField(
        label=_("Inactive account threshold"),
        initial=30,
        help_text=_(
            "An account with a last login date greater than this threshold "
            "(in days) will be considered as inactive"),
    )

    top_notifications_check_interval = forms.IntegerField(
        label=_("Top notifications check interval"),
        initial=30,
        help_text=_(
            "Interval between two top notification checks (in seconds)"),
    )

    log_maximum_age = forms.IntegerField(
        label=ugettext_lazy("Maximum log record age"),
        initial=365,
        help_text=ugettext_lazy("The maximum age in days of a log record"),
    )

    items_per_page = forms.IntegerField(
        label=ugettext_lazy("Items per page"),
        initial=30,
        help_text=ugettext_lazy("Number of displayed items per page"),
    )

    default_top_redirection = forms.ChoiceField(
        label=ugettext_lazy("Default top redirection"),
        choices=[],
        initial="user",
        help_text=ugettext_lazy(
            "The default redirection used when no application is specified"),
    )

    # Visibility rules
    visibility_rules = {
        "ldap_secondary_server_address": "ldap_enable_secondary_server=True",
        "ldap_secondary_server_port": "ldap_enable_secondary_server=True",
        "ldap_auth_sep": "authentication_type=ldap",
        "ldap_auth_method": "authentication_type=ldap",
        "ldap_bind_dn": "ldap_auth_method=searchbind",
        "ldap_bind_password": "******",
        "ldap_search_base": "ldap_auth_method=searchbind",
        "ldap_search_filter": "ldap_auth_method=searchbind",
        "ldap_user_dn_template": "ldap_auth_method=directbind",
        "ldap_admin_groups": "authentication_type=ldap",
        "ldap_group_type": "authentication_type=ldap",
        "ldap_groups_search_base": "authentication_type=ldap",
        "ldap_sync_delete_remote_account": "ldap_enable_sync=True",
        "ldap_sync_account_dn_template": "ldap_enable_sync=True",
        "ldap_import_search_base": "ldap_enable_import=True",
        "ldap_import_search_filter": "ldap_enable_import=True",
        "ldap_import_username_attr": "ldap_enable_import=True",
        "check_new_versions": "enable_api_communication=True",
        "send_statistics": "enable_api_communication=True",
        "send_new_versions_email": "check_new_versions=True",
        "new_versions_email_rcpt": "check_new_versions=True"
    }

    def __init__(self, *args, **kwargs):
        super(GeneralParametersForm, self).__init__(*args, **kwargs)
        self.fields["default_top_redirection"].choices = enabled_applications()

    def clean_ldap_user_dn_template(self):
        tpl = self.cleaned_data["ldap_user_dn_template"]
        try:
            tpl % {"user": "******"}
        except (KeyError, ValueError):
            raise forms.ValidationError(_("Invalid syntax"))
        return tpl

    def clean_ldap_sync_account_dn_template(self):
        tpl = self.cleaned_data["ldap_sync_account_dn_template"]
        try:
            tpl % {"user": "******"}
        except (KeyError, ValueError):
            raise forms.ValidationError(_("Invalid syntax"))
        return tpl

    def clean_rounds_number(self):
        value = self.cleaned_data["rounds_number"]
        if value < 1000 or value > 999999999:
            raise forms.ValidationError(_("Invalid rounds number"))
        return value

    def clean_default_password(self):
        """Check password complexity."""
        value = self.cleaned_data["default_password"]
        password_validation.validate_password(value)
        return value

    def clean(self):
        """Custom validation method

        Depending on 'ldap_auth_method' value, we check for different
        required parameters.
        """
        super(GeneralParametersForm, self).clean()
        cleaned_data = self.cleaned_data
        if cleaned_data["authentication_type"] != "ldap":
            return cleaned_data

        if cleaned_data["ldap_auth_method"] == "searchbind":
            required_fields = ["ldap_search_base", "ldap_search_filter"]
        else:
            required_fields = ["ldap_user_dn_template"]

        for f in required_fields:
            if f not in cleaned_data or cleaned_data[f] == u'':
                self.add_error(f, _("This field is required"))

        return cleaned_data

    def _apply_ldap_settings(self, values, backend):
        """Apply configuration for given backend."""
        import ldap
        from django_auth_ldap.config import (LDAPSearch, PosixGroupType,
                                             GroupOfNamesType,
                                             ActiveDirectoryGroupType)

        if not hasattr(settings, backend.setting_fullname("USER_ATTR_MAP")):
            setattr(settings, backend.setting_fullname("USER_ATTR_MAP"), {
                "first_name": "givenName",
                "email": "mail",
                "last_name": "sn"
            })
        ldap_uri = "ldaps://" if values["ldap_secured"] == "ssl" else "ldap://"
        ldap_uri += "%s:%s" % (values[backend.srv_address_setting_name],
                               values[backend.srv_port_setting_name])
        setattr(settings, backend.setting_fullname("SERVER_URI"), ldap_uri)
        if values["ldap_secured"] == "starttls":
            setattr(settings, backend.setting_fullname("START_TLS"), True)

        if values["ldap_is_active_directory"]:
            setattr(settings, backend.setting_fullname("GROUP_TYPE"),
                    ActiveDirectoryGroupType())
            searchfilter = "(objectClass=group)"
        elif values["ldap_group_type"] == "groupofnames":
            setattr(settings, backend.setting_fullname("GROUP_TYPE"),
                    GroupOfNamesType())
            searchfilter = "(objectClass=groupOfNames)"
        else:
            setattr(settings, backend.setting_fullname("GROUP_TYPE"),
                    PosixGroupType())
            searchfilter = "(objectClass=posixGroup)"
        setattr(
            settings, backend.setting_fullname("GROUP_SEARCH"),
            LDAPSearch(values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE,
                       searchfilter))
        if values["ldap_auth_method"] == "searchbind":
            setattr(settings, backend.setting_fullname("BIND_DN"),
                    values["ldap_bind_dn"])
            setattr(settings, backend.setting_fullname("BIND_PASSWORD"),
                    values["ldap_bind_password"])
            search = LDAPSearch(values["ldap_search_base"], ldap.SCOPE_SUBTREE,
                                values["ldap_search_filter"])
            setattr(settings, backend.setting_fullname("USER_SEARCH"), search)
        else:
            setattr(settings, backend.setting_fullname("USER_DN_TEMPLATE"),
                    values["ldap_user_dn_template"])
            setattr(settings,
                    backend.setting_fullname("BIND_AS_AUTHENTICATING_USER"),
                    True)
        if values["ldap_is_active_directory"]:
            setting = backend.setting_fullname("GLOBAL_OPTIONS")
            if not hasattr(settings, setting):
                setattr(settings, setting, {ldap.OPT_REFERRALS: False})
            else:
                getattr(settings, setting)[ldap.OPT_REFERRALS] = False

    def to_django_settings(self):
        """Apply LDAP related parameters to Django settings.

        Doing so, we can use the django_auth_ldap module.
        """
        try:
            import ldap
            ldap_available = True
        except ImportError:
            ldap_available = False

        values = dict(param_tools.get_global_parameters("core"))
        if not ldap_available or values["authentication_type"] != "ldap":
            return

        from modoboa.lib.authbackends import LDAPBackend
        self._apply_ldap_settings(values, LDAPBackend)

        if not values["ldap_enable_secondary_server"]:
            return

        from modoboa.lib.authbackends import LDAPSecondaryBackend
        self._apply_ldap_settings(values, LDAPSecondaryBackend)
Exemplo n.º 9
0
class AdminParametersForm(parameters.AdminParametersForm):
    app = "admin"

    mbsep = SeparatorField(label=ugettext_lazy("Mailboxes"))

    handle_mailboxes = YesNoField(
        label=ugettext_lazy("Handle mailboxes on filesystem"),
        initial="no",
        help_text=ugettext_lazy(
            "Rename or remove mailboxes on the filesystem when they get"
            " renamed or removed within Modoboa"))

    mailboxes_owner = forms.CharField(
        label=ugettext_lazy("Mailboxes owner"),
        initial="vmail",
        help_text=ugettext_lazy(
            "The UNIX account who owns mailboxes on the filesystem"))

    default_domain_quota = forms.IntegerField(
        label=ugettext_lazy("Default domain quota"),
        initial=0,
        help_text=ugettext_lazy(
            "Default quota (in MB) applied to freshly created domains with no "
            "value specified. A value of 0 means no quota."))

    auto_account_removal = YesNoField(
        label=ugettext_lazy("Automatic account removal"),
        initial="no",
        help_text=ugettext_lazy(
            "When a mailbox is removed, also remove the associated account"))

    auto_create_domain_and_mailbox = YesNoField(
        label=ugettext_lazy("Automatic domain/mailbox creation"),
        initial="yes",
        help_text=ugettext_lazy(
            "Create a domain and a mailbox when an account is automatically "
            "created."))

    # Visibility rules
    visibility_rules = {
        "mailboxes_owner": "handle_mailboxes=yes",
    }

    def __init__(self, *args, **kwargs):
        super(AdminParametersForm, self).__init__(*args, **kwargs)
        self.field_widths = {"default_domain_quota": 2}
        hide_fields = False
        dpath = None
        code, output = exec_cmd("which dovecot")
        if not code:
            dpath = output.strip()
        else:
            known_paths = getattr(
                settings, "DOVECOT_LOOKUP_PATH",
                ("/usr/sbin/dovecot", "/usr/local/sbin/dovecot"))
            for fpath in known_paths:
                if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
                    dpath = fpath
        if dpath:
            try:
                code, version = exec_cmd("%s --version" % dpath)
            except OSError:
                hide_fields = True
            else:
                if code or not version.strip().startswith("2"):
                    hide_fields = True
        else:
            hide_fields = True
        if hide_fields:
            del self.fields["handle_mailboxes"]
            del self.fields["mailboxes_owner"]

    def clean_default_domain_quota(self):
        """Ensure quota is a positive integer."""
        if self.cleaned_data['default_domain_quota'] < 0:
            raise forms.ValidationError(
                ugettext_lazy('Must be a positive integer'))
        return self.cleaned_data['default_domain_quota']
Exemplo n.º 10
0
class DomainFormOptions(forms.Form):

    """A form containing options for domain creation."""

    create_dom_admin = YesNoField(
        label=ugettext_lazy("Create a domain administrator"),
        initial=False,
        help_text=ugettext_lazy(
            "Automatically create an administrator for this domain"
        )
    )

    dom_admin_username = forms.CharField(
        label=ugettext_lazy("Name"),
        initial="admin",
        help_text=ugettext_lazy(
            "The administrator's name. Don't include the domain's name here, "
            "it will be automatically appended."
        ),
        required=False
    )

    create_aliases = YesNoField(
        label=ugettext_lazy("Create aliases"),
        initial=True,
        help_text=ugettext_lazy(
            "Automatically create standard aliases for this domain"
        ),
        required=False
    )

    def __init__(self, user, *args, **kwargs):
        super(DomainFormOptions, self).__init__(*args, **kwargs)
        results = core_signals.user_can_set_role.send(
            sender=self.__class__, user=user, role="DomainAdmins")
        if False in [result[1] for result in results]:
            self.fields = {}
            return

    def clean_dom_admin_username(self):
        """Ensure admin username is an email address."""
        if "@" in self.cleaned_data["dom_admin_username"]:
            raise forms.ValidationError(_("Invalid format"))
        return self.cleaned_data["dom_admin_username"]

    def clean(self):
        """Check required values."""
        cleaned_data = super(DomainFormOptions, self).clean()
        if cleaned_data.get("create_dom_admin"):
            if not cleaned_data.get("dom_admin_username"):
                self.add_error(
                    "dom_admin_username", _("This field is required."))
            if "create_aliases" not in cleaned_data:
                self.add_error(
                    "create_aliases", _("This field is required."))
        return cleaned_data

    def save(self, *args, **kwargs):
        if not self.fields:
            return
        if not self.cleaned_data["create_dom_admin"]:
            return
        user = kwargs.pop("user")
        domain = kwargs.pop("domain")
        username = "******" % (
            self.cleaned_data["dom_admin_username"], domain.name)
        try:
            da = User.objects.get(username=username)
        except User.DoesNotExist:
            pass
        else:
            raise Conflict(_("User '%s' already exists") % username)
        core_signals.can_create_object.send(
            self.__class__, context=user, object_type="mailboxes")
        da = User(username=username, email=username, is_active=True)
        da.set_password("password")
        da.save()
        da.role = "DomainAdmins"
        da.post_create(user)

        dom_admin_username = self.cleaned_data["dom_admin_username"]
        mb = Mailbox(
            address=dom_admin_username, domain=domain,
            user=da, use_domain_quota=True
        )
        mb.set_quota(
            override_rules=user.has_perm("admin.change_domain"))
        mb.save(creator=user)

        condition = (
            domain.type == "domain" and
            self.cleaned_data["create_aliases"] and
            dom_admin_username != "postmaster"
        )
        if condition:
            core_signals.can_create_object.send(
                self.__class__, context=user, object_type="mailbox_aliases")
            address = u"postmaster@{}".format(domain.name)
            alias = Alias.objects.create(
                address=address, domain=domain, enabled=True)
            alias.set_recipients([mb.full_address])
            alias.post_create(user)

        domain.add_admin(da)
Exemplo n.º 11
0
class UserSettings(UserParametersForm):
    app = "webmail"

    sep1 = SeparatorField(label=_("Display"))

    displaymode = forms.ChoiceField(
        initial="plain",
        label=_("Default message display mode"),
        choices=[("html", "html"), ("plain", "text")],
        help_text=_("The default mode used when displaying a message"),
        widget=InlineRadioSelect())

    enable_links = YesNoField(initial="no",
                              label=_("Enable HTML links display"),
                              help_text=_("Enable/Disable HTML links display"))

    messages_per_page = forms.IntegerField(
        initial=40,
        label=_("Number of displayed emails per page"),
        help_text=_("Sets the maximum number of messages displayed in a page"))

    refresh_interval = forms.IntegerField(
        initial=300,
        label=_("Listing refresh rate"),
        help_text=_("Automatic folder refresh rate (in seconds)"))

    mboxes_col_width = forms.IntegerField(
        initial=200,
        label=_("Mailboxes container's width"),
        help_text=_("The width of the mailbox list container"))

    sep2 = SeparatorField(label=_("Mailboxes"))

    trash_folder = forms.CharField(
        initial="Trash",
        label=_("Trash folder"),
        help_text=_("Folder where deleted messages go"))

    sent_folder = forms.CharField(
        initial="Sent",
        label=_("Sent folder"),
        help_text=_("Folder where copies of sent messages go"))

    drafts_folder = forms.CharField(initial="Drafts",
                                    label=_("Drafts folder"),
                                    help_text=_("Folder where drafts go"))

    sep3 = SeparatorField(label=_("Composing messages"))

    editor = forms.ChoiceField(
        initial="plain",
        label=_("Default editor"),
        choices=[("html", "html"), ("plain", "text")],
        help_text=_("The default editor to use when composing a message"),
        widget=InlineRadioSelect())

    signature = forms.CharField(initial="",
                                label=_("Signature text"),
                                help_text=_("User defined email signature"),
                                required=False)

    visibility_rules = {"enable_links": "displaymode=html"}

    @staticmethod
    def has_access(user):
        return user.mailbox_set.count() != 0

    def clean_mboxes_col_width(self):
        """Check if the entered value is a positive integer.

        It must also be different from 0.
        """
        if self.cleaned_data['mboxes_col_width'] <= 0:
            raise forms.ValidationError(
                _('Value must be a positive integer (> 0)'))
        return self.cleaned_data['mboxes_col_width']
Exemplo n.º 12
0
class ParametersForm(param_forms.AdminParametersForm):
    """Available admin parameters."""

    app = "limits"

    defv_sep = SeparatorField(label=_("Default per-admin limits"))

    enable_admin_limits = YesNoField(
        label=_("Enable per-admin limits"),
        initial=True,
        help_text=_("Enable or disable per-admin limits"))

    deflt_user_domain_admins_limit = forms.IntegerField(
        label=_("Domain admins"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domain administrators for a new "
            "administrator. (0 to deny any creation, -1 to allow unlimited "
            "creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_domains_limit = forms.IntegerField(
        label=_("Domains"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domains for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_domain_aliases_limit = forms.IntegerField(
        label=_("Domain aliases"),
        initial=0,
        help_text=_("Maximum number of allowed domain aliases for a new "
                    "administrator. (0 to deny any creation, -1 to allow "
                    "unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_mailboxes_limit = forms.IntegerField(
        label=_("Mailboxes"),
        initial=0,
        help_text=_(
            "Maximum number of allowed mailboxes for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_mailbox_aliases_limit = forms.IntegerField(
        label=_("Mailbox aliases"),
        initial=0,
        help_text=_(
            "Maximum number of allowed aliases for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_quota_limit = forms.IntegerField(
        label=_("Quota"),
        initial=0,
        help_text=_(
            "The quota a reseller will be allowed to share between the "
            "domains he creates. (0 means no quota)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))

    domain_limits_sep = SeparatorField(label=_("Default per-domain limits"))

    enable_domain_limits = YesNoField(
        label=_("Enable per-domain limits"),
        initial=False,
        help_text=_("Enable or disable per-domain limits"))

    deflt_domain_domain_admins_limit = forms.IntegerField(
        label=_("Domain admins"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domain administrators for a new "
            "domain. (0 to deny any creation, -1 to allow unlimited "
            "creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_domain_aliases_limit = forms.IntegerField(
        label=_("Domain aliases"),
        initial=0,
        help_text=_("Maximum number of allowed domain aliases for a new "
                    "domain. (0 to deny any creation, -1 to allow "
                    "unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_mailboxes_limit = forms.IntegerField(
        label=_("Mailboxes"),
        initial=0,
        help_text=_(
            "Maximum number of allowed mailboxes for a new domain. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_mailbox_aliases_limit = forms.IntegerField(
        label=_("Mailbox aliases"),
        initial=0,
        help_text=_(
            "Maximum number of allowed aliases for a new domain. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))

    visibility_rules = {
        "deflt_user_domains_limit": "enable_admin_limits=True",
        "deflt_user_domain_aliases_limit": "enable_admin_limits=True",
        "deflt_user_mailboxes_limit": "enable_admin_limits=True",
        "deflt_user_mailbox_aliases_limit": "enable_admin_limits=True",
        "deflt_user_domain_admins_limit": "enable_admin_limits=True",
        "deflt_domain_mailboxes_limit": "enable_domain_limits=True",
        "deflt_domain_mailbox_aliases_limit": "enable_domain_limits=True",
        "deflt_domain_domain_aliases_limit": "enable_domain_limits=True",
        "deflt_domain_domain_admins_limit": "enable_domain_limits=True",
    }
Exemplo n.º 13
0
class AdminParametersForm(param_forms.AdminParametersForm):
    app = "admin"

    dom_sep = SeparatorField(label=ugettext_lazy("Domains"))

    enable_mx_checks = YesNoField(
        label=ugettext_lazy("Enable MX checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check that every domain has a valid MX record"))

    valid_mxs = forms.CharField(
        label=ugettext_lazy("Valid MXs"),
        initial="",
        help_text=ugettext_lazy(
            "A list of IP or network address every MX record should match."
            " A warning will be sent if a record does not respect it."),
        widget=forms.Textarea,
        required=False)

    domains_must_have_authorized_mx = YesNoField(
        label=ugettext_lazy("New domains must use authorized MX(s)"),
        initial=False,
        help_text=ugettext_lazy(
            "Prevent the creation of a new domain if its MX record does "
            "not use one of the defined addresses."))

    enable_spf_checks = YesNoField(
        label=ugettext_lazy("Enable SPF checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check if every domain has a valid SPF record"))

    enable_dkim_checks = YesNoField(
        label=ugettext_lazy("Enable DKIM checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check if every domain with DKIM signin enabled has a valid DNS "
            "record"))

    enable_dmarc_checks = YesNoField(
        label=ugettext_lazy("Enable DMARC checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check if every domain has a valid DMARC record"))

    enable_autoconfig_checks = YesNoField(
        label=ugettext_lazy("Enable autoconfig checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check if every domain has a valid records for autoconfiguration"))

    enable_dnsbl_checks = YesNoField(
        label=ugettext_lazy("Enable DNSBL checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check every domain against major DNSBL providers"))

    custom_dns_server = GenericIPAddressField(
        label=ugettext_lazy("Custom DNS server"),
        required=False,
        help_text=ugettext_lazy(
            "Use a custom DNS server instead of local server configuration"))

    dkim_keys_storage_dir = forms.CharField(
        label=ugettext_lazy("DKIM keys storage directory"),
        initial="",
        help_text=ugettext_lazy(
            "Absolute path of the directory where DKIM private keys will "
            "be stored. Make sure this directory belongs to root user "
            "and is not readable by the outside world."),
        required=False)

    dkim_default_key_length = forms.ChoiceField(
        label=ugettext_lazy("Default DKIM key length"),
        initial=2048,
        choices=constants.DKIM_KEY_LENGTHS,
        help_text=ugettext_lazy(
            "Default length in bits for newly generated DKIM keys."))

    default_domain_quota = forms.IntegerField(
        label=ugettext_lazy("Default domain quota"),
        initial=0,
        help_text=ugettext_lazy(
            "Default quota (in MB) applied to freshly created domains with no "
            "value specified. A value of 0 means no quota."))

    default_domain_message_limit = forms.IntegerField(
        label=ugettext_lazy("Default domain sending limit"),
        required=False,
        help_text=ugettext_lazy(
            "Number of messages freshly created domains will be "
            "allowed to send per day. Leave empty for no limit."))

    mbsep = SeparatorField(label=ugettext_lazy("Mailboxes"))

    handle_mailboxes = YesNoField(
        label=ugettext_lazy("Handle mailboxes on filesystem"),
        initial=False,
        help_text=ugettext_lazy(
            "Rename or remove mailboxes on the filesystem when they get"
            " renamed or removed within Modoboa"))

    default_mailbox_quota = forms.IntegerField(
        label=ugettext_lazy("Default mailbox quota"),
        initial=0,
        help_text=ugettext_lazy(
            "Default mailbox quota (in MB) applied to freshly created "
            "mailboxes with no value specified. A value of 0 means no quota."))

    default_mailbox_message_limit = forms.IntegerField(
        label=ugettext_lazy("Default mailbox sending limit"),
        required=False,
        help_text=ugettext_lazy(
            "Number of messages freshly created mailboxes will be "
            "allowed to send per day. Leave empty for no limit."))

    auto_account_removal = YesNoField(
        label=ugettext_lazy("Automatic account removal"),
        initial=False,
        help_text=ugettext_lazy(
            "When a mailbox is removed, also remove the associated account"))

    auto_create_domain_and_mailbox = YesNoField(
        label=ugettext_lazy("Automatic domain/mailbox creation"),
        initial=True,
        help_text=ugettext_lazy(
            "Create a domain and a mailbox when an account is automatically "
            "created."))

    create_alias_on_mbox_rename = YesNoField(
        label=ugettext_lazy("Create an alias when a mailbox is renamed"),
        initial=False,
        help_text=ugettext_lazy(
            "Create an alias using the old address when a mailbox is renamed.")
    )

    # Visibility rules
    visibility_rules = {
        "valid_mxs": "enable_mx_checks=True",
        "domains_must_have_authorized_mx": "enable_mx_checks=True"
    }

    def __init__(self, *args, **kwargs):
        super(AdminParametersForm, self).__init__(*args, **kwargs)
        self.field_widths = {
            "default_domain_quota": 2,
            "default_mailbox_quota": 2
        }
        hide_fields = False
        dpath = None
        code, output = exec_cmd("which dovecot")
        if not code:
            dpath = force_text(output).strip()
        else:
            known_paths = getattr(
                settings, "DOVECOT_LOOKUP_PATH",
                ("/usr/sbin/dovecot", "/usr/local/sbin/dovecot"))
            for fpath in known_paths:
                if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
                    dpath = fpath
        if dpath:
            try:
                code, version = exec_cmd("%s --version" % dpath)
            except OSError:
                hide_fields = True
            else:
                version = force_text(version)
                if code or not version.strip().startswith("2"):
                    hide_fields = True
        else:
            hide_fields = True
        if hide_fields:
            del self.fields["handle_mailboxes"]

    def clean_default_domain_quota(self):
        """Ensure quota is a positive integer."""
        if self.cleaned_data["default_domain_quota"] < 0:
            raise forms.ValidationError(
                ugettext_lazy("Must be a positive integer"))
        return self.cleaned_data["default_domain_quota"]

    def clean_default_mailbox_quota(self):
        """Ensure quota is a positive integer."""
        if self.cleaned_data["default_mailbox_quota"] < 0:
            raise forms.ValidationError(
                ugettext_lazy("Must be a positive integer"))
        return self.cleaned_data["default_mailbox_quota"]

    def clean_dkim_keys_storage_dir(self):
        """Check that directory exists."""
        storage_dir = self.cleaned_data.get("dkim_keys_storage_dir", "")
        if storage_dir:
            if not os.path.isdir(storage_dir):
                raise forms.ValidationError(
                    ugettext_lazy("Directory not found."))
            code, output = exec_cmd("which openssl")
            if code:
                raise forms.ValidationError(
                    ugettext_lazy(
                        "openssl not found, please make sure it is installed.")
                )
        return storage_dir

    def clean(self):
        """Check MX options."""
        cleaned_data = super(AdminParametersForm, self).clean()
        condition = (cleaned_data.get("enable_mx_checks")
                     and cleaned_data.get("domains_must_have_authorized_mx")
                     and not cleaned_data.get("valid_mxs"))
        if condition:
            self.add_error(
                "valid_mxs",
                _("Define at least one authorized network / address"))
        return cleaned_data
Exemplo n.º 14
0
class AdminParametersForm(param_forms.AdminParametersForm):
    app = "admin"

    dom_sep = SeparatorField(label=ugettext_lazy("Domains"))

    enable_mx_checks = YesNoField(
        label=ugettext_lazy("Enable MX checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check that every domain has a valid MX record"))

    valid_mxs = forms.CharField(
        label=ugettext_lazy("Valid MXs"),
        initial="",
        help_text=ugettext_lazy(
            "A list of IP or network address every MX record should match."
            " A warning will be sent if a record does not respect it."),
        widget=forms.Textarea,
        required=False)

    enable_dnsbl_checks = YesNoField(
        label=ugettext_lazy("Enable DNSBL checks"),
        initial=True,
        help_text=ugettext_lazy(
            "Check every domain against major DNSBL providers"))

    mbsep = SeparatorField(label=ugettext_lazy("Mailboxes"))

    handle_mailboxes = YesNoField(
        label=ugettext_lazy("Handle mailboxes on filesystem"),
        initial=False,
        help_text=ugettext_lazy(
            "Rename or remove mailboxes on the filesystem when they get"
            " renamed or removed within Modoboa"))

    mailboxes_owner = forms.CharField(
        label=ugettext_lazy("Mailboxes owner"),
        initial="vmail",
        help_text=ugettext_lazy(
            "The UNIX account who owns mailboxes on the filesystem"))

    default_domain_quota = forms.IntegerField(
        label=ugettext_lazy("Default domain quota"),
        initial=0,
        help_text=ugettext_lazy(
            "Default quota (in MB) applied to freshly created domains with no "
            "value specified. A value of 0 means no quota."))

    default_mailbox_quota = forms.IntegerField(
        label=ugettext_lazy("Default mailbox quota"),
        initial=0,
        help_text=ugettext_lazy(
            "Default mailbox quota (in MB) applied to freshly created domains "
            "with no value specified. A value of 0 means no quota."))

    auto_account_removal = YesNoField(
        label=ugettext_lazy("Automatic account removal"),
        initial=False,
        help_text=ugettext_lazy(
            "When a mailbox is removed, also remove the associated account"))

    auto_create_domain_and_mailbox = YesNoField(
        label=ugettext_lazy("Automatic domain/mailbox creation"),
        initial=True,
        help_text=ugettext_lazy(
            "Create a domain and a mailbox when an account is automatically "
            "created."))

    # Visibility rules
    visibility_rules = {
        "valid_mxs": "enable_mx_checks=True",
        "mailboxes_owner": "handle_mailboxes=True",
    }

    def __init__(self, *args, **kwargs):
        super(AdminParametersForm, self).__init__(*args, **kwargs)
        self.field_widths = {
            "default_domain_quota": 2,
            "default_mailbox_quota": 2
        }
        hide_fields = False
        dpath = None
        code, output = exec_cmd("which dovecot")
        if not code:
            dpath = output.strip()
        else:
            known_paths = getattr(
                settings, "DOVECOT_LOOKUP_PATH",
                ("/usr/sbin/dovecot", "/usr/local/sbin/dovecot"))
            for fpath in known_paths:
                if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
                    dpath = fpath
        if dpath:
            try:
                code, version = exec_cmd("%s --version" % dpath)
            except OSError:
                hide_fields = True
            else:
                version = force_text(version)
                if code or not version.strip().startswith("2"):
                    hide_fields = True
        else:
            hide_fields = True
        if hide_fields:
            del self.fields["handle_mailboxes"]
            del self.fields["mailboxes_owner"]

    def clean_default_domain_quota(self):
        """Ensure quota is a positive integer."""
        if self.cleaned_data["default_domain_quota"] < 0:
            raise forms.ValidationError(
                ugettext_lazy("Must be a positive integer"))
        return self.cleaned_data["default_domain_quota"]

    def clean_default_mailbox_quota(self):
        """Ensure quota is a positive integer."""
        if self.cleaned_data["default_mailbox_quota"] < 0:
            raise forms.ValidationError(
                ugettext_lazy("Must be a positive integer"))
        return self.cleaned_data["default_mailbox_quota"]
Exemplo n.º 15
0
class ParametersForm(AdminParametersForm):
    """Extension settings."""

    app = "modoboa_amavis"

    qsettings_sep = SeparatorField(label=_("Quarantine settings"))

    max_messages_age = forms.IntegerField(
        label=_("Maximum message age"),
        initial=14,
        help_text=_(
            "Quarantine messages maximum age (in days) before deletion"))

    sep1 = SeparatorField(label=_("Messages releasing"))

    released_msgs_cleanup = YesNoField(
        label=_("Remove released messages"),
        initial="no",
        help_text=_("Remove messages marked as released while cleaning up "
                    "the database"))

    am_pdp_mode = forms.ChoiceField(
        label=_("Amavis connection mode"),
        choices=[("inet", "inet"), ("unix", "unix")],
        initial="unix",
        help_text=_("Mode used to access the PDP server"),
        widget=InlineRadioSelect(attrs={"type": "checkbox"}))

    am_pdp_host = forms.CharField(
        label=_("PDP server address"),
        initial="localhost",
        help_text=_("PDP server address (if inet mode)"),
        widget=forms.TextInput(attrs={"class": "form-control"}))

    am_pdp_port = forms.IntegerField(
        label=_("PDP server port"),
        initial=9998,
        help_text=_("PDP server port (if inet mode)"))

    am_pdp_socket = forms.CharField(
        label=_("PDP server socket"),
        initial="/var/amavis/amavisd.sock",
        help_text=_("Path to the PDP server socket (if unix mode)"))

    user_can_release = YesNoField(
        label=_("Allow direct release"),
        initial="no",
        help_text=_("Allow users to directly release their messages"))

    self_service = YesNoField(label=_("Enable self-service mode"),
                              initial="no",
                              help_text=_("Activate the 'self-service' mode"))

    notifications_sender = forms.EmailField(
        label=_("Notifications sender"),
        initial="*****@*****.**",
        help_text=_("The e-mail address used to send notitications"))

    lsep = SeparatorField(label=_("Manual learning"))

    manual_learning = YesNoField(
        label=_("Enable manual learning"),
        initial="yes",
        help_text=_(
            "Allow super administrators to manually train Spamassassin"))

    sa_is_local = YesNoField(
        label=_("Is Spamassassin local?"),
        initial="yes",
        help_text=_(
            "Tell if Spamassassin is running on the same server than modoboa"))

    default_user = forms.CharField(
        label=_("Default user"),
        initial="amavis",
        help_text=_("Name of the user owning the default bayesian database"))

    spamd_address = forms.CharField(
        label=_("Spamd address"),
        initial="127.0.0.1",
        help_text=_("The IP address where spamd can be reached"))

    spamd_port = forms.IntegerField(
        label=_("Spamd port"),
        initial=783,
        help_text=_("The TCP port spamd is listening on"))

    domain_level_learning = YesNoField(
        label=_("Enable per-domain manual learning"),
        initial="no",
        help_text=_("Allow domain administrators to train Spamassassin "
                    "(within dedicated per-domain databases)"))

    user_level_learning = YesNoField(
        label=_("Enable per-user manual learning"),
        initial="no",
        help_text=_("Allow simple users to personally train Spamassassin "
                    "(within a dedicated database)"))

    visibility_rules = {
        "am_pdp_host": "am_pdp_mode=inet",
        "am_pdp_port": "am_pdp_mode=inet",
        "am_pdp_socket": "am_pdp_mode=unix",
        "sa_is_local": "manual_learning=yes",
        "default_user": "******",
        "spamd_address": "sa_is_local=no",
        "spamd_port": "sa_is_local=no",
        "domain_level_learning": "manual_learning=yes",
        "user_level_learning": "manual_learning=yes"
    }
Exemplo n.º 16
0
class ParametersForm(AdminParametersForm):
    """Available admin parameters."""

    app = "limits"

    defv_sep = SeparatorField(label=_("Default per-admin limits"))

    enable_admin_limits = YesNoField(
        label=_("Enable per-admin limits"),
        initial="yes",
        help_text=_("Enable or disable per-admin limits"))

    deflt_user_domain_admins_limit = forms.IntegerField(
        label=_("Domain admins"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domain administrators for a new "
            "administrator. (0 to deny any creation, -1 to allow unlimited "
            "creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_domains_limit = forms.IntegerField(
        label=_("Domains"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domains for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_domain_aliases_limit = forms.IntegerField(
        label=_("Domain aliases"),
        initial=0,
        help_text=_("Maximum number of allowed domain aliases for a new "
                    "administrator. (0 to deny any creation, -1 to allow "
                    "unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_mailboxes_limit = forms.IntegerField(
        label=_("Mailboxes"),
        initial=0,
        help_text=_(
            "Maximum number of allowed mailboxes for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_user_mailbox_aliases_limit = forms.IntegerField(
        label=_("Mailbox aliases"),
        initial=0,
        help_text=_(
            "Maximum number of allowed aliases for a new administrator. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))

    domain_limits_sep = SeparatorField(label=_("Default per-domain limits"))

    enable_domain_limits = YesNoField(
        label=_("Enable per-domain limits"),
        initial="no",
        help_text=_("Enable or disable per-domain limits"))

    deflt_domain_domain_admins_limit = forms.IntegerField(
        label=_("Domain admins"),
        initial=0,
        help_text=_(
            "Maximum number of allowed domain administrators for a new "
            "domain. (0 to deny any creation, -1 to allow unlimited "
            "creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_domain_aliases_limit = forms.IntegerField(
        label=_("Domain aliases"),
        initial=0,
        help_text=_("Maximum number of allowed domain aliases for a new "
                    "domain. (0 to deny any creation, -1 to allow "
                    "unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_mailboxes_limit = forms.IntegerField(
        label=_("Mailboxes"),
        initial=0,
        help_text=_(
            "Maximum number of allowed mailboxes for a new domain. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))
    deflt_domain_mailbox_aliases_limit = forms.IntegerField(
        label=_("Mailbox aliases"),
        initial=0,
        help_text=_(
            "Maximum number of allowed aliases for a new domain. "
            "(0 to deny any creation, -1 to allow unlimited creations)"),
        widget=forms.widgets.TextInput(
            attrs={"class": "col-md-1 form-control"}))

    visibility_rules = {
        "deflt_user_domains_limit": "enable_admin_limits=yes",
        "deflt_user_domain_aliases_limit": "enable_admin_limits=yes",
        "deflt_user_mailboxes_limit": "enable_admin_limits=yes",
        "deflt_user_mailbox_aliases_limit": "enable_admin_limits=yes",
        "deflt_user_domain_admins_limit": "enable_admin_limits=yes",
        "deflt_domain_mailboxes_limit": "enable_domain_limits=yes",
        "deflt_domain_mailbox_aliases_limit": "enable_domain_limits=yes",
        "deflt_domain_domain_aliases_limit": "enable_domain_limits=yes",
        "deflt_domain_domain_admins_limit": "enable_domain_limits=yes",
    }

    def __init__(self, *args, **kwargs):
        super(AdminParametersForm, self).__init__(*args, **kwargs)
        self._load_extra_parameters('A')