Zhang Huangbin avatar Zhang Huangbin committed e227273

Continue working on marking mail user as global admin.

Comments (0)

Files changed (9)

controllers/ldap/basic.py

         # Get username, password.
         i = web.input(_unicode=False)
 
+        username = web.safestr(i.get('username', '').strip())
+        password = i.get('password', '').strip()
+        save_pass = web.safestr(i.get('save_pass', 'no').strip())
+
+        if not iredutils.isEmail(username):
+            raise web.seeother('/login?msg=INVALID_USERNAME')
+
+        if not password:
+            raise web.seeother('/login?msg=EMPTY_PASSWORD')
+
+        # Get LDAP URI.
+        uri = cfg.ldap.get('uri')
+
         # Verify bind_dn & bind_pw.
         try:
-            # Get LDAP URI.
-            uri = cfg.ldap.get('uri')
-
             # Detect STARTTLS support.
             if uri.startswith('ldaps://'):
                 starttls = True
         except Exception, e:
             raise web.seeother('/login?msg=%s' % web.safestr(e))
 
-        username = web.safestr(i.get('username', '').strip())
-        password = i.get('password', '').strip()
-        save_pass = web.safestr(i.get('save_pass', 'no').strip())
-
-        if not iredutils.isEmail(username):
-            raise web.seeother('/login?msg=INVALID_USERNAME')
-
-        if not password:
-            raise web.seeother('/login?msg=EMPTY_PASSWORD')
-
-        # Convert username to ldap dn.
-        userdn = ldaputils.convKeywordToDN(username, accountType='admin')
-        if userdn[0] is False:
-            raise web.seeother('/login?msg=%s' % userdn[1])
+        # Convert username to admin dn.
+        dn_login = ldaputils.convKeywordToDN(username, accountType='admin')
+        if dn_login[0] is False:
+            raise web.seeother('/login?msg=%s' % dn_login[1])
 
         # Return True if auth success, otherwise return error msg.
-        qr_admin_auth = auth.Auth(cfg.ldap.get('uri', 'ldap://127.0.0.1/'), userdn, password,)
+        qr_admin_auth = auth.Auth(uri, dn_login, password)
 
-        if qr_admin_auth is True:
+        # Check whether it's a mail user
+        qr_user_auth = False
+        if qr_admin_auth is not True:
+            dn_user = ldaputils.convKeywordToDN(username, accountType='user')
+            qr_user_auth = auth.Auth(uri, dn_user, password)
+
+        if qr_admin_auth is True or qr_user_auth is True:
             session['username'] = username
             session['logged'] = True
 
-            # Read preferred language from db.
-            adminLib = adminlib.Admin()
-            #session['lang'] = adminLib.getPreferredLanguage(userdn) or cfg.general.get('lang', 'en_US')
-            adminProfile = adminLib.profile(username)
-            if adminProfile[0] is True:
-                cn = adminProfile[1][0][1].get('cn', [None])[0]
-                lang = adminProfile[1][0][1].get('preferredLanguage', [cfg.general.get('lang', 'en_US')])[0]
+            # Read preferred language from LDAP
+            if qr_admin_auth is True:
+                adminLib = adminlib.Admin()
+                adminProfile = adminLib.profile(username, attributes=['preferredLanguage'])
+                if adminProfile[0] is True:
+                    dn, entry = adminProfile[1][0]
+                    lang = entry.get('preferredLanguage', [cfg.general.get('lang', 'en_US')])[0]
+                    session['lang'] = lang
 
-                session['cn'] = cn
-                session['lang'] = lang
-            else:
-                pass
+            if qr_user_auth is True:
+                session['isMailUser'] = True
 
             web.config.session_parameters['cookie_name'] = 'iRedAdmin-Pro'
             # Session expire when client ip was changed.

controllers/ldap/user.py

 
 import web
 from libs import iredutils, settings
-from libs.language import getLanguageMaps
+from libs.languages import getLanguageMaps
 from libs.ldaplib import decorators, domain as domainlib, user, ldaputils, connUtils
 
 cfg = web.iredconfig

libs/ldaplib/admin.py

     # List all admin accounts.
     @decorators.require_global_admin
     def listAccounts(self, attrs=attrs.ADMIN_SEARCH_ATTRS):
-        filter = "(objectClass=mailAdmin)"
         try:
-            result = self.conn.search_s(
+            result_admin = self.conn.search_s(
                 self.domainadmin_dn,
                 ldap.SCOPE_ONELEVEL,
-                filter,
+                '(objectClass=mailAdmin)',
                 attrs,
             )
-            return (True, result)
+            result_user = self.conn.search_s(
+                self.basedn,
+                ldap.SCOPE_SUBTREE,
+                '(&(objectClass=mailUser)(accountStatus=active)(enabledService=domainadmin))',
+                attrs,
+            )
+            return (True, result_admin + result_user)
         except Exception, e:
             return (False, ldaputils.getExceptionDesc(e))
 

libs/ldaplib/attrs.py

 # ---------------------------------------------------------
 # Admin related.
 # ---------------------------------------------------------
-ADMIN_SEARCH_ATTRS = [
-    'mail', 'accountStatus', 'domainGlobalAdmin', 'cn', 'enabledService',
-]
-ADMIN_ATTRS_ALL = [
-    'mail', 'accountStatus', 'cn', 'preferredLanguage', 'domainGlobalAdmin',
-]
+ADMIN_SEARCH_ATTRS = ['mail', 'accountStatus', 'cn', 'preferredLanguage',
+                      'domainGlobalAdmin', 'enabledService',
+                      'objectClass',
+                     ]
+ADMIN_ATTRS_ALL = ADMIN_SEARCH_ATTRS
 
 # ---------------------------------------------------------
 # Domain related.

libs/ldaplib/auth.py

             conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
 
         try:
+            # Verify username and password
             res = conn.bind_s(dn, password)
 
             if res:
+                filter = '(&' + \
+                        '(accountStatus=active)' + \
+                        '(|' + \
+                        '(objectClass=mailAdmin)' + \
+                        '(&(objectClass=mailUser)(enabledService=domainadmin))' + \
+                        ')' + \
+                        ')'
+
                 # Check whether this user is a site wide global admin.
-                global_admin_result = conn.search_s(
-                    dn,
-                    ldap.SCOPE_BASE,
-                    "(&(objectClass=mailAdmin)(accountStatus=active))",
-                    ['domainGlobalAdmin']
-                )
-                if not global_admin_result:
+                qr = conn.search_s(dn, ldap.SCOPE_BASE, filter, ['objectClass', 'domainGlobalAdmin'])
+                if not qr:
                     raise ldap.INVALID_CREDENTIALS
 
-                result = global_admin_result[0][1]
-                if result.get('domainGlobalAdmin', 'no')[0].lower() == 'yes':
+                entry = qr[0][1]
+                if entry.get('domainGlobalAdmin', 'no')[0].lower() == 'yes':
                     session['domainGlobalAdmin'] = True
-                else:
-                    session['domainGlobalAdmin'] = False
 
+                if 'mailUser' in entry.get('objectClass'):
+                    session['isMailUser'] = True
+
+                conn.unbind_s()
                 return True
             else:
                 return False

libs/ldaplib/user.py

                 # Update domainGlobalAdmin=yes
                 if 'domainGlobalAdmin' in data:
                     mod_attrs = [(ldap.MOD_REPLACE, 'domainGlobalAdmin', 'yes')]
+                    # Update enabledService=domainadmin
+                    connutils.addOrDelAttrValue(
+                        dn=self.dn,
+                        attr='enabledService',
+                        value='domainadmin',
+                        action='add',
+                    )
                 else:
                     mod_attrs = [(ldap.MOD_REPLACE, 'domainGlobalAdmin', None)]
+                    # Remove enabledService=domainadmin
+                    connutils.addOrDelAttrValue(
+                        dn=self.dn,
+                        attr='enabledService',
+                        value='domainadmin',
+                        action='delete',
+                    )
 
             # Get display name.
             cn = data.get('cn', None)

templates/default/layout.html

             <div class="head_top">
                 <div class="topbuts">
                     <ul class="clear">
-                        <li><a href="{{ctx.homepath}}/profile/admin/general/{{session.get('username')}}">{{ _('Preferences') }}</a></li>
+                        <li><a href="{{ctx.homepath}}/profile/{%if session.get('isMailUser') is sameas true%}user{%else%}admin{%endif%}/general/{{session.get('username')}}">{{ _('Preferences') }}</a></li>
                         <li><a href="{{ctx.homepath}}/logout" class="red">{{ _('Logout') }}</a></li>
                     </ul>
 

templates/default/ldap/admin/list.html

             <tr class="{{ accountStatus }}">
                 <td><input type="checkbox" class="checkbox " name="mail" value="{{mail}}" {% if mail == session.get('username') %}disabled{% endif %}/></td>
                 <td>
-                    <a href="{{ctx.homepath}}/profile/admin/general/{{mail}}"><img src="{{ctx.homepath}}/static/{{skin}}/images/action_edit.png" title="{{ _('Edit account profile') }}" class="fr-space"/></a>
+                    <a href="{{ctx.homepath}}/profile/{% if 'mailUser' in entry.get('objectClass', []) %}user{% else %}admin{% endif %}/general/{{mail}}"><img src="{{ctx.homepath}}/static/{{skin}}/images/action_edit.png" title="{{ _('Edit account profile') }}" class="fr-space"/></a>
                     {{ set_account_status_img(accountStatus) }}
                     {{ cn |cutString }}
                 </td>

templates/default/ldap/user/list.html

                                 <th>{{ _('User ID') }}</th>
                                 <th>{{ _('Job Title') }}</th>
                                 <th>{{ _('Quota') }}</th>
-                                <th>{{ _('Created') }}</th>
                             </tr>
                         </thead>
 
                         {% else %}
                             <tr>
                                 <td class="checkbox"></td>
-                                <td colspan="6">{{ _('No mail user available.') }} <a href="{{ctx.homepath}}/create/user/{{ cur_domain }}">{{ _('Add one') }}</a>?</td>
+                                <td colspan="5">{{ _('No mail user available.') }} <a href="{{ctx.homepath}}/create/user/{{ cur_domain }}">{{ _('Add one') }}</a>?</td>
                             </tr>
                         {% endif %}
                     </tbody>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.