mirror of
https://github.com/ansible/awx.git
synced 2026-01-18 05:01:19 -03:30
Merge pull request #1265 from anoek/rbac
Various small fixes and progress on making 'old' tests work again on RBAC
This commit is contained in:
commit
8a1f21de12
@ -299,7 +299,7 @@ class SubListAPIView(ListAPIView, ParentMixin):
|
||||
parent = self.get_parent_object()
|
||||
self.check_parent_access(parent)
|
||||
qs = self.request.user.get_queryset(self.model).distinct()
|
||||
sublist_qs = getattr(parent, self.relationship).distinct()
|
||||
sublist_qs = getattrd(parent, self.relationship).distinct()
|
||||
return qs & sublist_qs
|
||||
|
||||
class SubListCreateAPIView(SubListAPIView, ListCreateAPIView):
|
||||
|
||||
@ -117,6 +117,7 @@ class ModelAccessPermission(permissions.BasePermission):
|
||||
check_method = getattr(self, 'check_%s_permissions' % request.method.lower(), None)
|
||||
result = check_method and check_method(request, view, obj)
|
||||
if not result:
|
||||
print('Yarr permission denied: %s %s %s' % (request.method, repr(view), repr(obj),)) # TODO: XXX: This shouldn't have been committed but anoek is sloppy, remove me after we're done fixing bugs
|
||||
raise PermissionDenied()
|
||||
|
||||
return result
|
||||
|
||||
@ -274,7 +274,6 @@ v1_urls = patterns('awx.api.views',
|
||||
url(r'^me/$', 'user_me_list'),
|
||||
url(r'^dashboard/$', 'dashboard_view'),
|
||||
url(r'^dashboard/graphs/jobs/$', 'dashboard_jobs_graph_view'),
|
||||
url(r'^dashboard/graphs/inventory/$', 'dashboard_inventory_graph_view'),
|
||||
url(r'^settings/', include(settings_urls)),
|
||||
url(r'^schedules/', include(schedule_urls)),
|
||||
url(r'^organizations/', include(organization_urls)),
|
||||
|
||||
@ -288,8 +288,7 @@ class DashboardView(APIView):
|
||||
def get(self, request, format=None):
|
||||
''' Show Dashboard Details '''
|
||||
data = OrderedDict()
|
||||
data['related'] = {'jobs_graph': reverse('api:dashboard_jobs_graph_view'),
|
||||
'inventory_graph': reverse('api:dashboard_inventory_graph_view')}
|
||||
data['related'] = {'jobs_graph': reverse('api:dashboard_jobs_graph_view')}
|
||||
user_inventory = get_user_queryset(request.user, Inventory)
|
||||
inventory_with_failed_hosts = user_inventory.filter(hosts_with_active_failures__gt=0)
|
||||
user_inventory_external = user_inventory.filter(has_inventory_sources=True)
|
||||
@ -435,49 +434,6 @@ class DashboardJobsGraphView(APIView):
|
||||
element[1]])
|
||||
return Response(dashboard_data)
|
||||
|
||||
class DashboardInventoryGraphView(APIView):
|
||||
|
||||
view_name = "Dashboard Inventory Graphs"
|
||||
new_in_200 = True
|
||||
|
||||
def get(self, request, format=None):
|
||||
period = request.query_params.get('period', 'month')
|
||||
|
||||
end_date = now()
|
||||
if period == 'month':
|
||||
start_date = end_date - dateutil.relativedelta.relativedelta(months=1)
|
||||
start_date = start_date.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
delta = dateutil.relativedelta.relativedelta(days=1)
|
||||
elif period == 'week':
|
||||
start_date = end_date - dateutil.relativedelta.relativedelta(weeks=1)
|
||||
start_date = start_date.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
delta = dateutil.relativedelta.relativedelta(days=1)
|
||||
elif period == 'day':
|
||||
start_date = end_date - dateutil.relativedelta.relativedelta(days=1)
|
||||
start_date = start_date.replace(minute=0, second=0, microsecond=0)
|
||||
delta = dateutil.relativedelta.relativedelta(hours=1)
|
||||
else:
|
||||
raise ParseError(u'Unknown period "%s"' % force_text(period))
|
||||
|
||||
host_stats = []
|
||||
date = start_date
|
||||
while date < end_date:
|
||||
next_date = date + delta
|
||||
# Find all hosts that existed at end of intevral that are still
|
||||
# active or were deleted after the end of interval. Slow but
|
||||
# accurate; haven't yet found a better way to do it.
|
||||
hosts_qs = Host.objects.filter(created__lt=next_date)
|
||||
hosts_qs = hosts_qs.filter(Q(active=True) | Q(active=False, modified__gte=next_date))
|
||||
hostnames = set()
|
||||
for name, active in hosts_qs.values_list('name', 'active').iterator():
|
||||
if not active:
|
||||
name = re.sub(r'^_deleted_.*?_', '', name)
|
||||
hostnames.add(name)
|
||||
host_stats.append((time.mktime(date.timetuple()), len(hostnames)))
|
||||
date = next_date
|
||||
|
||||
return Response({'hosts': host_stats})
|
||||
|
||||
|
||||
class ScheduleList(ListAPIView):
|
||||
|
||||
@ -633,16 +589,16 @@ class OrganizationUsersList(SubListCreateAttachDetachAPIView):
|
||||
model = User
|
||||
serializer_class = UserSerializer
|
||||
parent_model = Organization
|
||||
relationship = 'users'
|
||||
relationship = 'member_role.members'
|
||||
|
||||
class OrganizationAdminsList(SubListCreateAttachDetachAPIView):
|
||||
|
||||
model = User
|
||||
serializer_class = UserSerializer
|
||||
parent_model = Organization
|
||||
relationship = 'admins'
|
||||
relationship = 'admin_role.members'
|
||||
|
||||
class OrganizationProjectsList(SubListCreateAttachDetachAPIView):
|
||||
class OrganizationProjectsList(SubListCreateAPIView):
|
||||
|
||||
model = Project
|
||||
serializer_class = ProjectSerializer
|
||||
@ -725,7 +681,7 @@ class TeamUsersList(SubListCreateAttachDetachAPIView):
|
||||
model = User
|
||||
serializer_class = UserSerializer
|
||||
parent_model = Team
|
||||
relationship = 'users'
|
||||
relationship = 'member_role.members'
|
||||
|
||||
|
||||
class TeamRolesList(SubListCreateAttachDetachAPIView):
|
||||
@ -1481,7 +1437,7 @@ class GroupAllHostsList(SubListAPIView):
|
||||
def get_queryset(self):
|
||||
parent = self.get_parent_object()
|
||||
self.check_parent_access(parent)
|
||||
qs = self.request.user.get_queryset(self.model)
|
||||
qs = self.request.user.get_queryset(self.model).distinct() # need distinct for '&' operator
|
||||
sublist_qs = parent.all_hosts.distinct()
|
||||
return qs & sublist_qs
|
||||
|
||||
|
||||
@ -7,10 +7,9 @@ import sys
|
||||
import logging
|
||||
|
||||
# Django
|
||||
from django.db.models import F, Q
|
||||
from django.db.models import Q
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models.aggregates import Max
|
||||
|
||||
# Django REST Framework
|
||||
from rest_framework.exceptions import ParseError, PermissionDenied
|
||||
@ -67,15 +66,7 @@ def user_admin_role(self):
|
||||
return Role.objects.get(content_type=ContentType.objects.get_for_model(User), object_id=self.id)
|
||||
|
||||
def user_accessible_objects(user, permissions):
|
||||
content_type = ContentType.objects.get_for_model(User)
|
||||
qs = RolePermission.objects.filter(
|
||||
content_type=content_type,
|
||||
role__ancestors__members=user
|
||||
)
|
||||
for perm in permissions:
|
||||
qs = qs.annotate(**{'max_' + perm: Max(perm)})
|
||||
qs = qs.filter(**{'max_' + perm: int(permissions[perm])})
|
||||
return qs
|
||||
return ResourceMixin._accessible_objects(User, user, permissions)
|
||||
|
||||
def user_accessible_by(instance, user, permissions):
|
||||
perms = get_user_permissions_on_resource(instance, user)
|
||||
@ -222,7 +213,7 @@ class UserAccess(BaseAccess):
|
||||
model = User
|
||||
|
||||
def get_queryset(self):
|
||||
qs = self.model.accessible_objects(self.user, {'read':True})
|
||||
qs = User.accessible_objects(self.user, {'read':True})
|
||||
return qs
|
||||
|
||||
def can_add(self, data):
|
||||
@ -639,7 +630,7 @@ class ProjectAccess(BaseAccess):
|
||||
def can_add(self, data):
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
qs = Organization.accessible_objects(self.uesr, ALL_PERMISSIONS)
|
||||
qs = Organization.accessible_objects(self.user, ALL_PERMISSIONS)
|
||||
return bool(qs.count() > 0)
|
||||
|
||||
def can_change(self, obj, data):
|
||||
@ -813,47 +804,11 @@ class JobAccess(BaseAccess):
|
||||
qs = qs.prefetch_related('unified_job_template')
|
||||
if self.user.is_superuser:
|
||||
return qs
|
||||
|
||||
credential_ids = self.user.get_queryset(Credential)
|
||||
base_qs = qs.filter(
|
||||
return qs.filter(
|
||||
credential_id__in=credential_ids,
|
||||
)
|
||||
org_admin_ids = base_qs.filter(
|
||||
Q(project__organizations__admins__in=[self.user]) |
|
||||
(Q(project__isnull=True) & Q(job_type=PERM_INVENTORY_SCAN) & Q(inventory__organization__admins__in=[self.user]))
|
||||
)
|
||||
|
||||
allowed_deploy = [PERM_JOBTEMPLATE_CREATE, PERM_INVENTORY_DEPLOY]
|
||||
allowed_check = [PERM_JOBTEMPLATE_CREATE, PERM_INVENTORY_DEPLOY, PERM_INVENTORY_CHECK]
|
||||
team_ids = Team.objects.filter(users__in=[self.user])
|
||||
|
||||
# TODO: I think the below queries can be combined
|
||||
deploy_permissions_ids = Permission.objects.filter(
|
||||
Q(user=self.user) | Q(team__in=team_ids),
|
||||
permission_type__in=allowed_deploy,
|
||||
)
|
||||
check_permissions_ids = Permission.objects.filter(
|
||||
Q(user=self.user) | Q(team__in=team_ids),
|
||||
permission_type__in=allowed_check,
|
||||
)
|
||||
|
||||
perm_deploy_ids = base_qs.filter(
|
||||
job_type=PERM_INVENTORY_DEPLOY,
|
||||
inventory__permissions__in=deploy_permissions_ids,
|
||||
project__permissions__in=deploy_permissions_ids,
|
||||
inventory__permissions__pk=F('project__permissions__pk'),
|
||||
)
|
||||
|
||||
perm_check_ids = base_qs.filter(
|
||||
job_type=PERM_INVENTORY_CHECK,
|
||||
inventory__permissions__in=check_permissions_ids,
|
||||
project__permissions__in=check_permissions_ids,
|
||||
inventory__permissions__pk=F('project__permissions__pk'),
|
||||
)
|
||||
|
||||
return base_qs.filter(
|
||||
Q(id__in=org_admin_ids) |
|
||||
Q(id__in=perm_deploy_ids) |
|
||||
Q(id__in=perm_check_ids)
|
||||
job_template__in=JobTemplate.accessible_objects(self.user, {'read': True})
|
||||
)
|
||||
|
||||
def can_add(self, data):
|
||||
@ -938,21 +893,11 @@ class AdHocCommandAccess(BaseAccess):
|
||||
return qs
|
||||
|
||||
credential_ids = set(self.user.get_queryset(Credential).values_list('id', flat=True))
|
||||
team_ids = set(Team.objects.filter( users__in=[self.user]).values_list('id', flat=True))
|
||||
|
||||
permission_ids = set(Permission.objects.filter(
|
||||
Q(user=self.user) | Q(team__in=team_ids),
|
||||
permission_type__in=PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
|
||||
run_ad_hoc_commands=True,
|
||||
).values_list('id', flat=True))
|
||||
|
||||
inventory_qs = self.user.get_queryset(Inventory)
|
||||
inventory_qs = inventory_qs.filter(Q(permissions__in=permission_ids) | Q(organization__admins__in=[self.user]))
|
||||
inventory_ids = set(inventory_qs.values_list('id', flat=True))
|
||||
inventory_qs = Inventory.accessible_objects(self.user, {'read': True, 'execute': True})
|
||||
|
||||
qs = qs.filter(
|
||||
credential_id__in=credential_ids,
|
||||
inventory_id__in=inventory_ids,
|
||||
inventory__in=inventory_qs,
|
||||
)
|
||||
return qs
|
||||
|
||||
@ -1183,7 +1128,8 @@ class ScheduleAccess(BaseAccess):
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
if obj and obj.unified_job_template:
|
||||
return obj.unified_job_template.accessible_by(self.user, {'read':True})
|
||||
job_class = obj.unified_job_template
|
||||
return self.user.can_access(type(job_class), 'read', obj.unified_job_template)
|
||||
else:
|
||||
return False
|
||||
|
||||
@ -1193,7 +1139,7 @@ class ScheduleAccess(BaseAccess):
|
||||
pk = get_pk_from_dict(data, 'unified_job_template')
|
||||
obj = get_object_or_400(UnifiedJobTemplate, pk=pk)
|
||||
if obj:
|
||||
return obj.accessible_by(self.user, {'read':True, 'update':True, 'write':True})
|
||||
return self.user.can_access(type(obj), 'change', obj, None)
|
||||
else:
|
||||
return False
|
||||
|
||||
@ -1201,7 +1147,8 @@ class ScheduleAccess(BaseAccess):
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
if obj and obj.unified_job_template:
|
||||
return obj.unified_job_template.accessible_by(self.user, {'read':True, 'update':True, 'write':True})
|
||||
job_class = obj.unified_job_template
|
||||
return self.user.can_access(type(job_class), 'change', job_class, None)
|
||||
else:
|
||||
return False
|
||||
|
||||
@ -1209,7 +1156,8 @@ class ScheduleAccess(BaseAccess):
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
if obj and obj.unified_job_template:
|
||||
return obj.unified_job_template.accessible_by(self.user, {'read':True, 'update':True, 'write':True})
|
||||
job_class = obj.unified_job_template
|
||||
return self.user.can_access(type(job_class), 'change', job_class, None)
|
||||
else:
|
||||
return False
|
||||
|
||||
@ -1287,10 +1235,6 @@ class ActivityStreamAccess(BaseAccess):
|
||||
#Project Update Filter
|
||||
qs.filter(project_update__project__in=project_qs)
|
||||
|
||||
#Permission Filter
|
||||
permission_qs = self.user.get_queryset(Permission)
|
||||
qs.filter(permission__in=permission_qs)
|
||||
|
||||
#Job Template Filter
|
||||
jobtemplate_qs = self.user.get_queryset(JobTemplate)
|
||||
qs.filter(job_template__in=jobtemplate_qs)
|
||||
|
||||
@ -243,18 +243,26 @@ class ImplicitRoleField(models.ForeignKey):
|
||||
|
||||
def _calc_original_parents(self, instance):
|
||||
if not hasattr(self, '__original_parent_roles'):
|
||||
setattr(self, '__original_parent_roles', []) # do not just self.__original_parent_roles=[], it's not the same here
|
||||
paths = self.parent_role if type(self.parent_role) is list else [self.parent_role]
|
||||
original_parent_roles = set()
|
||||
for path in paths:
|
||||
if path.startswith("singleton:"):
|
||||
parents = [Role.singleton(path[10:])]
|
||||
else:
|
||||
parents = resolve_role_field(instance, path)
|
||||
for parent in parents:
|
||||
original_parent_roles.add(parent)
|
||||
setattr(self, '__original_parent_roles', set()) # do not just self.__original_parent_roles=[], it's not the same here, apparently.
|
||||
# NOTE: The above setattr is required to be called bofore
|
||||
# _resolve_parent_roles because we can end up recursing, so the enclosing
|
||||
# if not hasattr protects against this.
|
||||
original_parent_roles = self._resolve_parent_roles(instance)
|
||||
setattr(self, '__original_parent_roles', original_parent_roles)
|
||||
|
||||
def _resolve_parent_roles(self, instance):
|
||||
paths = self.parent_role if type(self.parent_role) is list else [self.parent_role]
|
||||
parent_roles = set()
|
||||
for path in paths:
|
||||
if path.startswith("singleton:"):
|
||||
parents = [Role.singleton(path[10:])]
|
||||
else:
|
||||
parents = resolve_role_field(instance, path)
|
||||
for parent in parents:
|
||||
parent_roles.add(parent)
|
||||
return parent_roles
|
||||
|
||||
|
||||
def _post_save(self, instance, created, *args, **kwargs):
|
||||
# Ensure that our field gets initialized after our first save
|
||||
this_role = getattr(instance, self.name)
|
||||
@ -269,16 +277,8 @@ class ImplicitRoleField(models.ForeignKey):
|
||||
self._calc_original_parents(instance)
|
||||
return
|
||||
|
||||
paths = self.parent_role if type(self.parent_role) is list else [self.parent_role]
|
||||
original_parents = getattr(self, '__original_parent_roles')
|
||||
new_parents = set()
|
||||
for path in paths:
|
||||
if path.startswith("singleton:"):
|
||||
parents = [Role.singleton(path[10:])]
|
||||
else:
|
||||
parents = resolve_role_field(instance, path)
|
||||
for parent in parents:
|
||||
new_parents.add(parent)
|
||||
new_parents = self._resolve_parent_roles(instance)
|
||||
|
||||
with batch_role_ancestor_rebuilding():
|
||||
for role in original_parents - new_parents:
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
# Django
|
||||
from django.conf import settings # noqa
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
|
||||
# AWX
|
||||
from awx.main.models.base import * # noqa
|
||||
@ -38,11 +39,13 @@ _PythonSerializer.handle_m2m_field = _new_handle_m2m_field
|
||||
from django.contrib.auth.models import User # noqa
|
||||
from awx.main.access import * # noqa
|
||||
|
||||
|
||||
User.add_to_class('get_queryset', get_user_queryset)
|
||||
User.add_to_class('can_access', check_user_access)
|
||||
User.add_to_class('accessible_by', user_accessible_by)
|
||||
User.add_to_class('accessible_objects', user_accessible_objects)
|
||||
User.add_to_class('admin_role', user_admin_role)
|
||||
User.add_to_class('role_permissions', GenericRelation('main.RolePermission'))
|
||||
|
||||
# Import signal handlers only after models have been defined.
|
||||
import awx.main.signals # noqa
|
||||
|
||||
@ -111,10 +111,12 @@ class Inventory(CommonModel, ResourceMixin):
|
||||
updater_role = ImplicitRoleField(
|
||||
role_name='Inventory Updater',
|
||||
role_description='May update the inventory',
|
||||
permissions = {'read': True, 'update': True}
|
||||
)
|
||||
executor_role = ImplicitRoleField(
|
||||
role_name='Inventory Executor',
|
||||
role_description='May execute jobs against this inventory',
|
||||
permissions = {'read': True, 'execute': True}
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
@ -545,6 +547,7 @@ class Group(CommonModelNameNotUnique, ResourceMixin):
|
||||
@transaction.atomic
|
||||
def delete_recursive(self):
|
||||
from awx.main.utils import ignore_inventory_computed_fields
|
||||
from awx.main.tasks import update_inventory_computed_fields
|
||||
from awx.main.signals import disable_activity_stream
|
||||
|
||||
|
||||
@ -1051,7 +1054,7 @@ class InventorySourceOptions(BaseModel):
|
||||
return ','.join(choices)
|
||||
|
||||
|
||||
class InventorySource(UnifiedJobTemplate, InventorySourceOptions, ResourceMixin):
|
||||
class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
|
||||
@ -32,7 +32,10 @@ class ResourceMixin(models.Model):
|
||||
performant to resolve the resource in question then call
|
||||
`myresource.get_permissions(user)`.
|
||||
'''
|
||||
return ResourceMixin._accessible_objects(cls, user, permissions)
|
||||
|
||||
@staticmethod
|
||||
def _accessible_objects(cls, user, permissions):
|
||||
qs = cls.objects.filter(
|
||||
role_permissions__role__ancestors__members=user
|
||||
)
|
||||
|
||||
@ -459,30 +459,19 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
self.check_get_list(url, 'nobody', qs)
|
||||
self.check_get_list(url, None, qs, expect=401)
|
||||
|
||||
# Explicitly give other user admin permission on the inventory (still
|
||||
# Explicitly give other user updater permission on the inventory (still
|
||||
# not allowed to run ad hoc commands).
|
||||
user_perm_url = reverse('api:user_permissions_list', args=(self.other_django_user.pk,))
|
||||
user_perm_data = {
|
||||
'name': 'Allow Other to Admin Inventory',
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'admin',
|
||||
}
|
||||
user_roles_list_url = reverse('api:user_roles_list', args=(self.other_django_user.pk,))
|
||||
with self.current_user('admin'):
|
||||
response = self.post(user_perm_url, user_perm_data, expect=201)
|
||||
user_perm_id = response['id']
|
||||
response = self.post(user_roles_list_url, {"id": self.inventory.updater_role.id}, expect=204)
|
||||
with self.current_user('other'):
|
||||
self.run_test_ad_hoc_command(expect=403)
|
||||
self.check_get_list(url, 'other', qs)
|
||||
|
||||
# Update permission to allow other user to run ad hoc commands. Fails
|
||||
# Add executor role permissions to other. Fails
|
||||
# when other user can't read credential.
|
||||
user_perm_url = reverse('api:permission_detail', args=(user_perm_id,))
|
||||
user_perm_data.update({
|
||||
'name': 'Allow Other to Admin Inventory and Run Ad Hoc Commands',
|
||||
'run_ad_hoc_commands': True,
|
||||
})
|
||||
with self.current_user('admin'):
|
||||
response = self.patch(user_perm_url, user_perm_data, expect=200)
|
||||
response = self.post(user_roles_list_url, {"id": self.inventory.executor_role.id}, expect=204)
|
||||
with self.current_user('other'):
|
||||
self.run_test_ad_hoc_command(expect=403)
|
||||
|
||||
@ -496,15 +485,9 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
self.check_get_list(url, 'other', qs)
|
||||
|
||||
# Explicitly give nobody user read permission on the inventory.
|
||||
user_perm_url = reverse('api:user_permissions_list', args=(self.nobody_django_user.pk,))
|
||||
user_perm_data = {
|
||||
'name': 'Allow Nobody to Read Inventory',
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'read',
|
||||
}
|
||||
nobody_roles_list_url = reverse('api:user_roles_list', args=(self.nobody_django_user.pk,))
|
||||
with self.current_user('admin'):
|
||||
response = self.post(user_perm_url, user_perm_data, expect=201)
|
||||
user_perm_id = response['id']
|
||||
response = self.post(nobody_roles_list_url, {"id": self.inventory.auditor_role.id}, expect=204)
|
||||
with self.current_user('nobody'):
|
||||
self.run_test_ad_hoc_command(credential=other_cred.pk, expect=403)
|
||||
self.check_get_list(url, 'other', qs)
|
||||
@ -520,13 +503,8 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
|
||||
# Give the nobody user the run_ad_hoc_commands flag, and can now see
|
||||
# the one ad hoc command previously run.
|
||||
user_perm_url = reverse('api:permission_detail', args=(user_perm_id,))
|
||||
user_perm_data.update({
|
||||
'name': 'Allow Nobody to Read Inventory and Run Ad Hoc Commands',
|
||||
'run_ad_hoc_commands': True,
|
||||
})
|
||||
with self.current_user('admin'):
|
||||
response = self.patch(user_perm_url, user_perm_data, expect=200)
|
||||
response = self.post(nobody_roles_list_url, {"id": self.inventory.executor_role.id}, expect=204)
|
||||
qs = AdHocCommand.objects.filter(credential_id=nobody_cred.pk)
|
||||
self.assertEqual(qs.count(), 1)
|
||||
self.check_get_list(url, 'nobody', qs)
|
||||
@ -947,7 +925,7 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
self.delete(url, expect=405)
|
||||
with self.current_user('normal'):
|
||||
response = self.get(url, expect=200)
|
||||
#self.assertEqual(response['count'], 1) # FIXME: Enable once activity stream RBAC is fixed.
|
||||
self.assertEqual(response['count'], 1)
|
||||
self.post(url, {}, expect=405)
|
||||
self.put(url, {}, expect=405)
|
||||
self.patch(url, {}, expect=405)
|
||||
@ -1026,29 +1004,17 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
# Create another unrelated inventory permission with run_ad_hoc_commands
|
||||
# set; this tests an edge case in the RBAC query where we'll return
|
||||
# can_run_ad_hoc_commands = True when we shouldn't.
|
||||
nobody_perm_url = reverse('api:user_permissions_list', args=(self.nobody_django_user.pk,))
|
||||
nobody_perm_data = {
|
||||
'name': 'Allow Nobody to Read Inventory',
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'read',
|
||||
'run_ad_hoc_commands': True,
|
||||
}
|
||||
nobody_roles_list_url = reverse('api:user_roles_list', args=(self.nobody_django_user.pk,))
|
||||
with self.current_user('admin'):
|
||||
response = self.post(nobody_perm_url, nobody_perm_data, expect=201)
|
||||
response = self.post(nobody_roles_list_url, {"id": self.inventory.executor_role.id}, expect=204)
|
||||
|
||||
# Create a credential for the other user and explicitly give other
|
||||
# user admin permission on the inventory (still not allowed to run ad
|
||||
# hoc commands; can get the list but can't see any items).
|
||||
other_cred = self.create_test_credential(user=self.other_django_user)
|
||||
user_perm_url = reverse('api:user_permissions_list', args=(self.other_django_user.pk,))
|
||||
user_perm_data = {
|
||||
'name': 'Allow Other to Admin Inventory',
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'admin',
|
||||
}
|
||||
user_roles_list_url = reverse('api:user_roles_list', args=(self.other_django_user.pk,))
|
||||
with self.current_user('admin'):
|
||||
response = self.post(user_perm_url, user_perm_data, expect=201)
|
||||
user_perm_id = response['id']
|
||||
response = self.post(user_roles_list_url, {"id": self.inventory.updater_role.id}, expect=204)
|
||||
with self.current_user('other'):
|
||||
response = self.get(url, expect=200)
|
||||
self.assertEqual(response['count'], 0)
|
||||
@ -1058,13 +1024,8 @@ class AdHocCommandApiTest(BaseAdHocCommandTest):
|
||||
|
||||
# Update permission to allow other user to run ad hoc commands. Can
|
||||
# only see his own ad hoc commands (because of credential permission).
|
||||
user_perm_url = reverse('api:permission_detail', args=(user_perm_id,))
|
||||
user_perm_data.update({
|
||||
'name': 'Allow Other to Admin Inventory and Run Ad Hoc Commands',
|
||||
'run_ad_hoc_commands': True,
|
||||
})
|
||||
with self.current_user('admin'):
|
||||
response = self.patch(user_perm_url, user_perm_data, expect=200)
|
||||
response = self.post(user_roles_list_url, {"id": self.inventory.executor_role.id}, expect=204)
|
||||
with self.current_user('other'):
|
||||
response = self.get(url, expect=200)
|
||||
self.assertEqual(response['count'], 0)
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
# All Rights Reserved.
|
||||
|
||||
# Python
|
||||
import datetime
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
@ -14,7 +13,6 @@ import time
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
# AWX
|
||||
from awx.main.models import * # noqa
|
||||
@ -47,9 +45,9 @@ class InventoryTest(BaseTest):
|
||||
self.setup_instances()
|
||||
self.setup_users()
|
||||
self.organizations = self.make_organizations(self.super_django_user, 3)
|
||||
self.organizations[0].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.other_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.normal_django_user)
|
||||
self.organizations[0].admin_role.members.add(self.normal_django_user)
|
||||
self.organizations[0].member_role.members.add(self.other_django_user)
|
||||
self.organizations[0].member_role.members.add(self.normal_django_user)
|
||||
|
||||
self.inventory_a = Inventory.objects.create(name='inventory-a', description='foo', organization=self.organizations[0])
|
||||
self.inventory_b = Inventory.objects.create(name='inventory-b', description='bar', organization=self.organizations[1])
|
||||
@ -58,10 +56,7 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# create a permission here on the 'other' user so they have edit access on the org
|
||||
# we may add another permission type later.
|
||||
self.perm_read = Permission.objects.create(
|
||||
inventory = self.inventory_b,
|
||||
user = self.other_django_user,
|
||||
permission_type = 'read')
|
||||
self.inventory_b.auditor_role.members.add(self.other_django_user)
|
||||
|
||||
def tearDown(self):
|
||||
super(InventoryTest, self).tearDown()
|
||||
@ -78,11 +73,11 @@ class InventoryTest(BaseTest):
|
||||
self.check_get_list(url, self.super_django_user, qs)
|
||||
|
||||
# an org admin can list inventories but is filtered to what he adminsters
|
||||
normal_qs = qs.filter(organization__deprecated_admins__in=[self.normal_django_user])
|
||||
normal_qs = qs.filter(organization__admin_role__members=self.normal_django_user)
|
||||
self.check_get_list(url, self.normal_django_user, normal_qs)
|
||||
|
||||
# a user who is on a team who has a read permissions on an inventory can see filtered inventories
|
||||
other_qs = qs.filter(permissions__user__in=[self.other_django_user])
|
||||
other_qs = Inventory.accessible_objects(self.other_django_user, {'read': True}).distinct()
|
||||
self.check_get_list(url, self.other_django_user, other_qs)
|
||||
|
||||
# a regular user not part of anything cannot see any inventories
|
||||
@ -263,24 +258,20 @@ class InventoryTest(BaseTest):
|
||||
|
||||
def test_inventory_access_deleted_permissions(self):
|
||||
temp_org = self.make_organizations(self.super_django_user, 1)[0]
|
||||
temp_org.deprecated_admins.add(self.normal_django_user)
|
||||
temp_org.deprecated_users.add(self.other_django_user)
|
||||
temp_org.deprecated_users.add(self.normal_django_user)
|
||||
temp_org.admin_role.members.add(self.normal_django_user)
|
||||
temp_org.member_role.members.add(self.other_django_user)
|
||||
temp_org.member_role.members.add(self.normal_django_user)
|
||||
temp_inv = temp_org.inventories.create(name='Delete Org Inventory')
|
||||
temp_inv.groups.create(name='Delete Org Inventory Group')
|
||||
|
||||
temp_perm_read = Permission.objects.create(
|
||||
inventory = temp_inv,
|
||||
user = self.other_django_user,
|
||||
permission_type = 'read'
|
||||
)
|
||||
temp_inv.auditor_role.members.add(self.other_django_user)
|
||||
|
||||
reverse('api:organization_detail', args=(temp_org.pk,))
|
||||
inventory_detail = reverse('api:inventory_detail', args=(temp_inv.pk,))
|
||||
permission_detail = reverse('api:permission_detail', args=(temp_perm_read.pk,))
|
||||
auditor_role_users_list = reverse('api:role_users_list', args=(temp_inv.auditor_role.pk,))
|
||||
|
||||
self.get(inventory_detail, expect=200, auth=self.get_other_credentials())
|
||||
self.delete(permission_detail, expect=204, auth=self.get_super_credentials())
|
||||
self.post(auditor_role_users_list, data={'disassociate': True, "id": self.other_django_user.id}, expect=204, auth=self.get_super_credentials())
|
||||
self.get(inventory_detail, expect=403, auth=self.get_other_credentials())
|
||||
|
||||
def test_create_inventory_script(self):
|
||||
@ -335,10 +326,8 @@ class InventoryTest(BaseTest):
|
||||
self.post(hosts, data=new_host_b, expect=403, auth=self.get_nobody_credentials())
|
||||
|
||||
# a normal user with inventory edit permissions (on any inventory) can create hosts
|
||||
Permission.objects.create(
|
||||
user = self.other_django_user,
|
||||
inventory = Inventory.objects.get(pk=inv.pk),
|
||||
permission_type = PERM_INVENTORY_WRITE)
|
||||
|
||||
inv.admin_role.members.add(self.other_django_user)
|
||||
host_data3 = self.post(hosts, data=new_host_c, expect=201, auth=self.get_other_credentials())
|
||||
|
||||
# Port should be split out into host variables, other variables kept intact.
|
||||
@ -393,11 +382,6 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with inventory edit permissions (on any inventory) can create groups
|
||||
# already done!
|
||||
#edit_perm = Permission.objects.create(
|
||||
# user = self.other_django_user,
|
||||
# inventory = Inventory.objects.get(pk=inv.pk),
|
||||
# permission_type = PERM_INVENTORY_WRITE
|
||||
#)
|
||||
self.post(groups, data=new_group_c, expect=201, auth=self.get_other_credentials())
|
||||
|
||||
# hostnames must be unique inside an organization
|
||||
@ -417,9 +401,10 @@ class InventoryTest(BaseTest):
|
||||
del_children_url = reverse('api:group_children_list', args=(del_group.pk,))
|
||||
nondel_url = reverse('api:group_detail',
|
||||
args=(Group.objects.get(name='nondel').pk,))
|
||||
assert(inv.accessible_by(self.normal_django_user, {'read': True}))
|
||||
del_group.delete()
|
||||
nondel_detail = self.get(nondel_url, expect=200, auth=self.get_normal_credentials())
|
||||
self.post(del_children_url, data=nondel_detail, expect=403, auth=self.get_normal_credentials())
|
||||
self.post(del_children_url, data=nondel_detail, expect=400, auth=self.get_normal_credentials())
|
||||
|
||||
|
||||
#################################################
|
||||
@ -656,11 +641,7 @@ class InventoryTest(BaseTest):
|
||||
gx5 = Group.objects.create(name='group-X5', inventory=inva)
|
||||
gx5.parents.add(gx4)
|
||||
|
||||
Permission.objects.create(
|
||||
inventory = inva,
|
||||
user = self.other_django_user,
|
||||
permission_type = PERM_INVENTORY_WRITE
|
||||
)
|
||||
inva.admin_role.members.add(self.other_django_user)
|
||||
|
||||
# data used for testing listing all hosts that are transitive members of a group
|
||||
g2 = Group.objects.get(name='web4')
|
||||
@ -1115,59 +1096,6 @@ class InventoryTest(BaseTest):
|
||||
self.assertEqual(response['hosts']['total'], 8)
|
||||
self.assertEqual(response['hosts']['failed'], 8)
|
||||
|
||||
def test_dashboard_inventory_graph_view(self):
|
||||
url = reverse('api:dashboard_inventory_graph_view')
|
||||
# Test with zero hosts.
|
||||
with self.current_user(self.super_django_user):
|
||||
response = self.get(url)
|
||||
self.assertFalse(sum([x[1] for x in response['hosts']]))
|
||||
# Create hosts in inventory_a, with created one day apart, and check
|
||||
# the time series results.
|
||||
dtnow = now()
|
||||
hostnames = list('abcdefg')
|
||||
for x in xrange(len(hostnames) - 1, -1, -1):
|
||||
hostname = hostnames[x]
|
||||
created = dtnow - datetime.timedelta(days=x, seconds=60)
|
||||
self.inventory_a.hosts.create(name=hostname, created=created)
|
||||
with self.current_user(self.super_django_user):
|
||||
response = self.get(url)
|
||||
for n, d in enumerate(reversed(response['hosts'])):
|
||||
self.assertEqual(d[1], max(len(hostnames) - n, 0))
|
||||
# Create more hosts a day apart in inventory_b and check the time
|
||||
# series results.
|
||||
hostnames2 = list('hijklmnop')
|
||||
for x in xrange(len(hostnames2) - 1, -1, -1):
|
||||
hostname = hostnames2[x]
|
||||
created = dtnow - datetime.timedelta(days=x, seconds=120)
|
||||
self.inventory_b.hosts.create(name=hostname, created=created)
|
||||
with self.current_user(self.super_django_user):
|
||||
response = self.get(url)
|
||||
for n, d in enumerate(reversed(response['hosts'])):
|
||||
self.assertEqual(d[1], max(len(hostnames2) - n, 0) + max(len(hostnames) - n, 0))
|
||||
# Now create some hosts in inventory_a with the same hostnames already
|
||||
# used in inventory_b; duplicate hostnames should only be counted the
|
||||
# first time they were seen in inventory_b.
|
||||
hostnames3 = list('lmnop')
|
||||
for x in xrange(len(hostnames3) - 1, -1, -1):
|
||||
hostname = hostnames3[x]
|
||||
created = dtnow - datetime.timedelta(days=x, seconds=180)
|
||||
self.inventory_a.hosts.create(name=hostname, created=created)
|
||||
with self.current_user(self.super_django_user):
|
||||
response = self.get(url)
|
||||
for n, d in enumerate(reversed(response['hosts'])):
|
||||
self.assertEqual(d[1], max(len(hostnames2) - n, 0) + max(len(hostnames) - n, 0))
|
||||
# Delete recently added hosts and verify the count drops.
|
||||
hostnames4 = list('defg')
|
||||
for host in Host.objects.filter(name__in=hostnames4):
|
||||
host.delete()
|
||||
with self.current_user(self.super_django_user):
|
||||
response = self.get(url)
|
||||
for n, d in enumerate(reversed(response['hosts'])):
|
||||
count = max(len(hostnames2) - n, 0) + max(len(hostnames) - n, 0)
|
||||
if n == 0:
|
||||
count -= 4
|
||||
self.assertEqual(d[1], count)
|
||||
|
||||
|
||||
@override_settings(CELERY_ALWAYS_EAGER=True,
|
||||
CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
|
||||
@ -1181,9 +1109,9 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
self.setup_instances()
|
||||
self.setup_users()
|
||||
self.organization = self.make_organizations(self.super_django_user, 1)[0]
|
||||
self.organization.deprecated_admins.add(self.normal_django_user)
|
||||
self.organization.deprecated_users.add(self.other_django_user)
|
||||
self.organization.deprecated_users.add(self.normal_django_user)
|
||||
self.organization.admin_role.members.add(self.normal_django_user)
|
||||
self.organization.member_role.members.add(self.other_django_user)
|
||||
self.organization.member_role.members.add(self.normal_django_user)
|
||||
self.inventory = self.organization.inventories.create(name='Cloud Inventory')
|
||||
self.group = self.inventory.groups.create(name='Cloud Group')
|
||||
self.inventory2 = self.organization.inventories.create(name='Cloud Inventory 2')
|
||||
@ -1256,7 +1184,7 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
url = reverse('api:inventory_source_hosts_list', args=(inventory_source.pk,))
|
||||
response = self.get(url, expect=200)
|
||||
self.assertNotEqual(response['count'], 0)
|
||||
for host in inventory.hosts:
|
||||
for host in inventory.hosts.all():
|
||||
source_pks = host.inventory_sources.values_list('pk', flat=True)
|
||||
self.assertTrue(inventory_source.pk in source_pks)
|
||||
self.assertTrue(host.has_inventory_sources)
|
||||
@ -1270,7 +1198,7 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
url = reverse('api:host_inventory_sources_list', args=(host.pk,))
|
||||
response = self.get(url, expect=200)
|
||||
self.assertNotEqual(response['count'], 0)
|
||||
for group in inventory.groups:
|
||||
for group in inventory.groups.all():
|
||||
source_pks = group.inventory_sources.values_list('pk', flat=True)
|
||||
self.assertTrue(inventory_source.pk in source_pks)
|
||||
self.assertTrue(group.has_inventory_sources)
|
||||
@ -1293,7 +1221,7 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
self.assertNotEqual(response['count'], 0)
|
||||
# Try to set a source on a child group that was imported. Should not
|
||||
# be allowed.
|
||||
for group in inventory_source.group.children:
|
||||
for group in inventory_source.group.children.all():
|
||||
inv_src_2 = group.inventory_source
|
||||
inv_src_url2 = reverse('api:inventory_source_detail', args=(inv_src_2.pk,))
|
||||
with self.current_user(self.super_django_user):
|
||||
@ -1540,16 +1468,9 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
self.post(inv_src_update_url, {}, expect=403)
|
||||
# If given read permission to the inventory, other user should be able
|
||||
# to see the inventory source and update view, but not start an update.
|
||||
other_perms_url = reverse('api:user_permissions_list',
|
||||
args=(self.other_django_user.pk,))
|
||||
other_perms_data = {
|
||||
'name': 'read only inventory permission for other',
|
||||
'user': self.other_django_user.pk,
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'read',
|
||||
}
|
||||
user_roles_list_url = reverse('api:user_roles_list', args=(self.other_django_user.pk,))
|
||||
with self.current_user(self.super_django_user):
|
||||
self.post(other_perms_url, other_perms_data, expect=201)
|
||||
self.post(user_roles_list_url, {"id": self.inventory.auditor_role.id}, expect=204)
|
||||
with self.current_user(self.other_django_user):
|
||||
self.get(inv_src_url, expect=200)
|
||||
response = self.get(inv_src_update_url, expect=200)
|
||||
@ -1557,14 +1478,8 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
self.post(inv_src_update_url, {}, expect=403)
|
||||
# Once given write permission, the normal user is able to update the
|
||||
# inventory source.
|
||||
other_perms_data = {
|
||||
'name': 'read-write inventory permission for other',
|
||||
'user': self.other_django_user.pk,
|
||||
'inventory': self.inventory.pk,
|
||||
'permission_type': 'write',
|
||||
}
|
||||
with self.current_user(self.super_django_user):
|
||||
self.post(other_perms_url, other_perms_data, expect=201)
|
||||
self.post(user_roles_list_url, {"id": self.inventory.admin_role.id}, expect=204)
|
||||
with self.current_user(self.other_django_user):
|
||||
self.get(inv_src_url, expect=200)
|
||||
response = self.get(inv_src_update_url, expect=200)
|
||||
@ -1649,7 +1564,7 @@ class InventoryUpdatesTest(BaseTransactionTest):
|
||||
inventory_source.overwrite = True
|
||||
inventory_source.save()
|
||||
self.check_inventory_source(inventory_source, initial=False)
|
||||
for host in self.inventory.hosts:
|
||||
for host in self.inventory.hosts.all():
|
||||
self.assertEqual(host.variables_dict['ec2_instance_type'], instance_type)
|
||||
|
||||
# Try invalid instance filters that should be ignored:
|
||||
|
||||
@ -19,7 +19,7 @@ class LicenseTests(BaseTest):
|
||||
self.setup_users()
|
||||
u = self.super_django_user
|
||||
org = Organization.objects.create(name='o1', created_by=u)
|
||||
org.deprecated_admins.add(self.normal_django_user)
|
||||
org.admin_role.members.add(self.normal_django_user)
|
||||
self.inventory = Inventory.objects.create(name='hi', organization=org, created_by=u)
|
||||
Host.objects.create(name='a1', inventory=self.inventory, created_by=u)
|
||||
Host.objects.create(name='a2', inventory=self.inventory, created_by=u)
|
||||
|
||||
@ -88,12 +88,12 @@ class OrganizationsTest(BaseTest):
|
||||
# nobody_user is a user not a member of any organizations
|
||||
|
||||
for x in self.organizations:
|
||||
x.deprecated_admins.add(self.super_django_user)
|
||||
x.deprecated_users.add(self.super_django_user)
|
||||
x.deprecated_users.add(self.other_django_user)
|
||||
x.admin_role.members.add(self.super_django_user)
|
||||
x.member_role.members.add(self.super_django_user)
|
||||
x.member_role.members.add(self.other_django_user)
|
||||
|
||||
self.organizations[0].deprecated_users.add(self.normal_django_user)
|
||||
self.organizations[1].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].member_role.members.add(self.normal_django_user)
|
||||
self.organizations[1].admin_role.members.add(self.normal_django_user)
|
||||
|
||||
def test_get_organization_list(self):
|
||||
url = reverse('api:organization_list')
|
||||
|
||||
@ -75,10 +75,10 @@ class ProjectsTest(BaseTransactionTest):
|
||||
for x in self.organizations:
|
||||
# NOTE: superuser does not have to be explicitly added to admin group
|
||||
# x.admins.add(self.super_django_user)
|
||||
x.deprecated_users.add(self.super_django_user)
|
||||
x.member_role.members.add(self.super_django_user)
|
||||
|
||||
self.organizations[0].deprecated_users.add(self.normal_django_user)
|
||||
self.organizations[1].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].member_role.members.add(self.normal_django_user)
|
||||
self.organizations[1].admin_role.members.add(self.normal_django_user)
|
||||
|
||||
self.team1 = Team.objects.create(
|
||||
name = 'team1', organization = self.organizations[0]
|
||||
@ -97,8 +97,8 @@ class ProjectsTest(BaseTransactionTest):
|
||||
self.team2.projects.add(self.projects[5])
|
||||
self.team1.save()
|
||||
self.team2.save()
|
||||
self.team1.deprecated_users.add(self.normal_django_user)
|
||||
self.team2.deprecated_users.add(self.other_django_user)
|
||||
self.team1.member_role.members.add(self.normal_django_user)
|
||||
self.team2.member_role.members.add(self.other_django_user)
|
||||
|
||||
def test_playbooks(self):
|
||||
def write_test_file(project, name, content):
|
||||
@ -312,7 +312,7 @@ class ProjectsTest(BaseTransactionTest):
|
||||
|
||||
# Verify that creatorship doesn't imply access if access is removed
|
||||
a_new_proj = self.make_project(created_by=self.other_django_user, playbook_content=TEST_PLAYBOOK)
|
||||
self.organizations[0].deprecated_admins.add(self.other_django_user)
|
||||
self.organizations[0].admin_role.members.add(self.other_django_user)
|
||||
self.organizations[0].projects.add(a_new_proj)
|
||||
proj_detail = reverse('api:project_detail', args=(a_new_proj.pk,))
|
||||
self.patch(proj_detail, data=dict(description="test"), expect=200, auth=self.get_other_credentials())
|
||||
@ -337,7 +337,7 @@ class ProjectsTest(BaseTransactionTest):
|
||||
self.assertEquals(got['url'], reverse('api:team_detail', args=(self.team1.pk,)))
|
||||
got = self.get(team1, expect=200, auth=self.get_normal_credentials())
|
||||
got = self.get(team1, expect=403, auth=self.get_other_credentials())
|
||||
self.team1.deprecated_users.add(User.objects.get(username='other'))
|
||||
self.team1.member_role.members.add(User.objects.get(username='other'))
|
||||
self.team1.save()
|
||||
got = self.get(team1, expect=200, auth=self.get_other_credentials())
|
||||
got = self.get(team1, expect=403, auth=self.get_nobody_credentials())
|
||||
@ -422,7 +422,7 @@ class ProjectsTest(BaseTransactionTest):
|
||||
team = Team.objects.filter( organization__pk=self.organizations[1].pk)[0]
|
||||
team_users = reverse('api:team_users_list', args=(team.pk,))
|
||||
for x in team.deprecated_users.all():
|
||||
team.deprecated_users.remove(x)
|
||||
team.member_role.members.remove(x)
|
||||
team.save()
|
||||
|
||||
# can list uses on teams
|
||||
@ -787,7 +787,7 @@ class ProjectsTest(BaseTransactionTest):
|
||||
# User is still a team member
|
||||
self.get(reverse('api:project_detail', args=(project.pk,)), expect=200, auth=self.get_other_credentials())
|
||||
|
||||
team.deprecated_users.remove(self.other_django_user)
|
||||
team.member_role.members.remove(self.other_django_user)
|
||||
|
||||
# User is no longer a team member and has no permissions
|
||||
self.get(reverse('api:project_detail', args=(project.pk,)), expect=403, auth=self.get_other_credentials())
|
||||
@ -1351,7 +1351,7 @@ class ProjectUpdatesTest(BaseTransactionTest):
|
||||
'scm_url': scm_url,
|
||||
}
|
||||
org = self.make_organizations(self.super_django_user, 1)[0]
|
||||
org.deprecated_admins.add(self.normal_django_user)
|
||||
org.admin_role.members.add(self.normal_django_user)
|
||||
with self.current_user(self.super_django_user):
|
||||
del_proj = self.post(projects_url, project_data, expect=201)
|
||||
del_proj = Project.objects.get(pk=del_proj["id"])
|
||||
|
||||
@ -54,12 +54,12 @@ class ScheduleTest(BaseTest):
|
||||
self.setup_instances()
|
||||
self.setup_users()
|
||||
self.organizations = self.make_organizations(self.super_django_user, 2)
|
||||
self.organizations[0].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.other_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.normal_django_user)
|
||||
self.organizations[0].admin_role.members.add(self.normal_django_user)
|
||||
self.organizations[0].member_role.members.add(self.other_django_user)
|
||||
self.organizations[0].member_role.members.add(self.normal_django_user)
|
||||
|
||||
self.diff_org_user = self.make_user('fred')
|
||||
self.organizations[1].deprecated_users.add(self.diff_org_user)
|
||||
self.organizations[1].member_role.members.add(self.diff_org_user)
|
||||
|
||||
self.cloud_source = Credential.objects.create(kind='awx', user=self.super_django_user,
|
||||
username='Dummy', password='Dummy')
|
||||
@ -71,11 +71,7 @@ class ScheduleTest(BaseTest):
|
||||
self.first_inventory_source.source = 'ec2'
|
||||
self.first_inventory_source.save()
|
||||
|
||||
Permission.objects.create(
|
||||
inventory = self.first_inventory,
|
||||
user = self.other_django_user,
|
||||
permission_type = 'read'
|
||||
)
|
||||
self.first_inventory.auditor_role.members.add(self.other_django_user)
|
||||
|
||||
self.second_inventory = Inventory.objects.create(name='test_inventory_2', description='for org 0', organization=self.organizations[0])
|
||||
self.second_inventory.hosts.create(name='host_2')
|
||||
@ -139,11 +135,7 @@ class ScheduleTest(BaseTest):
|
||||
self.post(first_url, data=unauth_schedule, expect=403)
|
||||
|
||||
#give normal user write access and then they can post
|
||||
Permission.objects.create(
|
||||
user = self.other_django_user,
|
||||
inventory = self.first_inventory,
|
||||
permission_type = PERM_INVENTORY_WRITE
|
||||
)
|
||||
self.first_inventory.admin_role.members.add(self.other_django_user)
|
||||
auth_schedule = unauth_schedule
|
||||
with self.current_user(self.other_django_user):
|
||||
self.post(first_url, data=auth_schedule, expect=201)
|
||||
|
||||
@ -100,7 +100,7 @@ class AuthTokenProxyTest(BaseTest):
|
||||
self.setup_users()
|
||||
self.setup_instances()
|
||||
self.organizations = self.make_organizations(self.super_django_user, 2)
|
||||
self.organizations[0].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].admin_role.members.add(self.normal_django_user)
|
||||
|
||||
self.assertIn('REMOTE_ADDR', settings.REMOTE_HOST_HEADERS)
|
||||
self.assertIn('REMOTE_HOST', settings.REMOTE_HOST_HEADERS)
|
||||
@ -174,10 +174,10 @@ class UsersTest(BaseTest):
|
||||
super(UsersTest, self).setUp()
|
||||
self.setup_users()
|
||||
self.organizations = self.make_organizations(self.super_django_user, 2)
|
||||
self.organizations[0].deprecated_admins.add(self.normal_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.other_django_user)
|
||||
self.organizations[0].deprecated_users.add(self.normal_django_user)
|
||||
self.organizations[1].deprecated_users.add(self.other_django_user)
|
||||
self.organizations[0].admin_role.members.add(self.normal_django_user)
|
||||
self.organizations[0].member_role.members.add(self.other_django_user)
|
||||
self.organizations[0].member_role.members.add(self.normal_django_user)
|
||||
self.organizations[1].member_role.members.add(self.other_django_user)
|
||||
|
||||
def test_user_creation_fails_without_password(self):
|
||||
url = reverse('api:user_list')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user