diff --git a/awx/main/models/organization.py b/awx/main/models/organization.py index 6dc92a06ac..f15ed9a859 100644 --- a/awx/main/models/organization.py +++ b/awx/main/models/organization.py @@ -114,6 +114,13 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi def _get_related_jobs(self): return UnifiedJob.objects.non_polymorphic().filter(organization=self) + def create_default_galaxy_credential(self): + from awx.main.models import Credential + + public_galaxy_credential = Credential.objects.filter(managed_by_tower=True, name='Ansible Galaxy').first() + if public_galaxy_credential not in self.galaxy_credentials.all(): + self.galaxy_credentials.add(public_galaxy_credential) + class OrganizationGalaxyCredentialMembership(models.Model): diff --git a/awx/sso/pipeline.py b/awx/sso/pipeline.py index 70adbc520a..5e95aa3fbe 100644 --- a/awx/sso/pipeline.py +++ b/awx/sso/pipeline.py @@ -87,6 +87,7 @@ def _update_org_from_attr(user, related, attr, remove, remove_admins, remove_aud try: if settings.SAML_AUTO_CREATE_OBJECTS: org = Organization.objects.get_or_create(name=org_name)[0] + org.create_default_galaxy_credential() else: org = Organization.objects.get(name=org_name) except ObjectDoesNotExist: @@ -117,6 +118,7 @@ def update_user_orgs(backend, details, user=None, *args, **kwargs): org_map = backend.setting('ORGANIZATION_MAP') or {} for org_name, org_opts in org_map.items(): org = Organization.objects.get_or_create(name=org_name)[0] + org.create_default_galaxy_credential() # Update org admins from expression(s). remove = bool(org_opts.get('remove', True)) @@ -145,6 +147,7 @@ def update_user_teams(backend, details, user=None, *args, **kwargs): if 'organization' not in team_opts: continue org = Organization.objects.get_or_create(name=team_opts['organization'])[0] + org.create_default_galaxy_credential() # Update team members from expression(s). team = Team.objects.get_or_create(name=team_name, organization=org)[0] @@ -205,6 +208,7 @@ def update_user_teams_by_saml_attr(backend, details, user=None, *args, **kwargs) try: if settings.SAML_AUTO_CREATE_OBJECTS: org = Organization.objects.get_or_create(name=organization_name)[0] + org.create_default_galaxy_credential() else: org = Organization.objects.get(name=organization_name) except ObjectDoesNotExist: diff --git a/awx/sso/tests/functional/test_pipeline.py b/awx/sso/tests/functional/test_pipeline.py index 489113a952..36247c4b11 100644 --- a/awx/sso/tests/functional/test_pipeline.py +++ b/awx/sso/tests/functional/test_pipeline.py @@ -2,9 +2,20 @@ import pytest import re from unittest import mock +from django.utils.timezone import now + from awx.sso.pipeline import update_user_orgs, update_user_teams, update_user_orgs_by_saml_attr, update_user_teams_by_saml_attr -from awx.main.models import User, Team, Organization +from awx.main.models import User, Team, Organization, Credential, CredentialType + + +@pytest.fixture +def galaxy_credential(): + galaxy_type = CredentialType.objects.create(kind='galaxy') + cred = Credential( + created=now(), modified=now(), name='Ansible Galaxy', managed_by_tower=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} + ) + cred.save() @pytest.fixture @@ -34,7 +45,7 @@ class TestSAMLMap: def org(self): return Organization.objects.create(name="Default") - def test_update_user_orgs(self, org, backend, users): + def test_update_user_orgs(self, org, backend, users, galaxy_credential): u1, u2, u3 = users # Test user membership logic with regular expressions @@ -66,7 +77,11 @@ class TestSAMLMap: assert org.admin_role.members.count() == 2 assert org.member_role.members.count() == 2 - def test_update_user_teams(self, backend, users): + for o in Organization.objects.all(): + assert o.galaxy_credentials.count() == 1 + assert o.galaxy_credentials.first().name == 'Ansible Galaxy' + + def test_update_user_teams(self, backend, users, galaxy_credential): u1, u2, u3 = users # Test user membership logic with regular expressions @@ -100,6 +115,10 @@ class TestSAMLMap: assert Team.objects.get(name="Red").member_role.members.count() == 2 assert Team.objects.get(name="Blue").member_role.members.count() == 2 + for o in Organization.objects.all(): + assert o.galaxy_credentials.count() == 1 + assert o.galaxy_credentials.first().name == 'Ansible Galaxy' + @pytest.mark.django_db class TestSAMLAttr: @@ -172,7 +191,7 @@ class TestSAMLAttr: return MockSettings() - def test_update_user_orgs_by_saml_attr(self, orgs, users, kwargs, mock_settings): + def test_update_user_orgs_by_saml_attr(self, orgs, users, galaxy_credential, kwargs, mock_settings): with mock.patch('django.conf.settings', mock_settings): o1, o2, o3 = orgs u1, u2, u3 = users @@ -205,7 +224,11 @@ class TestSAMLAttr: assert o2.member_role.members.count() == 3 assert o3.member_role.members.count() == 1 - def test_update_user_teams_by_saml_attr(self, orgs, users, kwargs, mock_settings): + for o in Organization.objects.all(): + assert o.galaxy_credentials.count() == 1 + assert o.galaxy_credentials.first().name == 'Ansible Galaxy' + + def test_update_user_teams_by_saml_attr(self, orgs, users, galaxy_credential, kwargs, mock_settings): with mock.patch('django.conf.settings', mock_settings): o1, o2, o3 = orgs u1, u2, u3 = users @@ -260,7 +283,11 @@ class TestSAMLAttr: 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 - def test_update_user_teams_alias_by_saml_attr(self, orgs, users, kwargs, mock_settings): + for o in Organization.objects.all(): + assert o.galaxy_credentials.count() == 1 + assert o.galaxy_credentials.first().name == 'Ansible Galaxy' + + def test_update_user_teams_alias_by_saml_attr(self, orgs, users, galaxy_credential, kwargs, mock_settings): with mock.patch('django.conf.settings', mock_settings): u1 = users[0] @@ -274,6 +301,11 @@ class TestSAMLAttr: assert Team.objects.filter(name='Yellow_Alias', organization__name='Default4_Alias').count() == 1 assert Team.objects.get(name='Yellow_Alias', organization__name='Default4_Alias').member_role.members.count() == 1 + # only Org 4 got created/updated + org = Organization.objects.get(name='Default4_Alias') + assert org.galaxy_credentials.count() == 1 + assert org.galaxy_credentials.first().name == 'Ansible Galaxy' + @pytest.mark.fixture_args(autocreate=False) def test_autocreate_disabled(self, users, kwargs, mock_settings): kwargs['response']['attributes']['memberOf'] = ['Default1', 'Default2', 'Default3'] @@ -312,3 +344,16 @@ class TestSAMLAttr: 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 + + def test_galaxy_credential_auto_assign(self, users, kwargs, galaxy_credential, 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() == 4 + for o in Organization.objects.all(): + assert o.galaxy_credentials.count() == 1 + assert o.galaxy_credentials.first().name == 'Ansible Galaxy'