示例#1
0
    def handle(self, *args, **options):
        Amavis().load()
        if options["debug"]:
            import logging
            l = logging.getLogger("django.db.backends")
            l.setLevel(logging.DEBUG)
            l.addHandler(logging.StreamHandler())
        self.verbose = options["verbose"]

        conf = dict(param_tools.get_global_parameters("modoboa_amavis"))

        flags = ["D"]
        if conf["released_msgs_cleanup"]:
            flags += ["R"]

        self.__vprint("Deleting marked messages...")
        ids = Msgrcpt.objects.filter(rs__in=flags).values("mail_id").distinct()
        for msg in Msgs.objects.filter(mail_id__in=ids):
            if not msg.msgrcpt_set.exclude(rs__in=flags).count():
                msg.delete()

        self.__vprint("Deleting messages older than %d days...".format(
            conf["max_messages_age"]))
        limit = int(time.time()) - (conf["max_messages_age"] * 24 * 3600)
        Msgs.objects.filter(time_num__lt=limit).delete()

        self.__vprint("Deleting unreferenced e-mail addresses...")
        for maddr in Maddr.objects.all():
            if not maddr.msgs_set.count() and not maddr.msgrcpt_set.count():
                maddr.delete()

        self.__vprint("Done.")
示例#2
0
 def __init__(self, user, recipient_db):
     """Constructor."""
     conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
     self._sa_is_local = conf["sa_is_local"]
     self._default_username = conf["default_user"]
     self._recipient_db = recipient_db
     self._setup_cache = {}
     self._username_cache = []
     if user.role == "SimpleUsers":
         if conf["user_level_learning"]:
             self._username = user.email
     else:
         self._username = None
     self.error = None
     if self._sa_is_local:
         self._learn_cmd = self._find_binary("sa-learn")
         self._learn_cmd += " --{0} --no-sync -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [0]
         self._sync_cmd = self._find_binary("sa-learn")
         self._sync_cmd += " -u {0} --sync"
     else:
         self._learn_cmd = self._find_binary("spamc")
         self._learn_cmd += " -d {0} -p {1}".format(conf["spamd_address"],
                                                    conf["spamd_port"])
         self._learn_cmd += " -L {0} -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [5, 6]
示例#3
0
    def authenticate(self, username=None, password=None):
        """Check the username/password and return a User."""
        if type(username) is unicode:
            username = username.encode("utf-8")
        if type(password) is unicode:
            password = password.encode("utf-8")
        conf = dict(
            param_tools.get_global_parameters("modoboa_imap_migration"))
        address = conf["server_address"]
        port = conf["server_port"]
        try:
            if conf["secured"]:
                conn = imaplib.IMAP4_SSL(address, port)
            else:
                conn = imaplib.IMAP4(address, port)
        except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error:
            raise ModoboaException(
                _("Connection to IMAP server failed: %s" % error))

        try:
            typ, data = conn.login(username, password)
        except imaplib.IMAP4.error:
            typ = "NO"
        conn.logout()
        if typ != "OK":
            return None
        return self.get_or_create_user(username, password)
示例#4
0
文件: mailbox.py 项目: tzwlwm/modoboa
    def mail_home(self):
        """Retrieve the home directory of this mailbox.

        The home directory refers to the place on the file system
        where the mailbox data is stored.

        We ask dovecot to give us this information because there are
        several patterns to understand and we don't want to implement
        them.
        """
        admin_params = dict(param_tools.get_global_parameters("admin"))
        if not admin_params.get("handle_mailboxes"):
            return None
        if self.__mail_home is None:
            curuser = pwd.getpwuid(os.getuid()).pw_name
            mbowner = admin_params["mailboxes_owner"]
            options = {}
            if curuser != mbowner:
                options["sudo_user"] = mbowner
            code, output = exec_cmd(
                "doveadm user -f home %s" % self.full_address, **options)
            if code:
                raise lib_exceptions.InternalError(
                    _("Failed to retrieve mailbox location (%s)") % output)
            self.__mail_home = output.strip()
        return self.__mail_home
示例#5
0
def make_query_args(address,
                    exact_extension=True,
                    wildcard=None,
                    domain_search=False):
    assert isinstance(address, six.text_type),\
        "address should be of type %s" % six.text_type.__name__
    conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
    local_part, domain = split_address(address)
    if not conf["localpart_is_case_sensitive"]:
        local_part = local_part.lower()
    if domain:
        domain = domain.lstrip("@").rstrip(".")
        domain = domain.lower()
        orig_domain = domain
        domain = idna.encode(domain, uts46=True).decode("ascii")
    delimiter = conf["recipient_delimiter"]
    local_part, extension = split_local_part(local_part, delimiter=delimiter)
    query_args = []
    if (conf["localpart_is_case_sensitive"]
            or (domain and domain != orig_domain)):
        query_args.append(address)
    if extension:
        query_args.append("%s%s%s@%s" %
                          (local_part, delimiter, extension, domain))
    if delimiter and not exact_extension and wildcard:
        query_args.append("%s%s%s@%s" %
                          (local_part, delimiter, wildcard, domain))
    query_args.append("%s@%s" % (local_part, domain))
    if domain_search:
        query_args.append("@%s" % domain)
        query_args.append("@.")

    return query_args
示例#6
0
    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
示例#7
0
    def __init__(self, user, *args, **kwargs):
        self.oldname = None
        if "instance" in kwargs:
            self.old_dkim_key_length = kwargs["instance"].dkim_key_length
            self.oldname = kwargs["instance"].name
        super(DomainFormGeneral, self).__init__(*args, **kwargs)
        params = dict(param_tools.get_global_parameters("admin"))
        self.fields["quota"].initial = params["default_domain_quota"]
        if params["default_domain_message_limit"] is not None:
            self.fields["message_limit"].initial = (
                params["default_domain_message_limit"])
        self.fields["default_mailbox_quota"].initial = (
            params["default_mailbox_quota"])
        self.fields["type"].choices = constants.DOMAIN_TYPES
        self.field_widths = {
            "quota": 3,
            "default_mailbox_quota": 3
        }
        self.user = user

        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 __init__(self, user=None, password=None):
     self.__hdelimiter = None
     self.conf = dict(
         param_tools.get_global_parameters("modoboa_sievefilters"))
     self.address = self.conf["imap_server"]
     self.port = self.conf["imap_port"]
     self.login(user, password)
示例#9
0
    def __init__(self, user, *args, **kwargs):
        self.oldname = None
        if "instance" in kwargs:
            self.oldname = kwargs["instance"].name
        super(DomainFormGeneral, self).__init__(*args, **kwargs)
        params = dict(param_tools.get_global_parameters("admin"))
        self.fields["quota"].initial = params["default_domain_quota"]
        self.fields["default_mailbox_quota"].initial = (
            params["default_mailbox_quota"])
        extra_domain_types = reduce(
            lambda a, b: a + b,
            [result[1] for result in signals.extra_domain_types.send(
                sender=self.__class__)]
        )
        self.fields["type"].choices = DOMAIN_TYPES + extra_domain_types
        self.field_widths = {
            "quota": 3,
            "default_mailbox_quota": 3
        }
        self.user = user

        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)
示例#10
0
    def mail_home(self):
        """Retrieve the home directory of this mailbox.

        The home directory refers to the place on the file system
        where the mailbox data is stored.

        We ask dovecot to give us this information because there are
        several patterns to understand and we don't want to implement
        them.
        """
        admin_params = dict(param_tools.get_global_parameters("admin"))
        if not admin_params.get("handle_mailboxes"):
            return None
        if self.__mail_home is None:
            curuser = pwd.getpwuid(os.getuid()).pw_name
            mbowner = admin_params["mailboxes_owner"]
            options = {}
            if curuser != mbowner:
                options["sudo_user"] = mbowner
            code, output = exec_cmd(
                "doveadm user %s -f home" % self.full_address, **options
            )
            if code:
                raise lib_exceptions.InternalError(
                    _(u"Failed to retrieve mailbox location (%s)") % output)
            self.__mail_home = output.strip()
        return self.__mail_home
示例#11
0
    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
示例#12
0
 def handle(self, *args, **options):
     """Entry point."""
     load_admin_settings()
     ImapMigration().load()
     conf = dict(
         param_tools.get_global_parameters("modoboa_imap_migration"))
     context = {
         "imap_server_address":
         conf["server_address"],
         "imap_server_port":
         conf["server_port"],
         "imap_server_secured":
         conf["secured"],
         "imap_create_folders":
         conf["create_folders"],
         "imap_folder_filter_exclude":
         conf["folder_filter_exclude"],
         "imap_folder_filter_include":
         ", ".join("'{0}'".format(w)
                   for w in conf["folder_filter_include"].split(",")),
         "migrations":
         Migration.objects.select_related("mailbox"),
     }
     with open(options["output"], "w") as fpo:
         content = render_to_string(
             "modoboa_imap_migration/offlineimap.conf", context)
         fpo.write(content)
示例#13
0
 def dns_global_status(self) -> str:
     """Return global DNS status."""
     if not self.enable_dns_checks or self.uses_a_reserved_tld:
         return "disabled"
     elif self.awaiting_checks():
         return "pending"
     config = dict(param_tools.get_global_parameters("admin"))
     errors = []
     if config["enable_mx_checks"] and not self.mxrecord_set.has_valids():
         errors.append("mx")
     if config["enable_dnsbl_checks"] and self.dnsblresult_set.blacklisted(
     ).exists():
         errors.append("dnsbl")
     if config["enable_spf_checks"]:
         if self.spf_record is None or not self.spf_record.is_valid:
             errors.append("spf")
         if self.dkim_record is None or not self.dkim_record.is_valid:
             errors.append("dkim")
         if self.dmarc_record is None or not self.dmarc_record.is_valid:
             errors.append("dmarc")
     if config["enable_autoconfig_checks"]:
         if self.autoconfig_record is None:
             errors.append("autoconfig")
         if self.autodiscover_record is None:
             errors.append("autodiscover")
     if len(errors) == 0:
         return "ok"
     return "critical"
示例#14
0
 def __init__(self, user=None, password=None):
     self.__hdelimiter = None
     self.quota_usage = -1
     self.criterions = []
     self.conf = dict(param_tools.get_global_parameters("modoboa_webmail"))
     self.address = self.conf["imap_server"]
     self.port = self.conf["imap_port"]
     self.login(user, password)
示例#15
0
def delete_ldap_account(sender, instance, **kwargs):
    """Delete LDAP account if needed."""
    config = dict(param_tools.get_global_parameters("core"))
    if not config["ldap_enable_sync"]:
        return
    if instance.role != "SimpleUsers":
        return
    lib.delete_ldap_account(instance, config)
示例#16
0
def create_domain_limits(sender, instance, **kwargs):
    """Create limits for new domain."""
    if not kwargs.get("created"):
        return
    global_params = dict(param_tools.get_global_parameters("limits"))
    for name, _definition in utils.get_domain_limit_templates():
        max_value = global_params["deflt_domain_{0}_limit".format(name)]
        models.DomainObjectLimit.objects.create(
            domain=instance, name=name, max_value=max_value)
示例#17
0
 def __init__(self):
     param_tools.apply_to_django_settings()
     self.global_params = dict(param_tools.get_global_parameters("core"))
     self.server_uri = self._setting("AUTH_LDAP_SERVER_URI",
                                     "ldap://localhost")
     self.pwd_attr = self._setting("LDAP_PASSWORD_ATTR", "userPassword")
     self.ldap_ad = self._setting("LDAP_ACTIVE_DIRECTORY", False)
     self.conn = None
     self.user_filter = self._setting("LDAP_USER_FILTER", "")
示例#18
0
文件: handlers.py 项目: mvb9/modoboa
def create_domain_limits(sender, instance, **kwargs):
    """Create limits for new domain."""
    if not kwargs.get("created"):
        return
    global_params = dict(param_tools.get_global_parameters("limits"))
    for name, definition in utils.get_domain_limit_templates():
        max_value = global_params["deflt_domain_{0}_limit".format(name)]
        models.DomainObjectLimit.objects.create(
            domain=instance, name=name, max_value=max_value)
示例#19
0
 def __init__(self):
     param_tools.apply_to_django_settings()
     self.global_params = dict(param_tools.get_global_parameters("core"))
     self.server_uri = self._setting(
         "AUTH_LDAP_SERVER_URI", "ldap://localhost"
     )
     self.pwd_attr = self._setting("LDAP_PASSWORD_ATTR", "userPassword")
     self.ldap_ad = self._setting("LDAP_ACTIVE_DIRECTORY", False)
     self.conn = None
     self.user_filter = self._setting("LDAP_USER_FILTER", "")
示例#20
0
    def handle(self, *args, **options):
        Amavis().load()
        if options["debug"]:
            import logging
            log = logging.getLogger("django.db.backends")
            log.setLevel(logging.DEBUG)
            log.addHandler(logging.StreamHandler())
        self.verbose = options["verbose"]

        conf = dict(param_tools.get_global_parameters("modoboa_amavis"))

        flags = ["D"]
        if conf["released_msgs_cleanup"]:
            flags += ["R"]

        self.__vprint("Deleting marked messages...")
        ids = Msgrcpt.objects.filter(rs__in=flags).values("mail_id").distinct()
        for msg in Msgs.objects.filter(mail_id__in=ids):
            if not msg.msgrcpt_set.exclude(rs__in=flags).count():
                msg.delete()

        self.__vprint("Deleting messages older than {} days...".format(
            conf["max_messages_age"]))
        limit = int(time.time()) - (conf["max_messages_age"] * 24 * 3600)
        # Delete older messages in batches.
        # This would avoid consuming too much RAM when
        # having to delete many thousands of messages
        # leading to process OOM kill or soft crash.
        res = Msgs.objects.filter(time_num__lt=limit)[:5000]
        while res.count() != 0:
            for item in res:
                item.delete()
            res = Msgs.objects.filter(time_num__lt=limit)[:5000]

        self.__vprint("Deleting unreferenced e-mail addresses...")
        # Delete unreferenced email addresses in batches.
        # This would avoid consuming too much RAM when
        # having to delete many thousands of messages
        # leading to process OOM kill or soft crash.
        res = Maddr.objects.annotate(msgs_count=Count("msgs"),
                                     msgrcpt_count=Count("msgrcpt")).filter(
                                         msgs_count=0,
                                         msgrcpt_count=0)[:100000]

        while res.count() != 0:
            for item in res:
                item.delete()

            res = Maddr.objects.annotate(
                msgs_count=Count("msgs"),
                msgrcpt_count=Count("msgrcpt")).filter(
                    msgs_count=0, msgrcpt_count=0)[:100000]

        self.__vprint("Done.")
 def handle(self, *args, **options):
     """Command entry point."""
     localconfig = models.LocalConfig.objects.first()
     if not localconfig.need_dovecot_update:
         return
     config = dict(param_tools.get_global_parameters("core"))
     condition = (config["authentication_type"] == "ldap"
                  and config["ldap_dovecot_sync"])
     if condition:
         lib.update_dovecot_config_file(config)
     localconfig.need_dovecot_update = False
     localconfig.save(update_fields=["need_dovecot_update"])
示例#22
0
 def __init__(self):
     conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
     try:
         if conf["am_pdp_mode"] == "inet":
             self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.sock.connect((conf["am_pdp_host"], conf["am_pdp_port"]))
         else:
             self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.sock.connect(conf["am_pdp_socket"])
     except socket.error as err:
         raise InternalError(_("Connection to amavis failed: %s" %
                               str(err)))
示例#23
0
 def __init__(self, user, *args, **kwargs):
     """Constructor."""
     super(LearningRecipientForm, self).__init__(*args, **kwargs)
     choices = []
     if user.role == "SuperAdmins":
         choices.append(("global", _("Global database")))
     conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
     if conf["domain_level_learning"]:
         choices.append(("domain", _("Domain's database")))
     if conf["user_level_learning"]:
         choices.append(("user", _("User's database")))
     self.fields["recipient"].choices = choices
示例#24
0
def send_mail(request, form, posturl=None):
    """Email verification and sending.

    If the form does not present any error, a new MIME message is
    constructed. Then, a connection is established with the defined
    SMTP server and the message is finally sent.

    :param request: a Request object
    :param posturl: the url to post the message form to
    :return: a 2-uple (True|False, HttpResponse)
    """
    if not form.is_valid():
        editormode = request.user.parameters.get_value("editor")
        listing = render_to_string(
            "modoboa_webmail/compose.html", {
                "form": form,
                "noerrors": True,
                "body": form.cleaned_data.get("body", "").strip(),
                "posturl": posturl
            }, request)
        return False, {
            "status": "ko",
            "listing": listing,
            "editor": editormode
        }

    msg = form.to_msg(request)
    conf = dict(param_tools.get_global_parameters("modoboa_webmail"))
    options = {"host": conf["smtp_server"], "port": conf["smtp_port"]}
    if conf["smtp_secured_mode"] == "ssl":
        options.update({"use_ssl": True})
    elif conf["smtp_secured_mode"] == "starttls":
        options.update({"use_tls": True})
    if conf["smtp_authentication"]:
        options.update({
            "username": request.user.username,
            "password": get_password(request)
        })
    try:
        with mail.get_connection(**options) as connection:
            msg.connection = connection
            msg.send()
    except Exception as inst:
        raise WebmailInternalError(str(inst))

    # Copy message to sent folder
    sentfolder = request.user.parameters.get_value("sent_folder")
    get_imapconnector(request).push_mail(sentfolder, msg.message())
    clean_attachments(request.session["compose_mail"]["attachments"])
    del request.session["compose_mail"]

    return True, {}
示例#25
0
def sync_ldap_account(sender, instance, created, **kwargs):
    """Create/modify a new LDAP account if needed."""
    config = dict(param_tools.get_global_parameters("core"))
    if not config["ldap_enable_sync"]:
        return
    if created:
        return
    if instance.role != "SimpleUsers":
        return
    update_fields = kwargs.get("update_fields")
    if update_fields and "last_login" in update_fields:
        return
    lib.update_ldap_account(instance, config)
示例#26
0
def index(request):
    """Default view."""
    check_learning_rcpt = "false"
    conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
    if conf["manual_learning"]:
        if request.user.role != "SimpleUsers":
            if conf["user_level_learning"] or conf["domain_level_learning"]:
                check_learning_rcpt = "true"
    context = {
        "selection": "quarantine",
        "check_learning_rcpt": check_learning_rcpt
    }
    return render(request, "modoboa_amavis/index.html", context)
示例#27
0
 def setUp(self):
     super().setUp()
     self.set_global_parameters({
         "ldap_enable_import": True,
         "ldap_server_port": settings.LDAP_SERVER_PORT,
         "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com",
         "ldap_sync_bind_password": "******",
         "ldap_import_search_base": "ou=users,dc=example,dc=com",
         "ldap_import_search_filter": "(objectClass=person)",
         "ldap_groups_search_base": "ou=groups,dc=example,dc=com",
         "ldap_admin_groups": "admins",
     }, app="core")
     self.config = dict(param_tools.get_global_parameters("core"))
     self.conn = lib.get_connection(self.config)
示例#28
0
文件: tests.py 项目: tonioo/modoboa
 def setUp(self):
     super(LDAPSyncTestCase, self).setUp()
     self.set_global_parameters({
         "ldap_enable_sync": True,
         "ldap_server_port": 3389,
         "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com",
         "ldap_sync_bind_password": "******",
         "ldap_sync_account_dn_template": (
             "cn=%(user)s,ou=users,dc=example,dc=com"),
     }, app="core")
     self.config = dict(param_tools.get_global_parameters("core"))
     self.conn = lib.get_connection(self.config)
     self.username = "******"
     self.dn = self.config["ldap_sync_account_dn_template"] % {
         "user": self.username}
示例#29
0
 def create(self, validated_data):
     """Set permissions."""
     params = dict(param_tools.get_global_parameters("admin"))
     domain = models.Domain(**validated_data)
     condition = (params["default_domain_message_limit"] is not None
                  and "message_limit" not in validated_data)
     if condition:
         domain.message_limit = params["default_domain_message_limit"]
     creator = self.context["request"].user
     core_signals.can_create_object.send(sender=self.__class__,
                                         context=creator,
                                         klass=models.Domain,
                                         instance=domain)
     domain.save(creator=creator)
     return domain
示例#30
0
def update_rspamd_dkim_maps(sender, domains, **kwargs):
    """Update config maps."""
    qset = admin_models.Domain.objects.filter(enable_dkim=True)
    config = dict(param_tools.get_global_parameters("modoboa_rspamd"))
    if not config["path_map_path"] or not config["selector_map_path"]:
        return
    dkim_path_map = open(config["path_map_path"], "w")
    dkim_selector_map = open(config["selector_map_path"], "w")
    for domain in qset:
        dkim_path_map.write("{} {}\n".format(domain.name,
                                             domain.dkim_private_key_path))
        dkim_selector_map.write("{} {}\n".format(domain.name,
                                                 domain.dkim_key_selector))
    dkim_path_map.close()
    dkim_selector_map.close()
示例#31
0
 def setUp(self):
     super().setUp()
     self.set_global_parameters({
         "ldap_enable_sync": True,
         "ldap_server_port": settings.LDAP_SERVER_PORT,
         "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com",
         "ldap_sync_bind_password": "******",
         "ldap_sync_account_dn_template": (
             "cn=%(user)s,ou=users,dc=example,dc=com"),
     }, app="core")
     self.config = dict(param_tools.get_global_parameters("core"))
     self.conn = lib.get_connection(self.config)
     self.username = "******"
     self.dn = self.config["ldap_sync_account_dn_template"] % {
         "user": self.username}
示例#32
0
文件: handlers.py 项目: mvb9/modoboa
def create_user_limits(sender, instance, **kwargs):
    """Create limits for new user."""
    if not kwargs.get("created"):
        return
    request = lib_signals.get_request()
    creator = request.user if request else None
    global_params = dict(param_tools.get_global_parameters("limits"))
    for name, definition in utils.get_user_limit_templates():
        ct = ContentType.objects.get_by_natural_key(
            *definition["content_type"].split("."))
        max_value = 0
        # creator can be None if user was created by a factory
        if not creator or creator.is_superuser:
            max_value = global_params["deflt_user_{0}_limit".format(name)]
        models.UserObjectLimit.objects.create(
            user=instance, name=name, content_type=ct, max_value=max_value)
示例#33
0
 def handle(self, *args, **options):
     """Entry point."""
     load_admin_settings()
     ImapMigration().load()
     conf = dict(
         param_tools.get_global_parameters("modoboa_imap_migration"))
     context = {
         "imap_server_address": conf["server_address"],
         "imap_server_port": conf["server_port"],
         "imap_server_secured": conf["secured"],
         "migrations": Migration.objects.select_related("mailbox").all(),
     }
     with open(options["output"], "w") as fpo:
         content = render_to_string(
             "modoboa_imap_migration/offlineimap.conf", context)
         fpo.write(content)
示例#34
0
def create_user_limits(sender, instance, **kwargs):
    """Create limits for new user."""
    if not kwargs.get("created"):
        return
    request = lib_signals.get_request()
    creator = request.user if request else None
    global_params = dict(param_tools.get_global_parameters("limits"))
    for name, definition in utils.get_user_limit_templates():
        ct = ContentType.objects.get_by_natural_key(
            *definition["content_type"].split("."))
        max_value = 0
        # creator can be None if user was created by a factory
        if not creator or creator.is_superuser:
            max_value = global_params["deflt_user_{0}_limit".format(name)]
        models.UserObjectLimit.objects.create(
            user=instance, name=name, content_type=ct, max_value=max_value)
示例#35
0
def manual_learning_enabled(user):
    """Check if manual learning is enabled or not.

    Also check for :kw:`user` if necessary.

    :return: True if learning is enabled, False otherwise.
    """
    conf = dict(param_tools.get_global_parameters("modoboa_amavis"))
    if not conf["manual_learning"]:
        return False
    if user.role != "SuperAdmins":
        if user.has_perm("admin.view_domains"):
            manual_learning = (conf["domain_level_learning"]
                               or conf["user_level_learning"])
        else:
            manual_learning = conf["user_level_learning"]
        return manual_learning
    return True
示例#36
0
 def login(self, user, password):
     conf = dict(param_tools.get_global_parameters("modoboa_sievefilters"))
     self.msc = managesieve.Client(
         conf["server"], conf["port"], debug=False)
     authmech = conf["authentication_mech"]
     if authmech == "AUTO":
         authmech = None
     try:
         ret = self.msc.connect(user, password,
                                starttls=conf["starttls"], authmech=authmech)
     except managesieve.Error:
         ret = False
     if not ret:
         return False, _(
             "Connection to MANAGESIEVE server failed, check your "
             "configuration"
         )
     return True, None
示例#37
0
文件: account.py 项目: tsabi/modoboa
    def __init__(self, user, *args, **kwargs):
        self.mb = kwargs.pop("instance", None)
        self.user = user
        super().__init__(*args, **kwargs)
        self.field_widths = {
            "quota": 3
        }
        params = dict(param_tools.get_global_parameters("admin"))
        if self.mb is not None:
            self.fields["email"].required = True
            qset = self.mb.aliasrecipient_set.filter(alias__internal=False)
            for cpt, ralias in enumerate(qset):
                name = "aliases_{}".format(cpt + 1)
                self._create_field(
                    lib_fields.UTF8AndEmptyUserEmailField, name,
                    ralias.alias.address)
            for cpt, saddress in enumerate(self.mb.senderaddress_set.all()):
                name = "senderaddress_{}".format(cpt + 1)
                self._create_field(
                    lib_fields.UTF8AndEmptyUserEmailField, name,
                    saddress.address)
            self.fields["email"].initial = self.mb.full_address
            self.fields["quota_act"].initial = self.mb.use_domain_quota
            if not self.mb.use_domain_quota and self.mb.quota:
                self.fields["quota"].initial = self.mb.quota
            if self.mb.message_limit:
                self.fields["message_limit"].initial = self.mb.message_limit
            self.fields["create_alias_with_old_address"].initial = (
                params["create_alias_on_mbox_rename"]
            )
        else:
            del self.fields["create_alias_with_old_address"]
            self.fields["quota_act"].initial = True
            if params["default_mailbox_message_limit"] is not None:
                self.fields["message_limit"].initial = (
                    params["default_mailbox_message_limit"])

        if len(args) and isinstance(args[0], QueryDict):
            self._load_from_qdict(
                args[0], "aliases", lib_fields.UTF8AndEmptyUserEmailField)
            self._load_from_qdict(
                args[0], "senderaddress",
                lib_fields.UTF8AndEmptyUserEmailField)
 def handle(self, *args, **options):
     """Entry point."""
     load_admin_settings()
     ImapMigration().load()
     conf = dict(
         param_tools.get_global_parameters("modoboa_imap_migration"))
     context = {
         "imap_create_folders": conf["create_folders"],
         "imap_folder_filter_exclude": conf["folder_filter_exclude"],
         "imap_folder_filter_include": ", ".join(
             "'{0}'".format(w)
             for w in conf["folder_filter_include"].split(",")),
         "migrations": Migration.objects.select_related(
             "provider", "mailbox__domain"),
     }
     with open(options["output"], "w") as fpo:
         content = render_to_string(
             "modoboa_imap_migration/offlineimap.conf", context)
         fpo.write(content)
示例#39
0
    def __init__(self, user, *args, **kwargs):
        self.oldname = None
        if "instance" in kwargs:
            self.old_dkim_key_length = kwargs["instance"].dkim_key_length
            self.oldname = kwargs["instance"].name
        super(DomainFormGeneral, self).__init__(*args, **kwargs)
        params = dict(param_tools.get_global_parameters("admin"))
        self.fields["quota"].initial = params["default_domain_quota"]
        self.fields["default_mailbox_quota"].initial = (
            params["default_mailbox_quota"])
        self.fields["type"].choices = constants.DOMAIN_TYPES
        self.field_widths = {
            "quota": 3,
            "default_mailbox_quota": 3
        }
        self.user = user

        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)
示例#40
0
 def __init__(self, *args, **kwargs):
     """Load LDAP settings."""
     param_tools.apply_to_django_settings()
     super(LDAPBackend, self).__init__(*args, **kwargs)
     self.global_params = dict(
         param_tools.get_global_parameters("core"))
示例#41
0
def credentials(account, password):
    """Generate a PDF document containing account credentials."""

    def page_template(canvas, doc):
        canvas.setTitle(_("Personal account information"))
        canvas.setAuthor(account.fullname)
        canvas.setCreator("Modoboa")
        footer = [Paragraph(_("Powered by Modoboa - Mail hosting made simple"),
                            styles["Footer"])]
        Frame(0, 0, 21 * cm, 2 * cm).addFromList(footer, canvas)

    conf = dict(
        param_tools.get_global_parameters("modoboa_pdfcredentials"))
    filename = lib.get_creds_filename(account)
    buff = BytesIO()
    doc = SimpleDocTemplate(buff, pagesize=A4)
    story = []
    story.append(resized_image(lib.get_document_logo(), 8*cm))
    story.append(Spacer(1, 1 * cm))
    story.append(Paragraph(conf["title"], styles["Title"]))
    story.append(Spacer(1, 1 * cm))
    story.append(Paragraph(_("""
Dear %s, this document contains the credentials you will need
to connect to Modoboa. Learn the content and destroy
the document as soon as possible.
""") % account.fullname, styles["Normal"]))
    story.append(Spacer(1, 0.2 * cm))
    story.append(Paragraph(_("Web panel:"), styles["h3"]))
    data = [
        ["URL", conf["webpanel_url"]],
        [_("Username"), account.username],
        [_("Password"), password]
    ]
    table = Table(data)
    table.setStyle(TableStyle([
        ('TEXTCOLOR', (1, 0), (1, 0), colors.blue),
        ('GRID', (0, 0), (-1, -1), 1, colors.black),
        ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
    ]))
    story.append(table)
    story.append(Spacer(1, 0.5 * cm))
    story.append(Paragraph(_("""
Here you can view your emails anytime online, create filters or manage
your contacts.
"""), styles["Normal"]))

    story.append(Spacer(1, 0.2 * cm))
    story.append(Paragraph(
        _("Please change your password!"),
        styles["Warning"]))

    if conf["include_connection_settings"]:
        story.append(Spacer(1, 1 * cm))
        story.append(Paragraph(
            _("PC/Tablet/Smartphone configuration:"), styles["h3"]))
        story.append(Spacer(1, 0.2 * cm))
        data = [
            [_("SMTP server address"), conf["smtp_server_address"]],
            [_("SMTP server port"), conf["smtp_server_port"]],
            [_("SMTP connection security"), conf["smtp_connection_security"]],
            [_("IMAP server address"), conf["imap_server_address"]],
            [_("IMAP server port"), conf["imap_server_port"]],
            [_("IMAP connection security"), conf["imap_connection_security"]],
        ]
        table = Table(data)
        table.setStyle(TableStyle([
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
        ]))
        story.append(table)
        story.append(Spacer(1, 0.5 * cm))
        story.append(Paragraph(
            _("Use those settings for your computer, tablet or phone."),
            styles["Normal"])
        )

    if conf["custom_message"]:
        story.append(Spacer(1, 2 * cm))
        story.append(Paragraph(conf["custom_message"], styles["Greeting"]))

    doc.build(story, onFirstPage=page_template, onLaterPages=page_template)
    length = len(buff.getvalue())
    buff.seek(0)
    lib.crypt_and_save_to_file(buff, filename, length)