瀏覽代碼

HUE-3521 [core] Provide a force_username_uppercase option

Jenny Kim 9 年之前
父節點
當前提交
c3203b1009

+ 6 - 1
apps/useradmin/src/useradmin/ldap_access.py

@@ -101,7 +101,10 @@ def get_or_create_ldap_user(username):
   if users.exists():
     return User.objects.get(**username_kwargs), False
   else:
-    username = desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username
+    if desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get():
+      username = username.lower()
+    elif desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get():
+      username = username.upper()
     return User.objects.create(username=username), True
 
 
@@ -232,6 +235,8 @@ class LdapConnection(object):
           group_name = data[group_name_attr][0]
           if desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get():
             group_name = group_name.lower()
+          elif desktop.conf.LDAP.FORCE_USERNAME_UPPERCASE.get():
+            group_name = group_name.upper()
 
           ldap_info = {
             'dn': dn,

+ 28 - 0
apps/useradmin/src/useradmin/test_ldap.py

@@ -473,6 +473,23 @@ class TestUserAdminLdap(BaseUserAdminTests):
       import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'Rock', sync_groups=False, import_by_dn=False)
       assert_false(User.objects.filter(username='Rock').exists())
       assert_true(User.objects.filter(username='rock').exists())
+
+      # Test upper case
+      User.objects.filter(username__iexact='rock').delete()
+      import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'rock', sync_groups=False, import_by_dn=False)
+      assert_false(User.objects.filter(username='Rock').exists())
+      assert_true(User.objects.filter(username='ROCK').exists())
+
+      done.append(desktop.conf.LDAP.FORCE_USERNAME_UPPERCASE.set_for_testing(True))
+
+      import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'Rock', sync_groups=False, import_by_dn=False)
+      assert_false(User.objects.filter(username='Rock').exists())
+      assert_true(User.objects.filter(username='ROCK').exists())
+
+      User.objects.filter(username='Rock').delete()
+      import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'Rock', sync_groups=False, import_by_dn=False)
+      assert_false(User.objects.filter(username='Rock').exists())
+      assert_true(User.objects.filter(username='ROCK').exists())
     finally:
       for finish in done:
         finish()
@@ -531,6 +548,17 @@ class TestUserAdminLdap(BaseUserAdminTests):
       assert_false(User.objects.filter(username='Rock').exists())
       assert_true(User.objects.filter(username='rock').exists())
 
+      # Test upper case
+      done.append(desktop.conf.LDAP.FORCE_USERNAME_UPPERCASE.set_for_testing(True))
+      User.objects.filter(username__iexact='Rock').delete()
+      assert_false(User.objects.filter(username='Rock').exists())
+      assert_false(User.objects.filter(username='ROCK').exists())
+      response = c.post(URL, dict(server='nonsense', username_pattern='ROCK', password1='test', password2='test'))
+      assert_true('Location' in response, response)
+      assert_true('/useradmin/users' in response['Location'], response)
+      assert_false(User.objects.filter(username='Rock').exists())
+      assert_true(User.objects.filter(username='ROCK').exists())
+
       # Test regular with spaces (should fail)
       response = c.post(URL, dict(server='nonsense', username_pattern='user with space', password1='test', password2='test'))
       assert_true("Username must not contain whitespaces and ':'" in response.context['form'].errors['username_pattern'][0], response)

+ 8 - 1
desktop/conf.dist/hue.ini

@@ -266,10 +266,13 @@
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## ignore_username_case=true
 
-    # Ignore the case of usernames when searching for existing users to authenticate with.
+    # Forcibly cast usernames to lowercase, takes precedence over force_username_uppercase
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## force_username_lowercase=true
 
+    # Forcibly cast usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Users will expire after they have not logged in for 'n' amount of seconds.
     # A negative number means that users will never expire.
     ## expires_after=-1
@@ -347,8 +350,12 @@
     ## ignore_username_case=true
 
     # Force usernames to lowercase when creating new users from LDAP.
+    # Takes precedence over force_username_uppercase
     ## force_username_lowercase=true
 
+    # Force usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Use search bind authentication.
     ## search_bind_authentication=true
 

+ 8 - 1
desktop/conf/pseudo-distributed.ini.tmpl

@@ -270,10 +270,13 @@
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## ignore_username_case=true
 
-    # Ignore the case of usernames when searching for existing users to authenticate with.
+    # Forcibly cast usernames to lowercase, takes precedence over force_username_uppercase
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## force_username_lowercase=true
 
+    # Forcibly cast usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Users will expire after they have not logged in for 'n' amount of seconds.
     # A negative number means that users will never expire.
     ## expires_after=-1
@@ -351,8 +354,12 @@
     ## ignore_username_case=true
 
     # Force usernames to lowercase when creating new users from LDAP.
+    # Takes precedence over force_username_uppercase
     ## force_username_lowercase=true
 
+    # Force usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Use search bind authentication.
     ## search_bind_authentication=true
 

+ 11 - 4
desktop/core/src/desktop/auth/backend.py

@@ -139,6 +139,12 @@ def ensure_has_a_group(user):
     user.groups.add(default_group)
     user.save()
 
+def force_username_case(username):
+  if desktop.conf.AUTH.FORCE_USERNAME_LOWERCASE.get():
+    username = username.lower()
+  elif desktop.conf.AUTH.FORCE_USERNAME_UPPERCASE.get():
+    username = username.upper()
+  return username
 
 class DesktopBackendBase(object):
   """
@@ -303,7 +309,7 @@ class PamBackend(DesktopBackendBase):
 
   @metrics.pam_authentication_time
   def authenticate(self, username, password):
-    username = desktop.conf.AUTH.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username
+    username = force_username_case(username)
 
     if pam.authenticate(username, password, desktop.conf.AUTH.PAM_SERVICE.get()):
       is_super = False
@@ -346,7 +352,8 @@ class LdapBackend(object):
     # Delegate to django_auth_ldap.LDAPBackend
     class _LDAPBackend(LDAPBackend):
       def get_or_create_user(self, username, ldap_user):
-        username = desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username
+        username = force_username_case(username)
+
         if desktop.conf.LDAP.IGNORE_USERNAME_CASE.get():
           try:
             return User.objects.get(username__iexact=username), False
@@ -493,7 +500,7 @@ class SpnegoDjangoBackend(django.contrib.auth.backends.ModelBackend):
   @metrics.spnego_authentication_time
   def authenticate(self, username=None):
     username = self.clean_username(username)
-    username = desktop.conf.AUTH.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username
+    username = force_username_case(username)
     is_super = False
     if User.objects.count() == 0:
       is_super = True
@@ -538,7 +545,7 @@ class RemoteUserDjangoBackend(django.contrib.auth.backends.RemoteUserBackend):
   """
   def authenticate(self, remote_user=None):
     username = self.clean_username(remote_user)
-    username = desktop.conf.AUTH.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username
+    username = force_username_case(username)
     is_super = False
     if User.objects.count() == 0:
       is_super = True

+ 8 - 0
desktop/core/src/desktop/conf.py

@@ -677,6 +677,10 @@ AUTH = ConfigSection(
                                       help=_("Force usernames to lowercase when creating new users."),
                                       type=coerce_bool,
                                       default=True),
+    FORCE_USERNAME_UPPERCASE = Config("force_username_uppercase",
+                                      help=_("Force usernames to uppercase when creating new users."),
+                                      type=coerce_bool,
+                                      default=False),
     EXPIRES_AFTER = Config("expires_after",
                             help=_("Users will expire after they have not logged in for 'n' amount of seconds."
                                    "A negative number means that users will never expire."),
@@ -751,6 +755,10 @@ LDAP = ConfigSection(
       help=_("Force usernames to lowercase when creating new users from LDAP."),
       type=coerce_bool,
       default=True),
+    FORCE_USERNAME_UPPERCASE = Config("force_username_uppercase",
+      help=_("Force usernames to uppercase when creating new users from LDAP."),
+      type=coerce_bool,
+      default=False),
     SUBGROUPS = Config("subgroups",
       help=_("Choose which kind of subgrouping to use: nested or suboordinate (deprecated)."),
       type=coerce_str_lowercase,