VirtualMailManager/domain.py
branchv0.6.x
changeset 331 270b57af85de
parent 320 011066435e6f
child 336 d24c2ea39710
equal deleted inserted replaced
330:3fe8d6cdbe3a 331:270b57af85de
    11 import os
    11 import os
    12 import re
    12 import re
    13 from random import choice
    13 from random import choice
    14 
    14 
    15 from VirtualMailManager.constants import \
    15 from VirtualMailManager.constants import \
    16      ACCOUNT_AND_ALIAS_PRESENT, ACCOUNT_PRESENT, ALIAS_PRESENT, \
    16      ACCOUNT_AND_ALIAS_PRESENT, DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, \
    17      DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, DOMAIN_INVALID, DOMAIN_TOO_LONG, \
    17      DOMAIN_INVALID, DOMAIN_TOO_LONG, NO_SUCH_DOMAIN
    18      NO_SUCH_DOMAIN
       
    19 from VirtualMailManager.errors import DomainError as DomErr
    18 from VirtualMailManager.errors import DomainError as DomErr
       
    19 from VirtualMailManager.pycompat import any
    20 from VirtualMailManager.transport import Transport
    20 from VirtualMailManager.transport import Transport
    21 
    21 
    22 
    22 
    23 MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
    23 MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
    24 RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$")
    24 RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$")
    81         dbc = self._dbh.cursor()
    81         dbc = self._dbh.cursor()
    82         dbc.execute("SELECT nextval('domain_gid')")
    82         dbc.execute("SELECT nextval('domain_gid')")
    83         self._gid = dbc.fetchone()[0]
    83         self._gid = dbc.fetchone()[0]
    84         dbc.close()
    84         dbc.close()
    85 
    85 
    86     def _has(self, what):
    86     def _check_for_addresses(self):
    87         """Checks if aliases or accounts are assigned to the domain.
    87         """Checks dependencies for deletion. Raises a DomainError if there
    88 
    88         are accounts, aliases and/or relocated users.
    89         If there are assigned accounts or aliases True will be returned,
    89         """
    90         otherwise False will be returned.
    90         dbc = self._dbh.cursor()
    91 
    91         dbc.execute('SELECT count(gid) FROM users WHERE gid = %(gid)u '
    92         Argument:
    92                     'UNION SELECT count(gid) FROM alias WHERE gid = %(gid)u '
    93 
    93                     'UNION SELECT count(gid) FROM relocated WHERE gid = '
    94         `what` : basestring
    94                     '%(gid)u' % {'gid': self._gid})
    95             "alias" or "users"
    95         result = dbc.fetchall()
    96         """
    96         dbc.close()
    97         assert what in ('alias', 'users')
    97         result = [count[0] for count in result]
    98         dbc = self._dbh.cursor()
    98         if any(result):
    99         if what == 'users':
    99             keys = ('account_count', 'alias_count', 'relocated_count')
   100             dbc.execute("SELECT count(gid) FROM users WHERE gid=%s", self._gid)
   100             raise DomErr(_(u'There are %(account_count)u accounts, '
   101         else:
   101                            u'%(alias_count)u aliases and %(relocated_count)u '
   102             dbc.execute("SELECT count(gid) FROM alias WHERE gid=%s", self._gid)
   102                            u'relocated users.') % dict(zip(keys, result)),
   103         count = dbc.fetchone()
       
   104         dbc.close()
       
   105         return count[0] > 0
       
   106 
       
   107     def _chk_delete(self, deluser, delalias):
       
   108         """Checks dependencies for deletion.
       
   109 
       
   110         Arguments:
       
   111         deluser -- ignore available accounts (bool)
       
   112         delalias -- ignore available aliases (bool)
       
   113         """
       
   114         if not deluser:
       
   115             hasuser = self._has('users')
       
   116         else:
       
   117             hasuser = False
       
   118         if not delalias:
       
   119             hasalias = self._has('alias')
       
   120         else:
       
   121             hasalias = False
       
   122         if hasuser and hasalias:
       
   123             raise DomErr(_(u'There are accounts and aliases.'),
       
   124                          ACCOUNT_AND_ALIAS_PRESENT)
   103                          ACCOUNT_AND_ALIAS_PRESENT)
   125         elif hasuser:
       
   126             raise DomErr(_(u'There are accounts.'), ACCOUNT_PRESENT)
       
   127         elif hasalias:
       
   128             raise DomErr(_(u'There are aliases.'), ALIAS_PRESENT)
       
   129 
   104 
   130     def _chk_state(self):
   105     def _chk_state(self):
   131         """Throws a DomainError if the Domain is new - not saved in the
   106         """Throws a DomainError if the Domain is new - not saved in the
   132         database."""
   107         database."""
   133         if self._new:
   108         if self._new:
   191                     self._gid, True)
   166                     self._gid, True)
   192         self._dbh.commit()
   167         self._dbh.commit()
   193         dbc.close()
   168         dbc.close()
   194         self._new = False
   169         self._new = False
   195 
   170 
   196     def delete(self, deluser=False, delalias=False):
   171     def delete(self, force=False):
   197         """Deletes the domain.
   172         """Deletes the domain.
   198 
   173 
   199         Arguments:
   174         Arguments:
   200 
   175 
   201         `deluser` : bool
   176         `force` : bool
   202           force deletion of all available accounts, default `False`
   177           force the deletion of all available accounts, aliases and
   203         `delalias` : bool
   178           relocated users.  When *force* is `False` and there are accounts,
   204           force deletion of all available aliases, default `False`
   179           aliases and/or relocated users a DomainError will be raised.
   205         """
   180           Default `False`
   206         self._chk_state()
   181         """
   207         self._chk_delete(deluser, delalias)
   182         if not isinstance(force, bool):
       
   183             raise TypeError('force must be a bool')
       
   184         self._chk_state()
       
   185         if not force:
       
   186             self._check_for_addresses()
   208         dbc = self._dbh.cursor()
   187         dbc = self._dbh.cursor()
   209         for tbl in ('alias', 'users', 'relocated', 'domain_name',
   188         for tbl in ('alias', 'users', 'relocated', 'domain_name',
   210                     'domain_data'):
   189                     'domain_data'):
   211             dbc.execute("DELETE FROM %s WHERE gid = %d" % (tbl, self._gid))
   190             dbc.execute("DELETE FROM %s WHERE gid = %u" % (tbl, self._gid))
   212         self._dbh.commit()
   191         self._dbh.commit()
   213         dbc.close()
   192         dbc.close()
   214         self._gid = 0
   193         self._gid = 0
   215         self._directory = self._transport = None
   194         self._directory = self._transport = None
   216         self._new = True
   195         self._new = True