From 2f7861db333983a16f1f5b07cc0745a11bf43337 Mon Sep 17 00:00:00 2001 From: Marc Aymerich Date: Tue, 10 Mar 2015 22:27:32 +0000 Subject: [PATCH] Fixes on website apache backend --- orchestra/apps/websites/backends/apache.py | 39 +++++++++++----------- orchestra/apps/websites/forms.py | 34 ++++--------------- orchestra/apps/websites/models.py | 4 ++- orchestra/apps/websites/serializers.py | 15 ++++----- orchestra/apps/websites/settings.py | 2 +- 5 files changed, 36 insertions(+), 58 deletions(-) diff --git a/orchestra/apps/websites/backends/apache.py b/orchestra/apps/websites/backends/apache.py index d4fce726..2f8b5428 100644 --- a/orchestra/apps/websites/backends/apache.py +++ b/orchestra/apps/websites/backends/apache.py @@ -147,50 +147,49 @@ class Apache2Backend(ServiceController): """) % context def get_ssl(self, directives): - config = [] + config = '' ca = directives.get('ssl_ca') if ca: - config.append("SSLCACertificateFile %s" % ca[0]) + config += "SSLCACertificateFile %s\n" % ca[0] cert = directives.get('ssl_cert') if cert: - config.append("SSLCertificateFile %" % cert[0]) + config += "SSLCertificateFile %\n" % cert[0] key = directives.get('ssl_key') if key: - config.append("SSLCertificateKeyFile %s" % key[0]) - return '\n'.join(config) + config += "SSLCertificateKeyFile %s\n" % key[0] + return config def get_security(self, directives): - config = [] + config = '' for rules in directives.get('sec_rule_remove', []): for rule in rules.value.split(): - config.append("SecRuleRemoveById %i" % int(rule)) + config += "SecRuleRemoveById %i\n" % int(rule) for modsecurity in directives.get('sec_rule_off', []): - config.append(textwrap.dedent("""\ + config += textwrap.dedent("""\ SecRuleEngine off - \ + """) % modsecurity - ) - return '\n'.join(config) + return config def get_redirects(self, directives): - config = [] + config = '' for redirect in directives.get('redirect', []): source, target = redirect.split() if re.match(r'^.*[\^\*\$\?\)]+.*$', redirect): - config.append("RedirectMatch %s %s" % (source, target)) + config += "RedirectMatch %s %s\n" % (source, target) else: - config.append("Redirect %s %s" % (source, target)) - return '\n'.join(config) + config += "Redirect %s %s\n" % (source, target) + return config def get_proxies(self, directives): - config = [] + config = '' for proxy in directives.get('proxy', []): - source, target = redirect.split() + source, target = proxy.split() source = normurlpath(source) - config.append('ProxyPass %s %s' % (source, target)) - config.append('ProxyPassReverse %s %s' % (source, target)) - return '\n'.join(directives) + config += 'ProxyPass %s %s\n' % (source, target) + config += 'ProxyPassReverse %s %s\n' % (source, target) + return config # def get_protections(self, site): # protections = '' diff --git a/orchestra/apps/websites/forms.py b/orchestra/apps/websites/forms.py index ea1335e3..9ee3f3fd 100644 --- a/orchestra/apps/websites/forms.py +++ b/orchestra/apps/websites/forms.py @@ -1,8 +1,7 @@ from django import forms from django.core.exceptions import ValidationError -from django.db.models import Q -from .models import Website +from .validators import validate_domain_protocol class WebsiteAdminForm(forms.ModelForm): @@ -12,32 +11,11 @@ class WebsiteAdminForm(forms.ModelForm): if not domains: return self.cleaned_data protocol = self.cleaned_data.get('protocol') - existing = [] for domain in domains.all(): - if protocol == Website.HTTP: - qset = Q( - Q(protocol=Website.HTTP) | - Q(protocol=Website.HTTP_AND_HTTPS) | - Q(protocol=Website.HTTPS_ONLY) - ) - elif protocol == Website.HTTPS: - qset = Q( - Q(protocol=Website.HTTPS) | - Q(protocol=Website.HTTP_AND_HTTPS) | - Q(protocol=Website.HTTPS_ONLY) - ) - elif protocol in (Website.HTTP_AND_HTTPS, Website.HTTPS_ONLY): - qset = Q() - else: - raise ValidationError({ - 'protocol': _("Unknown protocol %s") % protocol - }) - if domain.websites.filter(qset).exclude(pk=self.instance.pk).exists(): - existing.append(domain.name) - if existing: - context = (', '.join(existing), protocol) - raise ValidationError({ - 'domains': 'A website is already defined for "%s" on protocol %s' % context - }) + try: + validate_domain_protocol(self.instance, domain, protocol) + except ValidationError as e: + # TODO not sure about this one + self.add_error(None, e) return self.cleaned_data diff --git a/orchestra/apps/websites/models.py b/orchestra/apps/websites/models.py index 3505635c..8542402c 100644 --- a/orchestra/apps/websites/models.py +++ b/orchestra/apps/websites/models.py @@ -27,7 +27,9 @@ class Website(models.Model): related_name='websites') protocol = models.CharField(_("protocol"), max_length=16, choices=settings.WEBSITES_PROTOCOL_CHOICES, - default=settings.WEBSITES_DEFAULT_PROTOCOL) + default=settings.WEBSITES_DEFAULT_PROTOCOL, + help_text=_("Select the protocol(s) for this website
" + "HTTPS only performs a redirection from http to https.")) # port = models.PositiveIntegerField(_("port"), # choices=settings.WEBSITES_PORT_CHOICES, # default=settings.WEBSITES_DEFAULT_PORT) diff --git a/orchestra/apps/websites/serializers.py b/orchestra/apps/websites/serializers.py index 87287133..837f6d6b 100644 --- a/orchestra/apps/websites/serializers.py +++ b/orchestra/apps/websites/serializers.py @@ -1,4 +1,5 @@ from django.core.exceptions import ValidationError +from django.db.models import Q from django.shortcuts import get_object_or_404 from rest_framework import serializers @@ -7,6 +8,7 @@ from orchestra.api.serializers import HyperlinkedModelSerializer from orchestra.apps.accounts.serializers import AccountSerializerMixin from .models import Website, Content +from .validators import validate_domain_protocol class RelatedDomainSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer): @@ -53,14 +55,11 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer): def full_clean(self, instance): """ Prevent multiples domains on the same port """ - existing = [] for domain in instance._m2m_data['domains']: - if domain.websites.filter(port=instance.port).exclude(pk=instance.pk).exists(): - existing.append(domain.name) - if existing: - context = (', '.join(existing), instance.port) - raise ValidationError({ - 'domains': 'A website is already defined for "%s" on port %s' % context - }) + try: + validate_domain_protocol(instance, domain, instance.protocol) + except ValidationError as e: + # TODO not sure about this one + self.add_error(None, e) return instance diff --git a/orchestra/apps/websites/settings.py b/orchestra/apps/websites/settings.py index bacabeb1..7229450d 100644 --- a/orchestra/apps/websites/settings.py +++ b/orchestra/apps/websites/settings.py @@ -22,7 +22,7 @@ WEBSITES_PROTOCOL_CHOICES = getattr(settings, 'WEBSITES_PROTOCOL_CHOICES', ( WEBSITES_DEFAULT_PROTOCOL = getattr(settings, 'WEBSITES_DEFAULT_PROTOCOL', 'http') -WEBSITES_DEFAULT_PORT = getattr(settings, 'WEBSITES_DEFAULT_PORT', 80) +#WEBSITES_DEFAULT_PORT = getattr(settings, 'WEBSITES_DEFAULT_PORT', 80) WEBSITES_DEFAULT_IP = getattr(settings, 'WEBSITES_DEFAULT_IP', '*')