Przeglądaj źródła

HUE-3700 [core] Support force_username_lowercase and ignore_username_case for all Auth backends

Jenny Kim 9 lat temu
rodzic
commit
c0d6736

+ 3 - 0
desktop/core/src/desktop/auth/backend.py

@@ -182,7 +182,9 @@ class AllowFirstUserDjangoBackend(django.contrib.auth.backends.ModelBackend):
   ModelBackend.
   """
   def authenticate(self, username=None, password=None):
+    username = force_username_case(username)
     user = super(AllowFirstUserDjangoBackend, self).authenticate(username, password)
+
     if user is not None:
       if user.is_active:
         user = rewrite_user(user)
@@ -272,6 +274,7 @@ class DemoBackend(django.contrib.auth.backends.ModelBackend):
   Log automatically users without a session with a new user account.
   """
   def authenticate(self, username, password):
+    username = force_username_case(username)
     user = super(DemoBackend, self).authenticate(username, password)
 
     if not user:

+ 9 - 8
desktop/libs/liboauth/src/liboauth/backend.py

@@ -23,17 +23,13 @@ import json
 import urllib
 import cgi
 import logging
-import sys
 
-from django.contrib.auth import logout as auth_logout
 from django.contrib.auth.models import User
-from django.http import HttpResponseRedirect
 from django.utils.translation import ugettext as _
 
-from desktop.auth.backend import DesktopBackendBase
-from desktop.auth.backend import rewrite_user
+from desktop.auth.backend import force_username_case, DesktopBackendBase
+from desktop.conf import AUTH
 from useradmin.models import get_profile, get_default_user_group, UserProfile
-from hadoop.fs.exceptions import WebHdfsException
 
 import liboauth.conf
 import liboauth.metrics
@@ -53,14 +49,19 @@ class OAuthBackend(DesktopBackendBase):
     username = access_token['screen_name']
     password = access_token['oauth_token_secret']
 
+    username = force_username_case(username)
+
     try:
+      if AUTH.IGNORE_USERNAME_CASE.get():
+        user = User.objects.get(username__iexact=username)
+      else:
         user = User.objects.get(username=username)
     except User.DoesNotExist:
 
       if not UserProfile.objects.filter(creation_method=str(UserProfile.CreationMethod.EXTERNAL)).exists():
-        is_super=True
+        is_super = True
       else:
-        is_super=False
+        is_super = False
 
       # Could save oauth_token detail in the user profile here
       user = find_or_create_user(username, password)

+ 47 - 17
desktop/libs/libsaml/src/libsaml/backend.py

@@ -21,13 +21,18 @@ See desktop/auth/backend.py
 from __future__ import absolute_import
 
 import logging
+
 from django.contrib.auth import logout as auth_logout
 from django.contrib.auth.models import User
 from djangosaml2.backends import Saml2Backend as _Saml2Backend
 from djangosaml2.views import logout as saml_logout
-from desktop.auth.backend import rewrite_user
+
+from desktop.auth.backend import force_username_case, rewrite_user
+from desktop.conf import AUTH
+
 from libsaml import conf
 from libsaml import metrics
+
 from useradmin.models import get_profile, get_default_user_group, UserProfile
 
 LOG = logging.getLogger(__name__)
@@ -38,11 +43,31 @@ class SAML2Backend(_Saml2Backend):
   Wrapper around djangosaml2 backend.
   """
 
+  @classmethod
+  def manages_passwords_externally(cls):
+    return True
+
+
   @metrics.saml2_authentication_time
   def authenticate(self, *args, **kwargs):
     return super(SAML2Backend, self).authenticate(*args, **kwargs)
 
 
+  def clean_user_main_attribute(self, main_attribute):
+    """
+    Overrides the clean_user_main_attribute method to force case if needed
+    """
+    return force_username_case(main_attribute)
+
+
+  def get_user(self, user_id):
+    if isinstance(user_id, str):
+      user_id = force_username_case(user_id)
+    user = super(SAML2Backend, self).get_user(user_id)
+    user = rewrite_user(user)
+    return user
+
+
   def update_user(self, user, attributes, attribute_mapping, force_save=False):
     # Do this check up here, because the auth call creates a django user upon first login per user
     is_super = False
@@ -50,18 +75,20 @@ class SAML2Backend(_Saml2Backend):
       # If there are no LDAP users already in the system, the first one will
       # become a superuser
       is_super = True
-    elif User.objects.filter(username=user.username).exists():
-      # If the user already exists, we shouldn't change its superuser
-      # privileges. However, if there's a naming conflict with a non-external
-      # user, we should do the safe thing and turn off superuser privs.
-      user = User.objects.get(username=user.username)
-      existing_profile = get_profile(user)
-      if existing_profile.creation_method == str(UserProfile.CreationMethod.EXTERNAL):
-        is_super = user.is_superuser
+    else:
+      user = self._get_user_by_username(user.username)
+      if user is not None:
+        # If the user already exists, we shouldn't change its superuser
+        # privileges. However, if there's a naming conflict with a non-external
+        # user, we should do the safe thing and turn off superuser privs.
+        existing_profile = get_profile(user)
+        if existing_profile.creation_method == str(UserProfile.CreationMethod.EXTERNAL):
+          is_super = user.is_superuser
 
     user = super(SAML2Backend, self).update_user(user, attributes, attribute_mapping, force_save)
 
     if user is not None and user.is_active:
+      user.username = force_username_case(user.username)
       profile = get_profile(user)
       profile.creation_method = UserProfile.CreationMethod.EXTERNAL
       profile.save()
@@ -77,14 +104,6 @@ class SAML2Backend(_Saml2Backend):
 
     return None
 
-  def get_user(self, user_id):
-    user = super(SAML2Backend, self).get_user(user_id)
-    user = rewrite_user(user)
-    return user
-
-  @classmethod
-  def manages_passwords_externally(cls):
-    return True
 
   def logout(self, request, next_page=None):
     if conf.LOGOUT_ENABLED.get():
@@ -93,3 +112,14 @@ class SAML2Backend(_Saml2Backend):
       return response
     else:
       return None
+
+
+  def _get_user_by_username(self, username):
+    try:
+      if AUTH.IGNORE_USERNAME_CASE.get():
+        user = User.objects.get(username__iexact=username)
+      else:
+        user = User.objects.get(username=username)
+    except User.DoesNotExist, e:
+      user = None
+    return user