websites: Prevent multiple domains on the same port
This commit is contained in:
parent
01842f224b
commit
f2dbc0ed42
|
@ -131,15 +131,17 @@ class PostfixAddressBackend(ServiceController):
|
|||
self.append('sed -i "/^%(domain)s\s*/d" %(virtual_alias_domains)s' % context)
|
||||
|
||||
def update_virtual_alias_maps(self, address, context):
|
||||
destination = []
|
||||
for mailbox in address.get_mailboxes():
|
||||
context['mailbox'] = mailbox
|
||||
destination.append("%(mailbox)s@%(mailbox_domain)s" % context)
|
||||
for forward in address.forward:
|
||||
if '@' in forward:
|
||||
destination.append(forward)
|
||||
# Virtual mailbox stuff
|
||||
# destination = []
|
||||
# for mailbox in address.get_mailboxes():
|
||||
# context['mailbox'] = mailbox
|
||||
# destination.append("%(mailbox)s@%(mailbox_domain)s" % context)
|
||||
# for forward in address.forward:
|
||||
# if '@' in forward:
|
||||
# destination.append(forward)
|
||||
destination = address.destination
|
||||
if destination:
|
||||
context['destination'] = ' '.join(destination)
|
||||
context['destination'] = destination
|
||||
self.append(textwrap.dedent("""
|
||||
LINE="%(email)s\t%(destination)s"
|
||||
if [[ ! $(grep "^%(email)s\s" %(virtual_alias_maps)s) ]]; then
|
||||
|
@ -153,7 +155,7 @@ class PostfixAddressBackend(ServiceController):
|
|||
fi""") % context)
|
||||
else:
|
||||
logger.warning("Address %i is empty" % address.pk)
|
||||
self.append('sed -i "/^%(email)s\s/d" %(virtual_alias_maps)s')
|
||||
self.append('sed -i "/^%(email)s\s/d" %(virtual_alias_maps)s' % context)
|
||||
self.append('UPDATED_VIRTUAL_ALIAS_MAPS=1')
|
||||
|
||||
def exclude_virtual_alias_maps(self, context):
|
||||
|
@ -180,6 +182,7 @@ class PostfixAddressBackend(ServiceController):
|
|||
[[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]] && { /etc/init.d/postfix reload; }
|
||||
""") % context
|
||||
)
|
||||
self.append('exit 0')
|
||||
|
||||
def get_context_files(self):
|
||||
return {
|
||||
|
|
|
@ -111,12 +111,12 @@ class Address(models.Model):
|
|||
def email(self):
|
||||
return "%s@%s" % (self.name, self.domain)
|
||||
|
||||
# @property
|
||||
# def destination(self):
|
||||
# destinations = list(self.mailboxes.values_list('name', flat=True))
|
||||
# if self.forward:
|
||||
# destinations.append(self.forward)
|
||||
# return ' '.join(destinations)
|
||||
@cached_property
|
||||
def destination(self):
|
||||
destinations = list(self.mailboxes.values_list('name', flat=True))
|
||||
if self.forward:
|
||||
destinations += self.forward
|
||||
return ' '.join(destinations)
|
||||
|
||||
def clean(self):
|
||||
if self.account_id:
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.core.urlresolvers import resolve
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_link, change_url
|
||||
from orchestra.apps.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||
|
||||
from . import settings
|
||||
from .forms import WebsiteAdminForm
|
||||
from .models import Content, Website, WebsiteOption
|
||||
|
||||
|
||||
|
@ -65,6 +69,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
'fields': ('account_link', 'name', 'port', 'domains', 'is_active'),
|
||||
}),
|
||||
)
|
||||
form = WebsiteAdminForm
|
||||
filter_by_account_fields = ['domains']
|
||||
list_prefetch_related = ('domains', 'content_set__webapp')
|
||||
search_fields = ('name', 'account__username', 'domains__name')
|
||||
|
@ -91,9 +96,21 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
display_webapps.short_description = _("Web apps")
|
||||
|
||||
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||
if db_field.name == 'root':
|
||||
kwargs['widget'] = forms.TextInput(attrs={'size':'100'})
|
||||
return super(WebsiteAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
"""
|
||||
Exclude domains with exhausted ports
|
||||
has to be done here, on the form doesn't work because of filter_by_account_fields
|
||||
"""
|
||||
formfield = super(WebsiteAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
if db_field.name == 'domains':
|
||||
qset = Q()
|
||||
for port, __ in settings.WEBSITES_PORT_CHOICES:
|
||||
qset = qset & Q(websites__port=port)
|
||||
args = resolve(kwargs['request'].path).args
|
||||
if args:
|
||||
object_id = args[0]
|
||||
qset = Q(qset & ~Q(websites__pk=object_id))
|
||||
formfield.queryset = formfield.queryset.exclude(qset)
|
||||
return formfield
|
||||
|
||||
|
||||
admin.site.register(Website, WebsiteAdmin)
|
||||
|
|
20
orchestra/apps/websites/forms.py
Normal file
20
orchestra/apps/websites/forms.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
|
||||
class WebsiteAdminForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
""" Prevent multiples domains on the same port """
|
||||
domains = self.cleaned_data.get('domains')
|
||||
port = self.cleaned_data.get('port')
|
||||
existing = []
|
||||
for domain in domains.all():
|
||||
if domain.websites.filter(port=port).exclude(pk=self.instance.pk).exists():
|
||||
existing.append(domain.name)
|
||||
if existing:
|
||||
context = (', '.join(existing), port)
|
||||
raise ValidationError({
|
||||
'domains': 'A website is already defined for "%s" on port %s' % context
|
||||
})
|
||||
return self.cleaned_data
|
||||
|
|
@ -32,12 +32,6 @@ class Website(models.Model):
|
|||
def unique_name(self):
|
||||
return "%s-%i" % (self.name, self.pk)
|
||||
|
||||
@cached
|
||||
def get_options(self):
|
||||
return {
|
||||
opt.name: opt.value for opt in self.options.all()
|
||||
}
|
||||
|
||||
@property
|
||||
def protocol(self):
|
||||
if self.port == 80:
|
||||
|
@ -46,6 +40,12 @@ class Website(models.Model):
|
|||
return 'https'
|
||||
raise TypeError('No protocol for port "%s"' % self.port)
|
||||
|
||||
@cached
|
||||
def get_options(self):
|
||||
return {
|
||||
opt.name: opt.value for opt in self.options.all()
|
||||
}
|
||||
|
||||
def get_absolute_url(self):
|
||||
domain = self.domains.first()
|
||||
if domain:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework import serializers
|
||||
|
||||
|
@ -49,3 +50,17 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
|||
model = Website
|
||||
fields = ('url', 'name', 'port', 'domains', 'is_active', 'contents', 'options')
|
||||
postonly_fileds = ('name',)
|
||||
|
||||
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
|
||||
})
|
||||
return instance
|
||||
|
||||
|
|
Loading…
Reference in a new issue