mirror of
https://github.com/ansible/awx.git
synced 2026-03-13 23:17:32 -02:30
@@ -214,7 +214,7 @@ class ApiV1ConfigView(APIView):
|
|||||||
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_FLAGS_BY_GROUP', {}).keys())
|
user_ldap_fields.extend(getattr(settings, 'AUTH_LDAP_USER_FLAGS_BY_GROUP', {}).keys())
|
||||||
data['user_ldap_fields'] = user_ldap_fields
|
data['user_ldap_fields'] = user_ldap_fields
|
||||||
|
|
||||||
if request.user.is_superuser or request.user.admin_of_organizations.count():
|
if request.user.is_superuser or Organization.accessible_objects(request.user, {'write': True}).count():
|
||||||
data.update(dict(
|
data.update(dict(
|
||||||
project_base_dir = settings.PROJECTS_ROOT,
|
project_base_dir = settings.PROJECTS_ROOT,
|
||||||
project_local_paths = Project.get_local_path_choices(),
|
project_local_paths = Project.get_local_path_choices(),
|
||||||
@@ -999,13 +999,16 @@ class UserMeList(ListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.model.objects.filter(pk=self.request.user.pk)
|
return self.model.objects.filter(pk=self.request.user.pk)
|
||||||
|
|
||||||
class UserTeamsList(SubListAPIView):
|
class UserTeamsList(ListAPIView):
|
||||||
|
|
||||||
model = Team
|
model = User
|
||||||
serializer_class = TeamSerializer
|
serializer_class = TeamSerializer
|
||||||
parent_model = User
|
|
||||||
relationship = 'teams'
|
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
u = User.objects.get(pk=self.kwargs['pk'])
|
||||||
|
if not u.accessible_by(self.request.user, {'read': True}):
|
||||||
|
raise PermissionDenied()
|
||||||
|
return Team.accessible_objects(self.request.user, {'read': True}).filter(member_role__members=u)
|
||||||
|
|
||||||
class UserRolesList(SubListCreateAttachDetachAPIView):
|
class UserRolesList(SubListCreateAttachDetachAPIView):
|
||||||
|
|
||||||
@@ -1043,8 +1046,9 @@ class UserProjectsList(SubListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
parent = self.get_parent_object()
|
parent = self.get_parent_object()
|
||||||
self.check_parent_access(parent)
|
self.check_parent_access(parent)
|
||||||
qs = self.request.user.get_queryset(self.model)
|
my_qs = Project.accessible_objects(self.request.user, {'read': True})
|
||||||
return qs.filter(teams__in=parent.teams.distinct())
|
user_qs = Project.accessible_objects(parent, {'read': True})
|
||||||
|
return my_qs & user_qs
|
||||||
|
|
||||||
class UserCredentialsList(SubListCreateAttachDetachAPIView):
|
class UserCredentialsList(SubListCreateAttachDetachAPIView):
|
||||||
|
|
||||||
|
|||||||
@@ -198,12 +198,10 @@ class BaseAccess(object):
|
|||||||
class UserAccess(BaseAccess):
|
class UserAccess(BaseAccess):
|
||||||
'''
|
'''
|
||||||
I can see user records when:
|
I can see user records when:
|
||||||
- I'm a superuser.
|
- I'm a useruser
|
||||||
- I'm that user.
|
- I'm in a role with them (such as in an organization or team)
|
||||||
- I'm an org admin (org admins should be able to see all users, in order
|
- They are in a role which includes a role of mine
|
||||||
to add those users to the org).
|
- I am in a role that includes a role of theirs
|
||||||
- I'm in an org with that user.
|
|
||||||
- I'm on a team with that user.
|
|
||||||
I can change some fields for a user (mainly password) when I am that user.
|
I can change some fields for a user (mainly password) when I am that user.
|
||||||
I can change all fields for a user (admin access) or delete when:
|
I can change all fields for a user (admin access) or delete when:
|
||||||
- I'm a superuser.
|
- I'm a superuser.
|
||||||
@@ -213,8 +211,17 @@ class UserAccess(BaseAccess):
|
|||||||
model = User
|
model = User
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = User.accessible_objects(self.user, {'read':True})
|
if self.user.is_superuser:
|
||||||
return qs
|
return User.objects
|
||||||
|
|
||||||
|
viewable_users_set = set()
|
||||||
|
viewable_users_set.update(self.user.roles.values_list('ancestors__members__id', flat=True))
|
||||||
|
viewable_users_set.update(self.user.roles.values_list('descendents__members__id', flat=True))
|
||||||
|
|
||||||
|
return User.objects.filter(id__in=viewable_users_set)
|
||||||
|
#qs = User.objects.filter(self.user, {'read':True})
|
||||||
|
#qs = User.objects.
|
||||||
|
#return qs
|
||||||
|
|
||||||
def can_add(self, data):
|
def can_add(self, data):
|
||||||
if data is not None and 'is_superuser' in data:
|
if data is not None and 'is_superuser' in data:
|
||||||
@@ -237,7 +244,7 @@ class UserAccess(BaseAccess):
|
|||||||
# Admin implies changing all user fields.
|
# Admin implies changing all user fields.
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
return obj.accessible_by(self.user, {'create': True, 'write':True, 'update':True, 'read':True})
|
return Organization.objects.filter(member_role__members=obj, admin_role__members=self.user).exists()
|
||||||
|
|
||||||
def can_delete(self, obj):
|
def can_delete(self, obj):
|
||||||
if obj == self.user:
|
if obj == self.user:
|
||||||
@@ -623,6 +630,8 @@ class ProjectAccess(BaseAccess):
|
|||||||
model = Project
|
model = Project
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
if self.user.is_superuser:
|
||||||
|
return self.model.objects
|
||||||
qs = self.model.accessible_objects(self.user, {'read':True})
|
qs = self.model.accessible_objects(self.user, {'read':True})
|
||||||
qs = qs.select_related('modified_by', 'credential', 'current_job', 'last_job')
|
qs = qs.select_related('modified_by', 'credential', 'current_job', 'last_job')
|
||||||
return qs
|
return qs
|
||||||
@@ -654,6 +663,8 @@ class ProjectUpdateAccess(BaseAccess):
|
|||||||
model = ProjectUpdate
|
model = ProjectUpdate
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
if self.user.is_superuser:
|
||||||
|
return self.model.objects
|
||||||
qs = ProjectUpdate.objects.distinct()
|
qs = ProjectUpdate.objects.distinct()
|
||||||
qs = qs.select_related('created_by', 'modified_by', 'project')
|
qs = qs.select_related('created_by', 'modified_by', 'project')
|
||||||
project_ids = set(self.user.get_queryset(Project).values_list('id', flat=True))
|
project_ids = set(self.user.get_queryset(Project).values_list('id', flat=True))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db import connection
|
|
||||||
from django.db.models.signals import (
|
from django.db.models.signals import (
|
||||||
post_init,
|
post_init,
|
||||||
pre_save,
|
pre_save,
|
||||||
@@ -19,10 +18,6 @@ from django.db.models.fields.related import (
|
|||||||
ReverseManyRelatedObjectsDescriptor,
|
ReverseManyRelatedObjectsDescriptor,
|
||||||
)
|
)
|
||||||
|
|
||||||
from django.core.exceptions import FieldError
|
|
||||||
from django.db.transaction import TransactionManagementError
|
|
||||||
|
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models.rbac import RolePermission, Role, batch_role_ancestor_rebuilding
|
from awx.main.models.rbac import RolePermission, Role, batch_role_ancestor_rebuilding
|
||||||
|
|
||||||
@@ -155,9 +150,9 @@ class ImplicitRoleField(models.ForeignKey):
|
|||||||
for pk in pk_set:
|
for pk in pk_set:
|
||||||
obj = model.objects.get(pk=pk)
|
obj = model.objects.get(pk=pk)
|
||||||
if action == 'post_add':
|
if action == 'post_add':
|
||||||
getattr(instance, self.name).children.add(getattr(obj, field_attr))
|
getattr(instance, field_attr).children.add(getattr(obj, self.name))
|
||||||
if action == 'pre_remove':
|
if action == 'pre_remove':
|
||||||
getattr(instance, self.name).children.remove(getattr(obj, field_attr))
|
getattr(instance, field_attr).children.remove(getattr(obj, self.name))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for pk in pk_set:
|
for pk in pk_set:
|
||||||
@@ -182,8 +177,9 @@ class ImplicitRoleField(models.ForeignKey):
|
|||||||
if role:
|
if role:
|
||||||
return role
|
return role
|
||||||
role = Role.objects.create(
|
role = Role.objects.create(
|
||||||
name=self.role_name,
|
name=self.role_name,
|
||||||
description=self.role_description)
|
description=self.role_description
|
||||||
|
)
|
||||||
setattr(instance, self.name, role)
|
setattr(instance, self.name, role)
|
||||||
|
|
||||||
def _patch_role_content_object_and_grant_permissions(self, instance):
|
def _patch_role_content_object_and_grant_permissions(self, instance):
|
||||||
|
|||||||
@@ -202,12 +202,12 @@ class UserAccess(BaseAccess):
|
|||||||
qs = self.model.objects.distinct()
|
qs = self.model.objects.distinct()
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return qs
|
return qs
|
||||||
if tower_settings.ORG_ADMINS_CAN_SEE_ALL_USERS and self.user.admin_of_organizations.all().exists():
|
if tower_settings.ORG_ADMINS_CAN_SEE_ALL_USERS and self.user.deprecated_admin_of_organizations.all().exists():
|
||||||
return qs
|
return qs
|
||||||
return qs.filter(
|
return qs.filter(
|
||||||
Q(pk=self.user.pk) |
|
Q(pk=self.user.pk) |
|
||||||
Q(organizations__in=self.user.admin_of_organizations) |
|
Q(organizations__in=self.user.deprecated_admin_of_organizations) |
|
||||||
Q(organizations__in=self.user.organizations) |
|
Q(organizations__in=self.user.deprecated_organizations) |
|
||||||
Q(teams__in=self.user.teams)
|
Q(teams__in=self.user.teams)
|
||||||
).distinct()
|
).distinct()
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ class UserAccess(BaseAccess):
|
|||||||
if to_python_boolean(data['is_superuser'], allow_none=True) and not self.user.is_superuser:
|
if to_python_boolean(data['is_superuser'], allow_none=True) and not self.user.is_superuser:
|
||||||
return False
|
return False
|
||||||
return bool(self.user.is_superuser or
|
return bool(self.user.is_superuser or
|
||||||
self.user.admin_of_organizations.exists())
|
self.user.deprecated_admin_of_organizations.exists())
|
||||||
|
|
||||||
def can_change(self, obj, data):
|
def can_change(self, obj, data):
|
||||||
if data is not None and 'is_superuser' in data:
|
if data is not None and 'is_superuser' in data:
|
||||||
@@ -231,7 +231,7 @@ class UserAccess(BaseAccess):
|
|||||||
# Admin implies changing all user fields.
|
# Admin implies changing all user fields.
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
return bool(obj.organizations.filter(deprecated_admins__in=[self.user]).exists())
|
return bool(obj.deprecated_organizations.filter(deprecated_admins__in=[self.user]).exists())
|
||||||
|
|
||||||
def can_delete(self, obj):
|
def can_delete(self, obj):
|
||||||
if obj == self.user:
|
if obj == self.user:
|
||||||
@@ -242,7 +242,7 @@ class UserAccess(BaseAccess):
|
|||||||
# cannot delete the last active superuser
|
# cannot delete the last active superuser
|
||||||
return False
|
return False
|
||||||
return bool(self.user.is_superuser or
|
return bool(self.user.is_superuser or
|
||||||
obj.organizations.filter(deprecated_admins__in=[self.user]).exists())
|
obj.deprecated_organizations.filter(deprecated_admins__in=[self.user]).exists())
|
||||||
|
|
||||||
class OrganizationAccess(BaseAccess):
|
class OrganizationAccess(BaseAccess):
|
||||||
'''
|
'''
|
||||||
@@ -326,7 +326,7 @@ class InventoryAccess(BaseAccess):
|
|||||||
# If no data is specified, just checking for generic add permission?
|
# If no data is specified, just checking for generic add permission?
|
||||||
if not data:
|
if not data:
|
||||||
return bool(self.user.is_superuser or
|
return bool(self.user.is_superuser or
|
||||||
self.user.admin_of_organizations.exists())
|
self.user.deprecated_admin_of_organizations.exists())
|
||||||
# Otherwise, verify that the user has access to change the parent
|
# Otherwise, verify that the user has access to change the parent
|
||||||
# organization of this inventory.
|
# organization of this inventory.
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
@@ -568,11 +568,11 @@ class CredentialAccess(BaseAccess):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
# Get the list of organizations for which the user is an admin
|
# Get the list of organizations for which the user is an admin
|
||||||
orgs_as_admin_ids = set(self.user.admin_of_organizations.values_list('id', flat=True))
|
orgs_as_admin_ids = set(self.user.deprecated_admin_of_organizations.values_list('id', flat=True))
|
||||||
return qs.filter(
|
return qs.filter(
|
||||||
Q(user=self.user) |
|
Q(user=self.user) |
|
||||||
Q(user__organizations__id__in=orgs_as_admin_ids) |
|
Q(user__deprecated_organizations__id__in=orgs_as_admin_ids) |
|
||||||
Q(user__admin_of_organizations__id__in=orgs_as_admin_ids) |
|
Q(user__deprecated_admin_of_organizations__id__in=orgs_as_admin_ids) |
|
||||||
Q(team__organization__id__in=orgs_as_admin_ids) |
|
Q(team__organization__id__in=orgs_as_admin_ids) |
|
||||||
Q(team__deprecated_users__in=[self.user])
|
Q(team__deprecated_users__in=[self.user])
|
||||||
)
|
)
|
||||||
@@ -600,9 +600,9 @@ class CredentialAccess(BaseAccess):
|
|||||||
if obj.user:
|
if obj.user:
|
||||||
if self.user == obj.user:
|
if self.user == obj.user:
|
||||||
return True
|
return True
|
||||||
if obj.user.organizations.filter(deprecated_admins__in=[self.user]).exists():
|
if obj.user.deprecated_organizations.filter(deprecated_admins__in=[self.user]).exists():
|
||||||
return True
|
return True
|
||||||
if obj.user.admin_of_organizations.filter(deprecated_admins__in=[self.user]).exists():
|
if obj.user.deprecated_admin_of_organizations.filter(deprecated_admins__in=[self.user]).exists():
|
||||||
return True
|
return True
|
||||||
if obj.team:
|
if obj.team:
|
||||||
if self.user in obj.team.organization.deprecated_admins.all():
|
if self.user in obj.team.organization.deprecated_admins.all():
|
||||||
@@ -710,7 +710,7 @@ class ProjectAccess(BaseAccess):
|
|||||||
def can_add(self, data):
|
def can_add(self, data):
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
if self.user.admin_of_organizations.exists():
|
if self.user.deprecated_admin_of_organizations.exists():
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -772,10 +772,10 @@ class PermissionAccess(BaseAccess):
|
|||||||
'project')
|
'project')
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return qs
|
return qs
|
||||||
orgs_as_admin_ids = set(self.user.admin_of_organizations.values_list('id', flat=True))
|
orgs_as_admin_ids = set(self.user.deprecated_admin_of_organizations.values_list('id', flat=True))
|
||||||
return qs.filter(
|
return qs.filter(
|
||||||
Q(user__organizations__in=orgs_as_admin_ids) |
|
Q(user__deprecated_organizations__in=orgs_as_admin_ids) |
|
||||||
Q(user__admin_of_organizations__in=orgs_as_admin_ids) |
|
Q(user__deprecated_admin_of_organizations__in=orgs_as_admin_ids) |
|
||||||
Q(team__organization__in=orgs_as_admin_ids) |
|
Q(team__organization__in=orgs_as_admin_ids) |
|
||||||
Q(user=self.user) |
|
Q(user=self.user) |
|
||||||
Q(team__deprecated_users__in=[self.user])
|
Q(team__deprecated_users__in=[self.user])
|
||||||
@@ -1492,16 +1492,16 @@ class ActivityStreamAccess(BaseAccess):
|
|||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
user_admin_orgs = self.user.admin_of_organizations.all()
|
user_admin_orgs = self.user.deprecated_admin_of_organizations.all()
|
||||||
user_orgs = self.user.organizations.all()
|
user_orgs = self.user.deprecated_organizations.all()
|
||||||
|
|
||||||
#Organization filter
|
#Organization filter
|
||||||
qs = qs.filter(Q(organization__deprecated_admins__in=[self.user]) | Q(organization__deprecated_users__in=[self.user]))
|
qs = qs.filter(Q(organization__deprecated_admins__in=[self.user]) | Q(organization__deprecated_users__in=[self.user]))
|
||||||
|
|
||||||
#User filter
|
#User filter
|
||||||
qs = qs.filter(Q(user__pk=self.user.pk) |
|
qs = qs.filter(Q(user__pk=self.user.pk) |
|
||||||
Q(user__organizations__in=user_admin_orgs) |
|
Q(user__deprecated_organizations__in=user_admin_orgs) |
|
||||||
Q(user__organizations__in=user_orgs))
|
Q(user__deprecated_organizations__in=user_orgs))
|
||||||
|
|
||||||
#Inventory filter
|
#Inventory filter
|
||||||
inventory_qs = self.user.get_queryset(Inventory)
|
inventory_qs = self.user.get_queryset(Inventory)
|
||||||
@@ -1523,8 +1523,8 @@ class ActivityStreamAccess(BaseAccess):
|
|||||||
|
|
||||||
#Credential Update Filter
|
#Credential Update Filter
|
||||||
qs.filter(Q(credential__user=self.user) |
|
qs.filter(Q(credential__user=self.user) |
|
||||||
Q(credential__user__organizations__in=user_admin_orgs) |
|
Q(credential__user__deprecated_organizations__in=user_admin_orgs) |
|
||||||
Q(credential__user__admin_of_organizations__in=user_admin_orgs) |
|
Q(credential__user__deprecated_admin_of_organizations__in=user_admin_orgs) |
|
||||||
Q(credential__team__organization__in=user_admin_orgs) |
|
Q(credential__team__organization__in=user_admin_orgs) |
|
||||||
Q(credential__team__deprecated_users__in=[self.user]))
|
Q(credential__team__deprecated_users__in=[self.user]))
|
||||||
|
|
||||||
@@ -1606,7 +1606,7 @@ class CustomInventoryScriptAccess(BaseAccess):
|
|||||||
def can_read(self, obj):
|
def can_read(self, obj):
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
return bool(obj.organization in self.user.organizations.all() or obj.organization in self.user.admin_of_organizations.all())
|
return bool(obj.organization in self.user.deprecated_organizations.all() or obj.organization in self.user.deprecated_admin_of_organizations.all())
|
||||||
|
|
||||||
def can_add(self, data):
|
def can_add(self, data):
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin):
|
|||||||
deprecated_users = models.ManyToManyField(
|
deprecated_users = models.ManyToManyField(
|
||||||
'auth.User',
|
'auth.User',
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='organizations',
|
related_name='deprecated_organizations',
|
||||||
)
|
)
|
||||||
deprecated_admins = models.ManyToManyField(
|
deprecated_admins = models.ManyToManyField(
|
||||||
'auth.User',
|
'auth.User',
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='admin_of_organizations',
|
related_name='deprecated_admin_of_organizations',
|
||||||
)
|
)
|
||||||
deprecated_projects = models.ManyToManyField(
|
deprecated_projects = models.ManyToManyField(
|
||||||
'Project',
|
'Project',
|
||||||
@@ -94,7 +94,7 @@ class Team(CommonModelNameNotUnique, ResourceMixin):
|
|||||||
deprecated_users = models.ManyToManyField(
|
deprecated_users = models.ManyToManyField(
|
||||||
'auth.User',
|
'auth.User',
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='teams',
|
related_name='deprecated_teams',
|
||||||
)
|
)
|
||||||
organization = models.ForeignKey(
|
organization = models.ForeignKey(
|
||||||
'Organization',
|
'Organization',
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ from awx.main.models.mixins import ResourceMixin
|
|||||||
from awx.main.utils import update_scm_url
|
from awx.main.utils import update_scm_url
|
||||||
from awx.main.fields import ImplicitRoleField
|
from awx.main.fields import ImplicitRoleField
|
||||||
from awx.main.conf import tower_settings
|
from awx.main.conf import tower_settings
|
||||||
|
from awx.main.models.rbac import (
|
||||||
|
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||||
|
ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = ['Project', 'ProjectUpdate']
|
__all__ = ['Project', 'ProjectUpdate']
|
||||||
|
|
||||||
@@ -219,13 +223,20 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin):
|
|||||||
admin_role = ImplicitRoleField(
|
admin_role = ImplicitRoleField(
|
||||||
role_name='Project Administrator',
|
role_name='Project Administrator',
|
||||||
role_description='May manage this project',
|
role_description='May manage this project',
|
||||||
parent_role='organization.admin_role',
|
parent_role=[
|
||||||
|
'organization.admin_role',
|
||||||
|
'teams.member_role',
|
||||||
|
'singleton:' + ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||||
|
],
|
||||||
permissions = {'all': True}
|
permissions = {'all': True}
|
||||||
)
|
)
|
||||||
auditor_role = ImplicitRoleField(
|
auditor_role = ImplicitRoleField(
|
||||||
role_name='Project Auditor',
|
role_name='Project Auditor',
|
||||||
role_description='May read all settings associated with this project',
|
role_description='May read all settings associated with this project',
|
||||||
parent_role='organization.auditor_role',
|
parent_role=[
|
||||||
|
'organization.auditor_role',
|
||||||
|
'singleton:' + ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||||
|
],
|
||||||
permissions = {'read': True}
|
permissions = {'read': True}
|
||||||
)
|
)
|
||||||
member_role = ImplicitRoleField(
|
member_role = ImplicitRoleField(
|
||||||
|
|||||||
@@ -241,3 +241,20 @@ def test_auto_parenting():
|
|||||||
assert org2.admin_role.is_ancestor_of(prj1.admin_role)
|
assert org2.admin_role.is_ancestor_of(prj1.admin_role)
|
||||||
assert org2.admin_role.is_ancestor_of(prj2.admin_role)
|
assert org2.admin_role.is_ancestor_of(prj2.admin_role)
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_auto_m2m_parenting(team, project, user):
|
||||||
|
u = user('some-user')
|
||||||
|
team.member_role.members.add(u)
|
||||||
|
|
||||||
|
assert project.accessible_by(u, {'read': True}) is False
|
||||||
|
|
||||||
|
project.teams.add(team)
|
||||||
|
assert project.accessible_by(u, {'read': True})
|
||||||
|
project.teams.remove(team)
|
||||||
|
assert project.accessible_by(u, {'read': True}) is False
|
||||||
|
|
||||||
|
team.projects.add(project)
|
||||||
|
assert project.accessible_by(u, {'read': True})
|
||||||
|
team.projects.remove(project)
|
||||||
|
assert project.accessible_by(u, {'read': True}) is False
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class OrganizationsTest(BaseTest):
|
|||||||
# no admin rights? get empty list
|
# no admin rights? get empty list
|
||||||
with self.current_user(self.other_django_user):
|
with self.current_user(self.other_django_user):
|
||||||
response = self.get(url, expect=200)
|
response = self.get(url, expect=200)
|
||||||
self.check_pagination_and_size(response, self.other_django_user.organizations.count(), previous=None, next=None)
|
self.check_pagination_and_size(response, len(self.organizations), previous=None, next=None)
|
||||||
|
|
||||||
# not a member of any orgs? get empty list
|
# not a member of any orgs? get empty list
|
||||||
with self.current_user(self.nobody_django_user):
|
with self.current_user(self.nobody_django_user):
|
||||||
@@ -283,14 +283,14 @@ class OrganizationsTest(BaseTest):
|
|||||||
# find projects attached to the first org
|
# find projects attached to the first org
|
||||||
projects0_url = orgs['results'][0]['related']['projects']
|
projects0_url = orgs['results'][0]['related']['projects']
|
||||||
projects1_url = orgs['results'][1]['related']['projects']
|
projects1_url = orgs['results'][1]['related']['projects']
|
||||||
projects2_url = orgs['results'][2]['related']['projects']
|
|
||||||
|
|
||||||
# get all the projects on the first org
|
# get all the projects on the first org
|
||||||
projects0 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
|
projects0 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
|
||||||
a_project = projects0['results'][-1]
|
a_project = projects0['results'][-1]
|
||||||
|
|
||||||
# attempt to add the project to the 7th org and see what happens
|
# attempt to add the project to the 7th org and see what happens
|
||||||
self.post(projects1_url, a_project, expect=204, auth=self.get_super_credentials())
|
#self.post(projects1_url, a_project, expect=204, auth=self.get_super_credentials())
|
||||||
|
self.post(projects1_url, a_project, expect=400, auth=self.get_super_credentials())
|
||||||
projects1 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
|
projects1 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
|
||||||
self.assertEquals(projects1['count'], 3)
|
self.assertEquals(projects1['count'], 3)
|
||||||
|
|
||||||
@@ -300,32 +300,19 @@ class OrganizationsTest(BaseTest):
|
|||||||
|
|
||||||
# test that by posting a pk + disassociate: True we can remove a relationship
|
# test that by posting a pk + disassociate: True we can remove a relationship
|
||||||
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
||||||
self.assertEquals(projects1['count'], 6)
|
self.assertEquals(projects1['count'], 5)
|
||||||
a_project['disassociate'] = True
|
a_project['disassociate'] = True
|
||||||
self.post(projects1_url, a_project, expect=204, auth=self.get_super_credentials())
|
self.post(projects1_url, a_project, expect=400, auth=self.get_super_credentials())
|
||||||
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
||||||
self.assertEquals(projects1['count'], 5)
|
self.assertEquals(projects1['count'], 5)
|
||||||
|
|
||||||
a_project = projects1['results'][-1]
|
a_project = projects1['results'][-1]
|
||||||
a_project['disassociate'] = 1
|
a_project['disassociate'] = 1
|
||||||
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
||||||
self.post(projects1_url, a_project, expect=204, auth=self.get_normal_credentials())
|
self.post(projects1_url, a_project, expect=400, auth=self.get_normal_credentials())
|
||||||
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
projects1 = self.get(projects1_url, expect=200, auth=self.get_super_credentials())
|
||||||
self.assertEquals(projects1['count'], 4)
|
self.assertEquals(projects1['count'], 5)
|
||||||
|
|
||||||
new_project_a = self.make_projects(self.normal_django_user, 1)[0]
|
|
||||||
new_project_b = self.make_projects(self.other_django_user, 1)[0]
|
|
||||||
|
|
||||||
# admin of org can add projects that he can read
|
|
||||||
self.post(projects1_url, dict(id=new_project_a.pk), expect=204, auth=self.get_normal_credentials())
|
|
||||||
# but not those he cannot
|
|
||||||
self.post(projects1_url, dict(id=new_project_b.pk), expect=403, auth=self.get_normal_credentials())
|
|
||||||
|
|
||||||
# and can't post a project he can read to an org he cannot
|
|
||||||
# self.post(projects2_url, dict(id=new_project_a.pk), expect=403, auth=self.get_normal_credentials())
|
|
||||||
|
|
||||||
# and can't do post a project he can read to an organization he cannot
|
|
||||||
self.post(projects2_url, dict(id=new_project_a.pk), expect=403, auth=self.get_normal_credentials())
|
|
||||||
|
|
||||||
|
|
||||||
def test_post_item_subobjects_users(self):
|
def test_post_item_subobjects_users(self):
|
||||||
@@ -342,7 +329,7 @@ class OrganizationsTest(BaseTest):
|
|||||||
|
|
||||||
# post a completely new user to verify we can add users to the subcollection directly
|
# post a completely new user to verify we can add users to the subcollection directly
|
||||||
new_user = dict(username='NewUser9000', password='NewPassword9000')
|
new_user = dict(username='NewUser9000', password='NewPassword9000')
|
||||||
which_org = self.normal_django_user.admin_of_organizations.all()[0]
|
which_org = Organization.accessible_objects(self.normal_django_user, {'read': True, 'write': True})[0]
|
||||||
url = reverse('api:organization_users_list', args=(which_org.pk,))
|
url = reverse('api:organization_users_list', args=(which_org.pk,))
|
||||||
self.post(url, new_user, expect=201, auth=self.get_normal_credentials())
|
self.post(url, new_user, expect=201, auth=self.get_normal_credentials())
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
self.organizations[1].projects.add(project)
|
self.organizations[1].projects.add(project)
|
||||||
for project in self.projects[9:10]:
|
for project in self.projects[9:10]:
|
||||||
self.organizations[2].projects.add(project)
|
self.organizations[2].projects.add(project)
|
||||||
self.organizations[0].projects.add(self.projects[-1])
|
#self.organizations[0].projects.add(self.projects[-1])
|
||||||
self.organizations[9].projects.add(self.projects[-2])
|
#self.organizations[9].projects.add(self.projects[-2])
|
||||||
|
|
||||||
# get the URL for various organization records
|
# get the URL for various organization records
|
||||||
self.a_detail_url = "%s%s" % (self.collection(), self.organizations[0].pk)
|
self.a_detail_url = "%s%s" % (self.collection(), self.organizations[0].pk)
|
||||||
@@ -89,7 +89,9 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# create some teams in the first org
|
# create some teams in the first org
|
||||||
self.team1.projects.add(self.projects[0])
|
#self.team1.projects.add(self.projects[0])
|
||||||
|
self.projects[0].teams.add(self.team1)
|
||||||
|
#self.team1.projects.add(self.projects[0])
|
||||||
self.team2.projects.add(self.projects[1])
|
self.team2.projects.add(self.projects[1])
|
||||||
self.team2.projects.add(self.projects[2])
|
self.team2.projects.add(self.projects[2])
|
||||||
self.team2.projects.add(self.projects[3])
|
self.team2.projects.add(self.projects[3])
|
||||||
@@ -215,7 +217,7 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
self.assertEquals(results['count'], 10)
|
self.assertEquals(results['count'], 10)
|
||||||
# org admin
|
# org admin
|
||||||
results = self.get(projects, expect=200, auth=self.get_normal_credentials())
|
results = self.get(projects, expect=200, auth=self.get_normal_credentials())
|
||||||
self.assertEquals(results['count'], 9)
|
self.assertEquals(results['count'], 6)
|
||||||
# user on a team
|
# user on a team
|
||||||
results = self.get(projects, expect=200, auth=self.get_other_credentials())
|
results = self.get(projects, expect=200, auth=self.get_other_credentials())
|
||||||
self.assertEquals(results['count'], 5)
|
self.assertEquals(results['count'], 5)
|
||||||
@@ -296,31 +298,6 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
got = self.get(proj_playbooks, expect=200, auth=self.get_super_credentials())
|
got = self.get(proj_playbooks, expect=200, auth=self.get_super_credentials())
|
||||||
self.assertEqual(got, self.projects[2].playbooks)
|
self.assertEqual(got, self.projects[2].playbooks)
|
||||||
|
|
||||||
# can list member organizations for projects
|
|
||||||
proj_orgs = reverse('api:project_organizations_list', args=(self.projects[0].pk,))
|
|
||||||
# only usable as superuser
|
|
||||||
got = self.get(proj_orgs, expect=200, auth=self.get_normal_credentials())
|
|
||||||
got = self.get(proj_orgs, expect=200, auth=self.get_super_credentials())
|
|
||||||
self.get(proj_orgs, expect=403, auth=self.get_other_credentials())
|
|
||||||
self.assertEquals(got['count'], 1)
|
|
||||||
self.assertEquals(got['results'][0]['url'], reverse('api:organization_detail', args=(self.organizations[0].pk,)))
|
|
||||||
|
|
||||||
# post to create new org associated with this project.
|
|
||||||
self.post(proj_orgs, data={'name': 'New Org'}, expect=201, auth=self.get_super_credentials())
|
|
||||||
got = self.get(proj_orgs, expect=200, auth=self.get_super_credentials())
|
|
||||||
self.assertEquals(got['count'], 2)
|
|
||||||
|
|
||||||
# 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].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())
|
|
||||||
self.organizations[0].deprecated_admins.remove(self.other_django_user)
|
|
||||||
self.patch(proj_detail, data=dict(description="test_now"), expect=403, auth=self.get_other_credentials())
|
|
||||||
self.delete(proj_detail, expect=403, auth=self.get_other_credentials())
|
|
||||||
a_new_proj.delete()
|
|
||||||
|
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
# TEAMS
|
# TEAMS
|
||||||
|
|
||||||
@@ -421,7 +398,7 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
|
|
||||||
team = Team.objects.filter( organization__pk=self.organizations[1].pk)[0]
|
team = Team.objects.filter( organization__pk=self.organizations[1].pk)[0]
|
||||||
team_users = reverse('api:team_users_list', args=(team.pk,))
|
team_users = reverse('api:team_users_list', args=(team.pk,))
|
||||||
for x in team.deprecated_users.all():
|
for x in team.member_role.members.all():
|
||||||
team.member_role.members.remove(x)
|
team.member_role.members.remove(x)
|
||||||
team.save()
|
team.save()
|
||||||
|
|
||||||
@@ -446,7 +423,7 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
self.post(team_users, data=dict(username='attempted_superuser_create', password='thepassword',
|
self.post(team_users, data=dict(username='attempted_superuser_create', password='thepassword',
|
||||||
is_superuser=True), expect=201, auth=self.get_super_credentials())
|
is_superuser=True), expect=201, auth=self.get_super_credentials())
|
||||||
|
|
||||||
self.assertEqual(Team.objects.get(pk=team.pk).member_role.members.count(), 5)
|
self.assertEqual(Team.objects.get(pk=team.pk).member_role.members.count(), all_users['count'] + 1)
|
||||||
|
|
||||||
# can remove users from teams
|
# can remove users from teams
|
||||||
for x in all_users['results']:
|
for x in all_users['results']:
|
||||||
@@ -454,7 +431,7 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
self.post(team_users, data=y, expect=403, auth=self.get_nobody_credentials())
|
self.post(team_users, data=y, expect=403, auth=self.get_nobody_credentials())
|
||||||
self.post(team_users, data=y, expect=204, auth=self.get_normal_credentials())
|
self.post(team_users, data=y, expect=204, auth=self.get_normal_credentials())
|
||||||
|
|
||||||
self.assertEquals(Team.objects.get(pk=team.pk).deprecated_users.count(), 1) # Leaving just the super user we created
|
self.assertEquals(Team.objects.get(pk=team.pk).member_role.members.count(), 1) # Leaving just the super user we created
|
||||||
|
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
# USER TEAMS
|
# USER TEAMS
|
||||||
@@ -465,9 +442,12 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
self.get(url, expect=401)
|
self.get(url, expect=401)
|
||||||
self.get(url, expect=401, auth=self.get_invalid_credentials())
|
self.get(url, expect=401, auth=self.get_invalid_credentials())
|
||||||
self.get(url, expect=403, auth=self.get_nobody_credentials())
|
self.get(url, expect=403, auth=self.get_nobody_credentials())
|
||||||
other.organizations.add(Organization.objects.get(pk=self.organizations[1].pk))
|
self.organizations[1].member_role.members.add(other)
|
||||||
# Normal user can only see some teams that other user is a part of,
|
# Normal user can only see some teams that other user is a part of,
|
||||||
# since normal user is not an admin of that organization.
|
# since normal user is not an admin of that organization.
|
||||||
|
my_teams1 = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||||
|
my_teams2 = self.get(url, expect=200, auth=self.get_other_credentials())
|
||||||
|
|
||||||
my_teams1 = self.get(url, expect=200, auth=self.get_normal_credentials())
|
my_teams1 = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||||
self.assertEqual(my_teams1['count'], 1)
|
self.assertEqual(my_teams1['count'], 1)
|
||||||
# Other user should be able to see all his own teams.
|
# Other user should be able to see all his own teams.
|
||||||
@@ -622,7 +602,7 @@ class ProjectsTest(BaseTransactionTest):
|
|||||||
# Test post as organization admin where team is part of org, but user
|
# Test post as organization admin where team is part of org, but user
|
||||||
# creating credential is not a member of the team. UI may pass user
|
# creating credential is not a member of the team. UI may pass user
|
||||||
# as an empty string instead of None.
|
# as an empty string instead of None.
|
||||||
normal_org = self.normal_django_user.admin_of_organizations.all()[0]
|
normal_org = self.organizations[1] # normal user is an admin of this
|
||||||
org_team = normal_org.teams.create(name='new empty team')
|
org_team = normal_org.teams.create(name='new empty team')
|
||||||
with self.current_user(self.normal_django_user):
|
with self.current_user(self.normal_django_user):
|
||||||
data = {
|
data = {
|
||||||
@@ -1262,7 +1242,7 @@ class ProjectUpdatesTest(BaseTransactionTest):
|
|||||||
else:
|
else:
|
||||||
self.check_project_update(project, should_fail=should_still_fail)
|
self.check_project_update(project, should_fail=should_still_fail)
|
||||||
# Test that we can delete project updates.
|
# Test that we can delete project updates.
|
||||||
for pu in project.project_updates:
|
for pu in project.project_updates.all():
|
||||||
pu_url = reverse('api:project_update_detail', args=(pu.pk,))
|
pu_url = reverse('api:project_update_detail', args=(pu.pk,))
|
||||||
with self.current_user(self.super_django_user):
|
with self.current_user(self.super_django_user):
|
||||||
self.delete(pu_url, expect=204)
|
self.delete(pu_url, expect=204)
|
||||||
|
|||||||
@@ -87,11 +87,12 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
host = inventory.hosts.create(name='host-%02d-%02d.example.com' % (n, x),
|
host = inventory.hosts.create(name='host-%02d-%02d.example.com' % (n, x),
|
||||||
inventory=inventory,
|
inventory=inventory,
|
||||||
variables=variables)
|
variables=variables)
|
||||||
if x in (3, 7):
|
#if x in (3, 7):
|
||||||
host.delete()
|
# host.delete()
|
||||||
continue
|
# continue
|
||||||
hosts.append(host)
|
hosts.append(host)
|
||||||
|
|
||||||
|
|
||||||
# add localhost just to make sure it's thrown into all (Ansible github bug)
|
# add localhost just to make sure it's thrown into all (Ansible github bug)
|
||||||
local = inventory.hosts.create(name='localhost', inventory=inventory, variables={})
|
local = inventory.hosts.create(name='localhost', inventory=inventory, variables={})
|
||||||
hosts.append(local)
|
hosts.append(local)
|
||||||
@@ -106,9 +107,9 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
group = inventory.groups.create(name='group-%d' % x,
|
group = inventory.groups.create(name='group-%d' % x,
|
||||||
inventory=inventory,
|
inventory=inventory,
|
||||||
variables=variables)
|
variables=variables)
|
||||||
if x == 2:
|
#if x == 2:
|
||||||
group.delete()
|
# #group.delete()
|
||||||
continue
|
# #continue
|
||||||
groups.append(group)
|
groups.append(group)
|
||||||
group.hosts.add(hosts[x])
|
group.hosts.add(hosts[x])
|
||||||
group.hosts.add(hosts[x + 5])
|
group.hosts.add(hosts[x + 5])
|
||||||
@@ -118,6 +119,13 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
group.hosts.add(local)
|
group.hosts.add(local)
|
||||||
self.groups.extend(groups)
|
self.groups.extend(groups)
|
||||||
|
|
||||||
|
hosts[3].delete()
|
||||||
|
hosts[7].delete()
|
||||||
|
groups[2].delete()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(InventoryScriptTest, self).tearDown()
|
super(InventoryScriptTest, self).tearDown()
|
||||||
self.stop_redis()
|
self.stop_redis()
|
||||||
@@ -162,16 +170,16 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
# variable data or parent/child relationships.
|
# variable data or parent/child relationships.
|
||||||
for k,v in data.items():
|
for k,v in data.items():
|
||||||
if k != 'all':
|
if k != 'all':
|
||||||
self.assertTrue(isinstance(v, dict))
|
assert isinstance(v, dict)
|
||||||
self.assertTrue(isinstance(v['children'], (list,tuple)))
|
assert isinstance(v['children'], (list,tuple))
|
||||||
self.assertTrue(isinstance(v['hosts'], (list,tuple)))
|
assert isinstance(v['hosts'], (list,tuple))
|
||||||
self.assertTrue(isinstance(v['vars'], (dict)))
|
assert isinstance(v['vars'], (dict))
|
||||||
group = inventory.groups.get(name=k)
|
group = inventory.groups.get(name=k)
|
||||||
hosts = group.hosts
|
hosts = group.hosts
|
||||||
hostnames = hosts.values_list('name', flat=True)
|
hostnames = hosts.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v['hosts']), set(hostnames))
|
self.assertEqual(set(v['hosts']), set(hostnames))
|
||||||
else:
|
else:
|
||||||
self.assertTrue(v['hosts'] == ['localhost'])
|
assert v['hosts'] == ['host-00-02.example.com', 'localhost']
|
||||||
|
|
||||||
# Command line argument for inventory ID should take precedence over
|
# Command line argument for inventory ID should take precedence over
|
||||||
# environment variable.
|
# environment variable.
|
||||||
@@ -195,7 +203,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
# Groups for this inventory should have hosts, variable data, and one
|
# Groups for this inventory should have hosts, variable data, and one
|
||||||
# parent/child relationship.
|
# parent/child relationship.
|
||||||
for k,v in data.items():
|
for k,v in data.items():
|
||||||
self.assertTrue(isinstance(v, dict))
|
assert isinstance(v, dict)
|
||||||
if k == 'all':
|
if k == 'all':
|
||||||
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
||||||
continue
|
continue
|
||||||
@@ -210,7 +218,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
childnames = children.values_list('name', flat=True)
|
childnames = children.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v.get('children', [])), set(childnames))
|
self.assertEqual(set(v.get('children', [])), set(childnames))
|
||||||
else:
|
else:
|
||||||
self.assertTrue(len(v['children']) == 0)
|
assert len(v['children']) == 0
|
||||||
|
|
||||||
def test_list_with_hostvars_inline(self):
|
def test_list_with_hostvars_inline(self):
|
||||||
inventory = self.inventories[1]
|
inventory = self.inventories[1]
|
||||||
@@ -227,7 +235,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
# Groups for this inventory should have hosts, variable data, and one
|
# Groups for this inventory should have hosts, variable data, and one
|
||||||
# parent/child relationship.
|
# parent/child relationship.
|
||||||
for k,v in data.items():
|
for k,v in data.items():
|
||||||
self.assertTrue(isinstance(v, dict))
|
assert isinstance(v, dict)
|
||||||
if k == 'all':
|
if k == 'all':
|
||||||
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
||||||
continue
|
continue
|
||||||
@@ -237,18 +245,18 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
hosts = group.hosts
|
hosts = group.hosts
|
||||||
hostnames = hosts.values_list('name', flat=True)
|
hostnames = hosts.values_list('name', flat=True)
|
||||||
all_hostnames.update(hostnames)
|
all_hostnames.update(hostnames)
|
||||||
self.assertEqual(set(v.get('hosts', [])), set(hostnames))
|
assert set(v.get('hosts', [])) == set(hostnames)
|
||||||
if group.variables:
|
if group.variables:
|
||||||
self.assertEqual(v.get('vars', {}), group.variables_dict)
|
assert v.get('vars', {}) == group.variables_dict
|
||||||
if k == 'group-3':
|
if k == 'group-3':
|
||||||
children = group.children
|
children = group.children
|
||||||
childnames = children.values_list('name', flat=True)
|
childnames = children.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v.get('children', [])), set(childnames))
|
assert set(v.get('children', [])) == set(childnames)
|
||||||
else:
|
else:
|
||||||
self.assertTrue(len(v['children']) == 0)
|
assert len(v['children']) == 0
|
||||||
# Check hostvars in ['_meta']['hostvars'] dict.
|
# Check hostvars in ['_meta']['hostvars'] dict.
|
||||||
for hostname in all_hostnames:
|
for hostname in all_hostnames:
|
||||||
self.assertTrue(hostname in data['_meta']['hostvars'])
|
assert hostname in data['_meta']['hostvars']
|
||||||
host = inventory.hosts.get(name=hostname)
|
host = inventory.hosts.get(name=hostname)
|
||||||
self.assertEqual(data['_meta']['hostvars'][hostname],
|
self.assertEqual(data['_meta']['hostvars'][hostname],
|
||||||
host.variables_dict)
|
host.variables_dict)
|
||||||
@@ -258,12 +266,12 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
inventory=inventory.pk)
|
inventory=inventory.pk)
|
||||||
self.assertEqual(rc, 0, stderr)
|
self.assertEqual(rc, 0, stderr)
|
||||||
data = json.loads(stdout)
|
data = json.loads(stdout)
|
||||||
self.assertTrue('_meta' in data)
|
assert '_meta' in data
|
||||||
|
|
||||||
def test_valid_host(self):
|
def test_valid_host(self):
|
||||||
# Host without variable data.
|
# Host without variable data.
|
||||||
inventory = self.inventories[0]
|
inventory = self.inventories[0]
|
||||||
host = inventory.hosts[2]
|
host = inventory.hosts.all()[2]
|
||||||
os.environ['INVENTORY_ID'] = str(inventory.pk)
|
os.environ['INVENTORY_ID'] = str(inventory.pk)
|
||||||
rc, stdout, stderr = self.run_inventory_script(host=host.name)
|
rc, stdout, stderr = self.run_inventory_script(host=host.name)
|
||||||
self.assertEqual(rc, 0, stderr)
|
self.assertEqual(rc, 0, stderr)
|
||||||
@@ -271,7 +279,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
self.assertEqual(data, {})
|
self.assertEqual(data, {})
|
||||||
# Host with variable data.
|
# Host with variable data.
|
||||||
inventory = self.inventories[1]
|
inventory = self.inventories[1]
|
||||||
host = inventory.hosts[4]
|
host = inventory.hosts.all()[4]
|
||||||
os.environ['INVENTORY_ID'] = str(inventory.pk)
|
os.environ['INVENTORY_ID'] = str(inventory.pk)
|
||||||
rc, stdout, stderr = self.run_inventory_script(host=host.name)
|
rc, stdout, stderr = self.run_inventory_script(host=host.name)
|
||||||
self.assertEqual(rc, 0, stderr)
|
self.assertEqual(rc, 0, stderr)
|
||||||
@@ -348,7 +356,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
groupnames = list(groups.values_list('name', flat=True)) + ['all']
|
groupnames = list(groups.values_list('name', flat=True)) + ['all']
|
||||||
self.assertEqual(set(data.keys()), set(groupnames))
|
self.assertEqual(set(data.keys()), set(groupnames))
|
||||||
for k,v in data.items():
|
for k,v in data.items():
|
||||||
self.assertTrue(isinstance(v, dict))
|
assert isinstance(v, dict)
|
||||||
if k == 'all':
|
if k == 'all':
|
||||||
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
||||||
continue
|
continue
|
||||||
@@ -364,7 +372,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
childnames = children.values_list('name', flat=True)
|
childnames = children.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v.get('children', [])), set(childnames))
|
self.assertEqual(set(v.get('children', [])), set(childnames))
|
||||||
else:
|
else:
|
||||||
self.assertTrue(len(v['children']) == 0)
|
assert len(v['children']) == 0
|
||||||
# Load inventory list with all hosts.
|
# Load inventory list with all hosts.
|
||||||
rc, stdout, stderr = self.run_inventory_script(list=True, all=True)
|
rc, stdout, stderr = self.run_inventory_script(list=True, all=True)
|
||||||
self.assertEqual(rc, 0, stderr)
|
self.assertEqual(rc, 0, stderr)
|
||||||
@@ -373,7 +381,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
groupnames = list(groups.values_list('name', flat=True)) + ['all']
|
groupnames = list(groups.values_list('name', flat=True)) + ['all']
|
||||||
self.assertEqual(set(data.keys()), set(groupnames))
|
self.assertEqual(set(data.keys()), set(groupnames))
|
||||||
for k,v in data.items():
|
for k,v in data.items():
|
||||||
self.assertTrue(isinstance(v, dict))
|
assert isinstance(v, dict)
|
||||||
if k == 'all':
|
if k == 'all':
|
||||||
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
self.assertEqual(v.get('vars', {}), inventory.variables_dict)
|
||||||
continue
|
continue
|
||||||
@@ -381,7 +389,7 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
hosts = group.hosts
|
hosts = group.hosts
|
||||||
hostnames = hosts.values_list('name', flat=True)
|
hostnames = hosts.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v.get('hosts', [])), set(hostnames))
|
self.assertEqual(set(v.get('hosts', [])), set(hostnames))
|
||||||
self.assertTrue(hostnames)
|
assert hostnames
|
||||||
if group.variables:
|
if group.variables:
|
||||||
self.assertEqual(v.get('vars', {}), group.variables_dict)
|
self.assertEqual(v.get('vars', {}), group.variables_dict)
|
||||||
if k == 'group-3':
|
if k == 'group-3':
|
||||||
@@ -389,4 +397,4 @@ class InventoryScriptTest(BaseScriptTest):
|
|||||||
childnames = children.values_list('name', flat=True)
|
childnames = children.values_list('name', flat=True)
|
||||||
self.assertEqual(set(v.get('children', [])), set(childnames))
|
self.assertEqual(set(v.get('children', [])), set(childnames))
|
||||||
else:
|
else:
|
||||||
self.assertTrue(len(v['children']) == 0)
|
assert len(v['children']) == 0
|
||||||
|
|||||||
@@ -790,8 +790,8 @@ class UsersTest(BaseTest):
|
|||||||
self.check_get_list(url, self.super_django_user, qs)
|
self.check_get_list(url, self.super_django_user, qs)
|
||||||
|
|
||||||
# Filter by related organizations admins username.
|
# Filter by related organizations admins username.
|
||||||
url = '%s?organizations__deprecated_admins__username__startswith=norm' % base_url
|
url = '%s?organizationsadmin_role__members__username__startswith=norm' % base_url
|
||||||
qs = base_qs.filter(organizations__deprecated_admins__username__startswith='norm')
|
qs = base_qs.filter(organizationsadmin_role__members__username__startswith='norm')
|
||||||
self.assertTrue(qs.count())
|
self.assertTrue(qs.count())
|
||||||
self.check_get_list(url, self.super_django_user, qs)
|
self.check_get_list(url, self.super_django_user, qs)
|
||||||
|
|
||||||
@@ -839,11 +839,11 @@ class UsersTest(BaseTest):
|
|||||||
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
||||||
|
|
||||||
# Filter by invalid field across lookups.
|
# Filter by invalid field across lookups.
|
||||||
url = '%s?organizations__deprecated_users__teams__laser=green' % base_url
|
url = '%s?organizations__member_role.members__teams__laser=green' % base_url
|
||||||
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
||||||
|
|
||||||
# Filter by invalid relation within lookups.
|
# Filter by invalid relation within lookups.
|
||||||
url = '%s?organizations__deprecated_users__llamas__name=freddie' % base_url
|
url = '%s?organizations__member_role.members__llamas__name=freddie' % base_url
|
||||||
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
self.check_get_list(url, self.super_django_user, base_qs, expect=400)
|
||||||
|
|
||||||
# Filter by invalid query string field names.
|
# Filter by invalid query string field names.
|
||||||
@@ -1020,13 +1020,13 @@ class LdapTest(BaseTest):
|
|||||||
for org_name, org_result in settings.AUTH_LDAP_ORGANIZATION_MAP_RESULT.items():
|
for org_name, org_result in settings.AUTH_LDAP_ORGANIZATION_MAP_RESULT.items():
|
||||||
org = Organization.objects.get(name=org_name)
|
org = Organization.objects.get(name=org_name)
|
||||||
if org_result.get('admins', False):
|
if org_result.get('admins', False):
|
||||||
self.assertTrue(user in org.deprecated_admins.all())
|
self.assertTrue(user in org.admin_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in org.deprecated_admins.all())
|
self.assertFalse(user in org.admin_role.members.all())
|
||||||
if org_result.get('users', False):
|
if org_result.get('users', False):
|
||||||
self.assertTrue(user in org.deprecated_users.all())
|
self.assertTrue(user in org.member_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in org.deprecated_users.all())
|
self.assertFalse(user in org.member_role.members.all())
|
||||||
# Try again with different test mapping.
|
# Try again with different test mapping.
|
||||||
self.use_test_setting('ORGANIZATION_MAP', {},
|
self.use_test_setting('ORGANIZATION_MAP', {},
|
||||||
from_name='ORGANIZATION_MAP_2')
|
from_name='ORGANIZATION_MAP_2')
|
||||||
@@ -1038,13 +1038,13 @@ class LdapTest(BaseTest):
|
|||||||
for org_name, org_result in settings.AUTH_LDAP_ORGANIZATION_MAP_RESULT.items():
|
for org_name, org_result in settings.AUTH_LDAP_ORGANIZATION_MAP_RESULT.items():
|
||||||
org = Organization.objects.get(name=org_name)
|
org = Organization.objects.get(name=org_name)
|
||||||
if org_result.get('admins', False):
|
if org_result.get('admins', False):
|
||||||
self.assertTrue(user in org.deprecated_admins.all())
|
self.assertTrue(user in org.admin_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in org.deprecated_admins.all())
|
self.assertFalse(user in org.admin_role.members.all())
|
||||||
if org_result.get('users', False):
|
if org_result.get('users', False):
|
||||||
self.assertTrue(user in org.deprecated_users.all())
|
self.assertTrue(user in org.member_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in org.deprecated_users.all())
|
self.assertFalse(user in org.member_role.members.all())
|
||||||
|
|
||||||
def test_ldap_team_mapping(self):
|
def test_ldap_team_mapping(self):
|
||||||
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
||||||
@@ -1062,9 +1062,9 @@ class LdapTest(BaseTest):
|
|||||||
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
||||||
team = Team.objects.get(name=team_name)
|
team = Team.objects.get(name=team_name)
|
||||||
if team_result.get('users', False):
|
if team_result.get('users', False):
|
||||||
self.assertTrue(user in team.deprecated_users.all())
|
self.assertTrue(user in team.member_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in team.deprecated_users.all())
|
self.assertFalse(user in team.member_role.members.all())
|
||||||
# Try again with different test mapping.
|
# Try again with different test mapping.
|
||||||
self.use_test_setting('TEAM_MAP', {}, from_name='TEAM_MAP_2')
|
self.use_test_setting('TEAM_MAP', {}, from_name='TEAM_MAP_2')
|
||||||
self.use_test_setting('TEAM_MAP_RESULT', {},
|
self.use_test_setting('TEAM_MAP_RESULT', {},
|
||||||
@@ -1075,9 +1075,9 @@ class LdapTest(BaseTest):
|
|||||||
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
for team_name, team_result in settings.AUTH_LDAP_TEAM_MAP_RESULT.items():
|
||||||
team = Team.objects.get(name=team_name)
|
team = Team.objects.get(name=team_name)
|
||||||
if team_result.get('users', False):
|
if team_result.get('users', False):
|
||||||
self.assertTrue(user in team.deprecated_users.all())
|
self.assertTrue(user in team.member_role.members.all())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(user in team.deprecated_users.all())
|
self.assertFalse(user in team.member_role.members.all())
|
||||||
|
|
||||||
def test_prevent_changing_ldap_user_fields(self):
|
def test_prevent_changing_ldap_user_fields(self):
|
||||||
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
for name in ('USER_SEARCH', 'ALWAYS_UPDATE_USER', 'USER_ATTR_MAP',
|
||||||
|
|||||||
Reference in New Issue
Block a user