From 3575b32eab84b9586e91a92c904e8132abf5d282 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 11:35:30 -0400 Subject: [PATCH 01/10] Credential should have a unique org,kind,name --- awx/main/models/credential.py | 1 + 1 file changed, 1 insertion(+) diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index 8540be2ade..34a5b578b0 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -61,6 +61,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin): class Meta: app_label = 'main' ordering = ('kind', 'name') + unique_together = (('organization', 'name', 'kind'),) deprecated_user = models.ForeignKey( 'auth.User', From 14d67d560e9cb09656cf262d9d0ac32d57a93b8d Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 11:35:51 -0400 Subject: [PATCH 02/10] add Credential migration for unique_together --- .../migrations/0026_v300_credential_unique.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 awx/main/migrations/0026_v300_credential_unique.py diff --git a/awx/main/migrations/0026_v300_credential_unique.py b/awx/main/migrations/0026_v300_credential_unique.py new file mode 100644 index 0000000000..9ac4f06cc9 --- /dev/null +++ b/awx/main/migrations/0026_v300_credential_unique.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0025_v300_update_rbac_parents'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='credential', + unique_together=set([('organization', 'name', 'kind')]), + ), + ] From bc457ccef6608de7103b1702bd9cd490930c1325 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 11:36:31 -0400 Subject: [PATCH 03/10] assert Credential unique_togehter works --- awx/main/tests/functional/test_credential.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 awx/main/tests/functional/test_credential.py diff --git a/awx/main/tests/functional/test_credential.py b/awx/main/tests/functional/test_credential.py new file mode 100644 index 0000000000..7ed76fdd62 --- /dev/null +++ b/awx/main/tests/functional/test_credential.py @@ -0,0 +1,15 @@ +import pytest + +from django.db import IntegrityError +from awx.main.models import Credential + +@pytest.mark.django_db +def test_cred_unique_org_name_kind(organization_factory): + objects = organization_factory("test") + + cred = Credential(name="test", kind="net", organization=objects.organization) + cred.save() + + with pytest.raises(IntegrityError): + cred = Credential(name="test", kind="net", organization=objects.organization) + cred.save() From 4799b2710809fda5b0997991f10bb6019219f41f Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 13:07:58 -0400 Subject: [PATCH 04/10] ensure organization is empty when generating a new credential --- awx/main/migrations/_rbac.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awx/main/migrations/_rbac.py b/awx/main/migrations/_rbac.py index 0b3c3ccc37..ce271c8de3 100644 --- a/awx/main/migrations/_rbac.py +++ b/awx/main/migrations/_rbac.py @@ -162,9 +162,10 @@ def _discover_credentials(instances, cred, orgfunc): else: # Create a new credential cred.pk = None + cred.organization = None cred.save() - cred.owner_role, cred.use_role, cred.organization = None, None, None + cred.owner_role, cred.use_role = None, None for i in orgs[org]: i.credential = cred From 51150ce7fc8c4c22ee7f5c2cc2b287df0812a6a2 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 14:17:16 -0400 Subject: [PATCH 05/10] renaming test so pytest collector stops getting confused --- .../functional/{test_credential.py => test_db_credential.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename awx/main/tests/functional/{test_credential.py => test_db_credential.py} (100%) diff --git a/awx/main/tests/functional/test_credential.py b/awx/main/tests/functional/test_db_credential.py similarity index 100% rename from awx/main/tests/functional/test_credential.py rename to awx/main/tests/functional/test_db_credential.py From c7cf954476b5747cd8eec80892cbc014188bd7de Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 14:43:40 -0400 Subject: [PATCH 06/10] ensure org auditor can see org credentials --- awx/main/models/credential.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index 34a5b578b0..89647c873a 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -226,7 +226,8 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin): read_role = ImplicitRoleField(parent_role=[ 'singleton:' + ROLE_SINGLETON_SYSTEM_AUDITOR, 'use_role', - 'owner_role' + 'owner_role', + 'organization.auditor_role', ]) @property From 868b6b7e36989cc1d745ace8edd311d84ae013fc Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 14:44:04 -0400 Subject: [PATCH 07/10] add migration for read_role parents of credential --- awx/main/migrations/0026_v300_credential_unique.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/awx/main/migrations/0026_v300_credential_unique.py b/awx/main/migrations/0026_v300_credential_unique.py index 9ac4f06cc9..dae3a308e0 100644 --- a/awx/main/migrations/0026_v300_credential_unique.py +++ b/awx/main/migrations/0026_v300_credential_unique.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations, models - +from awx.main.migrations import _rbac as rbac +from django.db import migrations +import awx.main.fields class Migration(migrations.Migration): @@ -15,4 +16,10 @@ class Migration(migrations.Migration): name='credential', unique_together=set([('organization', 'name', 'kind')]), ), + migrations.AlterField( + model_name='credential', + name='read_role', + field=awx.main.fields.ImplicitRoleField(related_name='+', parent_role=[b'singleton:system_auditor', b'use_role', b'owner_role', b'organization.auditor_role'], to='main.Role', null=b'True'), + ), + migrations.RunPython(rbac.rebuild_role_hierarchy), ] From b4148313a00c91b06880de6e4500b33eba0ede9f Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 16:07:11 -0400 Subject: [PATCH 08/10] org auditor should be able to read credential --- awx/main/models/credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index 89647c873a..824493e8ac 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -225,9 +225,9 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin): ) read_role = ImplicitRoleField(parent_role=[ 'singleton:' + ROLE_SINGLETON_SYSTEM_AUDITOR, + 'organization.auditor_role', 'use_role', 'owner_role', - 'organization.auditor_role', ]) @property From dab3440275b7758cdba553a15e2bc79b69633a0a Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 16:07:47 -0400 Subject: [PATCH 09/10] assert org.auditor can read org credentials --- awx/main/tests/functional/test_rbac_credential.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/awx/main/tests/functional/test_rbac_credential.py b/awx/main/tests/functional/test_rbac_credential.py index a42c5b489d..83661932d4 100644 --- a/awx/main/tests/functional/test_rbac_credential.py +++ b/awx/main/tests/functional/test_rbac_credential.py @@ -64,6 +64,17 @@ def test_credential_access_superuser(): assert access.can_change(credential, None) assert access.can_delete(credential) +@pytest.mark.django_db +def test_credential_access_auditor(credential, organization_factory): + objects = organization_factory("org_cred_auditor", + users=["user1"], + roles=['org_cred_auditor.auditor_role:user1']) + credential.organization = objects.organization + credential.save() + + access = CredentialAccess(objects.users.user1) + assert access.can_read(credential) + @pytest.mark.django_db def test_credential_access_admin(user, team, credential): u = user('org-admin', False) From 52b16620cd68fef37406b3eeafb747b69942b41e Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Tue, 21 Jun 2016 16:30:06 -0400 Subject: [PATCH 10/10] added multi-team same credential name test --- awx/main/tests/functional/test_rbac_credential.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/awx/main/tests/functional/test_rbac_credential.py b/awx/main/tests/functional/test_rbac_credential.py index 83661932d4..31536a06f0 100644 --- a/awx/main/tests/functional/test_rbac_credential.py +++ b/awx/main/tests/functional/test_rbac_credential.py @@ -18,6 +18,19 @@ def test_credential_migration_user(credential, user, permissions): assert u in credential.owner_role +@pytest.mark.django_db +def test_two_teams_same_cred_name(organization_factory): + objects = organization_factory("test", + teams=["team1", "team2"]) + + cred1 = Credential.objects.create(name="test", kind="net", deprecated_team=objects.teams.team1) + cred2 = Credential.objects.create(name="test", kind="net", deprecated_team=objects.teams.team2) + + rbac.migrate_credential(apps, None) + + assert objects.teams.team1.member_role in cred1.owner_role.parents.all() + assert objects.teams.team2.member_role in cred2.owner_role.parents.all() + @pytest.mark.django_db def test_credential_use_role(credential, user, permissions): u = user('user', False)