VirtualMailManager/Domain.py
changeset 0 bb0aa2102206
child 3 a9b44e04bf01
equal deleted inserted replaced
-1:000000000000 0:bb0aa2102206
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: UTF-8 -*-
       
     3 # opyright 2007-2008 VEB IT
       
     4 # See COPYING for distribution information.
       
     5 # $Id$
       
     6 
       
     7 """Virtual Mail Manager's Domain class to manage email domains."""
       
     8 
       
     9 __author__ = 'Pascal Volk <p.volk@veb-it.de>'
       
    10 __version__ = 'rev '+'$Rev$'.split()[1]
       
    11 __date__ = '$Date$'.split()[1]
       
    12 
       
    13 from random import choice
       
    14 
       
    15 from Exceptions import VMMDomainException
       
    16 import constants.ERROR as ERR
       
    17 
       
    18 MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
       
    19 
       
    20 class Domain:
       
    21     """Class to manage email domains."""
       
    22     def __init__(self, dbh, domainname, basedir, transport=None):
       
    23         """Creates a new Domain instance.
       
    24         
       
    25         Keyword arguments:
       
    26         dbh -- a pyPgSQL.PgSQL.connection
       
    27         domainname -- name of the domain (str)
       
    28         transport -- see transport(5), default 'dovecot:'  (str)
       
    29         """
       
    30         self._dbh = dbh
       
    31         self._name = domainname
       
    32         self._basedir = basedir
       
    33         if transport is None:
       
    34             self._transport = 'dovecot:'
       
    35         else:
       
    36             self._transport = transport
       
    37         self._id = 0
       
    38         self._domaindir = None
       
    39         self._exists()
       
    40 
       
    41     def _exists(self):
       
    42         """Checks if the domain already exists.
       
    43 
       
    44         If the domain exists _id will be set and returns True, otherwise False
       
    45         will be returned.
       
    46         """
       
    47         dbc = self._dbh.cursor()
       
    48         dbc.execute("SELECT gid, domaindir FROM domains WHERE domainname=%s",
       
    49                 self._name)
       
    50         result = dbc.fetchone()
       
    51         dbc.close()
       
    52         if result is not None:
       
    53             self._id, self._domaindir = result[0], result[1]
       
    54             return True
       
    55         else:
       
    56             return False
       
    57 
       
    58     def _setID(self):
       
    59         """Sets the ID of the domain."""
       
    60         dbc = self._dbh.cursor()
       
    61         dbc.execute("SELECT nextval('domains_gid')")
       
    62         self._id = dbc.fetchone()[0]
       
    63         dbc.close()
       
    64 
       
    65     def _prepare(self):
       
    66         self._setID()
       
    67         self._domaindir = "%s/%s/%i" % (self._basedir, choice(MAILDIR_CHARS),
       
    68                 self._id)
       
    69 
       
    70     def _has(self, what):
       
    71         """Checks if aliases or accounts are assigned to the domain.
       
    72 
       
    73         If there are assigned accounts or aliases True will be returned,
       
    74         otherwise False will be returned.
       
    75 
       
    76         Keyword arguments:
       
    77         what -- 'alias' or 'users' (strings)
       
    78         """
       
    79         if what not in ['alias', 'users']:
       
    80             return False
       
    81         dbc = self._dbh.cursor()
       
    82         if what == 'users':
       
    83             dbc.execute("SELECT count(gid) FROM users WHERE gid=%s", self._id)
       
    84         else:
       
    85             dbc.execute("SELECT count(gid) FROM alias WHERE gid=%s", self._id)
       
    86         count = dbc.fetchone()
       
    87         dbc.close()
       
    88         if count[0] > 0:
       
    89             return True
       
    90         else:
       
    91             return False
       
    92 
       
    93     def _chkDelete(self, delUser, delAlias):
       
    94         """Checks dependencies for deletion.
       
    95         
       
    96         Keyword arguments:
       
    97         delUser -- ignore available accounts (bool)
       
    98         delAlias -- ignore available aliases (bool)
       
    99         """
       
   100         if not delUser:
       
   101             hasUser = self._has('users')
       
   102         else:
       
   103             hasUser = False
       
   104         if not delAlias:
       
   105             hasAlias = self._has('alias')
       
   106         else:
       
   107             hasAlias = False
       
   108         if hasUser and hasAlias:
       
   109             raise VMMDomainException(('There are accounts and aliases.',
       
   110                 ERR.ACCOUNT_AND_ALIAS_PRESENT))
       
   111         elif hasUser:
       
   112             raise VMMDomainException(('There are accounts.',
       
   113                 ERR.ACCOUNT_PRESENT))
       
   114         elif hasAlias:
       
   115             raise VMMDomainException(('There are aliases.', ERR.ALIAS_PRESENT))
       
   116 
       
   117     def save(self):
       
   118         """Stores the new domain in the database."""
       
   119         if self._id < 1:
       
   120             self._prepare()
       
   121             dbc = self._dbh.cursor()
       
   122             dbc.execute("INSERT INTO domains (gid, domainname, transport,\
       
   123  domaindir) VALUES (%s, %s, %s, %s)", self._id, self._name, self._transport,
       
   124                 self._domaindir)
       
   125             self._dbh.commit()
       
   126             dbc.close()
       
   127         else:
       
   128             raise VMMDomainException(('Domain already exists.',
       
   129                 ERR.DOMAIN_EXISTS))
       
   130 
       
   131     def delete(self, delUser=False, delAlias=False):
       
   132         """Deletes the domain.
       
   133 
       
   134         Keyword arguments:
       
   135         delUser -- force deletion of available accounts (bool)
       
   136         delAlias -- force deletion of available aliases (bool)
       
   137         """
       
   138         if self._id > 0:
       
   139             self._chkDelete(delUser, delAlias)
       
   140             dbc = self._dbh.cursor()
       
   141             dbc.execute('DELETE FROM alias WHERE gid=%s', self._id)
       
   142             dbc.execute('DELETE FROM users WHERE gid=%s', self._id)
       
   143             dbc.execute('DELETE FROM relocated WHERE gid=%s', self._id)
       
   144             dbc.execute('DELETE FROM domains WHERE gid=%s', self._id)
       
   145             self._dbh.commit()
       
   146             dbc.close()
       
   147         else:
       
   148             raise VMMDomainException(("Domain doesn't exist yet.",
       
   149                 ERR.NO_SUCH_DOMAIN))
       
   150 
       
   151     def updateTransport(self, transport):
       
   152         """Sets a new transport for the domain.
       
   153 
       
   154         Keyword arguments:
       
   155         transport -- the new transport (str)
       
   156         """
       
   157         if self._id > 0:
       
   158             dbc = self._dbh.cursor()
       
   159             dbc.execute("UPDATE domains SET transport=%s WHERE gid=%s",
       
   160                     transport, self._id)
       
   161             if dbc.rowcount > 0:
       
   162                 self._dbh.commit()
       
   163             dbc.close()
       
   164         else:
       
   165             raise VMMDomainException(("Domain doesn't exist yet.",
       
   166                 ERR.NO_SUCH_DOMAIN))
       
   167 
       
   168     def getID(self):
       
   169         """Returns the ID of the domain."""
       
   170         return self._id
       
   171 
       
   172     def getDir(self):
       
   173         """Returns the directory of the domain."""
       
   174         return self._domaindir
       
   175 
       
   176     def getInfo(self):
       
   177         """Returns a dictionary with information about the domain."""
       
   178         sql = """\
       
   179 SELECT gid, domainname, transport, domaindir, count(uid) AS accounts, aliases
       
   180   FROM domains
       
   181        LEFT JOIN users USING (gid)
       
   182        LEFT JOIN vmm_alias_count USING (gid)
       
   183  WHERE gid = %i
       
   184 GROUP BY gid, domainname, transport, domaindir, aliases""" % self._id
       
   185         dbc = self._dbh.cursor()
       
   186         dbc.execute(sql)
       
   187         info = dbc.fetchone()
       
   188         dbc.close()
       
   189         if info is None:
       
   190             raise VMMDomainException(("Domain doesn't exist yet.",
       
   191                 ERR.NO_SUCH_DOMAIN))
       
   192         else:
       
   193             keys = ['gid', 'domainname', 'transport', 'domaindir', 'accounts',
       
   194                     'aliases']
       
   195             return dict(zip(keys, info))
       
   196 
       
   197     def getAccounts(self):
       
   198         """Returns a list with all accounts from the domain."""
       
   199         dbc = self._dbh.cursor()
       
   200         dbc.execute("SELECT userid AS users FROM dovecot_user WHERE gid = %s",
       
   201                 self._id)
       
   202         users = dbc.fetchall()
       
   203         dbc.close()
       
   204         accounts = []
       
   205         if len(users) > 0:
       
   206             for account in users:
       
   207                 accounts.append(account[0])
       
   208         return accounts
       
   209 
       
   210     def getAliases(self):
       
   211         """Returns a list with all aliases from the domain."""
       
   212         dbc = self._dbh.cursor()
       
   213         dbc.execute("SELECT DISTINCT address FROM postfix_alias WHERE gid=%s",
       
   214                 self._id)
       
   215         addresses = dbc.fetchall()
       
   216         dbc.close()
       
   217         aliases = []
       
   218         if len(addresses) > 0:
       
   219             for alias in addresses:
       
   220                 aliases.append(alias[0])
       
   221         return aliases