mirror of
https://github.com/ansible/awx.git
synced 2026-02-12 15:14:45 -03:30
The UI isn't using this feature at the moment so we're going to remove it for 3.0, and probably bring it back in 3.1, potentially in different ways depending on UI needs then.
429 lines
15 KiB
Python
429 lines
15 KiB
Python
import mock # noqa
|
|
import pytest
|
|
|
|
from django.db import transaction
|
|
from django.core.urlresolvers import reverse
|
|
from awx.main.models.rbac import Role, ROLE_SINGLETON_SYSTEM_ADMINISTRATOR
|
|
|
|
def mock_feature_enabled(feature, bypass_database=None):
|
|
return True
|
|
|
|
#@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
|
|
|
@pytest.fixture
|
|
def role():
|
|
return Role.objects.create()
|
|
|
|
|
|
#
|
|
# /roles
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_roles_list_admin(organization, get, admin):
|
|
'Admin can see list of all roles'
|
|
url = reverse('api:role_list')
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
assert roles['count'] > 0
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_roles_list_user(organization, inventory, team, get, user):
|
|
'Users can see all roles they have access to, but not all roles'
|
|
this_user = user('user-test_get_roles_list_user')
|
|
organization.member_role.members.add(this_user)
|
|
custom_role = Role.objects.create(name='custom_role-test_get_roles_list_user')
|
|
organization.member_role.children.add(custom_role)
|
|
|
|
url = reverse('api:role_list')
|
|
response = get(url, this_user)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
assert roles['count'] > 0
|
|
assert roles['count'] == len(roles['results']) # just to make sure the tests below are valid
|
|
|
|
role_hash = {}
|
|
|
|
for r in roles['results']:
|
|
role_hash[r['id']] = r
|
|
|
|
assert Role.singleton(ROLE_SINGLETON_SYSTEM_ADMINISTRATOR).id in role_hash
|
|
assert organization.admin_role.id in role_hash
|
|
assert organization.member_role.id in role_hash
|
|
assert this_user.admin_role.id in role_hash
|
|
assert custom_role.id in role_hash
|
|
|
|
assert inventory.admin_role.id not in role_hash
|
|
assert team.member_role.id not in role_hash
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_cant_create_role(post, admin):
|
|
"Ensure we can't create new roles through the api"
|
|
# Some day we might want to do this, but until that is speced out, lets
|
|
# ensure we don't slip up and allow this implicitly through some helper or
|
|
# another
|
|
response = post(reverse('api:role_list'), {'name': 'New Role'}, admin)
|
|
assert response.status_code == 405
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_cant_delete_role(delete, admin):
|
|
"Ensure we can't delete roles through the api"
|
|
# Some day we might want to do this, but until that is speced out, lets
|
|
# ensure we don't slip up and allow this implicitly through some helper or
|
|
# another
|
|
response = delete(reverse('api:role_detail', args=(admin.admin_role.id,)), admin)
|
|
assert response.status_code == 405
|
|
|
|
|
|
|
|
#
|
|
# /user/<id>/roles
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_user_roles_list(get, admin):
|
|
url = reverse('api:user_roles_list', args=(admin.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
assert roles['count'] > 0 # 'system_administrator' role if nothing else
|
|
|
|
@pytest.mark.django_db
|
|
def test_user_view_other_user_roles(organization, inventory, team, get, alice, bob):
|
|
'Users can see roles for other users, but only the roles that that user has access to see as well'
|
|
organization.member_role.members.add(alice)
|
|
organization.admin_role.members.add(bob)
|
|
organization.member_role.members.add(bob)
|
|
custom_role = Role.objects.create(name='custom_role-test_user_view_admin_roles_list')
|
|
organization.member_role.children.add(custom_role)
|
|
team.member_role.members.add(bob)
|
|
|
|
# alice and bob are in the same org and can see some child role of that org.
|
|
# Bob is an org admin, alice can see this.
|
|
# Bob is in a team that alice is not, alice cannot see that bob is a member of that team.
|
|
|
|
url = reverse('api:user_roles_list', args=(bob.id,))
|
|
response = get(url, alice)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
assert roles['count'] > 0
|
|
assert roles['count'] == len(roles['results']) # just to make sure the tests below are valid
|
|
|
|
role_hash = {}
|
|
for r in roles['results']:
|
|
role_hash[r['id']] = r['name']
|
|
|
|
assert organization.admin_role.id in role_hash
|
|
assert custom_role.id not in role_hash # doesn't show up in the user roles list, not an explicit grant
|
|
assert Role.singleton(ROLE_SINGLETON_SYSTEM_ADMINISTRATOR).id not in role_hash
|
|
assert inventory.admin_role.id not in role_hash
|
|
assert team.member_role.id not in role_hash # alice can't see this
|
|
|
|
# again but this time alice is part of the team, and should be able to see the team role
|
|
team.member_role.members.add(alice)
|
|
response = get(url, alice)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
assert roles['count'] > 0
|
|
assert roles['count'] == len(roles['results']) # just to make sure the tests below are valid
|
|
|
|
role_hash = {}
|
|
for r in roles['results']:
|
|
role_hash[r['id']] = r['name']
|
|
|
|
assert team.member_role.id in role_hash # Alice can now see this
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_add_role_to_user(role, post, admin):
|
|
assert admin.roles.filter(id=role.id).count() == 0
|
|
url = reverse('api:user_roles_list', args=(admin.id,))
|
|
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert admin.roles.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert admin.roles.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {}, admin)
|
|
assert response.status_code == 400
|
|
assert admin.roles.filter(id=role.id).count() == 1
|
|
|
|
@pytest.mark.django_db
|
|
def test_remove_role_from_user(role, post, admin):
|
|
assert admin.roles.filter(id=role.id).count() == 0
|
|
url = reverse('api:user_roles_list', args=(admin.id,))
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert admin.roles.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {'disassociate': role.id, 'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert admin.roles.filter(id=role.id).count() == 0
|
|
|
|
|
|
|
|
|
|
#
|
|
# /team/<id>/roles
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_teams_roles_list(get, team, organization, admin):
|
|
team.member_role.children.add(organization.admin_role)
|
|
url = reverse('api:team_roles_list', args=(team.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
roles = response.data
|
|
|
|
assert roles['count'] == 2
|
|
assert roles['results'][0]['id'] == organization.admin_role.id or roles['results'][1]['id'] == organization.admin_role.id
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_add_role_to_teams(team, role, post, admin):
|
|
assert team.member_role.children.filter(id=role.id).count() == 0
|
|
url = reverse('api:team_roles_list', args=(team.id,))
|
|
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert team.member_role.children.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert team.member_role.children.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {}, admin)
|
|
assert response.status_code == 400
|
|
assert team.member_role.children.filter(id=role.id).count() == 1
|
|
|
|
@pytest.mark.django_db
|
|
def test_remove_role_from_teams(team, role, post, admin):
|
|
assert team.member_role.children.filter(id=role.id).count() == 0
|
|
url = reverse('api:team_roles_list', args=(team.id,))
|
|
response = post(url, {'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert team.member_role.children.filter(id=role.id).count() == 1
|
|
|
|
response = post(url, {'disassociate': role.id, 'id': role.id}, admin)
|
|
assert response.status_code == 204
|
|
assert team.member_role.children.filter(id=role.id).count() == 0
|
|
|
|
|
|
|
|
#
|
|
# /roles/<id>/
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_role(get, admin, role):
|
|
url = reverse('api:role_detail', args=(role.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
assert response.data['id'] == role.id
|
|
|
|
@pytest.mark.django_db
|
|
def test_put_role_405(put, admin, role):
|
|
url = reverse('api:role_detail', args=(role.id,))
|
|
response = put(url, {'name': 'Some new name'}, admin)
|
|
assert response.status_code == 405
|
|
#r = Role.objects.get(id=role.id)
|
|
#assert r.name == 'Some new name'
|
|
|
|
@pytest.mark.django_db
|
|
def test_put_role_access_denied(put, alice, role):
|
|
url = reverse('api:role_detail', args=(role.id,))
|
|
response = put(url, {'name': 'Some new name'}, alice)
|
|
assert response.status_code == 403 or response.status_code == 405
|
|
|
|
|
|
#
|
|
# /roles/<id>/users/
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_role_users(get, admin, role):
|
|
role.members.add(admin)
|
|
url = reverse('api:role_users_list', args=(role.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
assert response.data['count'] == 1
|
|
assert response.data['results'][0]['id'] == admin.id
|
|
|
|
@pytest.mark.django_db
|
|
def test_add_user_to_role(post, admin, role):
|
|
url = reverse('api:role_users_list', args=(role.id,))
|
|
assert role.members.filter(id=admin.id).count() == 0
|
|
post(url, {'id': admin.id}, admin)
|
|
assert role.members.filter(id=admin.id).count() == 1
|
|
|
|
@pytest.mark.django_db
|
|
def test_remove_user_to_role(post, admin, role):
|
|
role.members.add(admin)
|
|
url = reverse('api:role_users_list', args=(role.id,))
|
|
assert role.members.filter(id=admin.id).count() == 1
|
|
post(url, {'disassociate': True, 'id': admin.id}, admin)
|
|
assert role.members.filter(id=admin.id).count() == 0
|
|
|
|
@pytest.mark.django_db
|
|
def test_org_admin_add_user_to_job_template(post, organization, check_jobtemplate, user):
|
|
'Tests that a user with permissions to assign/revoke membership to a particular role can do so'
|
|
org_admin = user('org-admin')
|
|
joe = user('joe')
|
|
organization.admin_role.members.add(org_admin)
|
|
|
|
assert org_admin in check_jobtemplate.admin_role
|
|
assert joe not in check_jobtemplate.execute_role
|
|
|
|
post(reverse('api:role_users_list', args=(check_jobtemplate.execute_role.id,)), {'id': joe.id}, org_admin)
|
|
assert joe in check_jobtemplate.execute_role
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_org_admin_remove_user_from_job_template(post, organization, check_jobtemplate, user):
|
|
'Tests that a user with permissions to assign/revoke membership to a particular role can do so'
|
|
org_admin = user('org-admin')
|
|
joe = user('joe')
|
|
organization.admin_role.members.add(org_admin)
|
|
check_jobtemplate.execute_role.members.add(joe)
|
|
|
|
assert org_admin in check_jobtemplate.admin_role
|
|
assert joe in check_jobtemplate.execute_role
|
|
|
|
post(reverse('api:role_users_list', args=(check_jobtemplate.execute_role.id,)), {'disassociate': True, 'id': joe.id}, org_admin)
|
|
assert joe not in check_jobtemplate.execute_role
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_user_fail_to_add_user_to_job_template(post, organization, check_jobtemplate, user):
|
|
'Tests that a user without permissions to assign/revoke membership to a particular role cannot do so'
|
|
rando = user('rando')
|
|
joe = user('joe')
|
|
|
|
assert rando not in check_jobtemplate.admin_role
|
|
assert joe not in check_jobtemplate.execute_role
|
|
|
|
with transaction.atomic():
|
|
res = post(reverse('api:role_users_list', args=(check_jobtemplate.execute_role.id,)), {'id': joe.id}, rando)
|
|
assert res.status_code == 403
|
|
|
|
assert joe not in check_jobtemplate.execute_role
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_user_fail_to_remove_user_to_job_template(post, organization, check_jobtemplate, user):
|
|
'Tests that a user without permissions to assign/revoke membership to a particular role cannot do so'
|
|
rando = user('rando')
|
|
joe = user('joe')
|
|
check_jobtemplate.execute_role.members.add(joe)
|
|
|
|
assert rando not in check_jobtemplate.admin_role
|
|
assert joe in check_jobtemplate.execute_role
|
|
|
|
with transaction.atomic():
|
|
res = post(reverse('api:role_users_list', args=(check_jobtemplate.execute_role.id,)), {'disassociate': True, 'id': joe.id}, rando)
|
|
assert res.status_code == 403
|
|
|
|
assert joe in check_jobtemplate.execute_role
|
|
|
|
#
|
|
# /roles/<id>/teams/
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_get_role_teams(get, team, admin, role):
|
|
role.parents.add(team.member_role)
|
|
url = reverse('api:role_teams_list', args=(role.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
assert response.data['count'] == 1
|
|
assert response.data['results'][0]['id'] == team.id
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_add_team_to_role(post, team, admin, role):
|
|
url = reverse('api:role_teams_list', args=(role.id,))
|
|
assert role.members.filter(id=admin.id).count() == 0
|
|
res = post(url, {'id': team.id}, admin)
|
|
assert res.status_code == 204
|
|
assert role.parents.filter(id=team.member_role.id).count() == 1
|
|
|
|
@pytest.mark.django_db
|
|
def test_remove_team_from_role(post, team, admin, role):
|
|
role.members.add(admin)
|
|
url = reverse('api:role_teams_list', args=(role.id,))
|
|
assert role.members.filter(id=admin.id).count() == 1
|
|
res = post(url, {'disassociate': True, 'id': team.id}, admin)
|
|
assert res.status_code == 204
|
|
assert role.parents.filter(id=team.member_role.id).count() == 0
|
|
|
|
|
|
#
|
|
# /roles/<id>/parents/
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_role_parents(get, team, admin, role):
|
|
role.parents.add(team.member_role)
|
|
url = reverse('api:role_parents_list', args=(role.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
assert response.data['count'] == 1
|
|
assert response.data['results'][0]['id'] == team.member_role.id
|
|
|
|
|
|
#
|
|
# /roles/<id>/children/
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_role_children(get, team, admin, role):
|
|
role.parents.add(team.member_role)
|
|
url = reverse('api:role_children_list', args=(team.member_role.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
assert response.data['count'] == 2
|
|
assert response.data['results'][0]['id'] == role.id or response.data['results'][1]['id'] == role.id
|
|
|
|
|
|
|
|
#
|
|
# Generics
|
|
#
|
|
|
|
@pytest.mark.django_db
|
|
def test_ensure_rbac_fields_are_present(organization, get, admin):
|
|
url = reverse('api:organization_detail', args=(organization.id,))
|
|
response = get(url, admin)
|
|
assert response.status_code == 200
|
|
org = response.data
|
|
|
|
assert 'summary_fields' in org
|
|
assert 'object_roles' in org['summary_fields']
|
|
|
|
role_pk = org['summary_fields']['object_roles']['admin_role']['id']
|
|
role_url = reverse('api:role_detail', args=(role_pk,))
|
|
org_role_response = get(role_url, admin)
|
|
|
|
assert org_role_response.status_code == 200
|
|
role = org_role_response.data
|
|
assert role['related']['organization'] == url
|
|
|
|
@pytest.mark.django_db
|
|
def test_ensure_role_summary_is_present(organization, get, user):
|
|
url = reverse('api:organization_detail', args=(organization.id,))
|
|
response = get(url, user('admin', True))
|
|
assert response.status_code == 200
|
|
org = response.data
|
|
|
|
assert 'summary_fields' in org
|
|
assert 'object_roles' in org['summary_fields']
|
|
assert org['summary_fields']['object_roles']['admin_role']['id'] > 0
|