diff --git a/modoboa/auth/__init__.py b/modoboa/auth/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/modoboa/auth/forms.py b/modoboa/auth/forms.py deleted file mode 100644 index 143299654..000000000 --- a/modoboa/auth/forms.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding: utf-8 -from django import forms -from django.utils.translation import ugettext_lazy as _ - -class LoginForm(forms.Form): - username = forms.CharField( - label=_("Username"), - widget=forms.TextInput(attrs={"class": "input-block-level"}) - ) - password = forms.CharField( - label=_("Password"), - widget=forms.PasswordInput(attrs={"class": "input-block-level"}) - ) - rememberme = forms.BooleanField( - initial=False, - required=False - ) diff --git a/modoboa/auth/lib.py b/modoboa/auth/lib.py deleted file mode 100644 index 8808cd240..000000000 --- a/modoboa/auth/lib.py +++ /dev/null @@ -1,41 +0,0 @@ -# coding: utf-8 -from Crypto.Cipher import AES -import base64 -import random -import string -from modoboa.lib import parameters - - -def random_key(l=16): - """Generate a random key - - :param integer l: the key's length - :return: a string - """ - char_set = string.digits + string.letters + string.punctuation - return ''.join(random.sample(char_set * l, l)) - - -def encrypt(clear): - key = parameters.get_admin("SECRET_KEY", app="admin") - obj = AES.new(key, AES.MODE_ECB) - if type(clear) is unicode: - clear = clear.encode("utf-8") - if len(clear) % AES.block_size: - clear += " " * (AES.block_size - len(clear) % AES.block_size) - ciph = obj.encrypt(clear) - ciph = base64.b64encode(ciph) - return ciph - - -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(' ') - - -def get_password(request): - return decrypt(request.session["password"]) diff --git a/modoboa/auth/models.py b/modoboa/auth/models.py deleted file mode 100755 index 71a836239..000000000 --- a/modoboa/auth/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/modoboa/auth/tests.py b/modoboa/auth/tests.py deleted file mode 100755 index 082b0c52d..000000000 --- a/modoboa/auth/tests.py +++ /dev/null @@ -1,23 +0,0 @@ -# coding: utf-8 -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} diff --git a/modoboa/auth/views.py b/modoboa/auth/views.py deleted file mode 100755 index 9589e3414..000000000 --- a/modoboa/auth/views.py +++ /dev/null @@ -1,69 +0,0 @@ -# coding: utf-8 -import logging -from django.views.decorators.cache import never_cache -from django.contrib.auth import authenticate, login, logout -from django.http import HttpResponse, HttpResponseRedirect -from django.core.urlresolvers import reverse -from django.utils.translation import ugettext as _ -from modoboa.lib import events, parameters -from modoboa.lib.webutils import _render_to_string -from forms import LoginForm -from modoboa.auth.lib import encrypt - - -def dologin(request): - error = None - if request.method == "POST": - form = LoginForm(request.POST) - if form.is_valid(): - logger = logging.getLogger('modoboa.auth') - user = authenticate(username=form.cleaned_data["username"], - password=form.cleaned_data["password"]) - if user and user.is_active: - login(request, user) - if not form.cleaned_data["rememberme"]: - request.session.set_expiry(0) - if request.user.has_mailbox: - request.session["password"] = encrypt(form.cleaned_data["password"]) - - request.session["django_language"] = \ - parameters.get_user(request.user, "LANG", app="general") - - logger.info(_("User '%s' successfully logged in" % user.username)) - events.raiseEvent("UserLogin", request, - form.cleaned_data["username"], - form.cleaned_data["password"]) - - nextlocation = request.POST.get("next", None) - if nextlocation is None or nextlocation == "None": - if user.group == "SimpleUsers": - nextlocation = reverse("modoboa.lib.webutils.topredirection") - else: - nextlocation = reverse("domains") - return HttpResponseRedirect(nextlocation) - error = _("Your username and password didn't match. Please try again.") - logger.warning("Failed connection attempt from '%(addr)s' as user '%(user)s'" \ - % {"addr": request.META["REMOTE_ADDR"], - "user": form.cleaned_data["username"]}) - - nextlocation = request.POST.get("next", None) - httpcode = 401 - else: - form = LoginForm() - nextlocation = request.GET.get("next", None) - httpcode = 200 - - return HttpResponse(_render_to_string(request, "registration/login.html", { - "form": form, "error": error, "next": nextlocation, - "annoucements": events.raiseQueryEvent("GetAnnouncement", "loginpage") - }), status=httpcode) - -dologin = never_cache(dologin) - - -def dologout(request): - events.raiseEvent("UserLogout", request) - logger = logging.getLogger("modoboa.auth") - logger.info(_("User '%s' logged out" % request.user.username)) - logout(request) - return HttpResponseRedirect(reverse(dologin)) diff --git a/modoboa/core/app_settings.py b/modoboa/core/app_settings.py index 484d59de6..3160ecc9b 100644 --- a/modoboa/core/app_settings.py +++ b/modoboa/core/app_settings.py @@ -4,8 +4,8 @@ from django.conf import settings from django.utils.translation import ugettext as _, ugettext_lazy from modoboa.lib.formutils import YesNoField, SeparatorField, InlineRadioSelect from modoboa.lib.sysutils import exec_cmd +from modoboa.lib.cryptutils import random_key from modoboa.lib import parameters -from modoboa.auth.lib import random_key def enabled_applications(): diff --git a/modoboa/core/views/auth.py b/modoboa/core/views/auth.py index b892b0f58..3e2b25561 100644 --- a/modoboa/core/views/auth.py +++ b/modoboa/core/views/auth.py @@ -7,8 +7,8 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ from modoboa.lib import events, parameters from modoboa.lib.webutils import _render_to_string +from modoboa.lib.cryptutils import encrypt from modoboa.core.forms import LoginForm -from modoboa.auth.lib import encrypt def dologin(request): diff --git a/modoboa/extensions/sievefilters/__init__.py b/modoboa/extensions/sievefilters/__init__.py index 01c20a5bf..34fea4f6e 100644 --- a/modoboa/extensions/sievefilters/__init__.py +++ b/modoboa/extensions/sievefilters/__init__.py @@ -2,7 +2,7 @@ from django.utils.translation import ugettext as _, ugettext_lazy from django.core.urlresolvers import reverse from modoboa.lib import events, parameters -from modoboa.extensions import ModoExtension, exts_pool +from modoboa.core.extensions import ModoExtension, exts_pool class SieveFilters(ModoExtension): @@ -13,7 +13,7 @@ class SieveFilters(ModoExtension): url = "sfilters" def load(self): - from app_settings import ParametersForm, UserSettings + from .app_settings import ParametersForm, UserSettings parameters.register(ParametersForm, ugettext_lazy("Sieve filters")) parameters.register(UserSettings, ugettext_lazy("Message filters")) @@ -23,31 +23,31 @@ class SieveFilters(ModoExtension): exts_pool.register_extension(SieveFilters) + @events.observe("UserMenuDisplay") def menu(target, user): - import views - if target != "options_menu": return [] - if not user.has_mailbox: + if not user.mailbox_set.count(): return [] return [ - {"name" : "sievefilters", - "label" : _("Message filters"), - "url" : reverse(views.index), - "img" : "icon-check"} - ] + {"name": "sievefilters", + "label": _("Message filters"), + "url": reverse("modobooa.extensions.sievefilters.views.index"), + "img": "icon-check"} + ] + @events.observe("UserLogout") def userlogout(request): - from lib import SieveClient + from .lib import SieveClient if not request.user.has_mailbox: return try: sc = SieveClient(user=request.user.username, password=request.session["password"]) - except Exception, e: + except Exception: pass else: sc.logout() diff --git a/modoboa/extensions/sievefilters/app_settings.py b/modoboa/extensions/sievefilters/app_settings.py index 9fb60c365..75ae1a684 100644 --- a/modoboa/extensions/sievefilters/app_settings.py +++ b/modoboa/extensions/sievefilters/app_settings.py @@ -29,7 +29,7 @@ class ParametersForm(AdminParametersForm): initial=4190, help_text=_("Listening port of your MANAGESIEVE server") ) - + starttls = YesNoField( label=_("Connect using STARTTLS"), initial="no", @@ -59,4 +59,4 @@ class UserSettings(UserParametersForm): @staticmethod def has_access(user): - return user.has_mailbox + return user.mailbox_set.count() != 0 diff --git a/modoboa/extensions/sievefilters/forms.py b/modoboa/extensions/sievefilters/forms.py index 41ef3b16a..34cfd47ca 100644 --- a/modoboa/extensions/sievefilters/forms.py +++ b/modoboa/extensions/sievefilters/forms.py @@ -7,11 +7,15 @@ from django.utils.html import conditional_escape from django.utils.encoding import force_unicode from modoboa.extensions.admin.templatetags.admin_tags import gender + class FiltersSetForm(forms.Form): name = forms.CharField() - active = forms.BooleanField(label=gender("Active", "m"), required=False, - initial=False, - help_text=ugettext_lazy("Check to activate this filters set")) + active = forms.BooleanField( + label=gender("Active", "m"), required=False, + initial=False, + help_text=ugettext_lazy("Check to activate this filters set") + ) + class CustomRadioInput(RadioInput): def __unicode__(self): @@ -27,15 +31,16 @@ class CustomRadioInput(RadioInput): label_for = '' choice_label = conditional_escape(force_unicode(self.choice_label)) return mark_safe( - u'%s %s' \ - % (label_for, self.tag(), choice_label) - ) + u'%s %s' + % (label_for, self.tag(), choice_label) + ) + class CustomRadioFieldRenderer(RadioFieldRenderer): def __iter__(self): for i, choice in enumerate(self.choices): yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i) - + def __getitem__(self, idx): choice = self.choices[idx] return CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, idx) @@ -43,9 +48,11 @@ class CustomRadioFieldRenderer(RadioFieldRenderer): def render(self): return mark_safe(u'\n'.join([force_unicode(w) for w in self])) + class CustomRadioSelect(RadioSelect): renderer = CustomRadioFieldRenderer + class FilterForm(forms.Form): def __init__(self, conditions, actions, request, *args, **kwargs): super(FilterForm, self).__init__(*args, **kwargs) @@ -56,30 +63,32 @@ class FilterForm(forms.Form): ("anyof", _("Any of the following")), ("all", _("All messages"))], initial="anyof", - widget=CustomRadioSelect(attrs={"class" : "radio inline"}) - ) - - self.header_operators = [("contains", _("contains"), "string"), - ("notcontains", _("does not contain"), "string"), - ("is", _("is"), "string"), - ("isnot", _("is not"), "string")] - + widget=CustomRadioSelect(attrs={"class": "radio inline"}) + ) + + self.header_operators = [ + ("contains", _("contains"), "string"), + ("notcontains", _("does not contain"), "string"), + ("is", _("is"), "string"), + ("isnot", _("is not"), "string") + ] + self.cond_templates = [ - {"name" : "Subject", "label" : _("Subject"), "operators" : self.header_operators}, - {"name" : "From", "label" : _("Sender"), "operators" : self.header_operators}, - {"name" : "To", "label" : _("Recipient"), "operators" : self.header_operators}, - {"name" : "Cc", "label" : _("Cc"), "operators" : self.header_operators}, - {"name" : "size", "label" : _("Size"), - "operators" : [("over", _("is greater than"), "number"), - ("under", _("is less than"), "number")]}, - ] - + {"name": "Subject", "label": _("Subject"), "operators": self.header_operators}, + {"name": "From", "label": _("Sender"), "operators": self.header_operators}, + {"name": "To", "label": _("Recipient"), "operators": self.header_operators}, + {"name": "Cc", "label": _("Cc"), "operators": self.header_operators}, + {"name": "size", "label": _("Size"), + "operators": [("over", _("is greater than"), "number"), + ("under", _("is less than"), "number")]}, + ] + self.action_templates = [ - {"name" : "fileinto", "label" : _("Move message to"), - "args" : [{"type" : "list", "vloader" : "userfolders"}]}, - {"name" : "redirect", "label" : _("Redirect message to"), - "args" : [{"type" : "string"}]}, - ] + {"name": "fileinto", "label": _("Move message to"), + "args": [{"type": "list", "vloader": "userfolders"}]}, + {"name": "redirect", "label": _("Redirect message to"), + "args": [{"type": "string"}]}, + ] self.conds_cnt = 0 for c in conditions: @@ -93,7 +102,7 @@ class FilterForm(forms.Form): ops = [] vfield = None for tpl in self.cond_templates: - targets += [(tpl["name"], tpl["label"]),] + targets += [(tpl["name"], tpl["label"]), ] if tpl["name"] != name: continue for opdef in tpl["operators"]: @@ -109,7 +118,7 @@ class FilterForm(forms.Form): forms.ChoiceField(initial=op, choices=ops) self.fields["cond_value_%d" % self.conds_cnt] = vfield self.conds_cnt += 1 - + def _build_Subject_field(self, op, value): self._build_header_field("Subject", op, value) @@ -129,7 +138,7 @@ class FilterForm(forms.Form): actions = [] args = None for tpl in self.action_templates: - actions += [(tpl["name"], tpl["label"]),] + actions += [(tpl["name"], tpl["label"]), ] if name == tpl["name"]: args = tpl["args"] self.fields["action_name_%d" % self.actions_cnt] = \ @@ -153,12 +162,12 @@ class FilterForm(forms.Form): def __build_folders_list(self, folders, user, imapc, parentmb=None): ret = [] for fd in folders: - value = fd["path"] if fd.has_key("path") else fd["name"] + value = fd["path"] if "path" in fd else fd["name"] if parentmb: ret += [(value, fd["name"].replace("%s." % parentmb, ""))] else: ret += [(value, fd["name"])] - if fd.has_key("sub"): + if "sub" in fd: submboxes = imapc.getmboxes(user, value, unseen_messages=False) ret += self.__build_folders_list(submboxes, user, imapc, value) return ret @@ -191,7 +200,8 @@ class FilterForm(forms.Form): actions += [naction] return (conditions, actions) - + + def build_filter_form_from_qdict(request): conditions = [] actions = [] @@ -204,7 +214,7 @@ def build_filter_form_from_qdict(request): while True: if cpt == int(request.POST["conds"]): break - if request.POST.has_key("cond_target_%d" % i): + if "cond_target_%d" % i in request.POST: qdict["cond_target_%d" % cpt] = request.POST["cond_target_%d" % i] qdict["cond_operator_%d" % cpt] = request.POST["cond_operator_%d" % i] qdict["cond_value_%d" % cpt] = request.POST["cond_value_%d" % i] @@ -219,7 +229,7 @@ def build_filter_form_from_qdict(request): while True: if cpt == int(request.POST["actions"]): break - if request.POST.has_key("action_name_%d" % i): + if "action_name_%d" % i in request.POST: qdict["action_name_%d" % cpt] = request.POST["action_name_%d" % i] action = request.POST["action_name_%d" % i] argcpt = 0 @@ -239,6 +249,7 @@ def build_filter_form_from_qdict(request): return FilterForm(conditions, actions, request, qdict) + def build_filter_form_from_filter(request, name, fobj): from sievelib.commands import SizeCommand, TrueCommand @@ -252,8 +263,8 @@ def build_filter_form_from_filter(request, name, fobj): elif isinstance(t, SizeCommand): conditions += [("size", t["comparator"][1:], t["limit"])] else: - conditions += [(t["header-names"].strip('"'), - t["match-type"][1:], + conditions += [(t["header-names"].strip('"'), + t["match-type"][1:], t["key-list"].strip('"'))] actions = [] for c in fobj.children: diff --git a/modoboa/extensions/sievefilters/lib.py b/modoboa/extensions/sievefilters/lib.py index c6ed51883..3cd57d338 100644 --- a/modoboa/extensions/sievefilters/lib.py +++ b/modoboa/extensions/sievefilters/lib.py @@ -7,9 +7,11 @@ from sievelib.factory import FiltersSet from modoboa.lib import parameters from modoboa.lib.connections import ConnectionsManager, ConnectionError + class SieveClientError(Exception): pass + class SieveClient(object): __metaclass__ = ConnectionsManager @@ -22,7 +24,7 @@ class SieveClient(object): raise ConnectionError(msg) def login(self, user, password): - self.msc = Client(parameters.get_admin("SERVER"), + self.msc = Client(parameters.get_admin("SERVER"), int(parameters.get_admin("PORT")), debug=False) use_starttls = True if parameters.get_admin("STARTTLS") == "yes" else False @@ -31,7 +33,7 @@ class SieveClient(object): authmech = None try: ret = self.msc.connect(user, password, use_starttls, authmech) - except Error, e: + except Error: ret = False if not ret: return False, _("Connection to MANAGESIEVE server failed, check your configuration") @@ -40,7 +42,7 @@ class SieveClient(object): def logout(self): self.msc.logout() self.msc = None - + def refresh(self, user, password): import ssl @@ -85,7 +87,7 @@ class SieveClient(object): raise SieveClientError(self.msc.errmsg) if active and not self.msc.setactive(name): raise SieveClientError(self.msc.errmsg) - + def deletescript(self, name): if not self.msc.deletescript(name): raise SieveClientError(self.msc.errmsg) diff --git a/modoboa/extensions/sievefilters/templatetags/sfilters_tags.py b/modoboa/extensions/sievefilters/templatetags/sfilters_tags.py index dbed8e525..0f5667a47 100644 --- a/modoboa/extensions/sievefilters/templatetags/sfilters_tags.py +++ b/modoboa/extensions/sievefilters/templatetags/sfilters_tags.py @@ -2,106 +2,108 @@ from django import template from django.template.loader import render_to_string from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse -from modoboa.lib.webutils import render_actions +from modoboa.lib.webutils import render_actions, static_url register = template.Library() -from modoboa.lib.webutils import static_url @register.simple_tag def sfilters_menu(user): entries = [ - {"name" : "newfilterset", - "img" : "icon-plus", - "label" : _("New filters set"), - "url" : reverse("modoboa.extensions.sievefilters.views.new_filters_set"), - "modal" : True, - "modalcb" : "filtersetform_cb" + {"name": "newfilterset", + "img": "icon-plus", + "label": _("New filters set"), + "url": reverse("modoboa.extensions.sievefilters.views.new_filters_set"), + "modal": True, + "modalcb": "filtersetform_cb" } - ] + ] + + return render_to_string('common/menulist.html', + {"entries": entries, "user": user}) - return render_to_string('common/menulist.html', - {"entries" : entries, "user" : user}) @register.simple_tag def fset_menu(mode, setname): entries = [] if mode == "gui": entries += [ - {"name" : "newfilter", - "img" : "icon-plus", - "label" : _("New filter"), - "url" : reverse("modoboa.extensions.sievefilters.views.newfilter", + {"name": "newfilter", + "img": "icon-plus", + "label": _("New filter"), + "url": reverse("modoboa.extensions.sievefilters.views.newfilter", args=[setname]), - "modal" : True, - "autowidth" : True, - "modalcb" : "filterform_cb"} - ] + "modal": True, + "autowidth": True, + "modalcb": "filterform_cb"} + ] if mode == "raw": entries += [ - {"name" : "savefs", - "img" : "icon-download-alt", - "label" : _("Save filters set"), - "url" : reverse("modoboa.extensions.sievefilters.views.savefs", + {"name": "savefs", + "img": "icon-download-alt", + "label": _("Save filters set"), + "url": reverse("modoboa.extensions.sievefilters.views.savefs", args=[setname])}, - ] - - entries += [ - {"name" : "activatefs", - "img" : "icon-ok", - "label" : _("Activate filters set"), - "url" : reverse("modoboa.extensions.sievefilters.views.activate_filters_set", - args=[setname])}, - {"name" : "removefs", - "img" : "icon-trash", - "label" : _("Remove filters set"), - "url" : reverse("modoboa.extensions.sievefilters.views.remove_filters_set", - args=[setname])}, - {"name" : "downloadfs", - "img" : "icon-download", - "label" : _("Download"), - "url" : reverse("modoboa.extensions.sievefilters.views.download_filters_set", - args=[setname])} ] - return render_to_string('common/menulist.html', - {"entries" : entries}) + entries += [ + {"name": "activatefs", + "img": "icon-ok", + "label": _("Activate filters set"), + "url": reverse("modoboa.extensions.sievefilters.views.activate_filters_set", + args=[setname])}, + {"name": "removefs", + "img": "icon-trash", + "label": _("Remove filters set"), + "url": reverse("modoboa.extensions.sievefilters.views.remove_filters_set", + args=[setname])}, + {"name": "downloadfs", + "img": "icon-download", + "label": _("Download"), + "url": reverse("modoboa.extensions.sievefilters.views.download_filters_set", + args=[setname])} + ] + + return render_to_string('common/menulist.html', + {"entries": entries}) + @register.simple_tag def filter_actions(setname, f, position, islast): actions = [ - {"name" : "editfilter", - "url" : reverse("modoboa.extensions.sievefilters.views.editfilter", + {"name": "editfilter", + "url": reverse("modoboa.extensions.sievefilters.views.editfilter", args=[setname, f["name"]]), - "img" : "icon-edit", - "title" : _("Edit filter"), - "modal" : True, - "autowidth" : True, - "modalcb" : "filterform_cb"}, - {"name" : "removefilter", - "url" : reverse("modoboa.extensions.sievefilters.views.removefilter", + "img": "icon-edit", + "title": _("Edit filter"), + "modal": True, + "autowidth": True, + "modalcb": "filterform_cb"}, + {"name": "removefilter", + "url": reverse("modoboa.extensions.sievefilters.views.removefilter", args=[setname, f["name"]]), - "img" : "icon-trash", - "title" : _("Remove this filter")} - ] + "img": "icon-trash", + "title": _("Remove this filter")} + ] if position != 1: actions += [ - {"name" : "movefilter_up", - "url" : reverse("modoboa.extensions.sievefilters.views.move_filter_up", + {"name": "movefilter_up", + "url": reverse("modoboa.extensions.sievefilters.views.move_filter_up", args=[setname, f["name"]]), - "img" : "icon-arrow-up", - "title" : _("Move this filter up")} - ] + "img": "icon-arrow-up", + "title": _("Move this filter up")} + ] if not islast: actions += [ - {"name" : "movefilter_down", - "url" : reverse("modoboa.extensions.sievefilters.views.move_filter_down", + {"name": "movefilter_down", + "url": reverse("modoboa.extensions.sievefilters.views.move_filter_down", args=[setname, f["name"]]), - "img" : "icon-arrow-down", - "title" : _("Move this filter down")}, - ] + "img": "icon-arrow-down", + "title": _("Move this filter down")}, + ] return render_actions(actions) + @register.simple_tag def display_errors(errors): if not len(errors): @@ -114,8 +116,9 @@ def display_errors(errors): """) return t.render(template.Context({ - "errors" : errors - })) + "errors": errors + })) + @register.simple_tag def display_condition(form, cnt): @@ -128,12 +131,13 @@ def display_condition(form, cnt): """) return t.render(template.Context({ - "idx" : cnt, - "tfield" : target, - "ofield" : operator, - "vfield" : value, - "verrors" : display_errors(value.errors) - })) + "idx": cnt, + "tfield": target, + "ofield": operator, + "vfield": value, + "verrors": display_errors(value.errors) + })) + @register.simple_tag def display_action(form, cnt): @@ -155,7 +159,7 @@ def display_action(form, cnt): """) return t.render(template.Context({ - "idx" : cnt, - "afield" : action, "values" : values, - "verrors" : display_errors(verrors) - })) + "idx": cnt, + "afield": action, "values": values, + "verrors": display_errors(verrors) + })) diff --git a/modoboa/extensions/sievefilters/views.py b/modoboa/extensions/sievefilters/views.py index 8aa7fa06f..6c5999c9f 100644 --- a/modoboa/extensions/sievefilters/views.py +++ b/modoboa/extensions/sievefilters/views.py @@ -1,45 +1,51 @@ # coding: utf-8 from sievelib.managesieve import Error +from django.shortcuts import render from django.http import HttpResponse from django.template.loader import render_to_string from django.contrib.auth.decorators import login_required from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse from modoboa.lib import parameters -from modoboa.lib.webutils import _render, _render_to_string, _render_error, \ +from modoboa.lib.webutils import _render_to_string, _render_error, \ ajax_response, ajax_simple_response -from modoboa.lib.decorators import needs_mailbox from modoboa.lib.connections import ConnectionError -from modoboa.auth.lib import get_password -from lib import * -from forms import * +from modoboa.lib.cryptutils import get_password +from modoboa.extensions.admin.lib import needs_mailbox +from .lib import SieveClient, SieveClientError +from .forms import ( + FilterForm, build_filter_form_from_qdict, build_filter_form_from_filter, + FiltersSetForm +) from templatetags.sfilters_tags import fset_menu + @login_required @needs_mailbox() def index(request, tplname="sievefilters/index.html"): try: - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) except ConnectionError, e: - return _render_error(request, user_context={"error" : e}) - + return _render_error(request, user_context={"error": e}) + try: active_script, scripts = sc.listscripts() except Error, e: - return _render_error(request, user_context={"error" : e}) + return _render_error(request, user_context={"error": e}) if active_script is None: active_script = "" default_script = "%s/" % scripts[0] if len(scripts) else "" else: default_script = "%s/" % active_script - return _render(request, tplname, { - "selection" : "user", - "active_script" : active_script, - "default_script" : default_script, - "scripts" : sorted(scripts), - }) + return render(request, tplname, { + "selection": "user", + "active_script": active_script, + "default_script": default_script, + "scripts": sorted(scripts), + }) + @login_required @needs_mailbox() @@ -48,10 +54,11 @@ def get_templates(request, ftype): return ajax_simple_response(FilterForm([], [], request).cond_templates) return ajax_simple_response(FilterForm([], [], request).action_templates) + @login_required @needs_mailbox() def getfs(request, name): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) editormode = parameters.get_user(request.user, "EDITOR_MODE") error = None @@ -67,30 +74,32 @@ def getfs(request, name): return ajax_response(request, "ko", respmsg=error) if editormode == "raw": - htmlcontent = render_to_string("sievefilters/rawfilter.html", dict( - name=name, scriptcontent=content - )) + htmlcontent = render_to_string("sievefilters/rawfilter.html", dict( + name=name, scriptcontent=content + )) else: htmlcontent = render_to_string("sievefilters/guieditor.html", dict( - fs=content - )) + fs=content + )) menu = '' % \ - (_("Actions"), fset_menu(editormode, name)) + (_("Actions"), fset_menu(editormode, name)) resp = dict(status="ok", menu=menu, content=htmlcontent) return ajax_simple_response(resp) + def build_filter_ctx(ctx, form): ctx["form"] = form ctx["conds_nb"] = range(form.conds_cnt) ctx["actions_nb"] = range(form.actions_cnt) return ctx + def submitfilter(request, setname, okmsg, tplname, tplctx, update=False, sc=None): form = build_filter_form_from_qdict(request) if form.is_valid(): if sc is None: - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) fset = sc.getscript(setname, format="fset") conditions, actions = form.tofilter() @@ -110,6 +119,7 @@ def submitfilter(request, setname, okmsg, tplname, tplctx, update=False, sc=None tplctx = build_filter_ctx(tplctx, form) return ajax_response(request, status="ko", template=tplname, **tplctx) + @login_required @needs_mailbox() def newfilter(request, setname, tplname="sievefilters/filter.html"): @@ -119,15 +129,18 @@ def newfilter(request, setname, tplname="sievefilters/filter.html"): action=reverse(newfilter, args=[setname]), action_label=_("Create"), action_classes="submit" - ) + ) if request.method == "POST": - return submitfilter(request, setname, _("Filter created"), tplname, ctx) + return submitfilter( + request, setname, _("Filter created"), tplname, ctx + ) conds = [("Subject", "contains", "")] actions = [("fileinto", "")] form = FilterForm(conds, actions, request) ctx = build_filter_ctx(ctx, form) - return _render(request, tplname, ctx) + return render(request, tplname, ctx) + @login_required @needs_mailbox() @@ -138,13 +151,13 @@ def editfilter(request, setname, fname, tplname="sievefilters/filter.html"): action=reverse(editfilter, args=[setname, fname]), action_label=_("Update"), action_classes="submit" - ) - sc = SieveClient(user=request.user.username, + ) + sc = SieveClient(user=request.user.username, password=request.session["password"]) if request.method == "POST": return submitfilter(request, setname, _("Filter modified"), tplname, ctx, update=True, sc=sc) - + fset = sc.getscript(setname, format="fset") f = fset.getfilter(fname) form = build_filter_form_from_filter(request, fname, f) @@ -152,12 +165,13 @@ def editfilter(request, setname, fname, tplname="sievefilters/filter.html"): ctx["oldname"] = fname ctx["hidestyle"] = "none" \ if form.fields["match_type"].initial == "all" else "block" - return _render(request, tplname, ctx) + return render(request, tplname, ctx) + @login_required @needs_mailbox() def removefilter(request, setname, fname): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) fset = sc.getscript(setname, format="fset") if fset.removefilter(fname): @@ -165,12 +179,13 @@ def removefilter(request, setname, fname): return ajax_response(request, respmsg=_("Filter removed")) return ajax_response(request, "ko", respmsg=_("Failed to remove filter")) + @login_required @needs_mailbox() def savefs(request, name): - if not request.POST.has_key("scriptcontent"): + if not "scriptcontent" in request.POST: return - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: sc.pushscript(name, request.POST["scriptcontent"]) @@ -178,22 +193,23 @@ def savefs(request, name): error = str(e) return ajax_response(request, "ko", respmsg=error) return ajax_response(request, respmsg=_("Filters set saved")) - + + @login_required @needs_mailbox() def new_filters_set(request, tplname="common/generic_modal_form.html"): - ctx = {"title" : _("Create a new filters set"), - "formid" : "newfiltersset", - "action_label" : _("Create"), - "action_classes" : "submit", - "action" : reverse(new_filters_set), - "withmenu" : False, - "withunseen" : False} + ctx = {"title": _("Create a new filters set"), + "formid": "newfiltersset", + "action_label": _("Create"), + "action_classes": "submit", + "action": reverse(new_filters_set), + "withmenu": False, + "withunseen": False} if request.method == "POST": form = FiltersSetForm(request.POST) error = None if form.is_valid(): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: sc.pushscript(form.cleaned_data["name"], "# Empty script", @@ -202,7 +218,7 @@ def new_filters_set(request, tplname="common/generic_modal_form.html"): error = str(e) else: return ajax_simple_response({ - "status": "ok", + "status": "ok", "url": form.cleaned_data["name"], "active": form.cleaned_data["active"], "respmsg": _("Filters set created") @@ -213,12 +229,13 @@ def new_filters_set(request, tplname="common/generic_modal_form.html"): return ajax_response(request, status="ko", template=tplname, **ctx) ctx["form"] = FiltersSetForm() - return _render(request, tplname, ctx) + return render(request, tplname, ctx) + @login_required @needs_mailbox() def remove_filters_set(request, name): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: sc.deletescript(name) @@ -226,13 +243,14 @@ def remove_filters_set(request, name): return ajax_simple_response(dict(status="ko", respmsg=str(e))) acs, scripts = sc.listscripts() return ajax_simple_response(dict( - status="ok", respmsg=_("Filters set deleted"), newfs=acs - )) + status="ok", respmsg=_("Filters set deleted"), newfs=acs + )) + @login_required @needs_mailbox() def activate_filters_set(request, name): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: sc.activatescript(name) @@ -240,10 +258,11 @@ def activate_filters_set(request, name): return ajax_response(request, "ko", respmsg=str(e)) return ajax_response(request, respmsg=_("Filters set activated")) + @login_required @needs_mailbox() def download_filters_set(request, name): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: script = sc.getscript(name) @@ -256,10 +275,11 @@ def download_filters_set(request, name): resp["Content-Disposition"] = 'attachment; filename="%s.txt"' % name return resp + @login_required @needs_mailbox() def toggle_filter_state(request, setname, fname): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: fset = sc.getscript(setname, format="fset") @@ -276,15 +296,16 @@ def toggle_filter_state(request, setname, fname): sc.pushscript(setname, str(fset)) except SieveClientError, e: return ajax_response(request, "ko", respmsg=str(e)) - + return ajax_simple_response({ - "status" : "ok", - "label" : newstate, - "color" : color - }) + "status": "ok", + "label": newstate, + "color": color + }) + def move_filter(request, setname, fname, direction): - sc = SieveClient(user=request.user.username, + sc = SieveClient(user=request.user.username, password=request.session["password"]) try: fset = sc.getscript(setname, format="fset") @@ -292,13 +313,17 @@ def move_filter(request, setname, fname, direction): sc.pushscript(setname, str(fset)) except (SieveClientError), e: return ajax_response(request, "ko", respmsg=str(e)) - return ajax_response(request, template="sievefilters/guieditor.html", fs=fset) + return ajax_response( + request, template="sievefilters/guieditor.html", fs=fset + ) + @login_required @needs_mailbox() def move_filter_up(request, setname, fname): return move_filter(request, setname, fname, "up") + @login_required @needs_mailbox() def move_filter_down(request, setname, fname): diff --git a/modoboa/extensions/webmail/lib.py b/modoboa/extensions/webmail/lib.py index df40d947a..8f1bcccb8 100644 --- a/modoboa/extensions/webmail/lib.py +++ b/modoboa/extensions/webmail/lib.py @@ -644,7 +644,7 @@ def send_mail(request, posturl=None): from email.mime.multipart import MIMEMultipart from .forms import ComposeMailForm from modoboa.lib.webutils import _render_to_string - from modoboa.auth.lib import get_password + from modoboa.lib.cryptutils import get_password form = ComposeMailForm(request.POST) editormode = parameters.get_user(request.user, "EDITOR") diff --git a/modoboa/lib/connections.py b/modoboa/lib/connections.py index 0cff589e0..adbe58b94 100644 --- a/modoboa/lib/connections.py +++ b/modoboa/lib/connections.py @@ -1,23 +1,24 @@ -from modoboa.auth.lib import decrypt +from modoboa.lib.cryptutils import decrypt + class ConnectionsManager(type): """Singleton pattern implementation This class is specialized in connection management. """ - def __init__(cls, name, bases, dict): - super(ConnectionsManager, cls).__init__(name, bases, dict) + def __init__(cls, name, bases, ctx): + super(ConnectionsManager, cls).__init__(name, bases, ctx) cls.instances = {} def __call__(cls, **kwargs): key = None - if kwargs.has_key("user"): + if "user" in kwargs: key = kwargs["user"] else: return None - if not cls.instances.has_key(key): + if not key in cls.instances: cls.instances[key] = None - if kwargs.has_key("password"): + if "password" in kwargs: kwargs["password"] = decrypt(kwargs["password"]) if cls.instances[key] is None: @@ -27,5 +28,6 @@ class ConnectionsManager(type): cls.instances[key].refresh(key, kwargs["password"]) return cls.instances[key] + class ConnectionError(Exception): pass