VirtualMailManager/Domain.py
branchv0.6.x
changeset 254 8aecc83a0d32
parent 242 496099847480
child 290 e2785e04f92e
--- 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 _