mirror of
https://github.com/ansible/awx.git
synced 2026-05-13 04:17:36 -02:30
Sharing Credentials Across Organizations (#16106)
* Added tests for cross org sharing of credentials * added negative testing for sharing of credentials * added conditions and tests for roleteamslist regarding cross org credentials * removed redundant codes * made error message more articulated and specific
This commit is contained in:
@@ -720,9 +720,19 @@ class TeamRolesList(SubListAttachDetachAPIView):
|
|||||||
team = get_object_or_404(models.Team, pk=self.kwargs['pk'])
|
team = get_object_or_404(models.Team, pk=self.kwargs['pk'])
|
||||||
credential_content_type = ContentType.objects.get_for_model(models.Credential)
|
credential_content_type = ContentType.objects.get_for_model(models.Credential)
|
||||||
if role.content_type == credential_content_type:
|
if role.content_type == credential_content_type:
|
||||||
if not role.content_object.organization or role.content_object.organization.id != team.organization.id:
|
if not role.content_object.organization:
|
||||||
data = dict(msg=_("You cannot grant credential access to a team when the Organization field isn't set, or belongs to a different organization"))
|
data = dict(
|
||||||
|
msg=_("You cannot grant access to a credential that is not assigned to an organization (private credentials cannot be assigned to teams)")
|
||||||
|
)
|
||||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
elif role.content_object.organization.id != team.organization.id:
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
data = dict(
|
||||||
|
msg=_(
|
||||||
|
"You cannot grant a team access to a credential in a different organization. Only superusers can grant cross-organization credential access to teams"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
return super(TeamRolesList, self).post(request, *args, **kwargs)
|
return super(TeamRolesList, self).post(request, *args, **kwargs)
|
||||||
|
|
||||||
@@ -4203,9 +4213,21 @@ class RoleTeamsList(SubListAttachDetachAPIView):
|
|||||||
|
|
||||||
credential_content_type = ContentType.objects.get_for_model(models.Credential)
|
credential_content_type = ContentType.objects.get_for_model(models.Credential)
|
||||||
if role.content_type == credential_content_type:
|
if role.content_type == credential_content_type:
|
||||||
if not role.content_object.organization or role.content_object.organization.id != team.organization.id:
|
# Private credentials (no organization) are never allowed for teams
|
||||||
data = dict(msg=_("You cannot grant credential access to a team when the Organization field isn't set, or belongs to a different organization"))
|
if not role.content_object.organization:
|
||||||
|
data = dict(
|
||||||
|
msg=_("You cannot grant access to a credential that is not assigned to an organization (private credentials cannot be assigned to teams)")
|
||||||
|
)
|
||||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
# Cross-organization credentials are only allowed for superusers
|
||||||
|
elif role.content_object.organization.id != team.organization.id:
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
data = dict(
|
||||||
|
msg=_(
|
||||||
|
"You cannot grant a team access to a credential in a different organization. Only superusers can grant cross-organization credential access to teams"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
action = 'attach'
|
action = 'attach'
|
||||||
if request.data.get('disassociate', None):
|
if request.data.get('disassociate', None):
|
||||||
|
|||||||
@@ -287,6 +287,72 @@ def test_sa_grant_private_credential_to_team_through_role_teams(post, credential
|
|||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_grant_credential_to_team_different_organization_through_role_teams(post, get, credential, organizations, admin, org_admin, team, team_member):
|
||||||
|
# # Test that credential from different org can be assigned to team by a superuser through role_teams_list endpoint
|
||||||
|
orgs = organizations(2)
|
||||||
|
credential.organization = orgs[0]
|
||||||
|
credential.save()
|
||||||
|
team.organization = orgs[1]
|
||||||
|
team.save()
|
||||||
|
|
||||||
|
# Non-superuser (org_admin) trying cross-org assignment should be denied
|
||||||
|
response = post(reverse('api:role_teams_list', kwargs={'pk': credential.use_role.id}), {'id': team.id}, org_admin)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert (
|
||||||
|
"You cannot grant a team access to a credential in a different organization. Only superusers can grant cross-organization credential access to teams"
|
||||||
|
in response.data['msg']
|
||||||
|
)
|
||||||
|
|
||||||
|
# Superuser (admin) can do cross-org assignment
|
||||||
|
response = post(reverse('api:role_teams_list', kwargs={'pk': credential.use_role.id}), {'id': team.id}, admin)
|
||||||
|
assert response.status_code == 204
|
||||||
|
|
||||||
|
assert credential.use_role in team.member_role.children.all()
|
||||||
|
assert team_member in credential.read_role
|
||||||
|
assert team_member in credential.use_role
|
||||||
|
assert team_member not in credential.admin_role
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_grant_credential_to_team_different_organization(post, get, credential, organizations, admin, org_admin, team, team_member):
|
||||||
|
# Test that credential from different org can be assigned to team by a superuser
|
||||||
|
orgs = organizations(2)
|
||||||
|
credential.organization = orgs[0]
|
||||||
|
credential.save()
|
||||||
|
team.organization = orgs[1]
|
||||||
|
team.save()
|
||||||
|
|
||||||
|
# Non-superuser (org_admin, ...) trying cross-org assignment should be denied
|
||||||
|
response = post(reverse('api:team_roles_list', kwargs={'pk': team.id}), {'id': credential.use_role.id}, org_admin)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert (
|
||||||
|
"You cannot grant a team access to a credential in a different organization. Only superusers can grant cross-organization credential access to teams"
|
||||||
|
in response.data['msg']
|
||||||
|
)
|
||||||
|
|
||||||
|
# Superuser (system admin) can do cross-org assignment
|
||||||
|
response = post(reverse('api:team_roles_list', kwargs={'pk': team.id}), {'id': credential.use_role.id}, admin)
|
||||||
|
assert response.status_code == 204
|
||||||
|
|
||||||
|
assert credential.use_role in team.member_role.children.all()
|
||||||
|
|
||||||
|
assert team_member in credential.read_role
|
||||||
|
assert team_member in credential.use_role
|
||||||
|
assert team_member not in credential.admin_role
|
||||||
|
|
||||||
|
# Team member can see the credential in API
|
||||||
|
response = get(reverse('api:team_credentials_list', kwargs={'pk': team.id}), team_member)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.data['count'] == 1
|
||||||
|
assert response.data['results'][0]['id'] == credential.id
|
||||||
|
|
||||||
|
# Team member can see the credential in general credentials API
|
||||||
|
response = get(reverse('api:credential_list'), team_member)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert any(cred['id'] == credential.id for cred in response.data['results'])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_sa_grant_private_credential_to_team_through_team_roles(post, credential, admin, team):
|
def test_sa_grant_private_credential_to_team_through_team_roles(post, credential, admin, team):
|
||||||
# not even a system admin can grant a private cred to a team though
|
# not even a system admin can grant a private cred to a team though
|
||||||
|
|||||||
Reference in New Issue
Block a user