Fixes on website apache backend

This commit is contained in:
Marc Aymerich 2015-03-10 22:27:32 +00:00
parent 340a40262f
commit 2f7861db33
5 changed files with 36 additions and 58 deletions

View File

@ -147,50 +147,49 @@ class Apache2Backend(ServiceController):
""") % context """) % context
def get_ssl(self, directives): def get_ssl(self, directives):
config = [] config = ''
ca = directives.get('ssl_ca') ca = directives.get('ssl_ca')
if ca: if ca:
config.append("SSLCACertificateFile %s" % ca[0]) config += "SSLCACertificateFile %s\n" % ca[0]
cert = directives.get('ssl_cert') cert = directives.get('ssl_cert')
if cert: if cert:
config.append("SSLCertificateFile %" % cert[0]) config += "SSLCertificateFile %\n" % cert[0]
key = directives.get('ssl_key') key = directives.get('ssl_key')
if key: if key:
config.append("SSLCertificateKeyFile %s" % key[0]) config += "SSLCertificateKeyFile %s\n" % key[0]
return '\n'.join(config) return config
def get_security(self, directives): def get_security(self, directives):
config = [] config = ''
for rules in directives.get('sec_rule_remove', []): for rules in directives.get('sec_rule_remove', []):
for rule in rules.value.split(): 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', []): for modsecurity in directives.get('sec_rule_off', []):
config.append(textwrap.dedent("""\ config += textwrap.dedent("""\
<Location %s> <Location %s>
SecRuleEngine off SecRuleEngine off
</LocationMatch>\ </LocationMatch>
""") % modsecurity """) % modsecurity
) return config
return '\n'.join(config)
def get_redirects(self, directives): def get_redirects(self, directives):
config = [] config = ''
for redirect in directives.get('redirect', []): for redirect in directives.get('redirect', []):
source, target = redirect.split() source, target = redirect.split()
if re.match(r'^.*[\^\*\$\?\)]+.*$', redirect): if re.match(r'^.*[\^\*\$\?\)]+.*$', redirect):
config.append("RedirectMatch %s %s" % (source, target)) config += "RedirectMatch %s %s\n" % (source, target)
else: else:
config.append("Redirect %s %s" % (source, target)) config += "Redirect %s %s\n" % (source, target)
return '\n'.join(config) return config
def get_proxies(self, directives): def get_proxies(self, directives):
config = [] config = ''
for proxy in directives.get('proxy', []): for proxy in directives.get('proxy', []):
source, target = redirect.split() source, target = proxy.split()
source = normurlpath(source) source = normurlpath(source)
config.append('ProxyPass %s %s' % (source, target)) config += 'ProxyPass %s %s\n' % (source, target)
config.append('ProxyPassReverse %s %s' % (source, target)) config += 'ProxyPassReverse %s %s\n' % (source, target)
return '\n'.join(directives) return config
# def get_protections(self, site): # def get_protections(self, site):
# protections = '' # protections = ''

View File

@ -1,8 +1,7 @@
from django import forms from django import forms
from django.core.exceptions import ValidationError 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): class WebsiteAdminForm(forms.ModelForm):
@ -12,32 +11,11 @@ class WebsiteAdminForm(forms.ModelForm):
if not domains: if not domains:
return self.cleaned_data return self.cleaned_data
protocol = self.cleaned_data.get('protocol') protocol = self.cleaned_data.get('protocol')
existing = []
for domain in domains.all(): for domain in domains.all():
if protocol == Website.HTTP: try:
qset = Q( validate_domain_protocol(self.instance, domain, protocol)
Q(protocol=Website.HTTP) | except ValidationError as e:
Q(protocol=Website.HTTP_AND_HTTPS) | # TODO not sure about this one
Q(protocol=Website.HTTPS_ONLY) self.add_error(None, e)
)
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
})
return self.cleaned_data return self.cleaned_data

View File

@ -27,7 +27,9 @@ class Website(models.Model):
related_name='websites') related_name='websites')
protocol = models.CharField(_("protocol"), max_length=16, protocol = models.CharField(_("protocol"), max_length=16,
choices=settings.WEBSITES_PROTOCOL_CHOICES, choices=settings.WEBSITES_PROTOCOL_CHOICES,
default=settings.WEBSITES_DEFAULT_PROTOCOL) default=settings.WEBSITES_DEFAULT_PROTOCOL,
help_text=_("Select the protocol(s) for this website<br>"
"<tt>HTTPS only</tt> performs a redirection from <tt>http</tt> to <tt>https</tt>."))
# port = models.PositiveIntegerField(_("port"), # port = models.PositiveIntegerField(_("port"),
# choices=settings.WEBSITES_PORT_CHOICES, # choices=settings.WEBSITES_PORT_CHOICES,
# default=settings.WEBSITES_DEFAULT_PORT) # default=settings.WEBSITES_DEFAULT_PORT)

View File

@ -1,4 +1,5 @@
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import Q
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from rest_framework import serializers from rest_framework import serializers
@ -7,6 +8,7 @@ from orchestra.api.serializers import HyperlinkedModelSerializer
from orchestra.apps.accounts.serializers import AccountSerializerMixin from orchestra.apps.accounts.serializers import AccountSerializerMixin
from .models import Website, Content from .models import Website, Content
from .validators import validate_domain_protocol
class RelatedDomainSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer): class RelatedDomainSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
@ -53,14 +55,11 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
def full_clean(self, instance): def full_clean(self, instance):
""" Prevent multiples domains on the same port """ """ Prevent multiples domains on the same port """
existing = []
for domain in instance._m2m_data['domains']: for domain in instance._m2m_data['domains']:
if domain.websites.filter(port=instance.port).exclude(pk=instance.pk).exists(): try:
existing.append(domain.name) validate_domain_protocol(instance, domain, instance.protocol)
if existing: except ValidationError as e:
context = (', '.join(existing), instance.port) # TODO not sure about this one
raise ValidationError({ self.add_error(None, e)
'domains': 'A website is already defined for "%s" on port %s' % context
})
return instance return instance

View File

@ -22,7 +22,7 @@ WEBSITES_PROTOCOL_CHOICES = getattr(settings, 'WEBSITES_PROTOCOL_CHOICES', (
WEBSITES_DEFAULT_PROTOCOL = getattr(settings, 'WEBSITES_DEFAULT_PROTOCOL', 'http') 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', '*') WEBSITES_DEFAULT_IP = getattr(settings, 'WEBSITES_DEFAULT_IP', '*')