VirtualMailManager/Handler.py
branchv0.6.x
changeset 251 0963ad2f5fe2
parent 244 698ba4208ddc
child 254 8aecc83a0d32
equal deleted inserted replaced
250:73cd082cd724 251:0963ad2f5fe2
    26 from VirtualMailManager.Alias import Alias
    26 from VirtualMailManager.Alias import Alias
    27 from VirtualMailManager.AliasDomain import AliasDomain
    27 from VirtualMailManager.AliasDomain import AliasDomain
    28 from VirtualMailManager.Config import Config as Cfg
    28 from VirtualMailManager.Config import Config as Cfg
    29 from VirtualMailManager.Domain import Domain, get_gid
    29 from VirtualMailManager.Domain import Domain, get_gid
    30 from VirtualMailManager.EmailAddress import EmailAddress
    30 from VirtualMailManager.EmailAddress import EmailAddress
    31 from VirtualMailManager.errors import VMMError, AliasError, DomainError
    31 from VirtualMailManager.errors import VMMError, AliasError, DomainError, \
       
    32      RelocatedError
    32 from VirtualMailManager.Relocated import Relocated
    33 from VirtualMailManager.Relocated import Relocated
    33 from VirtualMailManager.Transport import Transport
    34 from VirtualMailManager.Transport import Transport
    34 from VirtualMailManager.ext.Postconf import Postconf
    35 from VirtualMailManager.ext.Postconf import Postconf
    35 
    36 
    36 
    37 
    37 SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    38 SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    38 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$"""
    39 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$"""
    39 RE_MBOX_NAMES = """^[\x20-\x25\x27-\x7E]*$"""
    40 RE_MBOX_NAMES = """^[\x20-\x25\x27-\x7E]*$"""
       
    41 TYPE_ACCOUNT = 0x1
       
    42 TYPE_ALIAS = 0x2
       
    43 TYPE_RELOCATED = 0x4
    40 
    44 
    41 
    45 
    42 class Handler(object):
    46 class Handler(object):
    43     """Wrapper class to simplify the access on all the stuff from
    47     """Wrapper class to simplify the access on all the stuff from
    44     VirtualMailManager"""
    48     VirtualMailManager"""
   141                 dbc.execute("SET NAMES 'UTF8'")
   145                 dbc.execute("SET NAMES 'UTF8'")
   142                 dbc.close()
   146                 dbc.close()
   143             except PgSQL.libpq.DatabaseError, e:
   147             except PgSQL.libpq.DatabaseError, e:
   144                 raise VMMError(str(e), ERR.DATABASE_ERROR)
   148                 raise VMMError(str(e), ERR.DATABASE_ERROR)
   145 
   149 
   146     def _exists(dbh, query):
   150     def _chk_other_address_types(self, address, exclude):
   147         dbc = dbh.cursor()
   151         """Checks if the EmailAddress *address* is known as `TYPE_ACCOUNT`,
   148         dbc.execute(query)
   152         `TYPE_ALIAS` or `TYPE_RELOCATED`, but not as the `TYPE_*` specified
   149         gid = dbc.fetchone()
   153         by *exclude*.  If the *address* is known as one of the `TYPE_*`s
   150         dbc.close()
   154         the according `TYPE_*` constant will be returned.  Otherwise 0 will
   151         if gid is None:
   155         be returned."""
   152             return False
   156         assert exclude in (TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED) and \
   153         else:
   157                 isinstance(address, EmailAddress)
   154             return True
   158         if exclude is not TYPE_ACCOUNT:
   155     _exists = staticmethod(_exists)
   159             account = Account(self._dbh, address)
   156 
   160             if account.uid > 0:
   157     def accountExists(dbh, address):
   161                 return TYPE_ACCOUNT
   158         sql = "SELECT gid FROM users WHERE gid = (SELECT gid FROM domain_name\
   162         if exclude is not TYPE_ALIAS:
   159  WHERE domainname = '%s') AND local_part = '%s'" % (address.domainname,
   163             alias = Alias(self._dbh, address)
   160             address.localpart)
   164             if alias:
   161         return Handler._exists(dbh, sql)
   165                 return TYPE_ALIAS
   162     accountExists = staticmethod(accountExists)
   166         if exclude is not TYPE_RELOCATED:
   163 
   167             relocated = Relocated(self._dbh, address)
   164     def aliasExists(dbh, address):
   168             if relocated:
   165         sql = "SELECT DISTINCT gid FROM alias WHERE gid = (SELECT gid FROM\
   169                 return TYPE_RELOCATED
   166  domain_name WHERE domainname = '%s') AND address = '%s'" % (
   170         return 0
   167                 address.domainname, address.localpart)
       
   168         return Handler._exists(dbh, sql)
       
   169     aliasExists = staticmethod(aliasExists)
       
   170 
       
   171     def relocatedExists(dbh, address):
       
   172         sql = "SELECT gid FROM relocated WHERE gid = (SELECT gid FROM\
       
   173  domain_name WHERE domainname = '%s') AND address = '%s'" % (
       
   174                 address.domainname, address.localpart)
       
   175         return Handler._exists(dbh, sql)
       
   176     relocatedExists = staticmethod(relocatedExists)
       
   177 
   171 
   178     def __getAccount(self, address, password=None):
   172     def __getAccount(self, address, password=None):
   179         address = EmailAddress(address)
   173         address = EmailAddress(address)
   180         if not password is None:
   174         if not password is None:
   181             password = self.__pwhash(password)
   175             password = self.__pwhash(password)
   595         """Returns an iterator object for all destinations (`EmailAddress`
   589         """Returns an iterator object for all destinations (`EmailAddress`
   596         instances) for the `Alias` with the given *aliasaddress*."""
   590         instances) for the `Alias` with the given *aliasaddress*."""
   597         alias = self.__getAlias(aliasaddress)
   591         alias = self.__getAlias(aliasaddress)
   598         try:
   592         try:
   599             return alias.get_destinations()
   593             return alias.get_destinations()
   600         except AliasError, e:
   594         except AliasError, err:
   601             if e.code == ERR.NO_SUCH_ALIAS:
   595             if err.code == ERR.NO_SUCH_ALIAS:
   602                 if Handler.accountExists(self._dbh, alias._addr):
   596                 other = self._chk_other_address_types(alias.address,
   603                     raise VMMError(
   597                                                       TYPE_ALIAS)
   604                         _(u'There is already an account with address ā€œ%sā€.') %
   598                 if other is TYPE_ACCOUNT:
   605                                        aliasaddress, ERR.ACCOUNT_EXISTS)
   599                     raise VMMError(_(u"There is already an account with the \
   606                 if Handler.relocatedExists(self._dbh, alias._addr):
   600 address '%s'.") %
   607                     raise VMMError(_(u'There is already a relocated user \
   601                                    alias.address, ERR.ACCOUNT_EXISTS)
   608 with the address ā€œ%sā€.') %
   602                 elif other is TYPE_RELOCATED:
   609                                        aliasaddress, ERR.RELOCATED_EXISTS)
   603                     raise VMMError(_(u"There is already a relocated user \
   610                 raise
   604 with the address '%s'.") %
   611             else:
   605                                    alias.address, ERR.RELOCATED_EXISTS)
       
   606                 else:  # unknown address
       
   607                     raise
       
   608             else:  # something other went wrong
   612                 raise
   609                 raise
   613 
   610 
   614     def aliasDelete(self, aliasaddress, targetaddress=None):
   611     def aliasDelete(self, aliasaddress, targetaddress=None):
   615         """Deletes the `Alias` *aliasaddress* with all its destinations from
   612         """Deletes the `Alias` *aliasaddress* with all its destinations from
   616         the database. If *targetaddress* is not ``None``, only this
   613         the database. If *targetaddress* is not ``None``, only this
   687 
   684 
   688     def relocatedInfo(self, emailaddress):
   685     def relocatedInfo(self, emailaddress):
   689         """Returns the target address of the relocated user with the given
   686         """Returns the target address of the relocated user with the given
   690         *emailaddress*."""
   687         *emailaddress*."""
   691         relocated = self.__getRelocated(emailaddress)
   688         relocated = self.__getRelocated(emailaddress)
   692         return relocated.get_info()
   689         try:
       
   690             return relocated.get_info()
       
   691         except RelocatedError, err:
       
   692             if err.code == ERR.NO_SUCH_RELOCATED:
       
   693                 other = self._chk_other_address_types(relocated.address,
       
   694                                                       TYPE_RELOCATED)
       
   695                 if other is TYPE_ACCOUNT:
       
   696                     raise VMMError(_(u"There is already an account with the \
       
   697 address '%s'.") %
       
   698                                    relocated.address, ERR.ACCOUNT_EXISTS)
       
   699                 elif other is TYPE_ALIAS:
       
   700                     raise VMMError(_(u"There is already an alias with the \
       
   701 address '%s'.") %
       
   702                                    relocated.address, ERR.ALIAS_EXISTS)
       
   703                 else:  # unknown address
       
   704                     raise
       
   705             else:  # something other went wrong
       
   706                 raise
   693 
   707 
   694     def relocatedDelete(self, emailaddress):
   708     def relocatedDelete(self, emailaddress):
   695         """Deletes the relocated user with the given *emailaddress* from
   709         """Deletes the relocated user with the given *emailaddress* from
   696         the database."""
   710         the database."""
   697         relocated = self.__getRelocated(emailaddress)
   711         relocated = self.__getRelocated(emailaddress)