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