Пример #1
0
 def __init__(self, user=None, password=None):
     self.__hdelimiter = None
     self.quota_usage = -1
     self.criterions = []
     self.address = parameters.get_admin("IMAP_SERVER")
     self.port = int(parameters.get_admin("IMAP_PORT"))
     self.login(user, password)
Пример #2
0
 def handle(self, *args, **options):
     Stats().load()
     if options["logfile"] is None:
         options["logfile"] = parameters.get_admin("LOGFILE", app="stats")
     p = LogParser(options, parameters.get_admin("RRD_ROOTDIR",
                                                 app="stats"))
     p.process()
Пример #3
0
    def delete(self, fromuser, keepdir=False):
        from modoboa.lib.permissions import \
            ungrant_access_to_object, ungrant_access_to_objects

        if self.domainalias_set.count():
            events.raiseEvent("DomainAliasDeleted", self.domainalias_set.all())
            ungrant_access_to_objects(self.domainalias_set.all())
        if self.mailbox_set.count():
            Quota.objects.filter(username__contains='@%s' % self.name).delete()
            events.raiseEvent("DeleteMailbox", self.mailbox_set.all())
            ungrant_access_to_objects(self.mailbox_set.all())
            hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
            if hm == "yes" and not keepdir:
                for mb in self.mailbox_set.all():
                    mb.delete_dir()
        if self.alias_set.count():
            events.raiseEvent("MailboxAliasDelete", self.alias_set.all())
            ungrant_access_to_objects(self.alias_set.all())
        if parameters.get_admin("AUTO_ACCOUNT_REMOVAL") == "yes":
            for account in User.objects.filter(
                    mailbox__domain__name=self.name):
                account.delete(fromuser, keepdir)
        events.raiseEvent("DeleteDomain", self)
        ungrant_access_to_object(self)
        super(Domain, self).delete()
Пример #4
0
 def __init__(self, user, recipient_db):
     """Constructor."""
     self._sa_is_local = parameters.get_admin("SA_IS_LOCAL")
     self._default_username = parameters.get_admin("DEFAULT_USER")
     self._recipient_db = recipient_db
     self._setup_cache = {}
     self._username_cache = []
     if user.role == "SimpleUsers":
         user_level_learning = parameters.get_admin("USER_LEVEL_LEARNING")
         if user_level_learning == "yes":
             self._username = user.email
     else:
         self._username = None
     self.error = None
     if self._sa_is_local == "yes":
         self._learn_cmd = "sa-learn --{0} --no-sync -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [0]
     else:
         self._learn_cmd = "spamc -d {0} -p {1}".format(
             parameters.get_admin("SPAMD_ADDRESS"),
             parameters.get_admin("SPAMD_PORT"))
         self._learn_cmd += " -L {0} -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [5, 6]
Пример #5
0
 def handle(self, *args, **options):
     Stats().load()
     if options["logfile"] is None:
         options["logfile"] = parameters.get_admin("LOGFILE", app="stats")
     p = LogParser(options, parameters.get_admin("RRD_ROOTDIR", app="stats"))
     p.process()
     db.close_connection()
Пример #6
0
def _domains(request):
    sort_order, sort_dir = get_sort_order(request.GET, "name")
    filters = dict(
        (flt, request.GET.get(flt, None))
        for flt in ['domfilter', 'searchquery']
        + events.raiseQueryEvent('ExtraDomainFilters')
    )
    request.session['domains_filters'] = filters
    domainlist = get_domains(request.user, **filters)
    if sort_order == 'name':
        domainlist = sorted(
            domainlist,
            key=lambda d: getattr(d, sort_order), reverse=sort_dir == '-'
        )
    else:
        domainlist = sorted(domainlist, key=lambda d: d.tags[0],
                            reverse=sort_dir == '-')
    context = {
        "handle_mailboxes": parameters.get_admin(
            "HANDLE_MAILBOXES", raise_error=False),
        "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL")
    }
    page = get_listing_page(domainlist, request.GET.get("page", 1))
    if page is None:
        context["length"] = 0
    else:
        context["rows"] = _render_to_string(
            request, "admin/domains_table.html", {
                'domains': page.object_list,
            }
        )
        context["pages"] = [page.number]
    return render_to_json_response(context)
Пример #7
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.
        """
        hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
        if hm is None or hm == "no":
            return None
        if self.__mail_home is None:
            curuser = pwd.getpwuid(os.getuid()).pw_name
            mbowner = parameters.get_admin("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(
                    _("Failed to retrieve mailbox location (%s)" % output))
            self.__mail_home = output.strip()
        return self.__mail_home
Пример #8
0
def extra_static_content(user):
    if parameters.get_admin("USER_CAN_RELEASE") == "yes" \
            or user.group == "SimpleUsers":
        return []

    tpl = Template("""<script type="text/javascript">
$(document).ready(function() {
    var poller = new Poller("{{ url }}", {
        interval: {{ interval }},
        success_cb: function(data) {
            var $link = $("#nbrequests");
            if (data.requests > 0) {
                $link.html(data.requests + " " + "{{ text }}");
                $link.parent().removeClass('hidden');
            } else {
                $link.parent().addClass('hidden');
            }
        }
    });

    $(document).bind('domform_init', function() {
        activate_widget.call($('#id_spam_subject_tag2_act'));
    });
});
</script>""")
    url = reverse("modoboa.extensions.amavis.views.nbrequests")
    interval = int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000
    return [
        tpl.render(
            Context(
                dict(url=url, interval=interval, text=_("pending requests"))))
    ]
Пример #9
0
def _domains(request):
    sort_order, sort_dir = get_sort_order(request.GET, "name")
    filters = dict((flt, request.GET.get(flt, None))
                   for flt in ['domfilter', 'searchquery'] +
                   events.raiseQueryEvent('ExtraDomainFilters'))
    request.session['domains_filters'] = filters
    domainlist = get_domains(request.user, **filters)
    if sort_order == 'name':
        domainlist = sorted(domainlist,
                            key=lambda d: getattr(d, sort_order),
                            reverse=sort_dir == '-')
    else:
        domainlist = sorted(domainlist,
                            key=lambda d: d.tags[0],
                            reverse=sort_dir == '-')
    context = {
        "handle_mailboxes":
        parameters.get_admin("HANDLE_MAILBOXES", raise_error=False),
        "auto_account_removal":
        parameters.get_admin("AUTO_ACCOUNT_REMOVAL")
    }
    page = get_listing_page(domainlist, request.GET.get("page", 1))
    if page is None:
        context["length"] = 0
    else:
        context["rows"] = _render_to_string(request,
                                            "admin/domains_table.html", {
                                                'domains': page.object_list,
                                            })
        context["pages"] = [page.number]
    return render_to_json_response(context)
Пример #10
0
 def __init__(self, user=None, password=None):
     self.__hdelimiter = None
     self.quota_usage = -1
     self.criterions = []
     self.address = parameters.get_admin("IMAP_SERVER")
     self.port = int(parameters.get_admin("IMAP_PORT"))
     self.login(user, password)
Пример #11
0
def extra_static_content(user):
    if user.group == "SimpleUsers":
        return []

    tpl = Template("""<script type="text/javascript">
$(document).ready(function() {
    {% if user_can_release == "no" %}var poller = new Poller("{{ url }}", {
        interval: {{ interval }},
        success_cb: function(data) {
            var $link = $("#nbrequests");
            if (data.requests > 0) {
                $link.html(data.requests + " " + "{{ text }}");
                $link.parent().removeClass('hidden');
            } else {
                $link.parent().addClass('hidden');
            }
        }
    });{% endif %}

    $(document).bind('domform_init', function() {
        activate_widget.call($('#id_spam_subject_tag2_act'));
    });
});
</script>""")

    return [tpl.render(
        Context(dict(
            url=reverse("modoboa.extensions.amavis.views.nbrequests"),
            interval=int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000,
            text=_("pending requests"),
            user_can_release=parameters.get_admin("USER_CAN_RELEASE")
        ))
    )]
Пример #12
0
    def delete(self, fromuser, keepdir=False):
        from modoboa.lib.permissions import \
            ungrant_access_to_object, ungrant_access_to_objects

        if self.domainalias_set.count():
            events.raiseEvent("DomainAliasDeleted", self.domainalias_set.all())
            ungrant_access_to_objects(self.domainalias_set.all())
        if self.mailbox_set.count():
            Quota.objects.filter(username__contains='@%s' % self.name).delete()
            events.raiseEvent("DeleteMailbox", self.mailbox_set.all())
            ungrant_access_to_objects(self.mailbox_set.all())
            hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
            if hm == "yes" and not keepdir:
                for mb in self.mailbox_set.all():
                    MailboxOperation.objects.create(
                        type='delete', argument=mb.mail_home
                    )
        if self.alias_set.count():
            events.raiseEvent("MailboxAliasDelete", self.alias_set.all())
            ungrant_access_to_objects(self.alias_set.all())
        if parameters.get_admin("AUTO_ACCOUNT_REMOVAL") == "yes":
            for account in User.objects.filter(mailbox__domain__name=self.name):
                account.delete(fromuser, keepdir)
        events.raiseEvent("DeleteDomain", self)
        ungrant_access_to_object(self)
        super(Domain, self).delete()
Пример #13
0
    def handle(self, *args, **options):
        if options["debug"]:
            import logging
            l = logging.getLogger("django.db.backends")
            l.setLevel(logging.DEBUG)
            l.addHandler(logging.StreamHandler())
        self.verbose = options["verbose"]

        max_messages_age = int(
            parameters.get_admin("MAX_MESSAGES_AGE", app="amavis"))

        flags = ['D']
        if parameters.get_admin("RELEASED_MSGS_CLEANUP",
                                app="amavis") == "yes":
            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..." %
                      max_messages_age)
        limit = int(time.time()) - (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.")
Пример #14
0
 def __init__(self, user, recipient_db):
     """Constructor."""
     self._sa_is_local = parameters.get_admin("SA_IS_LOCAL")
     self._default_username = parameters.get_admin("DEFAULT_USER")
     self._recipient_db = recipient_db
     self._setup_cache = {}
     self._username_cache = []
     if user.group == "SimpleUsers":
         user_level_learning = parameters.get_admin("USER_LEVEL_LEARNING")
         if user_level_learning == "yes":
             self._username = user.email
     else:
         self._username = None
     self.error = None
     if self._sa_is_local == "yes":
         self._learn_cmd = "sa-learn --{0} --no-sync -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [0]
     else:
         self._learn_cmd = "spamc -d {0} -p {1}".format(
             parameters.get_admin("SPAMD_ADDRESS"),
             parameters.get_admin("SPAMD_PORT")
         )
         self._learn_cmd += " -L {0} -u {1}"
         self._learn_cmd_kwargs = {}
         self._expected_exit_codes = [5, 6]
Пример #15
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.
        """
        hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
        if hm is None or hm == "no":
            return None
        if self.__mail_home is None:
            curuser = pwd.getpwuid(os.getuid()).pw_name
            mbowner = parameters.get_admin("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(
                    _("Failed to retrieve mailbox location (%s)" % output))
            self.__mail_home = output.strip()
        return self.__mail_home
Пример #16
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"]

        max_messages_age = int(parameters.get_admin("MAX_MESSAGES_AGE",
                                                    app="amavis"))

        flags = ['D']
        if parameters.get_admin("RELEASED_MSGS_CLEANUP",
                                app="amavis") == "yes":
            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..." % max_messages_age)
        limit = int(time.time()) - (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.")
Пример #17
0
 def _find_user_dn(self, user):
     sbase = parameters.get_admin("LDAP_SEARCH_BASE", app="admin")
     sfilter = parameters.get_admin("LDAP_SEARCH_FILTER", app="admin")
     sfilter = sfilter % {"user": user}
     res = self.conn.search_s(sbase, ldap.SCOPE_SUBTREE, sfilter)
     try:
         dn = res[0][0]
     except IndexError:
         return None
     return dn
Пример #18
0
 def _find_user_dn(self, user):
     sbase = parameters.get_admin("LDAP_SEARCH_BASE", app="core")
     sfilter = parameters.get_admin("LDAP_SEARCH_FILTER", app="core")
     sfilter = sfilter % {"user": user}
     res = self.conn.search_s(sbase, ldap.SCOPE_SUBTREE, sfilter)
     try:
         dn = res[0][0]
     except IndexError:
         return None
     return dn
Пример #19
0
def domains(request, tplname="admin/domains.html"):
    if not request.user.has_perm("admin.view_domains"):
        if request.user.has_perm("admin.view_mailboxes"):
            return HttpResponseRedirect(reverse("admin:identity_list"))
        return HttpResponseRedirect(reverse("core:user_index"))
    return render(
        request, tplname, {
            "selection": "domains",
            "enable_mx_checks": parameters.get_admin("ENABLE_MX_CHECKS"),
            "enable_dnsbl_checks": parameters.get_admin("ENABLE_DNSBL_CHECKS")
        })
Пример #20
0
 def delete_dir(self):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     if not os.path.exists(self.mail_home):
         return
     code, output = exec_cmd(
         "rm -r %s" % self.mail_home,
         sudo_user=parameters.get_admin("MAILBOXES_OWNER"))
     if code:
         raise AdminError(_("Failed to remove mailbox: %s" % output))
Пример #21
0
 def delete_dir(self):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     if not os.path.exists(self.mail_home):
         return
     code, output = exec_cmd(
         "rm -r %s" % self.mail_home,
         sudo_user=parameters.get_admin("MAILBOXES_OWNER")
     )
     if code:
         raise AdminError(_("Failed to remove mailbox: %s" % output))
Пример #22
0
 def rename_dir(self, old_mail_home):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     self.__mail_home = None
     if not os.path.exists(old_mail_home):
         return
     code, output = exec_cmd(
         "mv %s %s" % (old_mail_home, self.mail_home),
         sudo_user=parameters.get_admin("MAILBOXES_OWNER"))
     if code:
         raise AdminError(_("Failed to rename mailbox: %s" % output))
Пример #23
0
 def rename_dir(self, old_mail_home):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     self.__mail_home = None
     if not os.path.exists(old_mail_home):
         return
     code, output = exec_cmd(
         "mv %s %s" % (old_mail_home, self.mail_home),
         sudo_user=parameters.get_admin("MAILBOXES_OWNER")
     )
     if code:
         raise AdminError(_("Failed to rename mailbox: %s" % output))
Пример #24
0
 def __init__(self):
     mode = parameters.get_admin("AM_PDP_MODE")
     try:
         if mode == "inet":
             host = parameters.get_admin('AM_PDP_HOST')
             port = parameters.get_admin('AM_PDP_PORT')
             self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.sock.connect((host, int(port)))
         else:
             path = parameters.get_admin('AM_PDP_SOCKET')
             self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.sock.connect(path)
     except socket.error, err:
         raise ModoboaException(_("Connection to amavis failed: %s" % str(err)))
Пример #25
0
    def mail_home(self):
        """

        """
        hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
        if hm is None or hm == "no":
            return None
        if self.__mail_home is None:
            code, output = exec_cmd("doveadm user %s -f home" % self.full_address, 
                                    sudo_user=parameters.get_admin("MAILBOXES_OWNER"))
            if code:
                raise AdminError(_("Failed to retrieve mailbox location (%s)" % output))
            self.__mail_home = output.strip()
        return self.__mail_home
Пример #26
0
def index(request):
    """Default view."""
    check_learning_rcpt = "false"
    if parameters.get_admin("MANUAL_LEARNING") == "yes":
        if request.user.group != "SimpleUsers":
            user_level_learning = parameters.get_admin(
                "USER_LEVEL_LEARNING") == "yes"
            domain_level_learning = parameters.get_admin(
                "DOMAIN_LEVEL_LEARNING") == "yes"
            if user_level_learning or domain_level_learning:
                check_learning_rcpt = "true"
    return render(
        request, "amavis/index.html",
        dict(selection="quarantine", check_learning_rcpt=check_learning_rcpt))
Пример #27
0
    def mail_home(self):
        """

        """
        hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
        if hm is None or hm == "no":
            return None
        if self.__mail_home is None:
            code, output = exec_cmd("doveadm user %s -f home" % self.full_address, 
                                    sudo_user=parameters.get_admin("MAILBOXES_OWNER"))
            if code:
                raise AdminError(_("Failed to retrieve mailbox location (%s)" % output))
            self.__mail_home = output.strip()
        return self.__mail_home
Пример #28
0
def index(request):
    """Default view."""
    check_learning_rcpt = "false"
    if parameters.get_admin("MANUAL_LEARNING") == "yes":
        if request.user.group != "SimpleUsers":
            user_level_learning = parameters.get_admin(
                "USER_LEVEL_LEARNING") == "yes"
            domain_level_learning = parameters.get_admin(
                "DOMAIN_LEVEL_LEARNING") == "yes"
            if user_level_learning or domain_level_learning:
                check_learning_rcpt = "true"
    return render(request, "amavis/index.html", dict(
        selection="quarantine", check_learning_rcpt=check_learning_rcpt
    ))
Пример #29
0
 def __init__(self, user, *args, **kwargs):
     """Constructor."""
     super(LearningRecipientForm, self).__init__(*args, **kwargs)
     choices = []
     if user.group == "SuperAdmins":
         choices.append(("global", _("Global database")))
     domain_level_learning = parameters.get_admin(
         "DOMAIN_LEVEL_LEARNING") == "yes"
     user_level_learning = parameters.get_admin(
         "USER_LEVEL_LEARNING") == "yes"
     if domain_level_learning:
         choices.append(("domain", _("Domain's database")))
     if user_level_learning:
         choices.append(("user", _("User's database")))
     self.fields["recipient"].choices = choices
Пример #30
0
 def __init__(self, user, *args, **kwargs):
     """Constructor."""
     super(LearningRecipientForm, self).__init__(*args, **kwargs)
     choices = []
     if user.group == "SuperAdmins":
         choices.append(("global", _("Global database")))
     domain_level_learning = parameters.get_admin(
         "DOMAIN_LEVEL_LEARNING") == "yes"
     user_level_learning = parameters.get_admin(
         "USER_LEVEL_LEARNING") == "yes"
     if domain_level_learning:
         choices.append(("domain", _("Domain's database")))
     if user_level_learning:
         choices.append(("user", _("User's database")))
     self.fields["recipient"].choices = choices
Пример #31
0
 def __init__(self):
     mode = parameters.get_admin("AM_PDP_MODE")
     try:
         if mode == "inet":
             host = parameters.get_admin('AM_PDP_HOST')
             port = parameters.get_admin('AM_PDP_PORT')
             self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.sock.connect((host, int(port)))
         else:
             path = parameters.get_admin('AM_PDP_SOCKET')
             self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.sock.connect(path)
     except socket.error, err:
         raise InternalError(_("Connection to amavis failed: %s" %
                               str(err)))
Пример #32
0
def _identities(request):
    filters = dict((fname, request.GET.get(fname, None))
                   for fname in ['searchquery', 'idtfilter', 'grpfilter'])
    request.session['identities_filters'] = filters
    idents_list = get_identities(request.user, **filters)
    sort_order, sort_dir = get_sort_order(request.GET, "identity",
                                          ["identity", "name_or_rcpt", "tags"])
    if sort_order in ["identity", "name_or_rcpt"]:
        objects = sorted(idents_list, key=lambda o: getattr(o, sort_order),
                         reverse=sort_dir == '-')
    else:
        objects = sorted(idents_list, key=lambda o: o.tags[0],
                         reverse=sort_dir == '-')
    context = {
        "handle_mailboxes": parameters.get_admin(
            "HANDLE_MAILBOXES", raise_error=False)
    }
    page = get_listing_page(objects, request.GET.get("page", 1))
    if page is None:
        context["length"] = 0
    else:
        context["headers"] = _render_to_string(
            request, "admin/identity_headers.html", {})
        context["rows"] = _render_to_string(
            request, "admin/identities_table.html", {
                "identities": page.object_list
            }
        )
        context["pages"] = [page.number]
    return render_to_json_response(context)
Пример #33
0
    def login(self, user, passwd):
        """Custom login method

        We connect to the server, issue a LOGIN command. If
        successfull, we try to record a eventuel CAPABILITY untagged
        response. Otherwise, we issue the command.

        :param user: username
        :param passwd: password
        """
        import socket

        if isinstance(user, unicode):
            user = user.encode("utf-8")
        if isinstance(passwd, unicode):
            passwd = passwd.encode("utf-8")
        try:
            secured = parameters.get_admin("IMAP_SECURED")
            if secured == "yes":
                self.m = imaplib.IMAP4_SSL(self.address, self.port)
            else:
                self.m = imaplib.IMAP4(self.address, self.port)
        except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error:
            raise ImapError(_("Connection to IMAP server failed: %s" % error))

        data = self._cmd("LOGIN", user, passwd)
        self.m.state = "AUTH"
        if "CAPABILITY" in self.m.untagged_responses:
            self.capabilities = \
                self.m.untagged_responses.pop('CAPABILITY')[0].split()
        else:
            data = self._cmd("CAPABILITY")
            self.capabilities = data[0].split()
Пример #34
0
 def rename_dir(self, old_mail_home):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     MailboxOperation.objects.create(
         mailbox=self, type='rename', argument=old_mail_home
     )
Пример #35
0
def topredirection(request):
    """Simple view to redirect the request when no application is specified.

    The default "top redirection" can be specified in the *Admin >
    Settings* panel. It is the application that will be
    launched. Those not allowed to access the application will be
    redirected to their preferences page.

    This feature only applies to simple users.

    :param request: a Request object
    """
    from modoboa.lib import parameters
    from modoboa.core.extensions import exts_pool

    if request.user.group == 'SimpleUsers':
        topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core")
        if topredir != "user":
            infos = exts_pool.get_extension_infos(topredir)
            path = infos["url"] if infos["url"] else infos["name"]
        else:
            path = reverse("core:user_index")
    else:
        # FIXME
        path = reverse("admin:domain_list")
    return HttpResponseRedirect(path)
Пример #36
0
def send_autoreply(sender, mailbox, armessage):
    if armessage.fromdate > timezone.now():
        return
    if armessage.untildate is not None \
            and armessage.untildate < timezone.now():
        armessage.enabled = False
        armessage.save()
        return

    try:
        lastar = ARhistoric.objects.get(armessage=armessage.id, sender=sender)
        PostfixAutoreply().load()
        timeout = parameters.get_admin("AUTOREPLIES_TIMEOUT",
                                       app="postfix_autoreply")
        delta = datetime.timedelta(seconds=int(timeout))
        now = timezone.make_aware(datetime.datetime.now(),
                                  timezone.get_default_timezone())
        if lastar.last_sent + delta > now:
            sys.exit(0)
    except ARhistoric.DoesNotExist:
        lastar = ARhistoric()
        lastar.armessage = armessage
        lastar.sender = sender

    sendmail_simple(mailbox.user.encoded_address, sender, armessage.subject,
                    armessage.content.encode('utf-8'))

    lastar.last_sent = datetime.datetime.now()
    lastar.save()
Пример #37
0
def account_auto_created(user):
    from modoboa.core.models import User
    from modoboa.lib.permissions import grant_access_to_object
    from .lib import check_if_domain_exists

    if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no":
        return
    localpart, domname = split_mailbox(user.username)
    if user.group != 'SimpleUsers' and domname is None:
        return
    sadmins = User.objects.filter(is_superuser=True)
    try:
        domain = Domain.objects.get(name=domname)
    except Domain.DoesNotExist:
        label = check_if_domain_exists(
            domname, [(DomainAlias, _('domain alias'))])
        if label is not None:
            return
        domain = Domain(name=domname, enabled=True, quota=0)
        domain.save(creator=sadmins[0])
        for su in sadmins[1:]:
            grant_access_to_object(su, domain)
    try:
        mb = Mailbox.objects.get(domain=domain, address=localpart)
    except Mailbox.DoesNotExist:
        mb = Mailbox(
            address=localpart, domain=domain, user=user, use_domain_quota=True
        )
        mb.set_quota(override_rules=True)
        mb.save(creator=sadmins[0])
        for su in sadmins[1:]:
            grant_access_to_object(su, mb)
Пример #38
0
    def load_from_master_cf(self):
        """Load services from the master.cf file.

        Parse the configuration file to update the service table. New
        entries are saved and outdated ones (ie. present in the
        database but not in the file) are removed.
        """
        with open(parameters.get_admin('MASTER_CF_PATH')) as fp:
            content = fp.read()
        services = []
        for line in content.split('\n'):
            if not line or line.startswith('#'):
                continue
            parts = line.strip().split()
            if len(parts) != 8:
                continue
            if parts[7] != 'smtp':
                continue
            srv, created = self.get_or_create(name=parts[0])
            services.append(parts[0])
        to_delete = []
        for service in self.all():
            if service.name not in services:
                to_delete.append(service.name)
        Service.objects.filter(name__in=to_delete).delete()
Пример #39
0
    def login(self, user, passwd):
        """Custom login method

        We connect to the server, issue a LOGIN command. If
        successfull, we try to record a eventuel CAPABILITY untagged
        response. Otherwise, we issue the command.

        :param user: username
        :param passwd: password
        """
        import socket

        if isinstance(user, unicode):
            user = user.encode("utf-8")
        if isinstance(passwd, unicode):
            passwd = passwd.encode("utf-8")
        try:
            secured = parameters.get_admin("IMAP_SECURED")
            if secured == "yes":
                self.m = imaplib.IMAP4_SSL(self.address, self.port)
            else:
                self.m = imaplib.IMAP4(self.address, self.port)
        except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error:
            raise ImapError(_("Connection to IMAP server failed: %s" % error))

        data = self._cmd("LOGIN", user, passwd)
        self.m.state = "AUTH"
        if "CAPABILITY" in self.m.untagged_responses:
            self.capabilities = \
                self.m.untagged_responses.pop('CAPABILITY')[0].split()
        else:
            data = self._cmd("CAPABILITY")
            self.capabilities = data[0].split()
Пример #40
0
def topredirection(request):
    """Simple view to redirect the request when no application is specified

    The default "top redirection" can be specified in the *Admin >
    Settings* panel. It is the application that will be launched by
    default. Users that are not allowed to access this application
    will be redirected to the "User preferences" application.

    :param request: a Request object
    """
    from modoboa.lib import parameters
    from modoboa.core.extensions import exts_pool

    topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core")
    if not topredir in ["core"]:
        infos = exts_pool.get_extension_infos(topredir)
        path = infos["url"] if infos["url"] else infos["name"]
    else:
        path = "admin"  # topredir

    if topredir in ["core", "stats"] and \
            request.user.belongs_to_group('SimpleUsers'):
        path = "userprefs"

    return HttpResponseRedirect(path)
Пример #41
0
def attachments(request, tplname="webmail/attachments.html"):
    if request.method == "POST":
        csuploader = AttachmentUploadHandler()
        request.upload_handlers.insert(0, csuploader)
        error = None
        form = AttachmentForm(request.POST, request.FILES)
        if form.is_valid():
            try:
                fobj = request.FILES["attachment"]
                tmpname = save_attachment(fobj)
                request.session["compose_mail"]["attachments"] \
                    += [{"fname": str(fobj),
                         "content-type": fobj.content_type,
                         "size": fobj.size,
                         "tmpname": os.path.basename(tmpname)}]
                request.session.modified = True
                return render(
                    request, "webmail/upload_done.html", {
                        "status": "ok",
                        "fname": request.FILES["attachment"],
                        "tmpname": os.path.basename(tmpname)
                    })
            except WebmailError, inst:
                error = _("Failed to save attachment: ") + str(inst)

        if csuploader.toobig:
            error = _("Attachment is too big (limit: %s)" %
                      parameters.get_admin("MAX_ATTACHMENT_SIZE"))
        return render(request, "webmail/upload_done.html", {
            "status": "ko",
            "error": error
        })
Пример #42
0
    def __init__(self, user, *args, **kwargs):
        super(AccountFormGeneral, self).__init__(*args, **kwargs)
        self.fields.keyOrder = ['role', 'username', 'first_name', 'last_name',
                                'password1', 'password2', 'is_active']
        self.fields["is_active"].label = _("Enabled")
        self.user = user
        if user.group == "DomainAdmins":
            self.fields["role"] = forms.CharField(
                label="",
                widget=forms.HiddenInput, required=False
            )
        else:
            self.fields["role"].choices = [('', ugettext_lazy("Choose"))]
            self.fields["role"].choices += \
                get_account_roles(user, kwargs['instance']) \
                if 'instance' in kwargs else get_account_roles(user)

        if "instance" in kwargs:
            if args \
               and (args[0].get("password1", "") == ""
               and args[0].get("password2", "") == ""):
                self.fields["password1"].required = False
                self.fields["password2"].required = False
            account = kwargs["instance"]
            self.fields["role"].initial = account.group
            if not account.is_local \
               and parameters.get_admin("LDAP_AUTH_METHOD", app="core") == "directbind":
                del self.fields["password1"]
                del self.fields["password2"]
Пример #43
0
def account_auto_created(user):
    from modoboa.core.models import User
    from modoboa.lib.permissions import grant_access_to_object
    from .lib import check_if_domain_exists

    if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no":
        return
    localpart, domname = split_mailbox(user.username)
    if user.group != 'SimpleUsers' and domname is None:
        return
    sadmins = User.objects.filter(is_superuser=True)
    try:
        domain = Domain.objects.get(name=domname)
    except Domain.DoesNotExist:
        label = check_if_domain_exists(domname,
                                       [(DomainAlias, _('domain alias'))])
        if label is not None:
            return
        domain = Domain(name=domname, enabled=True, quota=0)
        domain.save(creator=sadmins[0])
        for su in sadmins[1:]:
            grant_access_to_object(su, domain)
    try:
        mb = Mailbox.objects.get(domain=domain, address=localpart)
    except Mailbox.DoesNotExist:
        mb = Mailbox(address=localpart,
                     domain=domain,
                     user=user,
                     use_domain_quota=True)
        mb.set_quota(override_rules=True)
        mb.save(creator=sadmins[0])
        for su in sadmins[1:]:
            grant_access_to_object(su, mb)
Пример #44
0
 def rename_dir(self, old_mail_home):
     hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
     if hm is None or hm == "no":
         return
     MailboxOperation.objects.create(mailbox=self,
                                     type='rename',
                                     argument=old_mail_home)
Пример #45
0
def _identities(request):
    filters = dict((fname, request.GET.get(fname, None))
                   for fname in ['searchquery', 'idtfilter', 'grpfilter'])
    request.session['identities_filters'] = filters
    idents_list = get_identities(request.user, **filters)
    sort_order, sort_dir = get_sort_order(request.GET, "identity",
                                          ["identity", "name_or_rcpt", "tags"])
    if sort_order in ["identity", "name_or_rcpt"]:
        objects = sorted(idents_list,
                         key=lambda o: getattr(o, sort_order),
                         reverse=sort_dir == '-')
    else:
        objects = sorted(idents_list,
                         key=lambda o: o.tags[0],
                         reverse=sort_dir == '-')
    context = {
        "handle_mailboxes":
        parameters.get_admin("HANDLE_MAILBOXES", raise_error=False)
    }
    page = get_listing_page(objects, request.GET.get("page", 1))
    if page is None:
        context["length"] = 0
    else:
        context["headers"] = _render_to_string(request,
                                               "admin/identity_headers.html",
                                               {})
        context["rows"] = _render_to_string(request,
                                            "admin/identities_table.html",
                                            {"identities": page.object_list})
        context["pages"] = [page.number]
    return render_to_json_response(context)
Пример #46
0
def attachments(request, tplname="webmail/attachments.html"):
    if request.method == "POST":
        csuploader = AttachmentUploadHandler()
        request.upload_handlers.insert(0, csuploader)
        error = None
        form = AttachmentForm(request.POST, request.FILES)
        if form.is_valid():
            try:
                fobj = request.FILES["attachment"]
                tmpname = save_attachment(fobj)
                request.session["compose_mail"]["attachments"] \
                    += [{"fname" : str(fobj),
                         "content-type" : fobj.content_type,
                         "size" : fobj.size,
                         "tmpname" : os.path.basename(tmpname)}]
                request.session.modified = True
                return _render(request, "webmail/upload_done.html", {
                        "status" : "ok", "fname" : request.FILES["attachment"],
                        "tmpname" : os.path.basename(tmpname)
                        })
            except WebmailError, inst:
                error = _("Failed to save attachment: ") + str(inst)

        if csuploader.toobig:
            error = _("Attachment is too big (limit: %s)" \
                          % parameters.get_admin("MAX_ATTACHMENT_SIZE"))
        return _render(request, "webmail/upload_done.html", {
                "status" : "ko", "error" : error
                })
Пример #47
0
    def notify_admins_pending_requests(self):
        self.sender = parameters.get_admin("NOTIFICATIONS_SENDER",
                                           app="amavis")
        self.baseurl = self.options["baseurl"].strip("/")
        self.listingurl = self.baseurl \
            + reverse("modoboa.extensions.amavis.views._listing") \
            + "?viewrequests=1"

        for da in User.objects.filter(groups__name="DomainAdmins"):
            if not da.mailbox_set.count():
                continue
            rcpt = da.mailbox_set.all()[0].full_address
            reqs = get_wrapper().get_domains_pending_requests(
                Domain.objects.get_for_admin(da))
            if reqs.count():
                self.send_pr_notification(rcpt, reqs)

        reqs = Msgrcpt.objects.filter(rs='p')
        if not reqs.count():
            if self.options["verbose"]:
                print "No release request currently pending"
            return
        for su in User.objects.filter(is_superuser=True):
            if not su.mailbox_set.count():
                continue
            rcpt = su.mailbox_set.all()[0].full_address
            self.send_pr_notification(rcpt, reqs)
Пример #48
0
def decrypt(ciph):
    obj = AES.new(
        parameters.get_admin("SECRET_KEY", app="admin"), AES.MODE_ECB
    )
    ciph = base64.b64decode(ciph)
    clear = obj.decrypt(ciph)
    return clear.rstrip(' ')
Пример #49
0
 def _crypt_password(self, raw_value):
     scheme = parameters.get_admin("PASSWORD_SCHEME")
     if type(raw_value) is unicode:
         raw_value = raw_value.encode("utf-8")
     if scheme == "crypt":
         salt = "".join(Random().sample(string.letters + string.digits, 2))
         result = crypt.crypt(raw_value, salt)
         prefix = "{CRYPT}"
     elif scheme == "md5":
         obj = hashlib.md5(raw_value)
         result = obj.hexdigest()
         prefix = "{MD5}"
     # The md5crypt scheme is the only supported method that has both:
     # (a) a salt ("crypt" has this too),
     # (b) supports passwords lengths of more than 8 characters (all except
     #     "crypt").
     elif scheme == "md5crypt":
         # The salt may vary from 12 to 48 bits. (Using all six bytes here
         # with a subset of characters means we get only 35 random bits.)
         salt = "".join(Random().sample(string.letters + string.digits, 6))
         result = md5crypt(raw_value, salt)
         prefix = ""  # the result already has $1$ prepended to it to signify what this is
     elif scheme == "sha256":
         obj = hashlib.sha256(raw_value)
         result = base64.b64encode(obj.digest())
         prefix = "{SHA256}"
     else:
         scheme = "plain"
         result = raw_value
         prefix = "{PLAIN}"
     return "%s%s" % (prefix, result)
Пример #50
0
    def _generate_file(self, target):
        """
        A user must not declare a rule for his direct admin!
        """
        self._cfgfile = open(target, "w")
        self._cfgfile.write("""# Rights management file for Radicale
# This file was generated by Modoboa on %s
# DO NOT EDIT MANUALLY!
        """ % datetime.datetime.today())

        allow_calendars_administration = parameters.get_admin(
            "ALLOW_CALENDARS_ADMINISTRATION", app="modoboa_radicale")
        if allow_calendars_administration == "yes":
            self._super_admin_rules()
            self._domain_admin_rules()

        self._generate_acr(
            "domain-shared-calendars", r"^(.+)@(.+)$", r"{1}/shared/.+$",
            comment="Access rule to domain shared calendars"
        )
        self._generate_acr(
            "owners-access", r"^(.+)@(.+)$", r"{1}/user/{0}/.+$",
            comment="Read/Write permission for calendar owners"
        )

        self._user_access_rules()
        self._cfgfile.close()
Пример #51
0
def _identities(request):
    filters = dict((fname, request.GET.get(fname, None))
                   for fname in ['searchquery', 'idtfilter', 'grpfilter'])
    request.session['identities_filters'] = filters
    idents_list = get_identities(request.user, **filters)
    sort_order, sort_dir = get_sort_order(request.GET, "identity",
                                          ["identity", "name_or_rcpt", "tags"])
    if sort_order in ["identity", "name_or_rcpt"]:
        objects = sorted(idents_list,
                         key=lambda o: getattr(o, sort_order),
                         reverse=sort_dir == '-')
    else:
        objects = sorted(idents_list,
                         key=lambda o: o.tags[0],
                         reverse=sort_dir == '-')
    page = get_listing_page(objects, request.GET.get("page", 1))
    return render_to_json_response({
        "table":
        _render_to_string(request, "admin/identities_table.html", {
            "identities": page.object_list,
            "tableid": "objects_table"
        }),
        "handle_mailboxes":
        parameters.get_admin("HANDLE_MAILBOXES", raise_error=False),
        "page":
        page.number,
        "paginbar":
        pagination_bar(page)
    })
Пример #52
0
def send_autoreply(sender, mailbox, armessage):
    if armessage.fromdate > timezone.now():
        return
    if armessage.untildate is not None \
        and armessage.untildate < timezone.now():
        armessage.enabled = False
        armessage.save()
        return

    try:
        lastar = ARhistoric.objects.get(armessage=armessage.id, sender=sender)
        PostfixAutoreply().load()
        timeout = parameters.get_admin("AUTOREPLIES_TIMEOUT",
                                       app="postfix_autoreply")
        delta = datetime.timedelta(seconds=int(timeout))
        now = timezone.make_aware(datetime.datetime.now(),
                                  timezone.get_default_timezone())
        if lastar.last_sent + delta > now:
            sys.exit(0)
    except ARhistoric.DoesNotExist:
        lastar = ARhistoric()
        lastar.armessage = armessage
        lastar.sender = sender

    sendmail_simple(mailbox.user.encoded_address, sender, armessage.subject,
                    armessage.content.encode('utf-8'))

    lastar.last_sent = datetime.datetime.now()
    lastar.save()
Пример #53
0
 def create_limits(self):
     for ltpl in limits_tpl:
         l = Limit()
         l.name = ltpl[0]
         l.pool = self
         l.maxvalue = int(parameters.get_admin("DEFLT_%s" % ltpl[0].upper()))
         l.save()
Пример #54
0
    def load_from_master_cf(self):
        """Load services from the master.cf file.

        Parse the configuration file to update the service table. New
        entries are saved and outdated ones (ie. present in the
        database but not in the file) are removed.
        """
        with open(parameters.get_admin('MASTER_CF_PATH')) as fp:
            content = fp.read()
        services = []
        for line in content.split('\n'):
            if not line or line.startswith('#'):
                continue
            parts = line.strip().split()
            if len(parts) != 8:
                continue
            if parts[7] != 'smtp':
                continue
            srv, created = self.get_or_create(name=parts[0])
            services.append(parts[0])
        to_delete = []
        for service in self.all():
            if service.name not in services:
                to_delete.append(service.name)
        Service.objects.filter(name__in=to_delete).delete()
Пример #55
0
 def load_from_user(self, user):
     for lname in self.fields.keys():
         self.fields[lname].initial = user.limitspool.getmaxvalue(lname)
         # The following lines will become useless in a near
         # future.
         if self.fields[lname].initial == -2:
             self.fields[lname].initial = parameters.get_admin("DEFLT_%s" % lname.upper())
Пример #56
0
    def notify_admins_pending_requests(self):
        self.sender = parameters.get_admin("NOTIFICATIONS_SENDER",
                                           app="amavis")
        self.baseurl = self.options["baseurl"].strip("/")
        self.listingurl = self.baseurl \
            + reverse("modoboa.extensions.amavis.views._listing") \
            + "?viewrequests=1"

        for da in User.objects.filter(groups__name="DomainAdmins"):
            if not da.mailbox_set.count():
                continue
            rcpt = da.mailbox_set.all()[0].full_address
            reqs = get_wrapper().get_domains_pending_requests(
                Domain.objects.get_for_admin(da)
            )
            if reqs.count():
                self.send_pr_notification(rcpt, reqs)

        reqs = Msgrcpt.objects.filter(rs='p')
        if not reqs.count():
            if self.options["verbose"]:
                print "No release request currently pending"
            return
        for su in User.objects.filter(is_superuser=True):
            if not su.mailbox_set.count():
                continue
            rcpt = su.mailbox_set.all()[0].full_address
            self.send_pr_notification(rcpt, reqs)
Пример #57
0
def topredirection(request):
    """Simple view to redirect the request when no application is specified.

    The default "top redirection" can be specified in the *Admin >
    Settings* panel. It is the application that will be
    launched. Those not allowed to access the application will be
    redirected to their preferences page.

    This feature only applies to simple users.

    :param request: a Request object
    """
    from modoboa.lib import parameters
    from modoboa.core.extensions import exts_pool

    if request.user.group == 'SimpleUsers':
        topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core")
        if topredir != "user":
            infos = exts_pool.get_extension_infos(topredir)
            path = infos["url"] if infos["url"] else infos["name"]
        else:
            path = reverse("core:user_index")
    else:
        # FIXME
        path = reverse("modoboa_admin:domain_list")
    return HttpResponseRedirect(path)