Bläddra i källkod

HUE-3521 [core] Provide a force_username_uppercase option

Jenny Kim 9 år sedan
förälder
incheckning
c3203b1009

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

@@ -101,7 +101,10 @@ def get_or_create_ldap_user(username):
   if users.exists():
   if users.exists():
     return User.objects.get(**username_kwargs), False
     return User.objects.get(**username_kwargs), False
   else:
   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
     return User.objects.create(username=username), True
 
 
 
 
@@ -232,6 +235,8 @@ class LdapConnection(object):
           group_name = data[group_name_attr][0]
           group_name = data[group_name_attr][0]
           if desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get():
           if desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.get():
             group_name = group_name.lower()
             group_name = group_name.lower()
+          elif desktop.conf.LDAP.FORCE_USERNAME_UPPERCASE.get():
+            group_name = group_name.upper()
 
 
           ldap_info = {
           ldap_info = {
             'dn': dn,
             '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)
       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_false(User.objects.filter(username='Rock').exists())
       assert_true(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:
     finally:
       for finish in done:
       for finish in done:
         finish()
         finish()
@@ -531,6 +548,17 @@ class TestUserAdminLdap(BaseUserAdminTests):
       assert_false(User.objects.filter(username='Rock').exists())
       assert_false(User.objects.filter(username='Rock').exists())
       assert_true(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)
       # Test regular with spaces (should fail)
       response = c.post(URL, dict(server='nonsense', username_pattern='user with space', password1='test', password2='test'))
       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)
       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
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## ignore_username_case=true
     ## 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
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## force_username_lowercase=true
     ## 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.
     # Users will expire after they have not logged in for 'n' amount of seconds.
     # A negative number means that users will never expire.
     # A negative number means that users will never expire.
     ## expires_after=-1
     ## expires_after=-1
@@ -347,8 +350,12 @@
     ## ignore_username_case=true
     ## ignore_username_case=true
 
 
     # Force usernames to lowercase when creating new users from LDAP.
     # Force usernames to lowercase when creating new users from LDAP.
+    # Takes precedence over force_username_uppercase
     ## force_username_lowercase=true
     ## force_username_lowercase=true
 
 
+    # Force usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Use search bind authentication.
     # Use search bind authentication.
     ## search_bind_authentication=true
     ## search_bind_authentication=true
 
 

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

@@ -270,10 +270,13 @@
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## ignore_username_case=true
     ## 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
     # Supported in remoteUserDjangoBackend and SpnegoDjangoBackend
     ## force_username_lowercase=true
     ## 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.
     # Users will expire after they have not logged in for 'n' amount of seconds.
     # A negative number means that users will never expire.
     # A negative number means that users will never expire.
     ## expires_after=-1
     ## expires_after=-1
@@ -351,8 +354,12 @@
     ## ignore_username_case=true
     ## ignore_username_case=true
 
 
     # Force usernames to lowercase when creating new users from LDAP.
     # Force usernames to lowercase when creating new users from LDAP.
+    # Takes precedence over force_username_uppercase
     ## force_username_lowercase=true
     ## force_username_lowercase=true
 
 
+    # Force usernames to uppercase, cannot be combined with force_username_lowercase
+    ## force_username_uppercase=false
+
     # Use search bind authentication.
     # Use search bind authentication.
     ## search_bind_authentication=true
     ## 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.groups.add(default_group)
     user.save()
     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):
 class DesktopBackendBase(object):
   """
   """
@@ -303,7 +309,7 @@ class PamBackend(DesktopBackendBase):
 
 
   @metrics.pam_authentication_time
   @metrics.pam_authentication_time
   def authenticate(self, username, password):
   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()):
     if pam.authenticate(username, password, desktop.conf.AUTH.PAM_SERVICE.get()):
       is_super = False
       is_super = False
@@ -346,7 +352,8 @@ class LdapBackend(object):
     # Delegate to django_auth_ldap.LDAPBackend
     # Delegate to django_auth_ldap.LDAPBackend
     class _LDAPBackend(LDAPBackend):
     class _LDAPBackend(LDAPBackend):
       def get_or_create_user(self, username, ldap_user):
       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():
         if desktop.conf.LDAP.IGNORE_USERNAME_CASE.get():
           try:
           try:
             return User.objects.get(username__iexact=username), False
             return User.objects.get(username__iexact=username), False
@@ -493,7 +500,7 @@ class SpnegoDjangoBackend(django.contrib.auth.backends.ModelBackend):
   @metrics.spnego_authentication_time
   @metrics.spnego_authentication_time
   def authenticate(self, username=None):
   def authenticate(self, username=None):
     username = self.clean_username(username)
     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
     is_super = False
     if User.objects.count() == 0:
     if User.objects.count() == 0:
       is_super = True
       is_super = True
@@ -538,7 +545,7 @@ class RemoteUserDjangoBackend(django.contrib.auth.backends.RemoteUserBackend):
   """
   """
   def authenticate(self, remote_user=None):
   def authenticate(self, remote_user=None):
     username = self.clean_username(remote_user)
     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
     is_super = False
     if User.objects.count() == 0:
     if User.objects.count() == 0:
       is_super = True
       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."),
                                       help=_("Force usernames to lowercase when creating new users."),
                                       type=coerce_bool,
                                       type=coerce_bool,
                                       default=True),
                                       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",
     EXPIRES_AFTER = Config("expires_after",
                             help=_("Users will expire after they have not logged in for 'n' amount of seconds."
                             help=_("Users will expire after they have not logged in for 'n' amount of seconds."
                                    "A negative number means that users will never expire."),
                                    "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."),
       help=_("Force usernames to lowercase when creating new users from LDAP."),
       type=coerce_bool,
       type=coerce_bool,
       default=True),
       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",
     SUBGROUPS = Config("subgroups",
       help=_("Choose which kind of subgrouping to use: nested or suboordinate (deprecated)."),
       help=_("Choose which kind of subgrouping to use: nested or suboordinate (deprecated)."),
       type=coerce_str_lowercase,
       type=coerce_str_lowercase,