--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualMailManager/Domain.py Sun Jan 06 18:22:10 2008 +0000
@@ -0,0 +1,221 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+# opyright 2007-2008 VEB IT
+# See COPYING for distribution information.
+# $Id$
+
+"""Virtual Mail Manager's Domain class to manage email domains."""
+
+__author__ = 'Pascal Volk <p.volk@veb-it.de>'
+__version__ = 'rev '+'$Rev$'.split()[1]
+__date__ = '$Date$'.split()[1]
+
+from random import choice
+
+from Exceptions import VMMDomainException
+import constants.ERROR as ERR
+
+MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
+
+class Domain:
+ """Class to manage email domains."""
+ def __init__(self, dbh, domainname, basedir, transport=None):
+ """Creates a new Domain instance.
+
+ Keyword arguments:
+ dbh -- a pyPgSQL.PgSQL.connection
+ domainname -- name of the domain (str)
+ transport -- see transport(5), default 'dovecot:' (str)
+ """
+ self._dbh = dbh
+ self._name = domainname
+ self._basedir = basedir
+ if transport is None:
+ self._transport = 'dovecot:'
+ else:
+ self._transport = transport
+ self._id = 0
+ self._domaindir = None
+ self._exists()
+
+ def _exists(self):
+ """Checks if the domain already exists.
+
+ If the domain exists _id will be set and returns True, otherwise False
+ will be returned.
+ """
+ dbc = self._dbh.cursor()
+ dbc.execute("SELECT gid, domaindir FROM domains WHERE domainname=%s",
+ self._name)
+ result = dbc.fetchone()
+ dbc.close()
+ if result is not None:
+ self._id, self._domaindir = result[0], result[1]
+ return True
+ else:
+ return False
+
+ def _setID(self):
+ """Sets the ID of the domain."""
+ dbc = self._dbh.cursor()
+ dbc.execute("SELECT nextval('domains_gid')")
+ self._id = dbc.fetchone()[0]
+ dbc.close()
+
+ def _prepare(self):
+ self._setID()
+ self._domaindir = "%s/%s/%i" % (self._basedir, choice(MAILDIR_CHARS),
+ self._id)
+
+ def _has(self, what):
+ """Checks if aliases or accounts are assigned to the domain.
+
+ If there are assigned accounts or aliases True will be returned,
+ otherwise False will be returned.
+
+ Keyword arguments:
+ what -- 'alias' or 'users' (strings)
+ """
+ if what not in ['alias', 'users']:
+ return False
+ dbc = self._dbh.cursor()
+ if what == 'users':
+ dbc.execute("SELECT count(gid) FROM users WHERE gid=%s", self._id)
+ else:
+ dbc.execute("SELECT count(gid) FROM alias WHERE gid=%s", self._id)
+ count = dbc.fetchone()
+ dbc.close()
+ if count[0] > 0:
+ return True
+ else:
+ return False
+
+ def _chkDelete(self, delUser, delAlias):
+ """Checks dependencies for deletion.
+
+ Keyword arguments:
+ delUser -- ignore available accounts (bool)
+ delAlias -- ignore available aliases (bool)
+ """
+ if not delUser:
+ hasUser = self._has('users')
+ else:
+ hasUser = False
+ if not delAlias:
+ hasAlias = self._has('alias')
+ else:
+ hasAlias = False
+ if hasUser and hasAlias:
+ raise VMMDomainException(('There are accounts and aliases.',
+ ERR.ACCOUNT_AND_ALIAS_PRESENT))
+ elif hasUser:
+ raise VMMDomainException(('There are accounts.',
+ ERR.ACCOUNT_PRESENT))
+ elif hasAlias:
+ raise VMMDomainException(('There are aliases.', ERR.ALIAS_PRESENT))
+
+ def save(self):
+ """Stores the new domain in the database."""
+ if self._id < 1:
+ self._prepare()
+ dbc = self._dbh.cursor()
+ dbc.execute("INSERT INTO domains (gid, domainname, transport,\
+ domaindir) VALUES (%s, %s, %s, %s)", self._id, self._name, self._transport,
+ self._domaindir)
+ self._dbh.commit()
+ dbc.close()
+ else:
+ raise VMMDomainException(('Domain already exists.',
+ ERR.DOMAIN_EXISTS))
+
+ def delete(self, delUser=False, delAlias=False):
+ """Deletes the domain.
+
+ Keyword arguments:
+ delUser -- force deletion of available accounts (bool)
+ delAlias -- force deletion of available aliases (bool)
+ """
+ if self._id > 0:
+ self._chkDelete(delUser, delAlias)
+ dbc = self._dbh.cursor()
+ dbc.execute('DELETE FROM alias WHERE gid=%s', self._id)
+ dbc.execute('DELETE FROM users WHERE gid=%s', self._id)
+ dbc.execute('DELETE FROM relocated WHERE gid=%s', self._id)
+ dbc.execute('DELETE FROM domains WHERE gid=%s', self._id)
+ self._dbh.commit()
+ dbc.close()
+ else:
+ raise VMMDomainException(("Domain doesn't exist yet.",
+ ERR.NO_SUCH_DOMAIN))
+
+ def updateTransport(self, transport):
+ """Sets a new transport for the domain.
+
+ Keyword arguments:
+ transport -- the new transport (str)
+ """
+ if self._id > 0:
+ dbc = self._dbh.cursor()
+ dbc.execute("UPDATE domains SET transport=%s WHERE gid=%s",
+ transport, self._id)
+ if dbc.rowcount > 0:
+ self._dbh.commit()
+ dbc.close()
+ else:
+ raise VMMDomainException(("Domain doesn't exist yet.",
+ ERR.NO_SUCH_DOMAIN))
+
+ def getID(self):
+ """Returns the ID of the domain."""
+ return self._id
+
+ def getDir(self):
+ """Returns the directory of the domain."""
+ return self._domaindir
+
+ def getInfo(self):
+ """Returns a dictionary with information about the domain."""
+ sql = """\
+SELECT gid, domainname, transport, domaindir, count(uid) AS accounts, aliases
+ FROM domains
+ LEFT JOIN users USING (gid)
+ LEFT JOIN vmm_alias_count USING (gid)
+ WHERE gid = %i
+GROUP BY gid, domainname, transport, domaindir, aliases""" % self._id
+ dbc = self._dbh.cursor()
+ dbc.execute(sql)
+ info = dbc.fetchone()
+ dbc.close()
+ if info is None:
+ raise VMMDomainException(("Domain doesn't exist yet.",
+ ERR.NO_SUCH_DOMAIN))
+ else:
+ keys = ['gid', 'domainname', 'transport', 'domaindir', 'accounts',
+ 'aliases']
+ return dict(zip(keys, info))
+
+ def getAccounts(self):
+ """Returns a list with all accounts from the domain."""
+ dbc = self._dbh.cursor()
+ dbc.execute("SELECT userid AS users FROM dovecot_user WHERE gid = %s",
+ self._id)
+ users = dbc.fetchall()
+ dbc.close()
+ accounts = []
+ if len(users) > 0:
+ for account in users:
+ accounts.append(account[0])
+ return accounts
+
+ def getAliases(self):
+ """Returns a list with all aliases from the domain."""
+ dbc = self._dbh.cursor()
+ dbc.execute("SELECT DISTINCT address FROM postfix_alias WHERE gid=%s",
+ self._id)
+ addresses = dbc.fetchall()
+ dbc.close()
+ aliases = []
+ if len(addresses) > 0:
+ for alias in addresses:
+ aliases.append(alias[0])
+ return aliases