28 ACCOUNT_EXISTS, ALIAS_EXISTS, CONF_NOFILE, CONF_NOPERM, CONF_WRONGPERM, \ |
28 ACCOUNT_EXISTS, ALIAS_EXISTS, CONF_NOFILE, CONF_NOPERM, CONF_WRONGPERM, \ |
29 DATABASE_ERROR, DOMAINDIR_GROUP_MISMATCH, DOMAIN_INVALID, \ |
29 DATABASE_ERROR, DOMAINDIR_GROUP_MISMATCH, DOMAIN_INVALID, \ |
30 FOUND_DOTS_IN_PATH, INVALID_ARGUMENT, MAILDIR_PERM_MISMATCH, \ |
30 FOUND_DOTS_IN_PATH, INVALID_ARGUMENT, MAILDIR_PERM_MISMATCH, \ |
31 NOT_EXECUTABLE, NO_SUCH_ACCOUNT, NO_SUCH_ALIAS, NO_SUCH_BINARY, \ |
31 NOT_EXECUTABLE, NO_SUCH_ACCOUNT, NO_SUCH_ALIAS, NO_SUCH_BINARY, \ |
32 NO_SUCH_DIRECTORY, NO_SUCH_RELOCATED, RELOCATED_EXISTS, UNKNOWN_SERVICE, \ |
32 NO_SUCH_DIRECTORY, NO_SUCH_RELOCATED, RELOCATED_EXISTS, UNKNOWN_SERVICE, \ |
33 VMM_ERROR |
33 VMM_ERROR, LOCALPART_INVALID, TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED |
34 from VirtualMailManager.domain import Domain |
34 from VirtualMailManager.domain import Domain |
35 from VirtualMailManager.emailaddress import DestinationEmailAddress, \ |
35 from VirtualMailManager.emailaddress import DestinationEmailAddress, \ |
36 EmailAddress |
36 EmailAddress, RE_LOCALPART |
37 from VirtualMailManager.errors import \ |
37 from VirtualMailManager.errors import \ |
38 DomainError, NotRootError, PermissionError, VMMError |
38 DomainError, NotRootError, PermissionError, VMMError |
39 from VirtualMailManager.mailbox import new as new_mailbox |
39 from VirtualMailManager.mailbox import new as new_mailbox |
40 from VirtualMailManager.pycompat import all, any |
40 from VirtualMailManager.pycompat import all, any |
41 from VirtualMailManager.quotalimit import QuotaLimit |
41 from VirtualMailManager.quotalimit import QuotaLimit |
48 _db_mod = None |
48 _db_mod = None |
49 |
49 |
50 CFG_FILE = 'vmm.cfg' |
50 CFG_FILE = 'vmm.cfg' |
51 CFG_PATH = '/root:/usr/local/etc:/etc' |
51 CFG_PATH = '/root:/usr/local/etc:/etc' |
52 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" |
52 RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" |
53 TYPE_ACCOUNT = 0x1 |
|
54 TYPE_ALIAS = 0x2 |
|
55 TYPE_RELOCATED = 0x4 |
|
56 OTHER_TYPES = { |
53 OTHER_TYPES = { |
57 TYPE_ACCOUNT: (_(u'an account'), ACCOUNT_EXISTS), |
54 TYPE_ACCOUNT: (_(u'an account'), ACCOUNT_EXISTS), |
58 TYPE_ALIAS: (_(u'an alias'), ALIAS_EXISTS), |
55 TYPE_ALIAS: (_(u'an alias'), ALIAS_EXISTS), |
59 TYPE_RELOCATED: (_(u'a relocated user'), RELOCATED_EXISTS), |
56 TYPE_RELOCATED: (_(u'a relocated user'), RELOCATED_EXISTS), |
60 } |
57 } |
61 |
|
62 |
58 |
63 class Handler(object): |
59 class Handler(object): |
64 """Wrapper class to simplify the access on all the stuff from |
60 """Wrapper class to simplify the access on all the stuff from |
65 VirtualMailManager""" |
61 VirtualMailManager""" |
66 __slots__ = ('_cfg', '_cfg_fname', '_db_connect', '_dbh', '_warnings') |
62 __slots__ = ('_cfg', '_cfg_fname', '_db_connect', '_dbh', '_warnings') |
591 raise VMMError(_(u"The pattern '%s' contains invalid " |
587 raise VMMError(_(u"The pattern '%s' contains invalid " |
592 u"characters.") % pattern, DOMAIN_INVALID) |
588 u"characters.") % pattern, DOMAIN_INVALID) |
593 self._db_connect() |
589 self._db_connect() |
594 return search(self._dbh, pattern=pattern, like=like) |
590 return search(self._dbh, pattern=pattern, like=like) |
595 |
591 |
|
592 def address_list(self, typelimit, pattern=None): |
|
593 """TODO""" |
|
594 llike = dlike = False |
|
595 lpattern = dpattern = None |
|
596 if pattern: |
|
597 parts = pattern.split('@', 2) |
|
598 if len(parts) == 2: |
|
599 # The pattern includes '@', so let's treat the |
|
600 # parts separately to allow for pattern search like %@domain.% |
|
601 lpattern = parts[0] |
|
602 llike = lpattern.startswith('%') or lpattern.endswith('%') |
|
603 dpattern = parts[1] |
|
604 dlike = dpattern.startswith('%') or dpattern.endswith('%') |
|
605 |
|
606 if llike: |
|
607 checkp = lpattern.strip('%') |
|
608 else: |
|
609 checkp = lpattern |
|
610 if len(checkp) > 0 and re.search(RE_LOCALPART, checkp): |
|
611 raise VMMError(_(u"The pattern '%s' contains invalid " |
|
612 u"characters.") % pattern, LOCALPART_INVALID) |
|
613 else: |
|
614 # else just match on domains |
|
615 # (or should that be local part, I don't know…) |
|
616 dpattern = parts[0] |
|
617 dlike = dpattern.startswith('%') or dpattern.endswith('%') |
|
618 |
|
619 if dlike: |
|
620 checkp = dpattern.strip('%') |
|
621 else: |
|
622 checkp = dpattern |
|
623 if len(checkp) > 0 and not re.match(RE_DOMAIN_SEARCH, checkp): |
|
624 raise VMMError(_(u"The pattern '%s' contains invalid " |
|
625 u"characters.") % pattern, DOMAIN_INVALID) |
|
626 self._db_connect() |
|
627 from VirtualMailManager.common import search_addresses |
|
628 return search_addresses(self._dbh, typelimit=typelimit, |
|
629 lpattern=lpattern, llike=llike, |
|
630 dpattern=dpattern, dlike=dlike) |
|
631 |
596 def user_add(self, emailaddress, password): |
632 def user_add(self, emailaddress, password): |
597 """Wrapper around Account.set_password() and Account.save().""" |
633 """Wrapper around Account.set_password() and Account.save().""" |
598 acc = self._get_account(emailaddress) |
634 acc = self._get_account(emailaddress) |
599 if acc: |
635 if acc: |
600 raise VMMError(_(u"The account '%s' already exists.") % |
636 raise VMMError(_(u"The account '%s' already exists.") % |