add separate models for mail addresses, domains and mailboxes

This commit is contained in:
Jan Dittberner 2014-05-19 22:28:25 +02:00
parent 402c02203d
commit 618a9b8c11
5 changed files with 343 additions and 8 deletions

View file

@ -1,3 +1,140 @@
from django.utils.html import format_html
from django.contrib import admin from django.contrib import admin
from django import forms
from django.forms.util import flatatt
from django.utils.translation import ugettext as _
# Register your models here. from .models import (
MailDomain,
Mailbox,
MailAddress
)
PASSWORD_MISMATCH_ERROR = _("Passwords don't match")
class ReadOnlyPasswordHashWidget(forms.Widget):
def render(self, name, value, attrs):
final_attrs = self.build_attrs(attrs)
summary = format_html("<strong>{0}</strong>: {1} ",
_('Hash'), value)
return format_html("<div{0}>{1}</div>", flatatt(final_attrs), summary)
class ReadOnlyPasswordHashField(forms.Field):
widget = ReadOnlyPasswordHashWidget
def __init__(self, *args, **kwargs):
kwargs.setdefault("required", False)
super(ReadOnlyPasswordHashField, self).__init__(*args, **kwargs)
def bound_data(self, data, initial):
return initial
def _has_changed(self, initial, data):
return False
class MailboxCreationForm(forms.ModelForm):
"""
A form for creating mailboxes.
"""
password1 = forms.CharField(label=_('Password'),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_('Password (again)'),
widget=forms.PasswordInput)
class Meta:
model = Mailbox
fields = ('username', 'domain')
def clean_password2(self):
"""
Check that the two password entries match.
"""
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError(PASSWORD_MISMATCH_ERROR)
return password2
def save(self, commit=True):
"""
Save the provided password in hashed format.
"""
mailbox = super(MailboxCreationForm, self).save(commit=False)
mailbox.set_password(self.cleaned_data['password1'])
mailbox.uid = 0
mailbox.gid = 0
if commit:
mailbox.save()
return mailbox
class MailboxChangeForm(forms.ModelForm):
"""
A form for updating mailboxes.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = Mailbox
fields = ('username', 'domain', 'password', 'home', 'uid', 'gid',
'active')
def clean_password(self):
return self.initial['password']
class MailboxAdmin(admin.ModelAdmin):
"""
Custom admin page for mailboxes.
"""
form = MailboxChangeForm
add_form = MailboxCreationForm
list_display = ('username', 'domain', 'active')
list_filter = ('active',)
fieldsets = (
(None, {
'fields': ('username', 'domain', 'password', 'active')}),
(_('System'), {
'fields': ('home', 'uid', 'gid')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'domain', 'password1', 'password2')}),
)
search_fields = ('username', 'domain')
ordering = ('username', 'domain')
filter_horizontal = ()
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(MailboxAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during mailbox creation.
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(MailboxAdmin, self).get_form(request, obj, **defaults)
admin.site.register(MailDomain)
admin.site.register(Mailbox, MailboxAdmin)
admin.site.register(MailAddress)

View file

@ -8,11 +8,18 @@ from django.db import models
class Migration(SchemaMigration): class Migration(SchemaMigration):
def forwards(self, orm): def forwards(self, orm):
# Adding model 'MailDomain'
db.create_table(u'managemails_maildomain', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('domain', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
))
db.send_create_signal(u'managemails', ['MailDomain'])
# Adding model 'Mailbox' # Adding model 'Mailbox'
db.create_table(u'managemails_mailbox', ( db.create_table(u'managemails_mailbox', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('username', self.gf('django.db.models.fields.CharField')(max_length=128)), ('username', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
('domain', self.gf('django.db.models.fields.CharField')(max_length=128)), ('domain', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['managemails.MailDomain'])),
('password', self.gf('django.db.models.fields.CharField')(max_length=64)), ('password', self.gf('django.db.models.fields.CharField')(max_length=64)),
('home', self.gf('django.db.models.fields.CharField')(max_length=255)), ('home', self.gf('django.db.models.fields.CharField')(max_length=255)),
('uid', self.gf('django.db.models.fields.PositiveSmallIntegerField')()), ('uid', self.gf('django.db.models.fields.PositiveSmallIntegerField')()),
@ -21,23 +28,102 @@ class Migration(SchemaMigration):
)) ))
db.send_create_signal(u'managemails', ['Mailbox']) db.send_create_signal(u'managemails', ['Mailbox'])
# Adding model 'MailAddress'
db.create_table(u'managemails_mailaddress', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('localpart', self.gf('django.db.models.fields.CharField')(max_length=128)),
('domain', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['managemails.MailDomain'])),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
))
db.send_create_signal(u'managemails', ['MailAddress'])
# Adding unique constraint on 'MailAddress', fields ['localpart', 'domain']
db.create_unique(u'managemails_mailaddress', ['localpart', 'domain_id'])
# Adding model 'MailAddressMailbox'
db.create_table(u'managemails_mailaddressmailbox', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('mailaddress', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['managemails.MailAddress'])),
('mailbox', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['managemails.Mailbox'])),
))
db.send_create_signal(u'managemails', ['MailAddressMailbox'])
# Adding unique constraint on 'MailAddressMailbox', fields ['mailaddress', 'mailbox']
db.create_unique(u'managemails_mailaddressmailbox', ['mailaddress_id', 'mailbox_id'])
# Adding model 'MailAddressForward'
db.create_table(u'managemails_mailaddressforward', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('mailaddress', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['managemails.MailAddress'])),
('target', self.gf('django.db.models.fields.EmailField')(max_length=254)),
))
db.send_create_signal(u'managemails', ['MailAddressForward'])
# Adding unique constraint on 'MailAddressForward', fields ['mailaddress', 'target']
db.create_unique(u'managemails_mailaddressforward', ['mailaddress_id', 'target'])
def backwards(self, orm): def backwards(self, orm):
# Removing unique constraint on 'MailAddressForward', fields ['mailaddress', 'target']
db.delete_unique(u'managemails_mailaddressforward', ['mailaddress_id', 'target'])
# Removing unique constraint on 'MailAddressMailbox', fields ['mailaddress', 'mailbox']
db.delete_unique(u'managemails_mailaddressmailbox', ['mailaddress_id', 'mailbox_id'])
# Removing unique constraint on 'MailAddress', fields ['localpart', 'domain']
db.delete_unique(u'managemails_mailaddress', ['localpart', 'domain_id'])
# Deleting model 'MailDomain'
db.delete_table(u'managemails_maildomain')
# Deleting model 'Mailbox' # Deleting model 'Mailbox'
db.delete_table(u'managemails_mailbox') db.delete_table(u'managemails_mailbox')
# Deleting model 'MailAddress'
db.delete_table(u'managemails_mailaddress')
# Deleting model 'MailAddressMailbox'
db.delete_table(u'managemails_mailaddressmailbox')
# Deleting model 'MailAddressForward'
db.delete_table(u'managemails_mailaddressforward')
models = { models = {
u'managemails.mailaddress': {
'Meta': {'unique_together': "(('localpart', 'domain'),)", 'object_name': 'MailAddress'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailDomain']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'localpart': ('django.db.models.fields.CharField', [], {'max_length': '128'})
},
u'managemails.mailaddressforward': {
'Meta': {'unique_together': "(('mailaddress', 'target'),)", 'object_name': 'MailAddressForward'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mailaddress': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailAddress']"}),
'target': ('django.db.models.fields.EmailField', [], {'max_length': '254'})
},
u'managemails.mailaddressmailbox': {
'Meta': {'unique_together': "(('mailaddress', 'mailbox'),)", 'object_name': 'MailAddressMailbox'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mailaddress': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailAddress']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.Mailbox']"})
},
u'managemails.mailbox': { u'managemails.mailbox': {
'Meta': {'object_name': 'Mailbox'}, 'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'domain': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailDomain']"}),
'gid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}), 'gid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'home': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 'home': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 'password': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
'uid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}), 'uid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '128'}) 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
},
u'managemails.maildomain': {
'Meta': {'object_name': 'MailDomain'},
'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
} }
} }

View file

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Mailbox.password'
db.alter_column(u'managemails_mailbox', 'password', self.gf('django.db.models.fields.CharField')(max_length=255))
def backwards(self, orm):
# Changing field 'Mailbox.password'
db.alter_column(u'managemails_mailbox', 'password', self.gf('django.db.models.fields.CharField')(max_length=64))
models = {
u'managemails.mailaddress': {
'Meta': {'unique_together': "(('localpart', 'domain'),)", 'object_name': 'MailAddress'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailDomain']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'localpart': ('django.db.models.fields.CharField', [], {'max_length': '128'})
},
u'managemails.mailaddressforward': {
'Meta': {'unique_together': "(('mailaddress', 'target'),)", 'object_name': 'MailAddressForward'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mailaddress': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailAddress']"}),
'target': ('django.db.models.fields.EmailField', [], {'max_length': '254'})
},
u'managemails.mailaddressmailbox': {
'Meta': {'unique_together': "(('mailaddress', 'mailbox'),)", 'object_name': 'MailAddressMailbox'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mailaddress': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailAddress']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.Mailbox']"})
},
u'managemails.mailbox': {
'Meta': {'object_name': 'Mailbox'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['managemails.MailDomain']"}),
'gid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'home': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'uid': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
},
u'managemails.maildomain': {
'Meta': {'object_name': 'MailDomain'},
'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['managemails']

View file

@ -1,11 +1,64 @@
from django.db import models from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _
from passlib.hash import sha512_crypt
@python_2_unicode_compatible
class MailDomain(models.Model):
domain = models.CharField(max_length=128, unique=True)
class Meta:
verbose_name = _('Mail domain')
verbose_name_plural = _('Mail domains')
def __str__(self):
return self.domain
class Mailbox(models.Model): class Mailbox(models.Model):
username = models.CharField(max_length=128) username = models.CharField(max_length=128, unique=True)
domain = models.CharField(max_length=128) domain = models.ForeignKey(MailDomain)
password = models.CharField(max_length=64) password = models.CharField(max_length=255)
home = models.CharField(max_length=255) home = models.CharField(max_length=255)
uid = models.PositiveSmallIntegerField() uid = models.PositiveSmallIntegerField()
gid = models.PositiveSmallIntegerField() gid = models.PositiveSmallIntegerField()
active = models.BooleanField(default=True) active = models.BooleanField(default=True)
class Meta:
verbose_name = _('Mailbox')
verbose_name_plural = _('Mailboxes')
def set_password(self, password):
self.password = sha512_crypt.encrypt(password)
@python_2_unicode_compatible
class MailAddress(models.Model):
localpart = models.CharField(max_length=128)
domain = models.ForeignKey(MailDomain)
active = models.BooleanField(default=True)
class Meta:
unique_together = ('localpart', 'domain')
verbose_name = _('Mail address')
verbose_name_plural = _('Mail addresses')
def __str__(self):
return "{0}@{1}".format(self.localpart, self.domain)
class MailAddressMailbox(models.Model):
mailaddress = models.ForeignKey(MailAddress)
mailbox = models.ForeignKey(Mailbox)
class Meta:
unique_together = ('mailaddress', 'mailbox')
class MailAddressForward(models.Model):
mailaddress = models.ForeignKey(MailAddress)
target = models.EmailField(max_length=254)
class Meta:
unique_together = ('mailaddress', 'target')

View file

@ -5,3 +5,4 @@ django-model-utils==2.0.3
logutils==0.3.3 logutils==0.3.3
South==0.8.4 South==0.8.4
psycopg2==2.5.3 psycopg2==2.5.3
passlib==1.6.2