def test_group_permissions(self): # Get ourselves set up with a user and a group c = make_logged_in_client(username="******", is_superuser=True) Group.objects.create(name="test-group") test_user = User.objects.get(username="******") test_user.groups.add(Group.objects.get(name="test-group")) test_user.save() # Make sure that a superuser can always access applications response = c.get('/useradmin/users') assert_true('Hue Users' in response.content) assert_true(len(GroupPermission.objects.all()) == 0) c.post('/useradmin/groups/edit/test-group', dict(name="test-group", members=[User.objects.get(username="******").pk], permissions=[ HuePermission.objects.get(app='useradmin', action='access').pk ], save="Save"), follow=True) assert_true(len(GroupPermission.objects.all()) == 1) # Now test that we have limited access c1 = make_logged_in_client(username="******", is_superuser=False) response = c1.get('/useradmin/users') assert_true( 'You do not have permission to access the Useradmin application.' in response.content) # Add the non-admin to a group that should grant permissions to the app test_user = User.objects.get(username="******") test_user.groups.add(Group.objects.get(name='test-group')) test_user.save() # Check that we have access now response = c1.get('/useradmin/users') assert_true( get_profile(test_user).has_hue_permission('access', 'useradmin')) assert_true('Hue Users' in response.content) # Make sure we can't modify permissions response = c1.get('/useradmin/permissions/edit/useradmin/access') assert_true( 'must be a superuser to change permissions' in response.content) # And revoke access from the group c.post('/useradmin/permissions/edit/useradmin/access', dict(app='useradmin', priv='access', groups=[], save="Save"), follow=True) assert_true(len(GroupPermission.objects.all()) == 0) assert_false( get_profile(test_user).has_hue_permission('access', 'useradmin')) # We should no longer have access to the app response = c1.get('/useradmin/users') assert_true( 'You do not have permission to access the Useradmin application.' in response.content)
def test_useradmin_ldap_user_integration(): reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users('larry', import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(len(User.objects.all()), 1) assert_equal(len(Group.objects.all()), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users('otherguy', import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different')
def test_useradmin_ldap_integration(): reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_user("larry", import_by_dn=False) larry = User.objects.get(username="******") assert_true(larry.first_name == "Larry") assert_true(larry.last_name == "Stooge") assert_true(larry.email == "*****@*****.**") assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(len(User.objects.all()), 1) assert_equal(len(Group.objects.all()), 0) # Should import a group, but will only sync already-imported members import_ldap_group("Test Administrators", import_members=False, import_by_dn=False) assert_equal(len(User.objects.all()), 1) assert_equal(len(Group.objects.all()), 1) test_admins = Group.objects.get(name="Test Administrators") assert_equal(len(test_admins.user_set.all()), 1) assert_equal(test_admins.user_set.all()[0].username, larry.username) # Import all members of TestUsers import_ldap_group("TestUsers", import_members=True, import_by_dn=False) test_users = Group.objects.get(name="TestUsers") assert_true(LdapGroup.objects.filter(group=test_users).exists()) assert_equal(len(test_users.user_set.all()), 3) ldap_access.CACHED_LDAP_CONN.remove_user_group_for_test("moe", "TestUsers") import_ldap_group("TestUsers", import_members=False, import_by_dn=False) assert_equal(len(test_users.user_set.all()), 2) assert_equal(len(User.objects.get(username="******").groups.all()), 0) ldap_access.CACHED_LDAP_CONN.add_user_group_for_test("moe", "TestUsers") import_ldap_group("TestUsers", import_members=False, import_by_dn=False) assert_equal(len(test_users.user_set.all()), 3) assert_equal(len(User.objects.get(username="******").groups.all()), 1) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username="******", first_name="Different", last_name="Guy") import_ldap_user("otherguy", import_by_dn=False) hue_user = User.objects.get(username="******") assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, "Different") # Make sure Hue groups with naming collisions don't get marked as LDAP groups hue_group = Group.objects.create(name="OtherGroup") hue_group.user_set.add(hue_user) hue_group.save() import_ldap_group("OtherGroup", import_members=False, import_by_dn=False) assert_false(LdapGroup.objects.filter(group=hue_group).exists()) assert_true(hue_group.user_set.filter(username=hue_user.username).exists())
def test_useradmin_ldap_user_integration(): reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users('lårry', import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true( get_profile(larry).creation_method == str( UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(len(User.objects.all()), 1) assert_equal(len(Group.objects.all()), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users('otherguy', import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal( get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different')
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 if not UserProfile.objects.filter(creation_method=str(UserProfile.CreationMethod.EXTERNAL)).exists(): # 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 user = super(SAML2Backend, self).update_user(user, attributes, attribute_mapping, force_save) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super user = rewrite_user(user) default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) user.save() return user return None
def test_group_permissions(): reset_all_users() reset_all_groups() # Get ourselves set up with a user and a group c = make_logged_in_client(username="******", is_superuser=True) Group.objects.create(name="test-group") test_user = User.objects.get(username="******") test_user.groups.add(Group.objects.get(name="test-group")) test_user.save() # Make sure that a superuser can always access applications response = c.get("/useradmin/users") assert_true("Hue Users" in response.content) assert_true(len(GroupPermission.objects.all()) == 0) c.post( "/useradmin/groups/edit/test-group", dict( name="test-group", members=[User.objects.get(username="******").pk], permissions=[HuePermission.objects.get(app="useradmin", action="access").pk], save="Save", ), follow=True, ) assert_true(len(GroupPermission.objects.all()) == 1) # Now test that we have limited access c1 = make_logged_in_client(username="******", is_superuser=False) response = c1.get("/useradmin/users") assert_true("You do not have permission to access the Useradmin application." in response.content) # Add the non-admin to a group that should grant permissions to the app test_user = User.objects.get(username="******") test_user.groups.add(Group.objects.get(name="test-group")) test_user.save() # Check that we have access now response = c1.get("/useradmin/users") assert_true(get_profile(test_user).has_hue_permission("access", "useradmin")) assert_true("Hue Users" in response.content) # Make sure we can't modify permissions response = c1.get("/useradmin/permissions/edit/useradmin/access") assert_true("must be a superuser to change permissions" in response.content) # And revoke access from the group c.post( "/useradmin/permissions/edit/useradmin/access", dict(app="useradmin", priv="access", groups=[], save="Save"), follow=True, ) assert_true(len(GroupPermission.objects.all()) == 0) assert_false(get_profile(test_user).has_hue_permission("access", "useradmin")) # We should no longer have access to the app response = c1.get("/useradmin/users") assert_true("You do not have permission to access the Useradmin application." in response.content)
def authenticate(self, request=None, username=None, password=None, server=None): self.add_ldap_config_for_server(server) username_filter_kwargs = ldap_access.get_ldap_user_kwargs(username) # Do this check up here, because the auth call creates a django user upon first login per user is_super = False if not UserProfile.objects.filter(creation_method=UserProfile.CreationMethod.EXTERNAL.name).exists(): # 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_filter_kwargs).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. existing_user = User.objects.get(**username_filter_kwargs) existing_profile = get_profile(existing_user) if existing_profile.creation_method == UserProfile.CreationMethod.EXTERNAL.name: is_super = User.objects.get(**username_filter_kwargs).is_superuser elif not LDAP.CREATE_USERS_ON_LOGIN.get(): LOG.warning("Create users when they login with their LDAP credentials is turned off") return None try: allowed_group = self.check_ldap_access_groups(server, username) if allowed_group: if sys.version_info[0] > 2: user = self._backend.authenticate(request, username=username, password=password) else: user = self._backend.authenticate(username=username, password=password) else: LOG.warning("%s not in an allowed login group" % username) return None except ImproperlyConfigured as detail: LOG.warning("LDAP was not properly configured: %s", detail) return None if AUTH.PAM_USE_PWD_MODULE.get() and user is not None: LOG.debug('Setting LDAP username to %s using PAM pwd module for user %s' % (getpwnam(username).pw_name, username)) pam_user = getpwnam(username).pw_name try: user = User.objects.get(username__iexact=pam_user) except User.DoesNotExist: user = find_or_create_user(pam_user, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL.name profile.save() user.is_superuser = is_super user = rewrite_user(user) ensure_has_a_group(user) if LDAP.SYNC_GROUPS_ON_LOGIN.get(): self.import_groups(server, user) return user
def test_useradmin_ldap_user_integration(): reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users('lårry', sync_groups=False, import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true( get_profile(larry).creation_method == str( UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users('otherguy', sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal( get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different') # Try importing a user and sync groups import_ldap_users('curly', sync_groups=True, import_by_dn=False) curly = User.objects.get(username='******') assert_equal(curly.first_name, 'Curly') assert_equal(curly.last_name, 'Stooge') assert_equal(curly.email, '*****@*****.**') assert_equal( get_profile(curly).creation_method, str(UserProfile.CreationMethod.EXTERNAL)) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() # Test import case sensitivity reset = desktop.conf.LDAP.IGNORE_USERNAME_CASE.set_for_testing(True) import_ldap_users('Lårry', sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username='******').exists()) assert_true(User.objects.filter(username='******').exists()) reset()
def test_useradmin_ldap_user_integration(): done = [] try: reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'lårry', sync_groups=False, import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users(ldap_access.CACHED_LDAP_CONN) sync_ldap_groups(ldap_access.CACHED_LDAP_CONN) assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'otherguy', sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different') # Make sure LDAP groups exist or they won't sync import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'TestUsers', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'Test Administrators', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) # Try importing a user and sync groups import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'curly', sync_groups=True, import_by_dn=False) curly = User.objects.get(username='******') assert_equal(curly.first_name, 'Curly') assert_equal(curly.last_name, 'Stooge') assert_equal(curly.email, '*****@*****.**') assert_equal(get_profile(curly).creation_method, str(UserProfile.CreationMethod.EXTERNAL)) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() finally: for finish in done: finish()
def authenticate(self, access_token): username = access_token['screen_name'] password = access_token['oauth_token_secret'] try: user = User.objects.get(username=username) except User.DoesNotExist: if not UserProfile.objects.filter(creation_method=str(UserProfile.CreationMethod.EXTERNAL)).exists(): is_super=True else: is_super=False # Could save oauth_token detail in the user profile here user = find_or_create_user(username, password) profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super user.save() default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) return user
def _import_ldap_user(username, import_by_dn=False): """ Import a user from LDAP. If import_by_dn is true, this will import the user by the distinguished name, rather than the configured username attribute. """ conn = ldap_access.get_connection() user_info = conn.find_user(username, import_by_dn) if user_info is None: LOG.warn("Could not get LDAP details for user %s" % (username,)) return None user, created = User.objects.get_or_create(username=user_info['username']) profile = get_profile(user) if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE): # This is a Hue user, and shouldn't be overwritten LOG.warn('There was a naming conflict while importing user %s' % (username,)) return None default_group = get_default_user_group() if created and default_group is not None: user.groups.add(default_group) if 'first' in user_info: user.first_name = user_info['first'] if 'last' in user_info: user.last_name = user_info['last'] if 'email' in user_info: user.email = user_info['email'] profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.save() return user
def samlgroup_check(request): if 'SAML2Backend' in desktop.auth.forms.get_backend_names(): if REQUIRED_GROUPS.get(): try: userprofile = get_profile(request.user) except: return False json_data = json.loads(userprofile.json_data) if not json_data: LOG.info("Empty userprofile data for %s user" % (request.user.username)) return False if not json_data.get('saml_attributes', False): LOG.info("Empty saml_attributes data for %s user" % request.user.username) return False if not json_data['saml_attributes'].get( REQUIRED_GROUPS_ATTRIBUTE.get(), False): LOG.info( "Missing %s in SAMLResponse for %s user" % (REQUIRED_GROUPS_ATTRIBUTE.get(), request.user.username)) return False saml_group_found = set(REQUIRED_GROUPS.get()).issubset( set(json_data['saml_attributes'].get( REQUIRED_GROUPS_ATTRIBUTE.get()))) if not saml_group_found: LOG.info("User %s not found in required SAML groups, %s" % (request.user.username, REQUIRED_GROUPS.get())) return False return True
def authenticate(self, username, password): username = desktop.conf.AUTH.FORCE_USERNAME_LOWERCASE.get() and username.lower() or username if pam.authenticate(username, password, desktop.conf.AUTH.PAM_SERVICE.get()): is_super = False if User.objects.count() == 0: is_super = True try: if desktop.conf.AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user return None
def check_auth(self, username, password): if pam.authenticate(username, password, desktop.conf.AUTH.PAM_SERVICE.get()): is_super = False if User.objects.count() == 0: is_super = True try: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) user.save() user = rewrite_user(user) return user return None
def dt_login(request): redirect_to = request.REQUEST.get('next', '/') is_first_login_ever = first_login_ever() backend_names = get_backend_names() is_active_directory = 'LdapBackend' in backend_names and ( bool(LDAP.NT_DOMAIN.get()) or bool(LDAP.LDAP_SERVERS.get()) ) if is_active_directory: UserCreationForm = auth_forms.LdapUserCreationForm AuthenticationForm = auth_forms.LdapAuthenticationForm else: UserCreationForm = auth_forms.UserCreationForm AuthenticationForm = auth_forms.AuthenticationForm if request.method == 'POST': request.audit = { 'operation': 'USER_LOGIN', 'username': request.POST.get('username') } # For first login, need to validate user info! first_user_form = is_first_login_ever and UserCreationForm(data=request.POST) or None first_user = first_user_form and first_user_form.is_valid() if first_user or not is_first_login_ever: auth_form = AuthenticationForm(data=request.POST) if auth_form.is_valid(): # Must login by using the AuthenticationForm. # It provides 'backends' on the User object. user = auth_form.get_user() userprofile = get_profile(user) login(request, user) if request.session.test_cookie_worked(): request.session.delete_test_cookie() if is_first_login_ever or 'AllowAllBackend' in backend_names or 'LdapBackend' in backend_names: # Create home directory for first user. try: ensure_home_directory(request.fs, user.username) except (IOError, WebHdfsException), e: LOG.error(_('Could not create home directory.'), exc_info=e) request.error(_('Could not create home directory.')) if require_change_password(userprofile): return HttpResponseRedirect(urlresolvers.reverse('useradmin.views.edit_user', kwargs={'username': user.username})) userprofile.first_login = False userprofile.save() msg = 'Successful login for user: %s' % user.username request.audit['operationText'] = msg access_warn(request, msg) return HttpResponseRedirect(redirect_to) else: request.audit['allowed'] = False msg = 'Failed login for user: %s' % request.POST.get('username') request.audit['operationText'] = msg access_warn(request, msg)
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 is_super = False if User.objects.count() == 0: is_super = True try: if desktop.conf.AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) user.save() user = rewrite_user(user) return user
def authenticate(self, username=None, password=None, server=None): self.add_ldap_config_for_server(server) username_filter_kwargs = ldap_access.get_ldap_user_kwargs(username) # Do this check up here, because the auth call creates a django user upon first login per user is_super = False if not UserProfile.objects.filter(creation_method=str(UserProfile.CreationMethod.EXTERNAL)).exists(): # 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_filter_kwargs).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. existing_user = User.objects.get(**username_filter_kwargs) existing_profile = get_profile(existing_user) if existing_profile.creation_method == str(UserProfile.CreationMethod.EXTERNAL): is_super = User.objects.get(**username_filter_kwargs).is_superuser elif not desktop.conf.LDAP.CREATE_USERS_ON_LOGIN.get(): return None try: user = self._backend.authenticate(username, password) except ImproperlyConfigured, detail: LOG.warn("LDAP was not properly configured: %s", detail) return None
def authenticate(self, username=None, password=None, server=None): self.add_ldap_config_for_server(server) username_filter_kwargs = ldap_access.get_ldap_user_kwargs(username) # Do this check up here, because the auth call creates a django user upon first login per user is_super = False if not UserProfile.objects.filter(creation_method=str( UserProfile.CreationMethod.EXTERNAL)).exists(): # 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_filter_kwargs).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. existing_user = User.objects.get(**username_filter_kwargs) existing_profile = get_profile(existing_user) if existing_profile.creation_method == str( UserProfile.CreationMethod.EXTERNAL): is_super = User.objects.get( **username_filter_kwargs).is_superuser elif not desktop.conf.LDAP.CREATE_USERS_ON_LOGIN.get(): return None try: user = self._backend.authenticate(username, password) except ImproperlyConfigured, detail: LOG.warn("LDAP was not properly configured: %s", detail) return None
def process_request(self, request): user = request.user if not user or not user.is_authenticated: return profile = get_profile(user) expires_after = AUTH.IDLE_SESSION_TIMEOUT.get() now = datetime.now() logout = False if profile.last_activity and expires_after > 0 and self._total_seconds(now - profile.last_activity) > expires_after: logout = True # Save last activity for user except when polling if not (request.path.strip('/') == 'notebook/api/check_status') \ and not (request.path.strip('/').startswith('jobbrowser/api/job')) \ and not (request.path.strip('/') == 'jobbrowser/jobs' and request.POST.get('format') == 'json') \ and not (request.path.strip('/') == 'desktop/debug/is_idle') \ and not (request.path.strip('/').startswith('oozie/list_oozie_')): try: profile.last_activity = datetime.now() profile.hostname = get_localhost_name() profile.save() except DatabaseError: LOG.exception('Error saving profile information') if logout: dt_logout(request, next_page='/')
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 is_super = False if User.objects.count() == 0: is_super = True try: if desktop.conf.AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) user.save() user = rewrite_user(user) return user
def authenticate(self, username=None, email=None, password=None): if email is not None: username = email username = force_username_case(username) request = None user = super(AllowFirstUserDjangoBackend, self).authenticate(request, username=username, password=password) if user is not None: if user.is_active: user = rewrite_user(user) return user return user if self.is_first_login_ever(): user = find_or_create_user(username, password) user = rewrite_user(user) userprofile = get_profile(user) userprofile.first_login = False userprofile.save() ensure_has_a_group(user) return user return None
def authenticate(self, remote_user=None): username = self.clean_username(remote_user) username = force_username_case(username) is_super = False if User.objects.count() == 0: is_super = True try: if desktop.conf.AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user
def authenticate(self, request=None, username=None, password=None): username = force_username_case(username) if AUTH.PAM_USE_PWD_MODULE.get(): LOG.debug('Setting username to %s using PAM pwd module for user %s' % (getpwnam(username).pw_name, username)) username = getpwnam(username).pw_name if pam.authenticate(username, password, AUTH.PAM_SERVICE.get()): is_super = False if User.objects.exclude(id=install_sample_user().id).count() == 0: is_super = True try: if AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL.name profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user return None
def authenticate(self, username, password): username = force_username_case(username) if pam.authenticate(username, password, desktop.conf.AUTH.PAM_SERVICE.get()): is_super = False if User.objects.count() == 0: is_super = True try: if desktop.conf.AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user return None
def authenticate(self, *args, **kwargs): if sys.version_info[0] > 2: request = args[0] else: request = None password = kwargs['password'] if 'email' in kwargs: username = kwargs['email'] else: username = kwargs['username'] username = force_username_case(username) user = super(AllowFirstUserDjangoBackend, self).authenticate(request, username=username, password=password) if user is not None: if user.is_active: user = rewrite_user(user) return user return user if self.is_first_login_ever(): user = find_or_create_user(username, password) user = rewrite_user(user) userprofile = get_profile(user) userprofile.first_login = False userprofile.save() ensure_has_a_group(user) return user return None
def authenticate(self, remote_user=None): username = self.clean_username(remote_user) username = force_username_case(username) is_super = False if User.objects.count() == 0: is_super = True try: if AUTH.IGNORE_USERNAME_CASE.get(): user = User.objects.get(username__iexact=username) else: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL.name profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user
def authenticate(self, access_token): 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 else: is_super = False # Could save oauth_token detail in the user profile here user = find_or_create_user(username, password) profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super user.save() default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) return user
def test_useradmin_ldap_user_integration(): reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users('lårry', sync_groups=False, import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users('otherguy', sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different') # Try importing a user and sync groups import_ldap_users('curly', sync_groups=True, import_by_dn=False) curly = User.objects.get(username='******') assert_equal(curly.first_name, 'Curly') assert_equal(curly.last_name, 'Stooge') assert_equal(curly.email, '*****@*****.**') assert_equal(get_profile(curly).creation_method, str(UserProfile.CreationMethod.EXTERNAL)) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() # Test import case sensitivity reset = desktop.conf.LDAP.IGNORE_USERNAME_CASE.set_for_testing(True) import_ldap_users('Lårry', sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username='******').exists()) assert_true(User.objects.filter(username='******').exists()) reset()
def dt_login(request): redirect_to = request.REQUEST.get('next', '/') is_first_login_ever = first_login_ever() backend_names = get_backend_names() is_active_directory = 'LdapBackend' in backend_names and (bool( LDAP.NT_DOMAIN.get()) or bool(LDAP.LDAP_SERVERS.get())) if is_active_directory: UserCreationForm = auth_forms.LdapUserCreationForm AuthenticationForm = auth_forms.LdapAuthenticationForm else: UserCreationForm = auth_forms.UserCreationForm AuthenticationForm = auth_forms.AuthenticationForm if request.method == 'POST': # For first login, need to validate user info! first_user_form = is_first_login_ever and UserCreationForm( data=request.POST) or None first_user = first_user_form and first_user_form.is_valid() if first_user or not is_first_login_ever: auth_form = AuthenticationForm(data=request.POST) if auth_form.is_valid(): # Must login by using the AuthenticationForm. # It provides 'backends' on the User object. user = auth_form.get_user() userprofile = get_profile(user) login(request, user) if request.session.test_cookie_worked(): request.session.delete_test_cookie() if is_first_login_ever or 'AllowAllBackend' in backend_names or 'LdapBackend' in backend_names: # Create home directory for first user. try: ensure_home_directory(request.fs, user.username) except (IOError, WebHdfsException), e: LOG.error(_('Could not create home directory.'), exc_info=e) request.error(_('Could not create home directory.')) if require_change_password(userprofile): return HttpResponseRedirect( urlresolvers.reverse( 'useradmin.views.edit_user', kwargs={'username': user.username})) userprofile.first_login = False userprofile.save() access_warn(request, '"%s" login ok' % (user.username, )) return HttpResponseRedirect(redirect_to) else: access_warn( request, 'Failed login for user "%s"' % (request.POST.get('username'), ))
def getuser(self, **options): try: return User.objects.get(id=1) except User.DoesNotExist: form = SuperUserChangeForm( { "username": DEFAULT_USER.get(), "password1": DEFAULT_USER_PASSWORD.get(), "password2": DEFAULT_USER_PASSWORD.get(), "ensure_home_directory": True, "is_active": True, "is_superuser": True, } ) instance = form.save() get_profile(instance) return User.objects.get(username=DEFAULT_USER.get())
def test_get_profile(): # Ensure profiles are created after get_profile is called. reset_all_users() reset_all_groups() c = make_logged_in_client(username='******', password='******', is_superuser=True) assert_equal(0, UserProfile.objects.count()) p = get_profile(User.objects.get(username='******')) assert_equal(1, UserProfile.objects.count())
def test_get_profile(self): # Ensure profiles are created after get_profile is called. c = make_logged_in_client(username='******', password='******', is_superuser=True) assert_equal(0, UserProfile.objects.count()) p = get_profile(User.objects.get(username='******')) assert_equal(1, UserProfile.objects.count())
def _import_ldap_users_info(connection, user_info, sync_groups=False, import_by_dn=False): """ Import user_info found through ldap_access.find_users. """ imported_users = [] for ldap_info in user_info: # Extra validation in case import by DN and username has spaces or colons validate_username(ldap_info['username']) user, created = ldap_access.get_or_create_ldap_user(username=ldap_info['username']) profile = get_profile(user) if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE): # This is a Hue user, and shouldn't be overwritten LOG.warn(_('There was a naming conflict while importing user %(username)s') % { 'username': ldap_info['username'] }) return None default_group = get_default_user_group() if created and default_group is not None: user.groups.add(default_group) if 'first' in ldap_info: user.first_name = ldap_info['first'] if 'last' in ldap_info: user.last_name = ldap_info['last'] if 'email' in ldap_info: user.email = ldap_info['email'] profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.save() imported_users.append(user) # sync groups if sync_groups and 'groups' in ldap_info: old_groups = set(user.groups.all()) new_groups = set() # Skip if 'memberOf' or 'isMemberOf' are not set for group_dn in ldap_info['groups']: group_ldap_info = connection.find_groups(group_dn, find_by_dn=True, scope=ldap.SCOPE_BASE) for group_info in group_ldap_info: # Add only if user isn't part of group. if not user.groups.filter(name=group_info['name']).exists(): groups = import_ldap_groups(connection, group_info['dn'], import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=True) if groups: new_groups.update(groups) # Remove out of date groups remove_groups = old_groups - new_groups remove_ldap_groups = LdapGroup.objects.filter(group__in=remove_groups) remove_groups_filtered = [ldapgroup.group for ldapgroup in remove_ldap_groups] user.groups.filter(group__in=remove_groups_filtered).delete() user.groups.add(*new_groups) Group.objects.filter(group__in=remove_groups_filtered).delete() remove_ldap_groups.delete() return imported_users
def test_useradmin_ldap_user_integration(self): done = [] try: # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'lårry', sync_groups=False, import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true(get_profile(larry).creation_method == UserProfile.CreationMethod.EXTERNAL.name) # Should be a noop sync_ldap_users(ldap_access.CACHED_LDAP_CONN) sync_ldap_groups(ldap_access.CACHED_LDAP_CONN) assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'otherguy', sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal(get_profile(hue_user).creation_method, UserProfile.CreationMethod.HUE.name) assert_equal(hue_user.first_name, 'Different') # Make sure LDAP groups exist or they won't sync import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'TestUsers', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'Test Administrators', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) # Try importing a user and sync groups import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'curly', sync_groups=True, import_by_dn=False) curly = User.objects.get(username='******') assert_equal(curly.first_name, 'Curly') assert_equal(curly.last_name, 'Stooge') assert_equal(curly.email, '*****@*****.**') assert_equal(get_profile(curly).creation_method, UserProfile.CreationMethod.EXTERNAL.name) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() finally: for finish in done: finish()
def test_login_set_auth_backend_in_profile(self): client = make_logged_in_client(username=self.test_username, password="******") response = client.post('/hue/accounts/login/', {'username': self.test_username, 'password': '******'}) assert_equal(302, response.status_code) user = User.objects.get(username=self.test_username) existing_profile = get_profile(user) assert_equal('desktop.auth.backend.AllowFirstUserDjangoBackend', existing_profile.data['auth_backend'])
def ensure_home_directory(fs, user): """ Adds a users home directory if it doesn't already exist. Throws IOError, WebHdfsException. """ userprofile = get_profile(user) if userprofile is not None and userprofile.home_directory: fs.do_as_user(user.username, fs.create_home_dir, userprofile.home_directory) else: LOG.warn("Not creating home directory of %s as his profile is empty" % user)
def rewrite_user(user): """ Rewrites the user according to the augmentation class. We currently only re-write specific attributes, though this could be generalized. """ if user is None: LOG.warn('Failed to rewrite user, user is None.') else: augment = get_user_augmentation_class()(user) for attr in ('get_groups', 'get_home_directory', 'has_hue_permission', 'get_permissions'): setattr(user, attr, getattr(augment, attr)) setattr(user, 'profile', get_profile(user)) setattr(user, 'auth_backend', user.profile.data.get('auth_backend')) return user
def handle(self, *args, **options): LOG.info("Removing any orphaned docs") start = time.time() totalUsers = User.objects.filter().values_list("id", flat=True) totalDocs = Document2.objects.exclude(owner_id__in=totalUsers) docstorage_id = "docstorage" + str(uuid.uuid4()) docstorage_id = docstorage_id[:30] LOG.info("Creating new owner for all orphaned docs: %s" % docstorage_id) docstorage = find_or_create_user(docstorage_id) docstorage = rewrite_user(docstorage) userprofile = get_profile(docstorage) userprofile.first_login = False userprofile.save() ensure_has_a_group(docstorage) new_home_dir = Document2.objects.create_user_directories(docstorage) for doc in totalDocs: if not doc.type == "directory": new_dir_name = "recover-" + str(doc.owner_id) new_sub_dir = Directory.objects.create( name=new_dir_name, owner=docstorage, parent_directory=new_home_dir) doc1 = doc.doc.get() doc.owner = docstorage doc1.owner = docstorage doc.parent_directory = new_sub_dir doc.save() doc1.save() Document.objects.sync() LOG.info( "Migrating orphaned doc: %s : %s : %s : %s : to orphaned doc owner: %s" % (doc.name, doc.type, doc.owner_id, doc.parent_directory, docstorage_id)) for doc in totalDocs: if doc.type == "directory": LOG.info("Deleting orphaned directory: %s : %s : %s" % (doc.name, doc.type, doc.owner_id)) doc.delete() end = time.time() elapsed = (end - start) LOG.info("Total time elapsed (seconds): %.2f" % elapsed)
def authenticate(self, username=None, password=None): user = super(AllowFirstUserDjangoBackend, self).authenticate(username, password) if user is not None: if user.is_active: user = rewrite_user(user) return user return user if self.is_first_login_ever(): user = find_or_create_user(username, password) user = rewrite_user(user) userprofile = get_profile(user) userprofile.first_login = False userprofile.save() ensure_has_a_group(user) return user return None
def authenticate(self, username=None): username = self.clean_username(username) is_super = False if User.objects.count() == 0: is_super = True try: user = User.objects.get(username=username) except User.DoesNotExist: user = find_or_create_user(username, None) if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.is_superuser = is_super ensure_has_a_group(user) user.save() user = rewrite_user(user) return user
def samlgroup_check(request): if 'SAML2Backend' in desktop.auth.forms.get_backend_names(): if REQUIRED_GROUPS.get(): try: userprofile = get_profile(request.user) except: return False json_data = json.loads(userprofile.json_data) if not json_data: LOG.info("Empty userprofile data for %s user" % (request.user.username)) return False if not json_data.get('saml_attributes', False): LOG.info("Empty saml_attributes data for %s user" % request.user.username) return False if not json_data['saml_attributes'].get( REQUIRED_GROUPS_ATTRIBUTE.get(), False): LOG.info( "Missing %s in SAMLResponse for %s user" % (REQUIRED_GROUPS_ATTRIBUTE.get(), request.user.username)) return False # Earlier we had AND condition, It means user has to be there in all given groups. # Now we are doing OR condition, which means user must be in one of the given groups. saml_group_found = set(REQUIRED_GROUPS.get()).intersection( set(json_data['saml_attributes'].get( REQUIRED_GROUPS_ATTRIBUTE.get()))) if not saml_group_found: LOG.info("User %s not found in required SAML groups, %s" % (request.user.username, REQUIRED_GROUPS.get())) return False LOG.info("User %s found in the required SAML groups %s" % (request.user.username, ",".join(saml_group_found))) return True
def authenticate(self, username=None, password=None): user = super(AllowFirstUserDjangoBackend, self).authenticate(username, password) if user is not None: if user.is_active: user = rewrite_user(user) return user return user if self.is_first_login_ever(): user = find_or_create_user(username, password) user = rewrite_user(user) userprofile = get_profile(user) userprofile.first_login = False userprofile.save() default_group = get_default_user_group() if default_group is not None: user.groups.add(default_group) user.save() return user return None
LOG.warn("Create users when they login with their LDAP credentials is turned off") return None try: allowed_group = self.check_ldap_access_groups(server, username) if allowed_group: user = self._backend.authenticate(username, password) else: LOG.warn("%s not in an allowed login group" % username) return None except ImproperlyConfigured, detail: LOG.warn("LDAP was not properly configured: %s", detail) return None if user is not None and user.is_active: profile = get_profile(user) profile.creation_method = UserProfile.CreationMethod.EXTERNAL.name profile.save() user.is_superuser = is_super user = rewrite_user(user) ensure_has_a_group(user) if desktop.conf.LDAP.SYNC_GROUPS_ON_LOGIN.get(): self.import_groups(server, user) return user def get_user(self, user_id): user = self._backend.get_user(user_id) user = rewrite_user(user)
def test_get_profile(self): # Ensure profiles are created after get_profile is called. c = make_logged_in_client(username="******", password="******", is_superuser=True) assert_equal(0, UserProfile.objects.count()) p = get_profile(User.objects.get(username="******")) assert_equal(1, UserProfile.objects.count())
def test_useradmin_ldap_user_integration(): if is_live_cluster(): raise SkipTest('HUE-2897: Skipping because DB may not support unicode') done = [] # Set to nonsensical value just to force new config usage. # Should continue to use cached connection. done.append(desktop.conf.LDAP.LDAP_SERVERS.set_for_testing(get_nonsense_config())) try: reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'lårry', sync_groups=False, import_by_dn=False) larry = User.objects.get(username='******') assert_true(larry.first_name == 'Larry') assert_true(larry.last_name == 'Stooge') assert_true(larry.email == '*****@*****.**') assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users(ldap_access.CACHED_LDAP_CONN) sync_ldap_groups(ldap_access.CACHED_LDAP_CONN) assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username='******', first_name='Different', last_name='Guy') import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'otherguy', sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username='******') assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, 'Different') # Make sure LDAP groups exist or they won't sync import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'TestUsers', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) import_ldap_groups(ldap_access.CACHED_LDAP_CONN, 'Test Administrators', import_members=False, import_members_recursive=False, sync_users=False, import_by_dn=False) # Try importing a user and sync groups import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'curly', sync_groups=True, import_by_dn=False) curly = User.objects.get(username='******') assert_equal(curly.first_name, 'Curly') assert_equal(curly.last_name, 'Stooge') assert_equal(curly.email, '*****@*****.**') assert_equal(get_profile(curly).creation_method, str(UserProfile.CreationMethod.EXTERNAL)) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() # Test import case sensitivity done.append(desktop.conf.LDAP.IGNORE_USERNAME_CASE.set_for_testing(True)) import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'Lårry', sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username='******').exists()) assert_true(User.objects.filter(username='******').exists()) # Test lower 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='******').exists()) assert_true(User.objects.filter(username='******').exists()) done.append(desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.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='******').exists()) assert_true(User.objects.filter(username='******').exists()) User.objects.filter(username='******').delete() import_ldap_users(ldap_access.CACHED_LDAP_CONN, 'Rock', sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username='******').exists()) assert_true(User.objects.filter(username='******').exists()) finally: for finish in done: finish()
def edit_user(request, username=None): """ edit_user(request, username = None) -> reply @type request: HttpRequest @param request: The request object @type username: string @param username: Default to None, when creating a new user """ if request.user.username != username and not request.user.is_superuser: raise PopupException( _("You must be a superuser to add or edit another user."), error_code=401) if username is not None: instance = User.objects.get(username=username) else: instance = None if request.user.is_superuser: form_class = SuperUserChangeForm else: form_class = UserChangeForm if request.method == 'POST': form = form_class(request.POST, instance=instance) if form.is_valid(): # All validation rules pass if instance is None: instance = form.save() get_profile(instance) else: if username != form.instance.username: raise PopupException(_("You cannot change a username."), error_code=401) if request.user.username == username and not form.instance.is_active: raise PopupException( _("You cannot make yourself inactive."), error_code=401) global __users_lock __users_lock.acquire() try: # form.instance (and instance) now carry the new data orig = User.objects.get(username=username) if orig.is_superuser: if not form.instance.is_superuser or not form.instance.is_active: _check_remove_last_super(orig) else: if form.instance.is_superuser and not request.user.is_superuser: raise PopupException( _("You cannot make yourself a superuser."), error_code=401) # All ok form.save() request.info(_('User information updated')) finally: __users_lock.release() # Ensure home directory is created, if necessary. if form.cleaned_data['ensure_home_directory']: try: ensure_home_directory(request.fs, instance.username) except (IOError, WebHdfsException), e: request.error( _('Cannot make home directory for user %s.' % instance.username)) if request.user.is_superuser: return redirect(reverse(list_users)) else: return redirect( reverse(edit_user, kwargs={'username': username}))
def dt_login(request, from_modal=False): redirect_to = request.REQUEST.get("next", "/") is_first_login_ever = first_login_ever() backend_names = get_backend_names() is_active_directory = "LdapBackend" in backend_names and ( bool(LDAP.NT_DOMAIN.get()) or bool(LDAP.LDAP_SERVERS.get()) ) if is_active_directory: UserCreationForm = auth_forms.LdapUserCreationForm AuthenticationForm = auth_forms.LdapAuthenticationForm else: UserCreationForm = auth_forms.UserCreationForm AuthenticationForm = auth_forms.AuthenticationForm if request.method == "POST": request.audit = {"operation": "USER_LOGIN", "username": request.POST.get("username")} # For first login, need to validate user info! first_user_form = is_first_login_ever and UserCreationForm(data=request.POST) or None first_user = first_user_form and first_user_form.is_valid() if first_user or not is_first_login_ever: auth_form = AuthenticationForm(data=request.POST) if auth_form.is_valid(): # Must login by using the AuthenticationForm. # It provides 'backends' on the User object. user = auth_form.get_user() userprofile = get_profile(user) login(request, user) if request.session.test_cookie_worked(): request.session.delete_test_cookie() if is_first_login_ever or "AllowAllBackend" in backend_names or "LdapBackend" in backend_names: # Create home directory for first user. try: ensure_home_directory(request.fs, user.username) except (IOError, WebHdfsException), e: LOG.error(_("Could not create home directory."), exc_info=e) request.error(_("Could not create home directory.")) if require_change_password(userprofile): return HttpResponseRedirect( urlresolvers.reverse("useradmin.views.edit_user", kwargs={"username": user.username}) ) userprofile.first_login = False userprofile.last_activity = datetime.now() userprofile.save() msg = "Successful login for user: %s" % user.username request.audit["operationText"] = msg access_warn(request, msg) if from_modal or request.REQUEST.get("fromModal", "false") == "true": return JsonResponse({"auth": True}) else: return HttpResponseRedirect(redirect_to) else: request.audit["allowed"] = False msg = "Failed login for user: %s" % request.POST.get("username") request.audit["operationText"] = msg access_warn(request, msg) if from_modal or request.REQUEST.get("fromModal", "false") == "true": return JsonResponse({"auth": False})
def test_useradmin_ldap_user_integration(): done = [] try: reset_all_users() reset_all_groups() # Set up LDAP tests to use a LdapTestConnection instead of an actual LDAP connection ldap_access.CACHED_LDAP_CONN = LdapTestConnection() # Try importing a user import_ldap_users("lårry", sync_groups=False, import_by_dn=False) larry = User.objects.get(username="******") assert_true(larry.first_name == "Larry") assert_true(larry.last_name == "Stooge") assert_true(larry.email == "*****@*****.**") assert_true(get_profile(larry).creation_method == str(UserProfile.CreationMethod.EXTERNAL)) # Should be a noop sync_ldap_users() sync_ldap_groups() assert_equal(User.objects.all().count(), 1) assert_equal(Group.objects.all().count(), 0) # Make sure that if a Hue user already exists with a naming collision, we # won't overwrite any of that user's information. hue_user = User.objects.create(username="******", first_name="Different", last_name="Guy") import_ldap_users("otherguy", sync_groups=False, import_by_dn=False) hue_user = User.objects.get(username="******") assert_equal(get_profile(hue_user).creation_method, str(UserProfile.CreationMethod.HUE)) assert_equal(hue_user.first_name, "Different") # Try importing a user and sync groups import_ldap_users("curly", sync_groups=True, import_by_dn=False) curly = User.objects.get(username="******") assert_equal(curly.first_name, "Curly") assert_equal(curly.last_name, "Stooge") assert_equal(curly.email, "*****@*****.**") assert_equal(get_profile(curly).creation_method, str(UserProfile.CreationMethod.EXTERNAL)) assert_equal(2, curly.groups.all().count(), curly.groups.all()) reset_all_users() reset_all_groups() # Test import case sensitivity done.append(desktop.conf.LDAP.IGNORE_USERNAME_CASE.set_for_testing(True)) import_ldap_users("Lårry", sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username="******").exists()) assert_true(User.objects.filter(username="******").exists()) # Test lower case User.objects.filter(username__iexact="Rock").delete() import_ldap_users("Rock", sync_groups=False, import_by_dn=False) assert_true(User.objects.filter(username="******").exists()) assert_false(User.objects.filter(username="******").exists()) done.append(desktop.conf.LDAP.FORCE_USERNAME_LOWERCASE.set_for_testing(True)) import_ldap_users("Rock", sync_groups=False, import_by_dn=False) assert_true(User.objects.filter(username="******").exists()) assert_false(User.objects.filter(username="******").exists()) User.objects.filter(username="******").delete() import_ldap_users("Rock", sync_groups=False, import_by_dn=False) assert_false(User.objects.filter(username="******").exists()) assert_true(User.objects.filter(username="******").exists()) finally: for finish in done: finish()
def edit_user(request, username=None): """ edit_user(request, username = None) -> reply @type request: HttpRequest @param request: The request object @type username: string @param username: Default to None, when creating a new user """ if request.user.username != username and not request.user.is_superuser: request.audit = {'allowed': False} if username is not None: request.audit['operation'] = 'EDIT_USER' request.audit['operationText'] = _get_failed_operation_text(request.user.username, 'EDIT_USER') else: request.audit['operation'] = 'CREATE_USER' request.audit['operationText'] = _get_failed_operation_text(request.user.username, 'CREATE_USER') raise PopupException(_("You must be a superuser to add or edit another user."), error_code=401) userprofile = get_profile(request.user) if username is not None: instance = User.objects.get(username=username) else: instance = None if require_change_password(userprofile): form_class = PasswordChangeForm elif request.user.is_superuser: form_class = SuperUserChangeForm else: form_class = UserChangeForm if request.method == 'POST': form = form_class(request.POST, instance=instance) if request.user.is_superuser and request.user.username != username: form.fields.pop("password_old") if form.is_valid(): # All validation rules pass if instance is None: instance = form.save() get_profile(instance) else: if username != form.instance.username: raise PopupException(_("You cannot change a username."), error_code=401) if request.user.username == username and not form.instance.is_active: raise PopupException(_("You cannot make yourself inactive."), error_code=401) global __users_lock __users_lock.acquire() try: # form.instance (and instance) now carry the new data orig = User.objects.get(username=username) if orig.is_superuser: if not form.instance.is_superuser or not form.instance.is_active: _check_remove_last_super(orig) else: if form.instance.is_superuser and not request.user.is_superuser: raise PopupException(_("You cannot make yourself a superuser."), error_code=401) # All ok form.save() request.info(_('User information updated')) finally: __users_lock.release() # Ensure home directory is created, if necessary. if form.cleaned_data.get('ensure_home_directory'): try: ensure_home_directory(request.fs, instance.username) except (IOError, WebHdfsException), e: request.error(_('Cannot make home directory for user %s.') % instance.username) # Audit log if username is not None: request.audit = { 'operation': 'EDIT_USER', 'operationText': 'Edited User with username: %s' % username } else: request.audit = { 'operation': 'CREATE_USER', 'operationText': 'Created User with username: %s' % instance.username } if require_change_password(userprofile): userprofile.first_login = False userprofile.save() if request.user.is_superuser: return redirect(reverse('about:index')) else: return redirect(reverse('desktop.views.home')) elif request.user.is_superuser: return redirect(reverse(list_users)) else: return redirect(reverse(edit_user, kwargs={'username': username}))
def _import_ldap_users_info(connection, user_info, sync_groups=False, import_by_dn=False, server=None, failed_users=None): """ Import user_info found through ldap_access.find_users. """ imported_users = [] for ldap_info in user_info: # Extra validation in case import by DN and username has spaces or colons try: validate_username(ldap_info['username']) user, created = ldap_access.get_or_create_ldap_user(username=ldap_info['username']) profile = get_profile(user) if not created and profile.creation_method == str(UserProfile.CreationMethod.HUE): # This is a Hue user, and shouldn't be overwritten LOG.warn(_('There was a naming conflict while importing user %(username)s') % { 'username': ldap_info['username'] }) return None default_group = get_default_user_group() if created and default_group is not None: user.groups.add(default_group) if 'first' in ldap_info: validate_first_name(ldap_info['first']) user.first_name = ldap_info['first'] if 'last' in ldap_info: validate_last_name(ldap_info['last']) user.last_name = ldap_info['last'] if 'email' in ldap_info: user.email = ldap_info['email'] profile.creation_method = UserProfile.CreationMethod.EXTERNAL profile.save() user.save() imported_users.append(user) # sync groups if sync_groups: old_groups = set(user.groups.all()) new_groups = set() current_ldap_groups = set() ldap_config = desktop.conf.LDAP.LDAP_SERVERS.get()[server] if server else desktop.conf.LDAP group_member_attr = ldap_config.GROUPS.GROUP_MEMBER_ATTR.get() group_filter = ldap_config.GROUPS.GROUP_FILTER.get() # Search for groups based on group_member_attr=username and group_member_attr=dn # covers AD, Standard Ldap and posixAcount/posixGroup if not group_filter.startswith('('): group_filter = '(' + group_filter + ')' # Sanitizing the DN before using in a Search filter sanitized_dn = ldap.filter.escape_filter_chars(ldap_info['dn']).replace(r'\2a', r'*') sanitized_dn = sanitized_dn.replace(r'\5c,', r'\5c\2c') find_groups_filter = "(&" + group_filter + "(|(" + group_member_attr + "=" + ldap_info['username'] + ")(" + \ group_member_attr + "=" + sanitized_dn + ")))" group_ldap_info = connection.find_groups("*", group_filter=find_groups_filter) for group_info in group_ldap_info: if Group.objects.filter(name=group_info['name']).exists(): # Add only if user isn't part of group. current_ldap_groups.add(Group.objects.get(name=group_info['name'])) if not user.groups.filter(name=group_info['name']).exists(): groups = import_ldap_groups(connection, group_info['dn'], import_members=False, import_members_recursive=False, sync_users=True, import_by_dn=True, failed_users=failed_users) if groups: new_groups.update(groups) # Remove out of date groups remove_groups = old_groups - current_ldap_groups remove_ldap_groups = LdapGroup.objects.filter(group__in=remove_groups) remove_groups_filtered = [ldapgroup.group for ldapgroup in remove_ldap_groups] for group in remove_groups_filtered: user.groups.remove(group) user.groups.add(*new_groups) Group.objects.filter(group__in=remove_groups_filtered).delete() except (ValidationError, LdapSearchException) as e: if failed_users is None: failed_users = [] failed_users.append(ldap_info['username']) LOG.warn('Could not import %s: %s' % (ldap_info['username'], e.message)) return imported_users
def edit_user(request, username=None): """ edit_user(request, username = None) -> reply @type request: HttpRequest @param request: The request object @type username: string @param username: Default to None, when creating a new user """ if request.user.username != username and not request.user.is_superuser: raise PopupException(_("You must be a superuser to add or edit another user."), error_code=401) if username is not None: instance = User.objects.get(username=username) else: instance = None if request.user.is_superuser: form_class = SuperUserChangeForm else: form_class = UserChangeForm if request.method == 'POST': form = form_class(request.POST, instance=instance) if form.is_valid(): # All validation rules pass if instance is None: instance = form.save() get_profile(instance) else: if username != form.instance.username: raise PopupException(_("You cannot change a username."), error_code=401) if request.user.username == username and not form.instance.is_active: raise PopupException(_("You cannot make yourself inactive."), error_code=401) global __users_lock __users_lock.acquire() try: # form.instance (and instance) now carry the new data orig = User.objects.get(username=username) if orig.is_superuser: if not form.instance.is_superuser or not form.instance.is_active: _check_remove_last_super(orig) else: if form.instance.is_superuser and not request.user.is_superuser: raise PopupException(_("You cannot make yourself a superuser."), error_code=401) # All ok form.save() request.info(_('User information updated')) finally: __users_lock.release() # Ensure home directory is created, if necessary. if form.cleaned_data['ensure_home_directory']: try: ensure_home_directory(request.fs, instance.username) except (IOError, WebHdfsException), e: request.error(_('Cannot make home directory for user %s.' % instance.username)) if request.user.is_superuser: return redirect(reverse(list_users)) else: return redirect(reverse(edit_user, kwargs={'username': username}))
def test_user_admin(): FUNNY_NAME = '~`!@#$%^&*()_-+={}[]|\;"<>?/,.' FUNNY_NAME_QUOTED = urllib.quote(FUNNY_NAME) reset_all_users() reset_all_groups() useradmin.conf.DEFAULT_USER_GROUP.set_for_testing('test_default') useradmin.conf.PASSWORD_POLICY.IS_ENABLED.set_for_testing(False) reset_password_policy() c = make_logged_in_client('test', is_superuser=True) user = User.objects.get(username='******') # Test basic output. response = c.get('/useradmin/') assert_true(len(response.context["users"]) > 0) assert_true("Hue Users" in response.content) # Test editing a superuser # Just check that this comes back response = c.get('/useradmin/users/edit/test') # Edit it, to add a first and last name response = c.post('/useradmin/users/edit/test', dict(username="******", first_name=u"Inglés", last_name=u"Español", is_superuser="******", is_active="True"), follow=True) assert_true("User information updated" in response.content, "Notification should be displayed in: %s" % response.content) # Edit it, can't change username response = c.post('/useradmin/users/edit/test', dict(username="******", first_name=u"Inglés", last_name=u"Español", is_superuser="******", is_active="True"), follow=True) assert_true("You cannot change a username" in response.content) # Now make sure that those were materialized response = c.get('/useradmin/users/edit/test') assert_equal(smart_unicode("Inglés"), response.context["form"].instance.first_name) assert_true("Español" in response.content) # Shouldn't be able to demote to non-superuser response = c.post('/useradmin/users/edit/test', dict(username="******", first_name=u"Inglés", last_name=u"Español", is_superuser=False, is_active=True)) assert_true("You cannot remove" in response.content, "Shouldn't be able to remove the last superuser") # Shouldn't be able to delete oneself response = c.post('/useradmin/users/delete', {u'user_ids': [user.id]}) assert_true("You cannot remove yourself" in response.content, "Shouldn't be able to delete the last superuser") # Let's try changing the password response = c.post('/useradmin/users/edit/test', dict(username="******", first_name="Tom", last_name="Tester", is_superuser=True, password1="foo", password2="foobar")) assert_equal(["Passwords do not match."], response.context["form"]["password2"].errors, "Should have complained about mismatched password") # Old password not confirmed response = c.post('/useradmin/users/edit/test', dict(username="******", first_name="Tom", last_name="Tester", password1="foo", password2="foo", is_active=True, is_superuser=True)) assert_equal(["The old password does not match the current password."], response.context["form"]["password_old"].errors, "Should have complained about old password") # Good now response = c.post('/useradmin/users/edit/test', dict(username="******", first_name="Tom", last_name="Tester", password1="foo", password2="foo", password_old="test", is_active=True, is_superuser=True)) assert_true(User.objects.get(username="******").is_superuser) assert_true(User.objects.get(username="******").check_password("foo")) # Change it back! response = c.post('/useradmin/users/edit/test', dict(username="******", first_name="Tom", last_name="Tester", password1="test", password2="test", password_old="foo", is_active="True", is_superuser="******")) assert_true(User.objects.get(username="******").check_password("test")) assert_true(make_logged_in_client(username = "******", password = "******"), "Check that we can still login.") # Check new user form for default group group = get_default_user_group() response = c.get('/useradmin/users/new') assert_true(response) assert_true(('<option value="1" selected="selected">%s</option>' % group) in str(response)) # Create a new regular user (duplicate name) response = c.post('/useradmin/users/new', dict(username="******", password1="test", password2="test")) assert_equal({ 'username': ["User with this Username already exists."]}, response.context["form"].errors) # Create a new regular user (for real) response = c.post('/useradmin/users/new', dict(username=FUNNY_NAME, password1="test", password2="test", is_active="True")) response = c.get('/useradmin/') assert_true(FUNNY_NAME_QUOTED in response.content) assert_true(len(response.context["users"]) > 1) assert_true("Hue Users" in response.content) # Validate profile is created. assert_true(UserProfile.objects.filter(user__username=FUNNY_NAME).exists()) # Need to give access to the user for the rest of the test group = Group.objects.create(name="test-group") perm = HuePermission.objects.get(app='useradmin', action='access') GroupPermission.objects.create(group=group, hue_permission=perm) # Verify that we can modify user groups through the user admin pages response = c.post('/useradmin/users/new', dict(username="******", password1="test", password2="test", groups=[group.pk])) User.objects.get(username='******') assert_true(User.objects.get(username='******').groups.filter(name='test-group').exists()) response = c.post('/useradmin/users/edit/group_member', dict(username="******", groups=[])) assert_false(User.objects.get(username='******').groups.filter(name='test-group').exists()) # Check permissions by logging in as the new user c_reg = make_logged_in_client(username=FUNNY_NAME, password="******") test_user = User.objects.get(username=FUNNY_NAME) test_user.groups.add(Group.objects.get(name="test-group")) test_user.save() # Regular user should be able to modify oneself response = c_reg.post('/useradmin/users/edit/%s' % (FUNNY_NAME_QUOTED,), dict(username = FUNNY_NAME, first_name = "Hello", is_active = True, groups=[group.id for group in test_user.groups.all()]), follow=True) assert_equal(response.status_code, 200) response = c_reg.get('/useradmin/users/edit/%s' % (FUNNY_NAME_QUOTED,), follow=True) assert_equal(response.status_code, 200) assert_equal("Hello", response.context["form"].instance.first_name) funny_user = User.objects.get(username=FUNNY_NAME) # Can't edit other people. response = c_reg.post("/useradmin/users/delete", {u'user_ids': [funny_user.id]}) assert_true("You must be a superuser" in response.content, "Regular user can't edit other people") # Revert to regular "test" user, that has superuser powers. c_su = make_logged_in_client() # Inactivate FUNNY_NAME c_su.post('/useradmin/users/edit/%s' % (FUNNY_NAME_QUOTED,), dict(username = FUNNY_NAME, first_name = "Hello", is_active = False)) # Now make sure FUNNY_NAME can't log back in response = c_reg.get('/useradmin/users/edit/%s' % (FUNNY_NAME_QUOTED,)) assert_true(response.status_code == 302 and "login" in response["location"], "Inactivated user gets redirected to login page") # Delete that regular user funny_profile = get_profile(test_user) response = c_su.post('/useradmin/users/delete', {u'user_ids': [funny_user.id]}) assert_equal(302, response.status_code) assert_false(User.objects.filter(username=FUNNY_NAME).exists()) assert_false(UserProfile.objects.filter(id=funny_profile.id).exists()) # Bulk delete users u1 = User.objects.create(username='******', password="******") u2 = User.objects.create(username='******', password="******") assert_equal(User.objects.filter(username__in=['u1', 'u2']).count(), 2) response = c_su.post('/useradmin/users/delete', {u'user_ids': [u1.id, u2.id]}) assert_equal(User.objects.filter(username__in=['u1', 'u2']).count(), 0) # Make sure that user deletion works if the user has never performed a request. funny_user = User.objects.create(username=FUNNY_NAME, password='******') assert_true(User.objects.filter(username=FUNNY_NAME).exists()) assert_false(UserProfile.objects.filter(user__username=FUNNY_NAME).exists()) response = c_su.post('/useradmin/users/delete', {u'user_ids': [funny_user.id]}) assert_equal(302, response.status_code) assert_false(User.objects.filter(username=FUNNY_NAME).exists()) assert_false(UserProfile.objects.filter(user__username=FUNNY_NAME).exists()) # You shouldn't be able to create a user without a password response = c_su.post('/useradmin/users/new', dict(username="******")) assert_true("You must specify a password when creating a new user." in response.content)
def _get_profile(self): return get_profile(self._parent)