VirtualMailManager/handler.py
branchv0.7.x
changeset 694 b1bfd4d1d9c0
parent 686 5f4abdab738e
child 711 2a75058fc064
equal deleted inserted replaced
693:2e19ab98118a 694:b1bfd4d1d9c0
    16 import re
    16 import re
    17 
    17 
    18 from shutil import rmtree
    18 from shutil import rmtree
    19 from stat import S_IRGRP, S_IROTH, S_IWGRP, S_IWOTH
    19 from stat import S_IRGRP, S_IROTH, S_IWGRP, S_IWOTH
    20 from subprocess import Popen, PIPE
    20 from subprocess import Popen, PIPE
       
    21 
       
    22 import psycopg2
    21 
    23 
    22 from VirtualMailManager.account import Account
    24 from VirtualMailManager.account import Account
    23 from VirtualMailManager.alias import Alias
    25 from VirtualMailManager.alias import Alias
    24 from VirtualMailManager.aliasdomain import AliasDomain
    26 from VirtualMailManager.aliasdomain import AliasDomain
    25 from VirtualMailManager.catchall import CatchallAlias
    27 from VirtualMailManager.catchall import CatchallAlias
    43 from VirtualMailManager.serviceset import ServiceSet, SERVICES
    45 from VirtualMailManager.serviceset import ServiceSet, SERVICES
    44 from VirtualMailManager.transport import Transport
    46 from VirtualMailManager.transport import Transport
    45 
    47 
    46 
    48 
    47 _ = lambda msg: msg
    49 _ = lambda msg: msg
    48 _db_mod = None
       
    49 
    50 
    50 CFG_FILE = 'vmm.cfg'
    51 CFG_FILE = 'vmm.cfg'
    51 CFG_PATH = '/root:/usr/local/etc:/etc'
    52 CFG_PATH = '/root:/usr/local/etc:/etc'
    52 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$"""
    53 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$"""
    53 OTHER_TYPES = {
    54 OTHER_TYPES = {
    58 
    59 
    59 
    60 
    60 class Handler(object):
    61 class Handler(object):
    61     """Wrapper class to simplify the access on all the stuff from
    62     """Wrapper class to simplify the access on all the stuff from
    62     VirtualMailManager"""
    63     VirtualMailManager"""
    63     __slots__ = ('_cfg', '_cfg_fname', '_db_connect', '_dbh', '_warnings')
    64     __slots__ = ('_cfg', '_cfg_fname', '_dbh', '_warnings')
    64 
    65 
    65     def __init__(self, skip_some_checks=False):
    66     def __init__(self, skip_some_checks=False):
    66         """Creates a new Handler instance.
    67         """Creates a new Handler instance.
    67 
    68 
    68         ``skip_some_checks`` : bool
    69         ``skip_some_checks`` : bool
    74         """
    75         """
    75         self._cfg_fname = ''
    76         self._cfg_fname = ''
    76         self._warnings = []
    77         self._warnings = []
    77         self._cfg = None
    78         self._cfg = None
    78         self._dbh = None
    79         self._dbh = None
    79         self._db_connect = None
       
    80 
    80 
    81         if os.geteuid():
    81         if os.geteuid():
    82             raise NotRootError(_("You are not root.\n\tGood bye!\n"),
    82             raise NotRootError(_("You are not root.\n\tGood bye!\n"),
    83                                CONF_NOPERM)
    83                                CONF_NOPERM)
    84         if self._check_cfg_file():
    84         if self._check_cfg_file():
    85             self._cfg = Cfg(self._cfg_fname)
    85             self._cfg = Cfg(self._cfg_fname)
    86             self._cfg.load()
    86             self._cfg.load()
    87         if not skip_some_checks:
    87         if not skip_some_checks:
    88             self._cfg.check()
    88             self._cfg.check()
    89             self._chkenv()
    89             self._chkenv()
    90             self._set_db_connect()
       
    91 
    90 
    92     def _find_cfg_file(self):
    91     def _find_cfg_file(self):
    93         """Search the CFG_FILE in CFG_PATH.
    92         """Search the CFG_FILE in CFG_PATH.
    94         Raise a VMMError when no vmm.cfg could be found.
    93         Raise a VMMError when no vmm.cfg could be found.
    95         """
    94         """
   147                                    {'cfg_file': self._cfg_fname,
   146                                    {'cfg_file': self._cfg_fname,
   148                                     'option': opt}, err.code)
   147                                     'option': opt}, err.code)
   149                 else:
   148                 else:
   150                     raise
   149                     raise
   151 
   150 
   152     def _set_db_connect(self):
   151     def _db_connect(self):
   153         """check which module to use and set self._db_connect"""
       
   154         global _db_mod
       
   155         if self._cfg.dget('database.module').lower() == 'psycopg2':
       
   156             try:
       
   157                 _db_mod = __import__('psycopg2')
       
   158             except ImportError:
       
   159                 raise VMMError(_("Unable to import database module '%s'.") %
       
   160                                'psycopg2', VMM_ERROR)
       
   161             self._db_connect = self._psycopg2_connect
       
   162         else:
       
   163             try:
       
   164                 tmp = __import__('pyPgSQL', globals(), locals(), ['PgSQL'])
       
   165             except ImportError:
       
   166                 raise VMMError(_("Unable to import database module '%s'.") %
       
   167                                'pyPgSQL', VMM_ERROR)
       
   168             _db_mod = tmp.PgSQL
       
   169             self._db_connect = self._pypgsql_connect
       
   170 
       
   171     def _pypgsql_connect(self):
       
   172         """Creates a pyPgSQL.PgSQL.connection instance."""
       
   173         if self._dbh is None or (isinstance(self._dbh, _db_mod.Connection) and
       
   174                                   not self._dbh._isOpen):
       
   175             try:
       
   176                 self._dbh = _db_mod.connect(
       
   177                         database=self._cfg.dget('database.name'),
       
   178                         user=self._cfg.pget('database.user'),
       
   179                         host=self._cfg.dget('database.host'),
       
   180                         port=self._cfg.dget('database.port'),
       
   181                         password=self._cfg.pget('database.pass'),
       
   182                         client_encoding='utf8', unicode_results=True)
       
   183                 dbc = self._dbh.cursor()
       
   184                 dbc.execute("SET NAMES 'UTF8'")
       
   185                 dbc.close()
       
   186             except _db_mod.libpq.DatabaseError as err:
       
   187                 raise VMMError(str(err), DATABASE_ERROR)
       
   188 
       
   189     def _psycopg2_connect(self):
       
   190         """Return a new psycopg2 connection object."""
   152         """Return a new psycopg2 connection object."""
   191         if self._dbh is None or \
   153         if self._dbh is None or \
   192           (isinstance(self._dbh, _db_mod.extensions.connection) and
   154           (isinstance(self._dbh, psycopg2.extensions.connection) and
   193            self._dbh.closed):
   155            self._dbh.closed):
   194             try:
   156             try:
   195                 self._dbh = _db_mod.connect(
   157                 self._dbh = psycopg2.connect(
   196                         host=self._cfg.dget('database.host'),
   158                         host=self._cfg.dget('database.host'),
   197                         sslmode=self._cfg.dget('database.sslmode'),
   159                         sslmode=self._cfg.dget('database.sslmode'),
   198                         port=self._cfg.dget('database.port'),
   160                         port=self._cfg.dget('database.port'),
   199                         database=self._cfg.dget('database.name'),
   161                         database=self._cfg.dget('database.name'),
   200                         user=self._cfg.pget('database.user'),
   162                         user=self._cfg.pget('database.user'),
   201                         password=self._cfg.pget('database.pass'))
   163                         password=self._cfg.pget('database.pass'))
   202                 self._dbh.set_client_encoding('utf8')
   164                 self._dbh.set_client_encoding('utf8')
   203                 dbc = self._dbh.cursor()
   165                 dbc = self._dbh.cursor()
   204                 dbc.execute("SET NAMES 'UTF8'")
   166                 dbc.execute("SET NAMES 'UTF8'")
   205                 dbc.close()
   167                 dbc.close()
   206             except _db_mod.DatabaseError as err:
   168             except psycopg2.DatabaseError as err:
   207                 raise VMMError(str(err), DATABASE_ERROR)
   169                 raise VMMError(str(err), DATABASE_ERROR)
   208 
   170 
   209     def _chk_other_address_types(self, address, exclude):
   171     def _chk_other_address_types(self, address, exclude):
   210         """Checks if the EmailAddress *address* is known as `TYPE_ACCOUNT`,
   172         """Checks if the EmailAddress *address* is known as `TYPE_ACCOUNT`,
   211         `TYPE_ALIAS` or `TYPE_RELOCATED`, but not as the `TYPE_*` specified
   173         `TYPE_ALIAS` or `TYPE_RELOCATED`, but not as the `TYPE_*` specified