mirror of
https://github.com/ansible/awx.git
synced 2026-03-06 03:01:06 -03:30
Merge pull request #8069 from ryanpetrello/saml-autopop
add the ability to prevent SAML auto-population behavior Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -477,6 +477,7 @@ SOCIAL_AUTH_SAML_PIPELINE = _SOCIAL_AUTH_PIPELINE_BASE + (
|
|||||||
'awx.sso.pipeline.update_user_orgs',
|
'awx.sso.pipeline.update_user_orgs',
|
||||||
'awx.sso.pipeline.update_user_teams',
|
'awx.sso.pipeline.update_user_teams',
|
||||||
)
|
)
|
||||||
|
SAML_AUTO_CREATE_OBJECTS = True
|
||||||
|
|
||||||
SOCIAL_AUTH_LOGIN_URL = '/'
|
SOCIAL_AUTH_LOGIN_URL = '/'
|
||||||
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/sso/complete/'
|
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/sso/complete/'
|
||||||
|
|||||||
@@ -919,6 +919,17 @@ def get_saml_entity_id():
|
|||||||
return settings.TOWER_URL_BASE
|
return settings.TOWER_URL_BASE
|
||||||
|
|
||||||
|
|
||||||
|
register(
|
||||||
|
'SAML_AUTO_CREATE_OBJECTS',
|
||||||
|
field_class=fields.BooleanField,
|
||||||
|
default=True,
|
||||||
|
label=_('Automatically Create Organizations and Teams on SAML Login'),
|
||||||
|
help_text=_('When enabled (the default), mapped Organizations and Teams '
|
||||||
|
'will be created automatically on successful SAML login.'),
|
||||||
|
category=_('SAML'),
|
||||||
|
category_slug='saml',
|
||||||
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
'SOCIAL_AUTH_SAML_CALLBACK_URL',
|
'SOCIAL_AUTH_SAML_CALLBACK_URL',
|
||||||
field_class=fields.CharField,
|
field_class=fields.CharField,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import logging
|
|||||||
from social_core.exceptions import AuthException
|
from social_core.exceptions import AuthException
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
@@ -80,11 +81,18 @@ def _update_m2m_from_expression(user, related, expr, remove=True):
|
|||||||
|
|
||||||
def _update_org_from_attr(user, related, attr, remove, remove_admins, remove_auditors):
|
def _update_org_from_attr(user, related, attr, remove, remove_admins, remove_auditors):
|
||||||
from awx.main.models import Organization
|
from awx.main.models import Organization
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
org_ids = []
|
org_ids = []
|
||||||
|
|
||||||
for org_name in attr:
|
for org_name in attr:
|
||||||
org = Organization.objects.get_or_create(name=org_name)[0]
|
try:
|
||||||
|
if settings.SAML_AUTO_CREATE_OBJECTS:
|
||||||
|
org = Organization.objects.get_or_create(name=org_name)[0]
|
||||||
|
else:
|
||||||
|
org = Organization.objects.get(name=org_name)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
org_ids.append(org.id)
|
org_ids.append(org.id)
|
||||||
getattr(org, related).members.add(user)
|
getattr(org, related).members.add(user)
|
||||||
@@ -199,11 +207,24 @@ def update_user_teams_by_saml_attr(backend, details, user=None, *args, **kwargs)
|
|||||||
|
|
||||||
if organization_alias:
|
if organization_alias:
|
||||||
organization_name = organization_alias
|
organization_name = organization_alias
|
||||||
org = Organization.objects.get_or_create(name=organization_name)[0]
|
|
||||||
|
try:
|
||||||
|
if settings.SAML_AUTO_CREATE_OBJECTS:
|
||||||
|
org = Organization.objects.get_or_create(name=organization_name)[0]
|
||||||
|
else:
|
||||||
|
org = Organization.objects.get(name=organization_name)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
if team_alias:
|
if team_alias:
|
||||||
team_name = team_alias
|
team_name = team_alias
|
||||||
team = Team.objects.get_or_create(name=team_name, organization=org)[0]
|
try:
|
||||||
|
if settings.SAML_AUTO_CREATE_OBJECTS:
|
||||||
|
team = Team.objects.get_or_create(name=team_name, organization=org)[0]
|
||||||
|
else:
|
||||||
|
team = Team.objects.get(name=team_name, organization=org)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
team_ids.append(team.id)
|
team_ids.append(team.id)
|
||||||
team.member_role.members.add(user)
|
team.member_role.members.add(user)
|
||||||
|
|||||||
@@ -174,8 +174,15 @@ class TestSAMLAttr():
|
|||||||
return (o1, o2, o3)
|
return (o1, o2, o3)
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_settings(self):
|
def mock_settings(self, request):
|
||||||
|
fixture_args = request.node.get_closest_marker('fixture_args')
|
||||||
|
if fixture_args and 'autocreate' in fixture_args.kwargs:
|
||||||
|
autocreate = fixture_args.kwargs['autocreate']
|
||||||
|
else:
|
||||||
|
autocreate = True
|
||||||
|
|
||||||
class MockSettings():
|
class MockSettings():
|
||||||
|
SAML_AUTO_CREATE_OBJECTS = autocreate
|
||||||
SOCIAL_AUTH_SAML_ORGANIZATION_ATTR = {
|
SOCIAL_AUTH_SAML_ORGANIZATION_ATTR = {
|
||||||
'saml_attr': 'memberOf',
|
'saml_attr': 'memberOf',
|
||||||
'saml_admin_attr': 'admins',
|
'saml_admin_attr': 'admins',
|
||||||
@@ -304,3 +311,41 @@ class TestSAMLAttr():
|
|||||||
assert Team.objects.get(
|
assert Team.objects.get(
|
||||||
name='Yellow_Alias', organization__name='Default4_Alias').member_role.members.count() == 1
|
name='Yellow_Alias', organization__name='Default4_Alias').member_role.members.count() == 1
|
||||||
|
|
||||||
|
@pytest.mark.fixture_args(autocreate=False)
|
||||||
|
def test_autocreate_disabled(self, users, kwargs, mock_settings):
|
||||||
|
kwargs['response']['attributes']['memberOf'] = ['Default1', 'Default2', 'Default3']
|
||||||
|
kwargs['response']['attributes']['groups'] = ['Blue', 'Red', 'Green']
|
||||||
|
with mock.patch('django.conf.settings', mock_settings):
|
||||||
|
for u in users:
|
||||||
|
update_user_orgs_by_saml_attr(None, None, u, **kwargs)
|
||||||
|
update_user_teams_by_saml_attr(None, None, u, **kwargs)
|
||||||
|
assert Organization.objects.count() == 0
|
||||||
|
assert Team.objects.count() == 0
|
||||||
|
|
||||||
|
# precreate everything
|
||||||
|
o1 = Organization.objects.create(name='Default1')
|
||||||
|
o2 = Organization.objects.create(name='Default2')
|
||||||
|
o3 = Organization.objects.create(name='Default3')
|
||||||
|
Team.objects.create(name='Blue', organization_id=o1.id)
|
||||||
|
Team.objects.create(name='Blue', organization_id=o2.id)
|
||||||
|
Team.objects.create(name='Blue', organization_id=o3.id)
|
||||||
|
Team.objects.create(name='Red', organization_id=o1.id)
|
||||||
|
Team.objects.create(name='Green', organization_id=o1.id)
|
||||||
|
Team.objects.create(name='Green', organization_id=o3.id)
|
||||||
|
|
||||||
|
for u in users:
|
||||||
|
update_user_orgs_by_saml_attr(None, None, u, **kwargs)
|
||||||
|
update_user_teams_by_saml_attr(None, None, u, **kwargs)
|
||||||
|
|
||||||
|
assert o1.member_role.members.count() == 3
|
||||||
|
assert o2.member_role.members.count() == 3
|
||||||
|
assert o3.member_role.members.count() == 3
|
||||||
|
|
||||||
|
assert Team.objects.get(name='Blue', organization__name='Default1').member_role.members.count() == 3
|
||||||
|
assert Team.objects.get(name='Blue', organization__name='Default2').member_role.members.count() == 3
|
||||||
|
assert Team.objects.get(name='Blue', organization__name='Default3').member_role.members.count() == 3
|
||||||
|
|
||||||
|
assert Team.objects.get(name='Red', organization__name='Default1').member_role.members.count() == 3
|
||||||
|
|
||||||
|
assert Team.objects.get(name='Green', organization__name='Default1').member_role.members.count() == 3
|
||||||
|
assert Team.objects.get(name='Green', organization__name='Default3').member_role.members.count() == 3
|
||||||
|
|||||||
Reference in New Issue
Block a user