mirror of
https://github.com/ansible/awx.git
synced 2026-03-07 19:51:08 -03:30
Disable LDAP support when not allowed by license.
This commit is contained in:
@@ -608,11 +608,12 @@ class UserSerializer(BaseSerializer):
|
|||||||
new_password = getattr(obj, '_new_password', None)
|
new_password = getattr(obj, '_new_password', None)
|
||||||
# For now we're not raising an error, just not saving password for
|
# For now we're not raising an error, just not saving password for
|
||||||
# users managed by LDAP who already have an unusable password set.
|
# users managed by LDAP who already have an unusable password set.
|
||||||
try:
|
if getattr(settings, 'AUTH_LDAP_SERVER_URI', None) and feature_enabled('ldap'):
|
||||||
if obj.pk and obj.profile.ldap_dn and not obj.has_usable_password():
|
try:
|
||||||
new_password = None
|
if obj.pk and obj.profile.ldap_dn and not obj.has_usable_password():
|
||||||
except AttributeError:
|
new_password = None
|
||||||
pass
|
except AttributeError:
|
||||||
|
pass
|
||||||
if new_password:
|
if new_password:
|
||||||
obj.set_password(new_password)
|
obj.set_password(new_password)
|
||||||
if not obj.password:
|
if not obj.password:
|
||||||
@@ -633,6 +634,8 @@ class UserSerializer(BaseSerializer):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
def _validate_ldap_managed_field(self, attrs, source):
|
def _validate_ldap_managed_field(self, attrs, source):
|
||||||
|
if not getattr(settings, 'AUTH_LDAP_SERVER_URI', None) or not feature_enabled('ldap'):
|
||||||
|
return attrs
|
||||||
try:
|
try:
|
||||||
is_ldap_user = bool(self.object.profile.ldap_dn)
|
is_ldap_user = bool(self.object.profile.ldap_dn)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class ApiV1ConfigView(APIView):
|
|||||||
# If LDAP is enabled, user_ldap_fields will return a list of field
|
# If LDAP is enabled, user_ldap_fields will return a list of field
|
||||||
# names that are managed by LDAP and should be read-only for users with
|
# names that are managed by LDAP and should be read-only for users with
|
||||||
# a non-empty ldap_dn attribute.
|
# a non-empty ldap_dn attribute.
|
||||||
if getattr(settings, 'AUTH_LDAP_SERVER_URI', None):
|
if getattr(settings, 'AUTH_LDAP_SERVER_URI', None) and feature_enabled('ldap'):
|
||||||
user_ldap_fields = ['username', 'password']
|
user_ldap_fields = ['username', 'password']
|
||||||
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_ATTR_MAP', {}).keys())
|
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_ATTR_MAP', {}).keys())
|
||||||
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_FLAGS_BY_GROUP', {}).keys())
|
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_FLAGS_BY_GROUP', {}).keys())
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ from django_auth_ldap.backend import LDAPSettings as BaseLDAPSettings
|
|||||||
from django_auth_ldap.backend import LDAPBackend as BaseLDAPBackend
|
from django_auth_ldap.backend import LDAPBackend as BaseLDAPBackend
|
||||||
from django_auth_ldap.backend import populate_user
|
from django_auth_ldap.backend import populate_user
|
||||||
|
|
||||||
|
# Ansible Tower
|
||||||
|
from awx.api.license import feature_enabled
|
||||||
|
|
||||||
class LDAPSettings(BaseLDAPSettings):
|
class LDAPSettings(BaseLDAPSettings):
|
||||||
|
|
||||||
defaults = dict(BaseLDAPSettings.defaults.items() + {
|
defaults = dict(BaseLDAPSettings.defaults.items() + {
|
||||||
@@ -34,12 +37,12 @@ class LDAPBackend(BaseLDAPBackend):
|
|||||||
settings = property(_get_settings, _set_settings)
|
settings = property(_get_settings, _set_settings)
|
||||||
|
|
||||||
def authenticate(self, username, password):
|
def authenticate(self, username, password):
|
||||||
if not self.settings.SERVER_URI:
|
if not self.settings.SERVER_URI or not feature_enabled('ldap'):
|
||||||
return None
|
return None
|
||||||
return super(LDAPBackend, self).authenticate(username, password)
|
return super(LDAPBackend, self).authenticate(username, password)
|
||||||
|
|
||||||
def get_user(self, user_id):
|
def get_user(self, user_id):
|
||||||
if not self.settings.SERVER_URI:
|
if not self.settings.SERVER_URI or not feature_enabled('ldap'):
|
||||||
return None
|
return None
|
||||||
return super(LDAPBackend, self).get_user(user_id)
|
return super(LDAPBackend, self).get_user(user_id)
|
||||||
|
|
||||||
|
|||||||
@@ -860,6 +860,7 @@ class LdapTest(BaseTest):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(LdapTest, self).setUp()
|
super(LdapTest, self).setUp()
|
||||||
|
self.create_test_license_file(features={'ldap': True})
|
||||||
# Skip tests if basic LDAP test settings aren't defined.
|
# Skip tests if basic LDAP test settings aren't defined.
|
||||||
if not getattr(settings, 'TEST_AUTH_LDAP_SERVER_URI', None):
|
if not getattr(settings, 'TEST_AUTH_LDAP_SERVER_URI', None):
|
||||||
self.skipTest('no test LDAP auth server defined')
|
self.skipTest('no test LDAP auth server defined')
|
||||||
@@ -933,6 +934,15 @@ class LdapTest(BaseTest):
|
|||||||
user = self.check_login()
|
user = self.check_login()
|
||||||
for attr in settings.AUTH_LDAP_USER_FLAGS_BY_GROUP.keys():
|
for attr in settings.AUTH_LDAP_USER_FLAGS_BY_GROUP.keys():
|
||||||
self.assertTrue(getattr(user, attr))
|
self.assertTrue(getattr(user, attr))
|
||||||
|
# Check that LDAP login fails when not enabled by license, but using a
|
||||||
|
# local password will work in either case.
|
||||||
|
user.set_password('local pass')
|
||||||
|
user.save()
|
||||||
|
self.check_login()
|
||||||
|
self.check_login(password='local pass')
|
||||||
|
self.create_test_license_file(features={'ldap': False})
|
||||||
|
self.check_login(should_fail=True)
|
||||||
|
self.check_login(password='local pass')
|
||||||
|
|
||||||
def test_ldap_organization_mapping(self):
|
def test_ldap_organization_mapping(self):
|
||||||
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
||||||
@@ -1014,25 +1024,25 @@ class LdapTest(BaseTest):
|
|||||||
self.use_test_setting(name)
|
self.use_test_setting(name)
|
||||||
user = self.check_login()
|
user = self.check_login()
|
||||||
self.setup_users()
|
self.setup_users()
|
||||||
url = reverse('api:api_v1_config_view')
|
config_url = reverse('api:api_v1_config_view')
|
||||||
with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
response = self.get(url, expect=200)
|
response = self.get(config_url, expect=200)
|
||||||
user_ldap_fields = response.get('user_ldap_fields', [])
|
user_ldap_fields = response.get('user_ldap_fields', [])
|
||||||
self.assertTrue(user_ldap_fields)
|
self.assertTrue(user_ldap_fields)
|
||||||
url = reverse('api:user_detail', args=(user.pk,))
|
user_url = reverse('api:user_detail', args=(user.pk,))
|
||||||
for user_field in user_ldap_fields:
|
for user_field in user_ldap_fields:
|
||||||
with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
data = self.get(url, expect=200)
|
data = self.get(user_url, expect=200)
|
||||||
if user_field == 'password':
|
if user_field == 'password':
|
||||||
data[user_field] = 'my new password'
|
data[user_field] = 'my new password'
|
||||||
with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
self.put(url, data, expect=200)
|
self.put(user_url, data, expect=200)
|
||||||
|
user = User.objects.get(pk=user.pk)
|
||||||
|
self.assertFalse(user.has_usable_password())
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
self.patch(user_url, {'password': 'try again'}, expect=200)
|
||||||
user = User.objects.get(pk=user.pk)
|
user = User.objects.get(pk=user.pk)
|
||||||
self.assertFalse(user.has_usable_password())
|
self.assertFalse(user.has_usable_password())
|
||||||
#with self.current_user(self.super_django_user):
|
|
||||||
# self.patch(url, {'password': 'try again'}, expect=200)
|
|
||||||
#user = User.objects.get(pk=user.pk)
|
|
||||||
#self.assertFalse(user.has_usable_password())
|
|
||||||
elif user_field in data:
|
elif user_field in data:
|
||||||
value = data[user_field]
|
value = data[user_field]
|
||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
@@ -1041,7 +1051,40 @@ class LdapTest(BaseTest):
|
|||||||
value = unicode(value).upper()
|
value = unicode(value).upper()
|
||||||
data[user_field] = value
|
data[user_field] = value
|
||||||
with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
self.put(url, data, expect=400)
|
self.put(user_url, data, expect=400)
|
||||||
#patch_data = {user_field: data[user_field]}
|
patch_data = {user_field: data[user_field]}
|
||||||
#with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
# self.patch(url, patch_data, expect=400)
|
self.patch(user_url, patch_data, expect=400)
|
||||||
|
# Install a license with LDAP disabled; ldap fields should not be in
|
||||||
|
# config and all user fields should be changeable.
|
||||||
|
self.create_test_license_file(features={'ldap': False})
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
response = self.get(config_url, expect=200)
|
||||||
|
self.assertFalse('user_ldap_fields' in response)
|
||||||
|
for user_field in user_ldap_fields:
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
data = self.get(user_url, expect=200)
|
||||||
|
if user_field == 'password':
|
||||||
|
data[user_field] = 'my new password'
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
self.put(user_url, data, expect=200)
|
||||||
|
user = User.objects.get(pk=user.pk)
|
||||||
|
self.assertTrue(user.has_usable_password())
|
||||||
|
self.assertTrue(user.check_password, 'my new password')
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
self.patch(user_url, {'password': 'try again'}, expect=200)
|
||||||
|
user = User.objects.get(pk=user.pk)
|
||||||
|
self.assertTrue(user.has_usable_password())
|
||||||
|
self.assertTrue(user.check_password, 'try again')
|
||||||
|
elif user_field in data:
|
||||||
|
value = data[user_field]
|
||||||
|
if isinstance(value, bool):
|
||||||
|
value = not value
|
||||||
|
else:
|
||||||
|
value = unicode(value).upper()
|
||||||
|
data[user_field] = value
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
self.put(user_url, data, expect=200)
|
||||||
|
patch_data = {user_field: data[user_field]}
|
||||||
|
with self.current_user(self.super_django_user):
|
||||||
|
self.patch(user_url, patch_data, expect=200)
|
||||||
|
|||||||
Reference in New Issue
Block a user