diff --git a/TODO.md b/TODO.md
index 22cae58c..fab22ef0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -376,4 +376,5 @@ method(
arg, arg, arg)
-# Restart postfix on user pwd change/disabling
+# dovecot sieve only allolws one fucking active script. refactor mailbox shit to replace active script symlink by orchestra. Create a generic wrapper that includes al filters (rc, imp and orchestra)
+http://wiki2.dovecot.org/Pigeonhole/Sieve/Examples
diff --git a/orchestra/contrib/domains/forms.py b/orchestra/contrib/domains/forms.py
index 59560894..dad20233 100644
--- a/orchestra/contrib/domains/forms.py
+++ b/orchestra/contrib/domains/forms.py
@@ -9,7 +9,8 @@ from .models import Domain
class BatchDomainCreationAdminForm(forms.ModelForm):
name = forms.CharField(label=_("Names"), widget=forms.Textarea(attrs={'rows': 5, 'cols': 50}),
- help_text=_("Domain per line. All domains will have the provided account and records."))
+ help_text=_("Fully qualified domain name per line. "
+ "All domains will have the provided account and records."))
def clean_name(self):
self.extra_names = []
diff --git a/orchestra/contrib/domains/models.py b/orchestra/contrib/domains/models.py
index 994a7405..acfc3c57 100644
--- a/orchestra/contrib/domains/models.py
+++ b/orchestra/contrib/domains/models.py
@@ -247,7 +247,8 @@ class Record(models.Model):
help_text=_("Record TTL, defaults to %s") % settings.DOMAINS_DEFAULT_TTL,
validators=[validators.validate_zone_interval])
type = models.CharField(_("type"), max_length=32, choices=TYPE_CHOICES)
- value = models.CharField(_("value"), max_length=256)
+ value = models.CharField(_("value"), max_length=256, help_text=_("MX, NS and CNAME records "
+ "sould end with a dot."))
def __str__(self):
return "%s %s IN %s %s" % (self.domain, self.get_ttl(), self.type, self.value)
diff --git a/orchestra/contrib/mailboxes/admin.py b/orchestra/contrib/mailboxes/admin.py
index 1d9dc367..7240d5ef 100644
--- a/orchestra/contrib/mailboxes/admin.py
+++ b/orchestra/contrib/mailboxes/admin.py
@@ -124,7 +124,7 @@ class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
list_filter = (HasMailboxListFilter, HasForwardListFilter)
fields = ('account_link', 'email_link', 'mailboxes', 'forward')
add_fields = ('account_link', ('name', 'domain'), 'mailboxes', 'forward')
- inlines = [AutoresponseInline]
+# inlines = [AutoresponseInline]
search_fields = ('forward', 'mailboxes__name', 'account__username', 'computed_email')
readonly_fields = ('account_link', 'domain_link', 'email_link')
actions = (SendAddressEmail(),)
diff --git a/orchestra/contrib/mailboxes/backends.py b/orchestra/contrib/mailboxes/backends.py
index 1993a7e5..b54c67ee 100644
--- a/orchestra/contrib/mailboxes/backends.py
+++ b/orchestra/contrib/mailboxes/backends.py
@@ -31,12 +31,14 @@ class SieveFilteringMixin(object):
""") % context
)
context['filtering_path'] = settings.MAILBOXES_SIEVE_PATH % context
+ context['filtering_cpath'] = re.sub(r'\.sieve$', '.svbin', context['filtering_path'])
if content:
context['filtering'] = ('# %(banner)s\n' + content) % context
self.append(textwrap.dedent("""\
mkdir -p $(dirname '%(filtering_path)s')
echo '%(filtering)s' > %(filtering_path)s
- chown %(user)s:%(group)s %(filtering_path)s
+ sievec %(filtering_path)s
+ chown %(user)s:%(group)s {%(filtering_path)s,%(filtering_cpath)s}
""") % context
)
else:
diff --git a/orchestra/contrib/mailboxes/settings.py b/orchestra/contrib/mailboxes/settings.py
index 790678e0..49aa1361 100644
--- a/orchestra/contrib/mailboxes/settings.py
+++ b/orchestra/contrib/mailboxes/settings.py
@@ -28,8 +28,11 @@ MAILBOXES_HOME = Setting('MAILBOXES_HOME',
MAILBOXES_SIEVE_PATH = Setting('MAILBOXES_SIEVE_PATH',
- os.path.join('%(home)s/Maildir/sieve/orchestra.sieve'),
- help_text="Available fromat names: %s" % ', '.join(_names),
+ os.path.join('%(home)s/sieve/orchestra.sieve'),
+ help_text="If you are using Dovecot you can use "
+ ""
+ "sieve_before in order to make sure orchestra sieve script is exectued."
+ "
Available fromat names: %s" % ', '.join(_names),
validators=[Setting.string_format_validator(_backend_names)],
)
@@ -83,14 +86,14 @@ MAILBOXES_MAILBOX_FILTERINGS = Setting('MAILBOXES_MAILBOX_FILTERINGS',
# value: (verbose_name, filter)
'DISABLE': (_("Disable"), ''),
'REJECT': (mark_safe_lazy(_("Reject spam (Score≥9)")), textwrap.dedent("""\
- require ["fileinto","regex","envelope","vacation","reject","relational","comparator-i;ascii-numeric"];
- if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "9" {
+ require ["fileinto","regex","envelope","vacation","reject","relational","comparator-i;ascii-numeric"];
+ if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "9" {
discard;
stop;
}""")),
'REJECT5': (mark_safe_lazy(_("Reject spam (Score≥5)")), textwrap.dedent("""\
- require ["fileinto","regex","envelope","vacation","reject","relational","comparator-i;ascii-numeric"];
- if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "5" {
+ require ["fileinto","regex","envelope","vacation","reject","relational","comparator-i;ascii-numeric"];
+ if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "5" {
discard;
stop;
}""")),
diff --git a/orchestra/contrib/webapps/options.py b/orchestra/contrib/webapps/options.py
index 74b18da0..a3d2624e 100644
--- a/orchestra/contrib/webapps/options.py
+++ b/orchestra/contrib/webapps/options.py
@@ -95,7 +95,10 @@ class Processes(AppOption):
class PHPEnableFunctions(PHPAppOption):
name = 'enable_functions'
verbose_name = _("Enable functions")
- help_text = ','.join(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS)
+ help_text = '%s' % '
'.join([
+ ','.join(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS[i:i+10])
+ for i in range(0, len(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS), 10)
+ ])
regex = r'^[\w\.,-]+$'
diff --git a/orchestra/contrib/webapps/serializers.py b/orchestra/contrib/webapps/serializers.py
index e73d14fa..cd9f657a 100644
--- a/orchestra/contrib/webapps/serializers.py
+++ b/orchestra/contrib/webapps/serializers.py
@@ -1,3 +1,4 @@
+from django.db import models
from rest_framework import serializers
from orchestra.api.serializers import HyperlinkedModelSerializer
@@ -18,14 +19,27 @@ class OptionSerializer(serializers.ModelSerializer):
return data
+class DataField(serializers.Field):
+ def to_representation(self, data):
+ return data
+
+
class WebAppSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
options = OptionSerializer(required=False)
+ data = DataField()
class Meta:
model = WebApp
- fields = ('url', 'id', 'name', 'type', 'options')
+ fields = ('url', 'id', 'name', 'type', 'options', 'data')
postonly_fields = ('name', 'type')
+ def __init__(self, *args, **kwargs):
+ super(WebAppSerializer, self).__init__(*args, **kwargs)
+ if isinstance(self.instance, models.Model):
+ type_serializer = self.instance.type_instance.serializer
+ if type_serializer:
+ self.fields['data'] = type_serializer()
+
def create(self, validated_data):
options_data = validated_data.pop('options')
webapp = super(WebAppSerializer, self).create(validated_data)
diff --git a/orchestra/contrib/websites/models.py b/orchestra/contrib/websites/models.py
index c87553ab..62d660b9 100644
--- a/orchestra/contrib/websites/models.py
+++ b/orchestra/contrib/websites/models.py
@@ -31,7 +31,7 @@ class Website(models.Model):
# port = models.PositiveIntegerField(_("port"),
# choices=settings.WEBSITES_PORT_CHOICES,
# default=settings.WEBSITES_DEFAULT_PORT)
- domains = models.ManyToManyField(settings.WEBSITES_DOMAIN_MODEL,
+ domains = models.ManyToManyField(settings.WEBSITES_DOMAIN_MODEL, blank=True,
related_name='websites', verbose_name=_("domains"))
contents = models.ManyToManyField('webapps.WebApp', through='websites.Content')
is_active = models.BooleanField(_("active"), default=True)
diff --git a/requirements.txt b/requirements.txt
index aa074415..7547422c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-django==1.8.1
+django==1.8.2
django-celery-email==1.0.4
django-fluent-dashboard==0.5
https://github.com/glic3rinu/django-admin-tools/archive/master.zip