mirror of
https://github.com/ansible/awx.git
synced 2024-11-02 01:21:21 +03:00
AC-448 Add support for mapping LDAP users to teams based on LDAP group membership.
This commit is contained in:
parent
e8b0d7451e
commit
7eed13cca4
@ -13,6 +13,7 @@ class LDAPSettings(BaseLDAPSettings):
|
||||
|
||||
defaults = dict(BaseLDAPSettings.defaults.items() + {
|
||||
'ORGANIZATION_MAP': {},
|
||||
'TEAM_MAP': {},
|
||||
}.items())
|
||||
|
||||
class LDAPBackend(BaseLDAPBackend):
|
||||
@ -83,10 +84,10 @@ def _update_m2m_from_groups(user, ldap_user, rel, opts, remove=False):
|
||||
@receiver(populate_user)
|
||||
def on_populate_user(sender, **kwargs):
|
||||
'''
|
||||
Handle signal from LDAP backend to populate the user object. Update user's
|
||||
organization membership according to their LDAP groups.
|
||||
Handle signal from LDAP backend to populate the user object. Update user
|
||||
organization/team memberships according to their LDAP groups.
|
||||
'''
|
||||
from awx.main.models import Organization
|
||||
from awx.main.models import Organization, Team
|
||||
user = kwargs['user']
|
||||
ldap_user = kwargs['ldap_user']
|
||||
backend = ldap_user.backend
|
||||
@ -105,6 +106,18 @@ def on_populate_user(sender, **kwargs):
|
||||
_update_m2m_from_groups(user, ldap_user, org.users, users_opts,
|
||||
remove_users)
|
||||
|
||||
# Update team membership based on group memberships.
|
||||
team_map = getattr(backend.settings, 'TEAM_MAP', {})
|
||||
for team_name, team_opts in team_map.items():
|
||||
if 'organization' not in team_opts:
|
||||
continue
|
||||
org, created = Organization.objects.get_or_create(name=team_opts['organization'])
|
||||
team, created = Team.objects.get_or_create(name=team_name, organization=org)
|
||||
users_opts = team_opts.get('users', None)
|
||||
remove = bool(team_opts.get('remove', False))
|
||||
_update_m2m_from_groups(user, ldap_user, team.users, users_opts,
|
||||
remove)
|
||||
|
||||
# Update user profile to store LDAP DN.
|
||||
profile = user.profile
|
||||
if profile.ldap_dn != ldap_user.dn:
|
||||
|
@ -854,6 +854,39 @@ class LdapTest(BaseTest):
|
||||
else:
|
||||
self.assertFalse(user in org.users.all())
|
||||
|
||||
def test_ldap_team_mapping(self):
|
||||
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
||||
'GROUP_SEARCH', 'GROUP_TYPE', 'USER_FLAGS_BY_GROUP'):
|
||||
self.use_test_setting(name)
|
||||
self.assertEqual(User.objects.filter(username=self.ldap_username).count(), 0)
|
||||
self.use_test_setting('TEAM_MAP', {})
|
||||
self.use_test_setting('TEAM_MAP_RESULT', {})
|
||||
for team_name, team_opts in settings.AUTH_LDAP_TEAM_MAP.items():
|
||||
self.assertEqual(Team.objects.filter(name=team_name).count(), 0)
|
||||
self.assertEqual(Organization.objects.filter(name=team_opts['organization']).count(), 0)
|
||||
user = self.check_login()
|
||||
for team_name, team_opts in settings.AUTH_LDAP_TEAM_MAP.items():
|
||||
self.assertEqual(Team.objects.filter(name=team_name, organization__name=team_opts['organization']).count(), 1)
|
||||
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
||||
team = Team.objects.get(name=team_name)
|
||||
if team_result.get('users', False):
|
||||
self.assertTrue(user in team.users.all())
|
||||
else:
|
||||
self.assertFalse(user in team.users.all())
|
||||
# Try again with different test mapping.
|
||||
self.use_test_setting('TEAM_MAP', {}, from_name='TEAM_MAP_2')
|
||||
self.use_test_setting('TEAM_MAP_RESULT', {},
|
||||
from_name='TEAM_MAP_2_RESULT')
|
||||
user = self.check_login()
|
||||
for team_name, team_opts in settings.AUTH_LDAP_TEAM_MAP.items():
|
||||
self.assertEqual(Team.objects.filter(name=team_name, organization__name=team_opts['organization']).count(), 1)
|
||||
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
||||
team = Team.objects.get(name=team_name)
|
||||
if team_result.get('users', False):
|
||||
self.assertTrue(user in team.users.all())
|
||||
else:
|
||||
self.assertFalse(user in team.users.all())
|
||||
|
||||
def test_prevent_changing_ldap_user_fields(self):
|
||||
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
||||
'GROUP_SEARCH', 'GROUP_TYPE', 'USER_FLAGS_BY_GROUP'):
|
||||
|
@ -234,7 +234,7 @@ AUTH_LDAP_USER_FLAGS_BY_GROUP = {
|
||||
# If True/False, all LDAP users will be added/removed as admins.
|
||||
# If a string or list of strings, specifies the group DN(s). User will be
|
||||
# added as an org admin if the user is a member of ANY of these groups.
|
||||
# - remove_admins: True/False. Defaults to False. If True, a user who is not an
|
||||
# - remove_admins: True/False. Defaults to False. If True, a user who is not a
|
||||
# member of the given groups will be removed from the organization's admins.
|
||||
# - users: None, True/False, string or list/tuple of strings. Same rules apply
|
||||
# as for admins.
|
||||
@ -251,6 +251,33 @@ AUTH_LDAP_ORGANIZATION_MAP = {
|
||||
#},
|
||||
}
|
||||
|
||||
# Mapping between team members (users) and LDAP groups. Keys are team names
|
||||
# (will be created if not present). Values are dictionaries of options for
|
||||
# each team's membership, where each can contain the following parameters:
|
||||
# - organization: string. The name of the organization to which the team
|
||||
# belongs. The team will be created if the combination of organization and
|
||||
# team name does not exist. The organization will first be created if it
|
||||
# does not exist.
|
||||
# - users: None, True/False, string or list/tuple of strings.
|
||||
# If None, team members will not be updated.
|
||||
# If True/False, all LDAP users will be added/removed as team members.
|
||||
# If a string or list of strings, specifies the group DN(s). User will be
|
||||
# added as a team member if the user is a member of ANY of these groups.
|
||||
# - remove: True/False. Defaults to False. If True, a user who is not a member
|
||||
# of the given groups will be removed from the team.
|
||||
AUTH_LDAP_TEAM_MAP = {
|
||||
'My Team': {
|
||||
'organization': 'Test Org',
|
||||
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
|
||||
'remove': True,
|
||||
},
|
||||
'Other Team': {
|
||||
'organization': 'Test Org 2',
|
||||
'users': 'CN=Other Users,CN=Users,DC=example,DC=com',
|
||||
'remove': False,
|
||||
},
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# SCM TEST SETTINGS
|
||||
###############################################################################
|
||||
@ -387,6 +414,57 @@ TEST_AUTH_LDAP_ORGANIZATION_MAP_2_RESULT = {
|
||||
'Test Org 2': {'admins': True, 'users': False},
|
||||
}
|
||||
|
||||
# Test mapping between team users and LDAP groups.
|
||||
TEST_AUTH_LDAP_TEAM_MAP = {
|
||||
'Domain Users Team': {
|
||||
'organization': 'Test Org',
|
||||
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
|
||||
'remove': False,
|
||||
},
|
||||
'Admins Team': {
|
||||
'organization': 'Admins Org',
|
||||
'users': 'CN=Domain Admins,CN=Users,DC=example,DC=com',
|
||||
'remove': True,
|
||||
},
|
||||
'Everyone Team': {
|
||||
'organization': 'Test Org 2',
|
||||
'users': True,
|
||||
},
|
||||
}
|
||||
# Expected results from team mapping. After login, should user be a member of
|
||||
# the given team?
|
||||
TEST_AUTH_LDAP_TEAM_MAP_RESULT = {
|
||||
'Domain Users Team': {'users': False},
|
||||
'Admins Team': {'users': True},
|
||||
'Everyone Team': {'users': True},
|
||||
}
|
||||
|
||||
# Second test mapping for teams to remove user.
|
||||
TEST_AUTH_LDAP_TEAM_MAP_2 = {
|
||||
'Domain Users Team': {
|
||||
'organization': 'Test Org',
|
||||
'users': ['CN=Domain Users,CN=Users,DC=example,DC=com'],
|
||||
'remove': False,
|
||||
},
|
||||
'Admins Team': {
|
||||
'organization': 'Admins Org',
|
||||
'users': 'CN=Administrators,CN=Builtin,DC=example,DC=com',
|
||||
'remove': True,
|
||||
},
|
||||
'Everyone Team': {
|
||||
'organization': 'Test Org 2',
|
||||
'users': False,
|
||||
'remove': False,
|
||||
},
|
||||
}
|
||||
# Expected results from second team mapping. After login, should user be a
|
||||
# member of the given team?
|
||||
TEST_AUTH_LDAP_TEAM_MAP_2_RESULT = {
|
||||
'Domain Users Team': {'users': False},
|
||||
'Admins Team': {'users': False},
|
||||
'Everyone Team': {'users': True},
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# INVENTORY IMPORT TEST SETTINGS
|
||||
###############################################################################
|
||||
|
Loading…
Reference in New Issue
Block a user