Esempio n. 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)
Esempio n. 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()
Esempio n. 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()
Esempio n. 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]
Esempio n. 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()
Esempio n. 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)
Esempio n. 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
Esempio n. 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"))))
    ]
Esempio n. 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)
Esempio n. 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)
Esempio n. 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")
        ))
    )]
Esempio n. 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()
Esempio n. 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.")
Esempio n. 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]
Esempio n. 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
Esempio n. 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.")
Esempio n. 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
Esempio n. 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
Esempio n. 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")
        })
Esempio n. 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))
Esempio n. 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))
Esempio n. 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))
Esempio n. 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))
Esempio n. 24
0
File: lib.py Progetto: Tdey/modoboa
 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)))
Esempio n. 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
Esempio n. 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))
Esempio n. 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
Esempio n. 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
    ))
Esempio n. 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
Esempio n. 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
Esempio n. 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)))
Esempio n. 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)
Esempio n. 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()
Esempio n. 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
     )
Esempio n. 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)
Esempio n. 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()
Esempio n. 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)
Esempio n. 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()
Esempio n. 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()
Esempio n. 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)
Esempio n. 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
        })
Esempio n. 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"]
Esempio n. 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)
Esempio n. 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)
Esempio n. 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)
Esempio n. 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
                })
Esempio n. 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)
Esempio n. 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(' ')
Esempio n. 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)
Esempio n. 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()
Esempio n. 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)
    })
Esempio n. 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()
Esempio n. 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()
Esempio n. 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()
Esempio n. 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())
Esempio n. 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)
Esempio n. 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)