""" This module defines the database models for mail handling. """ from __future__ import unicode_literals 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 from model_utils.models import TimeStampedModel from domains.models import MailDomain from osusers.models import User as OsUser from fileservertasks.tasks import ( create_file_mailbox, delete_file_mailbox, ) class ActivateAbleMixin(models.Model): """ Mixin for model classes that can be active or inactive. """ active = models.BooleanField(default=True) class Meta: abstract = True class MailboxManager(models.Manager): """ This is the default manager class for :py:class:`Mailbox`. """ def get_next_mailbox_name(self, osuser): """ Get the next available mailbox name for the given operating system user. :param osuser: a :py:class:`operating system user ` instance :return: name of the mailbox :rtype: str """ count = 1 mailboxformat = "{0}p{1:02d}" mailboxname = mailboxformat.format(osuser.username, count) for box in self.values('username').filter(osuser=osuser).order_by( 'username' ): if box['username'] == mailboxname: count += 1 mailboxname = mailboxformat.format(osuser.username, count) else: break return mailboxname @python_2_unicode_compatible class Mailbox(ActivateAbleMixin, TimeStampedModel): """ This is the model class for a mailbox. """ osuser = models.ForeignKey(OsUser) username = models.CharField(max_length=128, unique=True) password = models.CharField(max_length=255) objects = MailboxManager() class Meta: ordering = ['osuser', 'username'] verbose_name = _('Mailbox') verbose_name_plural = _('Mailboxes') def set_password(self, password): """ Set the hashed password for the mailbox. :param str password: the clear text password """ self.password = sha512_crypt.encrypt(password) def save(self, *args, **kwargs): create_file_mailbox.delay(self.osuser.username, self.username).get() super(Mailbox, self).save(*args, **kwargs) def delete(self, *args, **kwargs): delete_file_mailbox.delay(self.osuser.username, self.username).get() super(Mailbox, self).delete(*args, **kwargs) def get_mailaddresses(self): """ Get a list of mail addresses assigned to this mailbox. """ addrs = [ mbadr.mailaddress for mbadr in self.mailaddressmailbox_set.all() ] return addrs mailaddresses = property(get_mailaddresses) def __str__(self): return self.username @python_2_unicode_compatible class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model): """ This is the model class for a mail address. """ localpart = models.CharField(_('local part'), max_length=128) domain = models.ForeignKey(MailDomain, verbose_name=_('domain')) class Meta: ordering = ['domain', 'localpart'] unique_together = ('localpart', 'domain') verbose_name = _('Mail address') verbose_name_plural = _('Mail addresses') def __str__(self): return "{0}@{1}".format(self.localpart, self.domain) @python_2_unicode_compatible class MailAddressMailbox(TimeStampedModel, models.Model): """ This is the model class to assign a mail address to a mailbox. """ mailaddress = models.OneToOneField( MailAddress, verbose_name=_('mailaddress'), primary_key=True) mailbox = models.ForeignKey(Mailbox, verbose_name=_('mailbox')) class Meta: unique_together = ('mailaddress', 'mailbox') def __str__(self): return self.mailbox.username class MailAddressForward(TimeStampedModel, models.Model): """ This is a model class to map mail addresses to forwarding addresses. """ mailaddress = models.ForeignKey(MailAddress) target = models.EmailField(max_length=254) class Meta: unique_together = ('mailaddress', 'target')