Commits

Zhang Huangbin committed cf27eb2

Per-usr i18n.
Code cleanup.

  • Participants
  • Parent commits 5021e07

Comments (0)

Files changed (18)

File controllers/ldap/core.py

 # Author: Zhang Huangbin <michaelbibby (at) gmail.com>
 
 import web, sys
-from libs.ldaplib import core, auth, domain, iredutils
+from libs import iredutils
+from libs.ldaplib import core, auth, domain, ldaputils
 from controllers.ldap import base
 
 session = web.config.get('_session')
         username = web.safestr(i.get('username').strip())
 
         # Convert username to ldap dn.
-        userdn = iredutils.convEmailToAdminDN(username)
+        userdn = ldaputils.convEmailToAdminDN(username)
         if not userdn:
             return render.login(msg='INVALID_USERNAME')
 
                 # Expire session when browser closed.
                 web.config.session_parameters['timeout'] = 600      # 10 minutes
 
+            # Per-user i18n.
+            try:
+                adminLib = admin.Admin()
+                lang = adminLib.getPreferredLanguage(username)
+                if lang is not False and lang != session.get('lang'):
+                    web.render = iredutils.setRenderLang(web.render, lang)
+                    session['lang'] = lang
+            except:
+                pass
+
             web.seeother('/dashboard')
         else:
             session['failedTimes'] += 1
 class dbinit:
     def __init__(self):
         self.dbwrap = core.LDAPWrap(app=web.app, session=session)
-        self.domain = domain.Domain()

File controllers/ldap/domain.py

 from web import iredconfig as cfg
 from controllers.ldap import base
 from controllers.ldap.core import dbinit
-from libs.ldaplib import core, admin, domain, iredutils
+from libs.ldaplib import core, admin, domain
 
 session = web.config.get('_session')
 

File controllers/ldap/user.py

 from web import iredconfig as cfg
 from controllers.ldap import base
 from controllers.ldap.core import dbinit
-from libs.ldaplib import domain, user, iredldif, iredutils
+from libs.ldaplib import domain, user, iredldif, ldaputils
 
 session = web.config.get('_session')
 
 
         if len(email.split('@', 1)) == 2:
             domain = email.split('@', 1)[1]
-            userdn = iredutils.convEmailToUserDN(email)
+            userdn = ldaputils.convEmailToUserDN(email)
 
             if userdn:
                 profile = userLib.profile(dn=userdn)
         newpw = web.safestr(i.get('newpw'))
         confirmpw = web.safestr(i.get('confirmpw'))
         if len(newpw) > 0 and len(confirmpw) > 0 and newpw == confirmpw:
-            passwd = iredutils.generatePasswd(newpw, pwscheme=cfg.general.get('default_pw_scheme', 'SSHA'))
+            passwd = ldaputils.generatePasswd(newpw, pwscheme=cfg.general.get('default_pw_scheme', 'SSHA'))
         else:
             return render.user_create(
                     domainName=domain,
                 quota=quota,
                 )
 
-        dn = iredutils.convEmailToUserDN(username + '@' + domain)
+        dn = ldaputils.convEmailToUserDN(username + '@' + domain)
         result = userLib.add(dn, ldif)
         if result is True:
             web.seeother('/users/' + domain)
 
         mails = i.get('mail', [])
         for mail in mails:
-            dn = ldap.filter.escape_filter_chars(iredutils.convEmailToUserDN(mail))
+            dn = ldap.filter.escape_filter_chars(ldaputils.convEmailToUserDN(mail))
         print >> sys.stderr, i 
         web.seeother('/users/' + web.safestr(domain))

File docs/.htaccess

+Order Deny,Allow
+Deny from all

File iredadmin.py

 
 rootdir = os.path.abspath(os.path.dirname(__file__))
 sys.path.insert(0, rootdir)
-from libs import iredbase
+from libs import iredbase, iredutils
 
 # start app
 app = iredbase.app
-web.notfound = iredbase.notfound
+web.notfound = iredutils.notfound
 
 if __name__ == '__main__':
     # Use webpy builtin http server.

File libs/iredbase.py

 
 # Author: Zhang Huangbin <michaelbibby@gmail.com>
 
-'''
-init settings
-'''
+# init settings
 
-import os, sys, time
+import os, sys
 import ConfigParser
-import gettext
 
 import web
 from web.contrib.template import render_jinja
 web.config.debug = eval(cfg.general.get('debug', 'False'))
 lang = cfg.general.get('lang', 'en_US')
 
-web.config.session_parameters['cookie_name'] = 'iRedAdmin'
+web.config.session_parameters['cookie_name'] = 'iRedAdmin-ent'
 web.config.session_parameters['cookie_domain'] = None
-#web.config.session_parameters['timeout'] = 600     # 10 minutes
+#web.config.session_parameters['timeout'] = 600          # 10 minutes
 web.config.session_parameters['ignore_expiry'] = False
 web.config.session_parameters['ignore_change_ip'] = False
 
         )
 web.config._session = session
 
-# Init translations.
-if lang == 'en_US':
-    translations = gettext.NullTranslations()
-else:
-    try:
-        translations = gettext.translation(
-                'iredadmin',
-                rootdir + 'i18n',
-                languages=[lang],
-                )
-    except IOError:
-        translations = gettext.NullTranslations()
-
 # Use JinJa2 template.
 tmpldir = rootdir + '/templates/' + \
         cfg.general.get('skin', 'default') +  '/' + \
         cfg.general.get('backend')
 
 # init render
-def set_render(tmpl_dir):
-    r = render_jinja(
-            tmpl_dir,                           # template dir.
-            extensions = ['jinja2.ext.i18n'],   # Jinja2 extensions.
-            encoding = 'utf-8',                 # Encoding.
-            globals = {
-                'skin': cfg.general.get('skin', 'default'), # Used for static files.
-                'session': web.config._session,  # Used for session.
-                'ctx': web.ctx,                  # Used to get 'homepath'.
-                },
-            )
-    r._lookup.install_gettext_translations(translations)
-    return r
+render = render_jinja(
+        tmpldir,                           # template dir.
+        extensions = ['jinja2.ext.i18n'],   # Jinja2 extensions.
+        encoding = 'utf-8',                 # Encoding.
+        globals = {
+            'skin': cfg.general.get('skin', 'default'), # Used for static files.
+            'session': web.config._session,  # Used for session.
+            'ctx': web.ctx,                  # Used to get 'homepath'.
+            },
+        )
 
-render = set_render(tmpldir)
+import iredutils
+render = iredutils.setRenderLang(render, lang)
 web.render = render
-
-def notfound():
-    return web.notfound(render.pageNotFound())

File libs/iredutils.py

+#!/usr/bin/env python
+# encoding: utf-8
+
+# Author: Zhang Huangbin <michaelbibby (at) gmail.com>
+
+import gettext
+import web
+
+cfg = web.iredconfig
+
+def setRenderLang(renderInst, lang):
+    # Init translations.
+    if lang == 'en_US':
+        translations = gettext.NullTranslations()
+    else:
+        try:
+            translations = gettext.translation(
+                    'iredadmin',
+                    cfg['rootdir'] + 'i18n',
+                    languages=[lang],
+                    )
+        except IOError:
+            translations = gettext.NullTranslations()
+
+    renderInst._lookup.install_gettext_translations(translations)
+    return renderInst
+
+def notfound():
+    return web.notfound(render.pageNotFound())

File libs/ldaplib/admin.py

 import sys
 import ldap
 import web
-from libs.ldaplib import core, attrs, iredutils
+from libs.ldaplib import core, attrs, ldaputils
 
 session = web.config.get('_session')
 
     def __del__(self):
         pass
 
+    # Get preferredLanguage.
+    def getPreferredLanguage(self, admin):
+        dn = ldaputils.convEmailToAdminDN(web.safestr(admin))
+        self.lang = self.conn.search_s(
+                dn,
+                ldap.SCOPE_BASE,
+                attrlist=['preferredLanguage'],
+                )
+        if self.lang[0][1].has_key('preferredLanguage'):
+            lang = self.lang[0][1]['preferredLanguage'][0]
+        else:
+            lang = session.get('lang')
+        return lang
+
     # List all admin accounts.
     def list(self):
         filter = attrs.DOMAINADMIN_SEARCH_FILTER

File libs/ldaplib/core.py

 import os, sys, time
 import web
 import ldap
-from libs.ldaplib import attrs, iredutils
+from libs.ldaplib import attrs, ldaputils
 
 cfg = web.iredconfig
 session = web.config.get('_session')
 
     def check_domain_access(self, domainDN, admin):
         domainDN = web.safestr(domainDN)
-        domainName = iredutils.extractValueFromDN(domainDN, 'domainName')
+        domainName = ldaputils.extractValueFromDN(domainDN, 'domainName')
         if domainName is None: return False
 
         admin = web.safestr(admin)
                 #"""
                 try:
                     self.access = self.conn.search_s(
-                            iredutils.convEmailToAdminDN(admin),
+                            ldaputils.convEmailToAdminDN(admin),
                             ldap.SCOPE_BASE,
                             "(&(objectClass=mailAdmin)(domainGlobalAdmin=yes))",
                             )

File libs/ldaplib/domain.py

 import sys
 import ldap
 import web
-from libs.ldaplib import core, attrs, iredldif, iredutils, deltree
+from libs.ldaplib import core, attrs, iredldif, ldaputils, deltree
 
 session = web.config.get('_session')
 
     def add(self, domainName, cn=None):
         # msg: {key: value}
         msg = {}
-        domainName = iredutils.removeSpaceAndDot(web.safestr(domainName)).lower()
+        domainName = ldaputils.removeSpaceAndDot(web.safestr(domainName)).lower()
         if domainName == '' or domainName == 'None' or domainName is None:
             return False
 
-        dn = iredutils.convDomainToDN(domainName)
+        dn = ldaputils.convDomainToDN(domainName)
         ldif = iredldif.ldif_maildomain(domainName, cn)
 
         # Add domain dn.
         
         msg = {}
         for domain in domainName:
-            dn = iredutils.convDomainToDN(web.safestr(domain))
+            dn = ldaputils.convDomainToDN(web.safestr(domain))
 
             try:
                 deltree.DelTree( self.conn, dn, ldap.SCOPE_SUBTREE )
     # Get domain attributes & values.
     def profile(self, domain):
         self.domain = web.safestr(domain)
-        self.domainDN = iredutils.convDomainToDN(self.domain)
+        self.domainDN = ldaputils.convDomainToDN(self.domain)
 
         # Access control.
         if self.check_domain_access(self.domainDN, session.get('username')):
             pass
 
         try:
-            dn = iredutils.convDomainToDN(domain)
+            dn = ldaputils.convDomainToDN(domain)
             self.conn.modify_s(dn, mod_attrs)
             return True
         except Exception, e:

File libs/ldaplib/iredldif.py

 
 import time
 from web import iredconfig as cfg
-from libs.ldaplib import iredutils
+from libs.ldaplib import ldaputils
 
 # Define and return LDIF structure of domain.
 def ldif_maildomain(domainName, cn=None,
     DATE = time.strftime('%Y.%m.%d.%H.%M.%S')
     domain = str(domain)
     quota = int(quota) * 1024 * 1024
-    username = iredutils.removeSpaceAndDot(str(username))
+    username = ldaputils.removeSpaceAndDot(str(username))
     mail = username.lower() + '@' + domain
     #dn = convEmailToUserDN(mail)
 

File libs/ldaplib/iredutils.py

-#!/usr/bin/env python
-# encoding: utf-8
-
-# Author: Zhang Huangbin <michaelbibby (at) gmail.com>
-
-import os, sys
-from base64 import b64encode
-import web
-import ldap
-from ldap.filter import escape_filter_chars
-from libs.ldaplib import attrs
-
-cfg = web.iredconfig
-session = web.config.get('_session')
-
-basedn = cfg.ldap['basedn']
-domainadmin_dn = cfg.ldap['domainadmin_dn']
-
-def convEmailToAdminDN(email):
-    """Convert email address to ldap dn of mail domain admin."""
-    email = str(email).strip()
-    if len(email.split('@', 1)) == 2:
-        user, domain = email.split('@', 1)
-    else:
-        return False
-
-    # Admin DN format.
-    # mail=user@domain.ltd,[LDAP_DOMAINADMIN_DN]
-    dn = '%s=%s,%s' % ( attrs.USER_RDN, email, domainadmin_dn)
-
-    return escape_filter_chars(dn)
-
-def convEmailToUserDN(email):
-    """Convert email address to ldap dn of normail mail user."""
-    email = str(email).strip()
-    if len(email.split('@', 1)) == 2:
-        user, domain = email.split('@', 1)
-    else:
-        return False
-
-    # User DN format.
-    # mail=user@domain.ltd,domainName=domain.ltd,[LDAP_BASEDN]
-    dn = '%s=%s,ou=Users,%s=%s,%s' % (
-            attrs.USER_RDN, email,
-            attrs.DOMAIN_RDN, domain,
-            basedn)
-
-    return escape_filter_chars(dn)
-
-def convDomainToDN(domain):
-    """Convert domain name to ldap dn."""
-    domain = str(domain).strip().replace(' ', '')
-    dn = attrs.DOMAIN_RDN + '=' + domain + ',' + basedn
-
-    return escape_filter_chars(dn)
-
-def extractValueFromDN(dn, attr):
-    """Extract value of attribute from dn string."""
-    dn = str(dn).strip().lower()
-    attr = str(attr).strip().lower()
-
-    for i in dn.split(','):
-        if i.startswith(attr + '='):
-            domain = i.split('=')[1]
-            break
-        else:
-            domain = None
-
-    return domain
-
-def removeSpaceAndDot(s):
-    """Remove leading and trailing dot and all whitespace."""
-    return str(s).strip(' .').replace(' ', '')
-
-# Sort LDAP query by dn.
-# Note: this function deprecated since we use JavaScript to implement
-# client-side sort.
-def sortResults(attr='dn'):
-    if attr == 'dn':
-        comp = lambda x,y: cmp(x[0].lower(), y[0].lower())
-    else:
-        comp = lambda x,y: cmp(x[1][attr][0].lower(), y[1][attr][0].lower())
-
-    return comp
-
-# Generate attribute list & values from form data.
-def get_mod_attrs(accountType, data):
-    accountType = web.safestr('accountType')
-    domainName = web.safestr(data.get('domainName', None))
-    if domainName == 'None' or domainName == '':
-        return False
-
-    mod_attrs = []
-
-    cn = data.get('cn', None)
-    if cn is not None and cn != '':
-        mod_attrs += [ ( ldap.MOD_REPLACE, 'cn', cn.encode('utf-8') ) ]
-
-    # Get accountStatus.
-    accountStatus = web.safestr(data.get('accountStatus', 'active'))
-    if accountStatus not in attrs.VALUES_ACCOUNT_STATUS: accountStatus = 'active'
-    mod_attrs += [ (ldap.MOD_REPLACE, 'accountStatus', accountStatus) ]
-
-    if session.get('domainGlobalAdmin') == 'yes':
-        # Convert to string, they don't contain non-ascii characters.
-
-        # Get domain attributes.
-        if accountType == 'domain':
-            dn = convDomainToDN('domainName')
-
-            domainBackupMX = web.safestr(data.get('domainBackupMX', 'no'))
-            if domainBackupMX not in attrs.VALUES_DOMAIN_BACKUPMX: domainBackupMX = 'no'
-            mod_attrs += [ (ldap.MOD_REPLACE, 'domainBackupMX', domainBackupMX) ]
-
-            return {'dn': dn, 'mod_attrs': mod_attrs}
-
-        elif accountType == 'user':
-            pass
-        elif accountType == 'maillist':
-            pass
-        elif accountType == 'alias':
-            pass
-    else:
-        pass
-
-# Generate hashed password from plain text.
-def generatePasswd(password, pwscheme='SSHA'):
-    pwscheme = pwscheme.upper()
-    salt = os.urandom(8)
-    if sys.version_info[1] < 5: # Python 2.5
-        import sha
-        if pwscheme == 'SSHA':
-            h = sha.new(password)
-            h.update(salt)
-            hash = "{SSHA}" + b64encode( h.digest() + salt )
-        else:
-            hash = password
-    else:
-        import hashlib
-        if pwscheme == 'SSHA':
-            h = hashlib.sha1(password)
-            h.update(salt)
-            hash = "{SSHA}" + b64encode( h.digest() + salt )
-        else:
-            hash = password
-
-    return hash

File libs/ldaplib/ldaputils.py

+#!/usr/bin/env python
+# encoding: utf-8
+
+# Author: Zhang Huangbin <michaelbibby (at) gmail.com>
+
+import os, sys
+from base64 import b64encode
+import web
+import ldap
+from ldap.filter import escape_filter_chars
+from libs.ldaplib import attrs
+
+cfg = web.iredconfig
+session = web.config.get('_session')
+
+basedn = cfg.ldap['basedn']
+domainadmin_dn = cfg.ldap['domainadmin_dn']
+
+def convEmailToAdminDN(email):
+    """Convert email address to ldap dn of mail domain admin."""
+    email = str(email).strip()
+    if len(email.split('@', 1)) == 2:
+        user, domain = email.split('@', 1)
+    else:
+        return False
+
+    # Admin DN format.
+    # mail=user@domain.ltd,[LDAP_DOMAINADMIN_DN]
+    dn = '%s=%s,%s' % ( attrs.USER_RDN, email, domainadmin_dn)
+
+    return escape_filter_chars(dn)
+
+def convEmailToUserDN(email):
+    """Convert email address to ldap dn of normail mail user."""
+    email = str(email).strip()
+    if len(email.split('@', 1)) == 2:
+        user, domain = email.split('@', 1)
+    else:
+        return False
+
+    # User DN format.
+    # mail=user@domain.ltd,domainName=domain.ltd,[LDAP_BASEDN]
+    dn = '%s=%s,ou=Users,%s=%s,%s' % (
+            attrs.USER_RDN, email,
+            attrs.DOMAIN_RDN, domain,
+            basedn)
+
+    return escape_filter_chars(dn)
+
+def convDomainToDN(domain):
+    """Convert domain name to ldap dn."""
+    domain = str(domain).strip().replace(' ', '')
+    dn = attrs.DOMAIN_RDN + '=' + domain + ',' + basedn
+
+    return escape_filter_chars(dn)
+
+def extractValueFromDN(dn, attr):
+    """Extract value of attribute from dn string."""
+    dn = str(dn).strip().lower()
+    attr = str(attr).strip().lower()
+
+    for i in dn.split(','):
+        if i.startswith(attr + '='):
+            domain = i.split('=')[1]
+            break
+        else:
+            domain = None
+
+    return domain
+
+def removeSpaceAndDot(s):
+    """Remove leading and trailing dot and all whitespace."""
+    return str(s).strip(' .').replace(' ', '')
+
+# Sort LDAP query by dn.
+# Note: this function deprecated since we use JavaScript to implement
+# client-side sort.
+def sortResults(attr='dn'):
+    if attr == 'dn':
+        comp = lambda x,y: cmp(x[0].lower(), y[0].lower())
+    else:
+        comp = lambda x,y: cmp(x[1][attr][0].lower(), y[1][attr][0].lower())
+
+    return comp
+
+# Generate attribute list & values from form data.
+def get_mod_attrs(accountType, data):
+    accountType = web.safestr('accountType')
+    domainName = web.safestr(data.get('domainName', None))
+    if domainName == 'None' or domainName == '':
+        return False
+
+    mod_attrs = []
+
+    cn = data.get('cn', None)
+    if cn is not None and cn != '':
+        mod_attrs += [ ( ldap.MOD_REPLACE, 'cn', cn.encode('utf-8') ) ]
+
+    # Get accountStatus.
+    accountStatus = web.safestr(data.get('accountStatus', 'active'))
+    if accountStatus not in attrs.VALUES_ACCOUNT_STATUS: accountStatus = 'active'
+    mod_attrs += [ (ldap.MOD_REPLACE, 'accountStatus', accountStatus) ]
+
+    if session.get('domainGlobalAdmin') == 'yes':
+        # Convert to string, they don't contain non-ascii characters.
+
+        # Get domain attributes.
+        if accountType == 'domain':
+            dn = convDomainToDN('domainName')
+
+            domainBackupMX = web.safestr(data.get('domainBackupMX', 'no'))
+            if domainBackupMX not in attrs.VALUES_DOMAIN_BACKUPMX: domainBackupMX = 'no'
+            mod_attrs += [ (ldap.MOD_REPLACE, 'domainBackupMX', domainBackupMX) ]
+
+            return {'dn': dn, 'mod_attrs': mod_attrs}
+
+        elif accountType == 'user':
+            pass
+        elif accountType == 'maillist':
+            pass
+        elif accountType == 'alias':
+            pass
+    else:
+        pass
+
+# Generate hashed password from plain text.
+def generatePasswd(password, pwscheme='SSHA'):
+    pwscheme = pwscheme.upper()
+    salt = os.urandom(8)
+    if sys.version_info[1] < 5: # Python 2.5
+        import sha
+        if pwscheme == 'SSHA':
+            h = sha.new(password)
+            h.update(salt)
+            hash = "{SSHA}" + b64encode( h.digest() + salt )
+        else:
+            hash = password
+    else:
+        import hashlib
+        if pwscheme == 'SSHA':
+            h = hashlib.sha1(password)
+            h.update(salt)
+            hash = "{SSHA}" + b64encode( h.digest() + salt )
+        else:
+            hash = password
+
+    return hash

File libs/ldaplib/preferences.py

 import web
 from web import iredconfig as cfg
 from libs import languages
-from libs.ldaplib import core, attrs, iredutils
+from libs.ldaplib import core, attrs, ldaputils
 
 session = web.config.get('_session')
 

File libs/ldaplib/user.py

 import sys
 import ldap, ldap.filter
 import web
-from libs.ldaplib import core, attrs, iredutils, deltree
+from libs.ldaplib import core, attrs, ldaputils, deltree
 
 session = web.config.get('_session')
 
     # List all users under one domain.
     def list(self, domain):
         self.domain = domain
-        self.domainDN = iredutils.convDomainToDN(self.domain)
+        self.domainDN = ldaputils.convDomainToDN(self.domain)
 
         # Check whether user is admin of domain.
         if self.check_domain_access(self.domainDN, session.get('username')):
 
         msg = {}
         for mail in mails:
-            dn = iredutils.convEmailToUserDN(mail)
+            dn = ldaputils.convEmailToUserDN(mail)
 
             try:
                 deltree.DelTree( self.conn, dn, ldap.SCOPE_SUBTREE )

File templates/default/ldap/dashboard.html

 {% block jquery_docoment_ready %} {% endblock %}
 {% block title %} {{ _('Dashboard') }} {% endblock %}
 
+{% block submenu %}{% endblock submenu %}
+
 {% block main %}
 <div class="gen-content">
     <h3>Please report bugs and feature request to our forum or mail to author directly: <a href="mailto:michaelbibby@gmail.com">Zhang Huangbin</a>:</h3>

File templates/default/ldap/login.html

             {{ _('Login required') }}
         {% elif msg == 'SERVER_DOWN' %}
             {{ _('Server is down, Please contact <a href="mailto:%s">webmaster</a> to solve it.' % webmaster ) }}
+        {% elif msg is sameas false %}
+            {{ _('Authentication failed.') }}
         {% else %}
             {{msg}}
         {% endif %}

File templates/default/ldap/preferences.html

 {% extends "layout.html" %}
 
 {% block js_tablesorter %}{% endblock %}
-
 {% block title %}{{ _('Preferences') }}{% endblock %}
+{% block submenu %}{% endblock submenu %}
 
 {% block main %}
 <div class="main-subhead">