mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
New layout. Not the prettiest one but we need to release something :p
We'll do better for a future version. see #260
This commit is contained in:
@@ -200,6 +200,18 @@ Raised when an existing domain alias is about to be deleted.
|
||||
|
||||
* ``domain_alias`` is a ``DomainAlias`` instance
|
||||
|
||||
DomainModified
|
||||
==============
|
||||
|
||||
Raised when a domain has been modified.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(domain): pass
|
||||
|
||||
* ``domain`` is the modified ``Domain`` instance, it contains an extra
|
||||
``oldname`` field which contains the old domain name
|
||||
|
||||
ExtDisabled
|
||||
===========
|
||||
|
||||
|
||||
@@ -114,9 +114,13 @@ def editdomain(request, dom_id, tplname="admin/editdomainform.html"):
|
||||
"formid" : "domform",
|
||||
"domain" : domain}
|
||||
if request.method == "POST":
|
||||
def editdomain_cb(user, newdomain):
|
||||
events.raiseEvent("DomainModified", domain)
|
||||
|
||||
domain.oldname = domain.name
|
||||
form = DomainForm(request.user, request.POST, instances=instances)
|
||||
return _validate_domain(request, form, _("Domain modified"), commonctx, tplname,
|
||||
tpl_form_name="tabs")
|
||||
tpl_form_name="tabs", callback=editdomain_cb)
|
||||
|
||||
commonctx["tabs"] = DomainForm(request.user, instances=instances)
|
||||
commonctx["domadmins"] = domadmins
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# coding: utf-8
|
||||
"""
|
||||
Amavis quarantine manager (SQL based)
|
||||
Amavis management frontend.
|
||||
|
||||
Provides:
|
||||
|
||||
* SQL quarantine management
|
||||
* Per-domain settings
|
||||
|
||||
"""
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
@@ -20,22 +25,18 @@ class Amavis(ModoExtension):
|
||||
"""Init function
|
||||
|
||||
Only run once, when the extension is enabled. We create records
|
||||
for existing mailboxes in order Amavis considers them local.
|
||||
for existing domains to let Amavis consider them local.
|
||||
"""
|
||||
from modoboa.admin.models import Mailbox
|
||||
from models import Users
|
||||
from modoboa.admin.models import Domain
|
||||
from models import Users, Policy
|
||||
|
||||
for mb in Mailbox.objects.all():
|
||||
for dom in Domain.objects.all():
|
||||
try:
|
||||
u = Users.objects.get(email=mb.full_address)
|
||||
u = Users.objects.get(email="@%s" % dom.name)
|
||||
except Users.DoesNotExist:
|
||||
u = Users()
|
||||
u.email = mb.full_address
|
||||
u.fullname = mb.user.fullname
|
||||
u.local = "1"
|
||||
u.priority = 7
|
||||
u.policy_id = 1
|
||||
u.save()
|
||||
p = Policy.objects.create(policy_name=dom.name)
|
||||
Users.objects.create(email="@%s" % dom.name, fullname=dom.name,
|
||||
local="1", priority=7, policy=p)
|
||||
|
||||
def load(self):
|
||||
parameters.register_admin(
|
||||
@@ -76,9 +77,9 @@ class Amavis(ModoExtension):
|
||||
help=ugettext_lazy("Sets the maximum number of messages displayed in a page")
|
||||
)
|
||||
|
||||
def destroy(self):
|
||||
events.unregister("UserMenuDisplay", menu)
|
||||
parameters.unregister_app("amavis")
|
||||
def destroy(self):
|
||||
events.unregister("UserMenuDisplay", menu)
|
||||
parameters.unregister_app("amavis")
|
||||
|
||||
exts_pool.register_extension(Amavis)
|
||||
|
||||
@@ -94,6 +95,24 @@ def menu(target, user):
|
||||
]
|
||||
return []
|
||||
|
||||
@events.observe("CreateDomain")
|
||||
def on_create_domain(user, domain):
|
||||
from models import Users, Policy
|
||||
p = Policy.objects.create(policy_name=domain.name)
|
||||
Users.objects.create(email="@%s" % domain.name, fullname=domain.name,
|
||||
local="1", priority=7, policy=p)
|
||||
|
||||
@events.observe("DomainModified")
|
||||
def on_domain_modified(domain):
|
||||
if domain.oldname != domain.name:
|
||||
from models import Users
|
||||
u = Users.objects.get(email="@%s" % domain.oldname)
|
||||
u.email = "@%s" % domain.name
|
||||
u.fullname = domain.name
|
||||
u.policy.policy_name = domain.name
|
||||
u.policy.save()
|
||||
u.save()
|
||||
|
||||
@events.observe("DeleteDomain")
|
||||
def on_delete_domain(domain):
|
||||
from models import Users
|
||||
@@ -105,42 +124,6 @@ def on_delete_domain(domain):
|
||||
u.policy.delete()
|
||||
u.delete()
|
||||
|
||||
@events.observe("CreateMailbox")
|
||||
def create_user_record(user, mailbox):
|
||||
from models import Users
|
||||
|
||||
try:
|
||||
Users.objects.get(email=mailbox.full_address)
|
||||
except Users.DoesNotExist:
|
||||
u = Users()
|
||||
u.email = mailbox.full_address
|
||||
u.fullname = mailbox.user.fullname
|
||||
u.local = "1"
|
||||
u.priority = 7
|
||||
u.policy_id = 1
|
||||
u.save()
|
||||
|
||||
@events.observe("ModifyMailbox")
|
||||
def modify_user_record(mailbox, oldmailbox):
|
||||
if mailbox.full_address == oldmailbox.full_address:
|
||||
return
|
||||
u = Users.objects.get(email=oldmailbox.full_address)
|
||||
u.email = mailbox.full_address
|
||||
u.save()
|
||||
|
||||
@events.observe("DeleteMailbox")
|
||||
def remove_user_record(mailboxes):
|
||||
from models import Users
|
||||
from modoboa.admin.models import Mailbox
|
||||
|
||||
if isinstance(mailboxes, Mailbox):
|
||||
mailboxes = [mailboxes]
|
||||
for mailbox in mailboxes:
|
||||
try:
|
||||
Users.objects.get(email=mailbox.full_address).delete()
|
||||
except Users.DoesNotExist:
|
||||
pass
|
||||
|
||||
@events.observe("GetStaticContent")
|
||||
def extra_static_content(user):
|
||||
if parameters.get_admin("USER_CAN_RELEASE") == "yes" \
|
||||
|
||||
@@ -3,38 +3,32 @@
|
||||
from django import forms
|
||||
from models import Policy, Users
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.forms.widgets import RadioSelect, RadioInput
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
def is_yes(v): return v == 'Y'
|
||||
class CustomRadioInput(RadioInput):
|
||||
def __unicode__(self):
|
||||
if 'id' in self.attrs:
|
||||
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
|
||||
else:
|
||||
label_for = ''
|
||||
choice_label = conditional_escape(force_unicode(self.choice_label))
|
||||
return mark_safe(u'<label class="radio inline" %s>%s %s</label>' % (label_for, self.tag(), choice_label))
|
||||
|
||||
class CustomInputField(forms.CharField):
|
||||
"""Custom <input> field
|
||||
class InlineRadioRenderer(RadioSelect.renderer):
|
||||
def __iter__(self):
|
||||
for i, choice in enumerate(self.choices):
|
||||
yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)
|
||||
|
||||
Most of the columns defined by amavis use the *char* type even if
|
||||
they only support 2 values (Y/N). As we want to display them using
|
||||
checkboxes, we need to make some modifications in order that
|
||||
values are correctly interpreted.
|
||||
"""
|
||||
def validate(self, value):
|
||||
value = "N" if not value else "Y"
|
||||
super(CustomInputField, self).validate(value)
|
||||
def render(self):
|
||||
return mark_safe(u'\n'.join([u'%s\n' % force_unicode(w) for w in self]))
|
||||
|
||||
def clean(self, value):
|
||||
value = "N" if not value else "Y"
|
||||
return super(CustomInputField, self).clean(value)
|
||||
class InlineRadioSelect(RadioSelect):
|
||||
renderer = InlineRadioRenderer
|
||||
|
||||
class DomainPolicyForm(forms.ModelForm):
|
||||
bypass_spam_checks = CustomInputField(label=ugettext_lazy("Spam filter"),
|
||||
widget=forms.CheckboxInput(check_test=is_yes),
|
||||
help_text=ugettext_lazy("enabled"))
|
||||
bypass_virus_checks = CustomInputField(label=ugettext_lazy("Virus filter"),
|
||||
widget=forms.CheckboxInput(check_test=is_yes),
|
||||
help_text=ugettext_lazy("enabled"))
|
||||
bypass_banned_checks = CustomInputField(label=ugettext_lazy("Banned filter"),
|
||||
widget=forms.CheckboxInput(check_test=is_yes),
|
||||
help_text=ugettext_lazy("enabled"))
|
||||
spam_modifies_subj = CustomInputField(label=ugettext_lazy("Spam marker"),
|
||||
widget=forms.CheckboxInput(check_test=is_yes),
|
||||
help_text=ugettext_lazy("tag subject"))
|
||||
|
||||
class Meta:
|
||||
model = Policy
|
||||
@@ -42,8 +36,12 @@ class DomainPolicyForm(forms.ModelForm):
|
||||
'spam_tag2_level', 'spam_modifies_subj',
|
||||
'spam_kill_level', 'bypass_banned_checks')
|
||||
widgets = {
|
||||
'bypass_virus_checks' : InlineRadioSelect(),
|
||||
'bypass_spam_checks' : InlineRadioSelect(),
|
||||
'spam_tag2_level' : forms.TextInput(attrs={'class' : 'span1'}),
|
||||
'spam_modifies_subj' : InlineRadioSelect(),
|
||||
'spam_kill_level' : forms.TextInput(attrs={'class' : 'span1'}),
|
||||
'bypass_banned_checks' : InlineRadioSelect(),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -55,20 +53,17 @@ class DomainPolicyForm(forms.ModelForm):
|
||||
except (Users.DoesNotExist, Policy.DoesNotExist), e:
|
||||
del kwargs["instance"]
|
||||
super(DomainPolicyForm, self).__init__(*args, **kwargs)
|
||||
|
||||
for f in self.fields.keys():
|
||||
self.fields[f].required = False
|
||||
|
||||
def save(self, user, commit=True):
|
||||
p = super(DomainPolicyForm, self).save(commit=False)
|
||||
if commit:
|
||||
p.save()
|
||||
try:
|
||||
u = Users.objects.get(policy__id=p.id)
|
||||
except Users.DoesNotExist:
|
||||
u = Users()
|
||||
u.email = "@%s" % self.domain.name
|
||||
u.fullname = self.domain.name
|
||||
u.policy = p
|
||||
u.local = "1"
|
||||
u.priority = 7
|
||||
u.save()
|
||||
p.save()
|
||||
try:
|
||||
u = Users.objects.get(policy=p)
|
||||
except Users.DoesNotExist:
|
||||
u = Users.objects.get(email="@%s" % self.domain.name)
|
||||
u.policy = p
|
||||
p.save()
|
||||
return p
|
||||
|
||||
@@ -69,17 +69,36 @@ class Msgrcpt(models.Model):
|
||||
unique_together = ("mail", "rid")
|
||||
|
||||
class Policy(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
policy_name = models.CharField(max_length=96, blank=True)
|
||||
virus_lover = models.CharField(max_length=3, blank=True)
|
||||
spam_lover = models.CharField(max_length=3, blank=True)
|
||||
banned_files_lover = models.CharField(max_length=3, blank=True)
|
||||
bad_header_lover = models.CharField(max_length=3, blank=True)
|
||||
bypass_virus_checks = models.CharField(max_length=3, blank=True)
|
||||
bypass_spam_checks = models.CharField(max_length=3, blank=True)
|
||||
bypass_banned_checks = models.CharField(max_length=3, blank=True)
|
||||
bypass_virus_checks = models.CharField(
|
||||
ugettext_lazy("Virus filter"), default='',
|
||||
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
|
||||
max_length=3,
|
||||
help_text=ugettext_lazy("Bypass virus checks or not. Choose 'default' to use global settings.")
|
||||
)
|
||||
bypass_spam_checks = models.CharField(
|
||||
ugettext_lazy("Spam filter"), default='',
|
||||
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
|
||||
max_length=3,
|
||||
help_text=ugettext_lazy("Bypass spam checks or not. Choose 'default' to use global settings.")
|
||||
)
|
||||
bypass_banned_checks = models.CharField(
|
||||
ugettext_lazy("Banned filter"), default='',
|
||||
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
|
||||
max_length=3,
|
||||
help_text=ugettext_lazy("Bypass banned checks or not. Choose 'default' to use global settings.")
|
||||
)
|
||||
bypass_header_checks = models.CharField(max_length=3, blank=True)
|
||||
spam_modifies_subj = models.CharField(max_length=3, blank=True)
|
||||
spam_modifies_subj = models.CharField(
|
||||
ugettext_lazy("Spam marker"), default='',
|
||||
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
|
||||
max_length=3,
|
||||
help_text=ugettext_lazy("Modify spam subject or not. Choose 'default' to use global settings.")
|
||||
)
|
||||
virus_quarantine_to = models.CharField(max_length=192, blank=True)
|
||||
spam_quarantine_to = models.CharField(max_length=192, blank=True)
|
||||
banned_quarantine_to = models.CharField(max_length=192, blank=True)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n libextras %}
|
||||
{% render_field form.bypass_virus_checks "inline" %}
|
||||
{% render_field form.bypass_spam_checks "inline" %}
|
||||
{% render_field form.bypass_virus_checks %}
|
||||
{% render_field form.bypass_spam_checks %}
|
||||
<div class="control-group">
|
||||
<label class="control-label">{% trans "Thresholds" %}</label>
|
||||
<div class="controls spaced">
|
||||
@@ -8,5 +8,5 @@
|
||||
{{ form.spam_kill_level }} <span class="help-inline">{% trans "or more throw spam message away" %}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.spam_modifies_subj "inline" %}
|
||||
{% render_field form.bypass_banned_checks "inline" %}
|
||||
{% render_field form.spam_modifies_subj %}
|
||||
{% render_field form.bypass_banned_checks %}
|
||||
|
||||
@@ -17,6 +17,7 @@ events = [
|
||||
"CanCreate",
|
||||
|
||||
"CreateDomain",
|
||||
"DomainModified",
|
||||
"DeleteDomain",
|
||||
|
||||
"DomainAliasCreated",
|
||||
|
||||
Reference in New Issue
Block a user