Impreved admin cross-reference between mailboxes and address
This commit is contained in:
parent
51ac729ce1
commit
202d1fd632
|
@ -4,7 +4,7 @@ from urllib.parse import parse_qs
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin, messages
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db.models import F, Value as V
|
from django.db.models import F, Count, Value as V
|
||||||
from django.db.models.functions import Concat
|
from django.db.models.functions import Concat
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
@ -96,7 +96,7 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
|
||||||
url = change_url(addr)
|
url = change_url(addr)
|
||||||
forwards.append('<a href="%s">%s</a>' % (url, addr.email))
|
forwards.append('<a href="%s">%s</a>' % (url, addr.email))
|
||||||
return '<br>'.join(forwards)
|
return '<br>'.join(forwards)
|
||||||
display_forwards.short_description = _("Forwards")
|
display_forwards.short_description = _("Forward from")
|
||||||
display_forwards.allow_tags = True
|
display_forwards.allow_tags = True
|
||||||
|
|
||||||
def display_filtering(self, mailbox):
|
def display_filtering(self, mailbox):
|
||||||
|
@ -203,13 +203,13 @@ class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
'display_email', 'account_link', 'domain_link', 'display_mailboxes', 'display_forward',
|
'display_email', 'account_link', 'domain_link', 'display_mailboxes', 'display_forward',
|
||||||
)
|
)
|
||||||
list_filter = (HasMailboxListFilter, HasForwardListFilter)
|
list_filter = (HasMailboxListFilter, HasForwardListFilter)
|
||||||
fields = ('account_link', 'email_link', 'mailboxes', 'forward')
|
fields = ('account_link', 'email_link', 'mailboxes', 'forward', 'display_all_mailboxes')
|
||||||
add_fields = ('account_link', ('name', 'domain'), 'mailboxes', 'forward')
|
add_fields = ('account_link', ('name', 'domain'), 'mailboxes', 'forward')
|
||||||
# inlines = [AutoresponseInline]
|
# inlines = [AutoresponseInline]
|
||||||
search_fields = (
|
search_fields = (
|
||||||
'forward', 'mailboxes__name', 'account__username', 'computed_email', 'domain__name'
|
'forward', 'mailboxes__name', 'account__username', 'computed_email', 'domain__name'
|
||||||
)
|
)
|
||||||
readonly_fields = ('account_link', 'domain_link', 'email_link')
|
readonly_fields = ('account_link', 'domain_link', 'email_link', 'display_all_mailboxes')
|
||||||
actions = (SendAddressEmail(),)
|
actions = (SendAddressEmail(),)
|
||||||
filter_by_account_fields = ('domain', 'mailboxes')
|
filter_by_account_fields = ('domain', 'mailboxes')
|
||||||
filter_horizontal = ['mailboxes']
|
filter_horizontal = ['mailboxes']
|
||||||
|
@ -237,6 +237,16 @@ class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
return '<br>'.join(boxes)
|
return '<br>'.join(boxes)
|
||||||
display_mailboxes.short_description = _("Mailboxes")
|
display_mailboxes.short_description = _("Mailboxes")
|
||||||
display_mailboxes.allow_tags = True
|
display_mailboxes.allow_tags = True
|
||||||
|
display_mailboxes.admin_order_field = 'mailboxes__count'
|
||||||
|
|
||||||
|
def display_all_mailboxes(self, address):
|
||||||
|
boxes = []
|
||||||
|
for mailbox in address.get_mailboxes():
|
||||||
|
url = change_url(mailbox)
|
||||||
|
boxes.append('<a href="%s">%s</a>' % (url, mailbox.name))
|
||||||
|
return '<br>'.join(boxes)
|
||||||
|
display_all_mailboxes.short_description = _("Mailboxes links")
|
||||||
|
display_all_mailboxes.allow_tags = True
|
||||||
|
|
||||||
def display_forward(self, address):
|
def display_forward(self, address):
|
||||||
forward_mailboxes = {m.name: m for m in address.get_forward_mailboxes()}
|
forward_mailboxes = {m.name: m for m in address.get_forward_mailboxes()}
|
||||||
|
@ -268,7 +278,8 @@ class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super(AddressAdmin, self).get_queryset(request)
|
qs = super(AddressAdmin, self).get_queryset(request)
|
||||||
return qs.annotate(computed_email=Concat(F('name'), V('@'), F('domain__name')))
|
qs = qs.annotate(computed_email=Concat(F('name'), V('@'), F('domain__name')))
|
||||||
|
return qs.annotate(Count('mailboxes'))
|
||||||
|
|
||||||
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
|
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
|
||||||
if not add:
|
if not add:
|
||||||
|
|
|
@ -151,13 +151,12 @@ class Address(models.Model):
|
||||||
|
|
||||||
def get_forward_mailboxes(self):
|
def get_forward_mailboxes(self):
|
||||||
rm_local_domain = re.compile(r'@%s$' % settings.MAILBOXES_LOCAL_DOMAIN)
|
rm_local_domain = re.compile(r'@%s$' % settings.MAILBOXES_LOCAL_DOMAIN)
|
||||||
|
mailboxes = []
|
||||||
for forward in self.forward.split():
|
for forward in self.forward.split():
|
||||||
forward = rm_local_domain.sub('', forward)
|
forward = rm_local_domain.sub('', forward)
|
||||||
if '@' not in forward:
|
if '@' not in forward:
|
||||||
try:
|
mailboxes.append(forward)
|
||||||
yield Mailbox.objects.get(name=forward)
|
return Mailbox.objects.filter(name__in=mailboxes)
|
||||||
except Mailbox.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_mailboxes(self):
|
def get_mailboxes(self):
|
||||||
for mailbox in self.mailboxes.all():
|
for mailbox in self.mailboxes.all():
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .models import Mailbox, Address
|
||||||
def delete_forwards(sender, *args, **kwargs):
|
def delete_forwards(sender, *args, **kwargs):
|
||||||
# Cleanup related addresses
|
# Cleanup related addresses
|
||||||
instance = kwargs['instance']
|
instance = kwargs['instance']
|
||||||
for address in Address.objects.filter(forward__regex=r'.*(^|\s)+%s($|\s)+.*' % instance.name):
|
for address in instance.get_forwards():
|
||||||
forward = address.forward.split()
|
forward = address.forward.split()
|
||||||
forward.remove(instance.name)
|
forward.remove(instance.name)
|
||||||
address.forward = ' '.join(forward)
|
address.forward = ' '.join(forward)
|
||||||
|
|
|
@ -28,59 +28,60 @@ class UNIXUserController(ServiceController):
|
||||||
context = self.get_context(user)
|
context = self.get_context(user)
|
||||||
if not context['user']:
|
if not context['user']:
|
||||||
return
|
return
|
||||||
groups = ','.join(self.get_groups(user))
|
|
||||||
context['groups_arg'] = '--groups %s' % groups if groups else ''
|
|
||||||
# TODO userd add will fail if %(user)s group already exists
|
# TODO userd add will fail if %(user)s group already exists
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Update/create user state for %(user)s
|
# Update/create user state for %(user)s
|
||||||
if id %(user)s ; then
|
if id %(user)s ; then
|
||||||
usermod %(user)s --home %(home)s \\
|
usermod %(user)s --home '%(home)s' \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s
|
--shell '%(shell)s' \\
|
||||||
|
--groups '%(groups)s'
|
||||||
else
|
else
|
||||||
useradd_code=0
|
useradd_code=0
|
||||||
useradd %(user)s --home %(home)s \\
|
useradd %(user)s --home '%(home)s' \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s || useradd_code=$?
|
--shell '%(shell)s' \\
|
||||||
|
--groups '%(groups)s' || useradd_code=$?
|
||||||
if [[ $useradd_code -eq 8 ]]; then
|
if [[ $useradd_code -eq 8 ]]; then
|
||||||
# User is logged in, kill and retry
|
# User is logged in, kill and retry
|
||||||
pkill -u %(user)s; sleep 2
|
pkill -u %(user)s; sleep 2
|
||||||
pkill -9 -u %(user)s; sleep 1
|
pkill -9 -u %(user)s; sleep 1
|
||||||
useradd %(user)s --home %(home)s \\
|
useradd %(user)s --home '%(home)s' \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s
|
--shell '%(shell)s' \\
|
||||||
|
--groups '%(groups)s'
|
||||||
elif [[ $useradd_code -ne 0 ]]; then
|
elif [[ $useradd_code -ne 0 ]]; then
|
||||||
exit $useradd_code
|
exit $useradd_code
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
mkdir -p %(base_home)s
|
mkdir -p '%(base_home)s'
|
||||||
chmod 750 %(base_home)s
|
chmod 750 '%(base_home)s'
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
if context['home'] != context['base_home']:
|
if context['home'] != context['base_home']:
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""\
|
||||||
# Set extra permissions: %(user)s home is inside %(mainuser)s home
|
# Set extra permissions: %(user)s home is inside %(mainuser)s home
|
||||||
if mount | grep "^$(df %(home)s|grep '^/'|cut -d' ' -f1)\s" | grep acl > /dev/null; then
|
if mount | grep "^$(df %(home)s|grep '^/'|cut -d' ' -f1)\s" | grep acl > /dev/null; then
|
||||||
# Account group as the owner
|
# Account group as the owner
|
||||||
chown %(mainuser)s:%(mainuser)s %(home)s
|
chown %(mainuser)s:%(mainuser)s '%(home)s'
|
||||||
chmod g+s %(home)s
|
chmod g+s '%(home)s'
|
||||||
# Home access
|
# Home access
|
||||||
setfacl -m u:%(user)s:--x '%(mainuser_home)s'
|
setfacl -m u:%(user)s:--x '%(mainuser_home)s'
|
||||||
# Grant perms to future files within the directory
|
# Grant perms to future files within the directory
|
||||||
setfacl -m d:u:%(user)s:rwx %(home)s
|
setfacl -m d:u:%(user)s:rwx '%(home)s'
|
||||||
# Grant access to main user
|
# Grant access to main user
|
||||||
setfacl -m d:u:%(mainuser)s:rwx %(home)s
|
setfacl -m d:u:%(mainuser)s:rwx '%(home)s'
|
||||||
else
|
else
|
||||||
chmod g+rxw %(home)s
|
chmod g+rxw %(home)s
|
||||||
fi""") % context
|
fi""") % context
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
chown %(user)s:%(group)s %(home)s
|
chown %(user)s:%(group)s '%(home)s'
|
||||||
ls -A /etc/skel/ | while read line; do
|
ls -A /etc/skel/ | while read line; do
|
||||||
if [[ ! -e %(home)s/${line} ]]; then
|
if [[ ! -e "%(home)s/${line}" ]]; then
|
||||||
cp -a /etc/skel/${line} %(home)s/${line} && \\
|
cp -a "/etc/skel/${line}" "%(home)s/${line}" && \\
|
||||||
chown -R %(user)s:%(group)s %(home)s/${line}
|
chown -R %(user)s:%(group)s "%(home)s/${line}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
""") % context
|
""") % context
|
||||||
|
@ -107,14 +108,14 @@ class UNIXUserController(ServiceController):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Move home into SYSTEMUSERS_MOVE_ON_DELETE_PATH, nesting if exists.
|
# Move home into SYSTEMUSERS_MOVE_ON_DELETE_PATH, nesting if exists.
|
||||||
deleted_home="%(deleted_home)s"
|
deleted_home="%(deleted_home)s"
|
||||||
while [[ -e $deleted_home ]]; do
|
while [[ -e "$deleted_home" ]]; do
|
||||||
deleted_home="${deleted_home}/$(basename ${deleted_home})"
|
deleted_home="${deleted_home}/$(basename ${deleted_home})"
|
||||||
done
|
done
|
||||||
mv %(base_home)s $deleted_home || exit_code=$?
|
mv '%(base_home)s' "$deleted_home" || exit_code=$?
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.append("rm -fr %(base_home)s" % context)
|
self.append("rm -fr '%(base_home)s'" % context)
|
||||||
|
|
||||||
def grant_permissions(self, user, context):
|
def grant_permissions(self, user, context):
|
||||||
context['perms'] = user.set_perm_perms
|
context['perms'] = user.set_perm_perms
|
||||||
|
@ -206,8 +207,8 @@ class UNIXUserController(ServiceController):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Create link
|
# Create link
|
||||||
su %(user)s --shell /bin/bash << 'EOF' || exit_code=1
|
su %(user)s --shell /bin/bash << 'EOF' || exit_code=1
|
||||||
if [[ ! -e %(link_name)s ]]; then
|
if [[ ! -e '%(link_name)s' ]]; then
|
||||||
ln -s %(link_target)s %(link_name)s
|
ln -s '%(link_target)s' '%(link_name)s'
|
||||||
else
|
else
|
||||||
echo "%(link_name)s already exists, doing nothing." >&2
|
echo "%(link_name)s already exists, doing nothing." >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -236,6 +237,7 @@ class UNIXUserController(ServiceController):
|
||||||
'object_id': user.pk,
|
'object_id': user.pk,
|
||||||
'user': user.username,
|
'user': user.username,
|
||||||
'group': user.username,
|
'group': user.username,
|
||||||
|
'groups': ','.join(self.get_groups(user)),
|
||||||
'password': user.password if user.active else '*%s' % user.password,
|
'password': user.password if user.active else '*%s' % user.password,
|
||||||
'shell': user.shell,
|
'shell': user.shell,
|
||||||
'mainuser': user.username if user.is_main else user.account.username,
|
'mainuser': user.username if user.is_main else user.account.username,
|
||||||
|
|
Loading…
Reference in New Issue