# HG changeset patch # User Pascal Volk # Date 1271390287 0 # Node ID 8aecc83a0d32021f546c462d5ba33ca9cce30dac # Parent 58d1b6f41664e4509186c799cfab5a3de34e987c VMM: moved functions ace2idna(), check_domainname(), idn2ascii() and relevant parts to the Domain module. Adjusted imports in modules AliasDomain, EmailAddress and Handler. diff -r 58d1b6f41664 -r 8aecc83a0d32 VirtualMailManager/AliasDomain.py --- a/VirtualMailManager/AliasDomain.py Fri Apr 16 03:02:34 2010 +0000 +++ b/VirtualMailManager/AliasDomain.py Fri Apr 16 03:58:07 2010 +0000 @@ -8,8 +8,7 @@ Virtual Mail Manager's AliasDomain class to manage alias domains. """ -from VirtualMailManager import check_domainname -from VirtualMailManager.Domain import Domain +from VirtualMailManager.Domain import Domain, check_domainname from VirtualMailManager.constants.ERROR import \ ALIASDOMAIN_EXISTS, ALIASDOMAIN_ISDOMAIN, ALIASDOMAIN_NO_DOMDEST, \ NO_SUCH_ALIASDOMAIN, NO_SUCH_DOMAIN diff -r 58d1b6f41664 -r 8aecc83a0d32 VirtualMailManager/Domain.py --- a/VirtualMailManager/Domain.py Fri Apr 16 03:02:34 2010 +0000 +++ b/VirtualMailManager/Domain.py Fri Apr 16 03:58:07 2010 +0000 @@ -9,18 +9,21 @@ """ import os +import re +from encodings.idna import ToASCII, ToUnicode from random import choice -from VirtualMailManager import check_domainname from VirtualMailManager.constants.ERROR import \ ACCOUNT_AND_ALIAS_PRESENT, ACCOUNT_PRESENT, ALIAS_PRESENT, \ - DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, NO_SUCH_DOMAIN + DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, DOMAIN_INVALID, DOMAIN_TOO_LONG, \ + NO_SUCH_DOMAIN from VirtualMailManager.errors import DomainError as DomErr from VirtualMailManager.Transport import Transport MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz' -_ = lambda x: x +RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$") +_ = lambda msg: msg class Domain(object): @@ -318,6 +321,51 @@ return aliasdomains +def ace2idna(domainname): + """Converts the domain name `domainname` from ACE according to IDNA.""" + return u'.'.join([ToUnicode(lbl) for lbl in domainname.split('.') if lbl]) + + +def check_domainname(domainname): + """Returns the validated domain name `domainname`. + + It also converts the name of the domain from IDN to ASCII, if + necessary. + + Throws an `DomainError`, if the domain name is too long or doesn't + look like a valid domain name (label.label.label). + + """ + if not RE_DOMAIN.match(domainname): + domainname = idn2ascii(domainname) + if len(domainname) > 255: + raise DomErr(_(u'The domain name is too long'), DOMAIN_TOO_LONG) + if not RE_DOMAIN.match(domainname): + raise DomErr(_(u"The domain name '%s' is invalid") % domainname, + DOMAIN_INVALID) + return domainname + + +def get_gid(dbh, domainname): + """Returns the group id of the domain *domainname*. + + If the domain couldn't be found in the database 0 will be returned. + """ + domainname = check_domainname(domainname) + dbc = dbh.cursor() + dbc.execute('SELECT gid FROM domain_name WHERE domainname=%s', domainname) + gid = dbc.fetchone() + dbc.close() + if gid: + return gid[0] + return 0 + + +def idn2ascii(domainname): + """Converts the idn domain name `domainname` into punycode.""" + return '.'.join([ToASCII(lbl) for lbl in domainname.split('.') if lbl]) + + def search(dbh, pattern=None, like=False): """'Search' for domains by *pattern* in the database. @@ -374,19 +422,4 @@ return gids, domains -def get_gid(dbh, domainname): - """Returns the group id of the domain *domainname*. - - If the domain couldn't be found in the database 0 will be returned. - """ - domainname = check_domainname(domainname) - dbc = dbh.cursor() - dbc.execute('SELECT gid FROM domain_name WHERE domainname=%s', domainname) - gid = dbc.fetchone() - dbc.close() - if gid: - return gid[0] - return 0 - - del _ diff -r 58d1b6f41664 -r 8aecc83a0d32 VirtualMailManager/EmailAddress.py --- a/VirtualMailManager/EmailAddress.py Fri Apr 16 03:02:34 2010 +0000 +++ b/VirtualMailManager/EmailAddress.py Fri Apr 16 03:58:07 2010 +0000 @@ -9,7 +9,7 @@ """ import re -from VirtualMailManager import check_domainname +from VirtualMailManager.Domain import check_domainname from VirtualMailManager.constants.ERROR import \ DOMAIN_NO_NAME, INVALID_ADDRESS, LOCALPART_INVALID, LOCALPART_TOO_LONG from VirtualMailManager.errors import EmailAddressError as EAErr diff -r 58d1b6f41664 -r 8aecc83a0d32 VirtualMailManager/Handler.py --- a/VirtualMailManager/Handler.py Fri Apr 16 03:02:34 2010 +0000 +++ b/VirtualMailManager/Handler.py Fri Apr 16 03:58:07 2010 +0000 @@ -21,12 +21,12 @@ from pyPgSQL import PgSQL # python-pgsql - http://pypgsql.sourceforge.net import VirtualMailManager.constants.ERROR as ERR -from VirtualMailManager import ENCODING, ace2idna, exec_ok +from VirtualMailManager import ENCODING, exec_ok from VirtualMailManager.Account import Account from VirtualMailManager.Alias import Alias from VirtualMailManager.AliasDomain import AliasDomain from VirtualMailManager.Config import Config as Cfg -from VirtualMailManager.Domain import Domain, get_gid +from VirtualMailManager.Domain import Domain, ace2idna, get_gid from VirtualMailManager.EmailAddress import EmailAddress from VirtualMailManager.errors import VMMError, AliasError, DomainError, \ RelocatedError diff -r 58d1b6f41664 -r 8aecc83a0d32 VirtualMailManager/__init__.py --- a/VirtualMailManager/__init__.py Fri Apr 16 03:02:34 2010 +0000 +++ b/VirtualMailManager/__init__.py Fri Apr 16 03:58:07 2010 +0000 @@ -10,14 +10,11 @@ import gettext import os -import re import locale -from encodings.idna import ToASCII, ToUnicode from VirtualMailManager.constants.ERROR import \ - DOMAIN_INVALID, DOMAIN_TOO_LONG, NOT_EXECUTABLE, NO_SUCH_BINARY, \ - NO_SUCH_DIRECTORY + NOT_EXECUTABLE, NO_SUCH_BINARY, NO_SUCH_DIRECTORY from VirtualMailManager.constants.version import __author__, __date__, \ __version__ from VirtualMailManager.errors import VMMError @@ -27,8 +24,7 @@ # version information from VERSION '__author__', '__date__', '__version__', # defined stuff - 'ENCODING', 'ace2idna', 'check_domainname', 'exec_ok', 'expand_path', - 'get_unicode', 'idn2ascii', 'is_dir', + 'ENCODING', 'exec_ok', 'expand_path', 'get_unicode', 'is_dir', ] @@ -40,9 +36,6 @@ locale.setlocale(locale.LC_ALL, 'C') ENCODING = locale.nl_langinfo(locale.CODESET) -# there may be many domain and e-mail address checks -RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$") - gettext.install('vmm', '/usr/local/share/locale', unicode=1) @@ -90,39 +83,9 @@ raise VMMError(_(u"'%s' is not a file") % get_unicode(binary), NO_SUCH_BINARY) if not os.access(binary, os.X_OK): - raise VMMError(_(u"File is not executable: '%s'") % + raise VMMError(_(u"File is not executable: '%s'") % get_unicode(binary), NOT_EXECUTABLE) return binary -def idn2ascii(domainname): - """Converts the idn domain name `domainname` into punycode.""" - return '.'.join([ToASCII(lbl) for lbl in domainname.split('.') if lbl]) - - -def ace2idna(domainname): - """Converts the domain name `domainname` from ACE according to IDNA.""" - return u'.'.join([ToUnicode(lbl) for lbl in domainname.split('.') if lbl]) - - -def check_domainname(domainname): - """Returns the validated domain name `domainname`. - - It also converts the name of the domain from IDN to ASCII, if - necessary. - - Throws an `VMMError`, if the domain name is too long or doesn't - look like a valid domain name (label.label.label). - - """ - if not RE_DOMAIN.match(domainname): - domainname = idn2ascii(domainname) - if len(domainname) > 255: - raise VMMError(_(u'The domain name is too long'), DOMAIN_TOO_LONG) - if not RE_DOMAIN.match(domainname): - raise VMMError(_(u'The domain name %r is invalid') % domainname, - DOMAIN_INVALID) - return domainname - - del _