Updated Organization and Credential access

This commit is contained in:
Wayne Witzel III
2016-02-29 15:37:59 -05:00
parent 380ccec687
commit 1d179574af
4 changed files with 71 additions and 58 deletions

View File

@@ -258,15 +258,14 @@ class OrganizationAccess(BaseAccess):
model = Organization model = Organization
def get_queryset(self): def get_queryset(self):
qs = self.model.objects.filter(active=True).distinct() qs = self.model.accessible_objects(self.user, {'read':True})
qs = qs.select_related('created_by', 'modified_by') qs = qs.select_related('created_by', 'modified_by')
if self.user.is_superuser: return qs
return qs
return qs.filter(Q(admins__in=[self.user]) | Q(users__in=[self.user]))
def can_change(self, obj, data): def can_change(self, obj, data):
return bool(self.user.is_superuser or if self.user.is_superuser:
self.user in obj.admins.all()) return True
return obj.accessible_by(self.user, ALL_PERMISSIONS)
def can_delete(self, obj): def can_delete(self, obj):
self.check_license(feature='multiple_organizations', check_expiration=False) self.check_license(feature='multiple_organizations', check_expiration=False)
@@ -567,55 +566,29 @@ class CredentialAccess(BaseAccess):
"""Return the queryset for credentials, based on what the user is """Return the queryset for credentials, based on what the user is
permitted to see. permitted to see.
""" """
# Create a base queryset. qs = self.model.accessible_objects(self.user, {'read':True})
# If the user is a superuser, and therefore can see everything, this
# is also sufficient, and we are done.
qs = self.model.objects.filter(active=True).distinct()
qs = qs.select_related('created_by', 'modified_by', 'user', 'team') qs = qs.select_related('created_by', 'modified_by', 'user', 'team')
if self.user.is_superuser: return qs
return qs
# Get the list of organizations for which the user is an admin
orgs_as_admin_ids = set(self.user.admin_of_organizations.filter(active=True).values_list('id', flat=True))
return qs.filter(
Q(user=self.user) |
Q(user__organizations__id__in=orgs_as_admin_ids) |
Q(user__admin_of_organizations__id__in=orgs_as_admin_ids) |
Q(team__organization__id__in=orgs_as_admin_ids, team__active=True) |
Q(team__users__in=[self.user], team__active=True)
)
def can_add(self, data): def can_add(self, data):
if self.user.is_superuser: if self.user.is_superuser:
return True return True
user_pk = get_pk_from_dict(data, 'user')
if user_pk: user, team = user_or_team(data)
user_obj = get_object_or_400(User, pk=user_pk) if user is None and team is None:
return self.user.can_access(User, 'change', user_obj, None) return False
team_pk = get_pk_from_dict(data, 'team')
if team_pk: if user is not None:
team_obj = get_object_or_400(Team, pk=team_pk) return user.resource.accessible_by(self.user, {'write': True})
return self.user.can_access(Team, 'change', team_obj, None) if team is not None:
return False return team.accessible_by(self.user, {'write':True})
def can_change(self, obj, data): def can_change(self, obj, data):
if self.user.is_superuser: if self.user.is_superuser:
return True return True
if not self.can_add(data): if not self.can_add(data):
return False return False
if self.user == obj.created_by: return obj.accessible_by(self.user, {'read':True, 'update': True, 'delete':True})
return True
if obj.user:
if self.user == obj.user:
return True
if obj.user.organizations.filter(active=True, admins__in=[self.user]).exists():
return True
if obj.user.admin_of_organizations.filter(active=True, admins__in=[self.user]).exists():
return True
if obj.team:
if self.user in obj.team.organization.admins.filter(is_active=True):
return True
return False
def can_delete(self, obj): def can_delete(self, obj):
# Unassociated credentials may be marked deleted by anyone, though we # Unassociated credentials may be marked deleted by anyone, though we

View File

@@ -69,11 +69,9 @@ def test_credential_access_superuser():
assert access.can_delete(credential) assert access.can_delete(credential)
@pytest.mark.django_db @pytest.mark.django_db
def test_credential_access_admin(user, organization, team, credential): def test_credential_access_admin(user, team, credential):
u = user('org-admin', False) u = user('org-admin', False)
organization.admins.add(u) team.organization.admin_role.members.add(u)
team.organization = organization
team.save()
access = CredentialAccess(u) access = CredentialAccess(u)
@@ -85,10 +83,16 @@ def test_credential_access_admin(user, organization, team, credential):
# unowned credential can be deleted # unowned credential can be deleted
assert access.can_delete(credential) assert access.can_delete(credential)
team.users.add(u) # credential is now part of a team
assert not access.can_change(credential, {'user': u.pk}) # that is part of an organization
# that I am an admin for
credential.team = team credential.team = team
credential.save() credential.save()
credential.owner_role.rebuild_role_ancestor_list()
cred = Credential.objects.create(kind='aws', name='test-cred')
cred.team = team
cred.save()
# should have can_change access as org-admin
assert access.can_change(credential, {'user': u.pk}) assert access.can_change(credential, {'user': u.pk})

View File

@@ -195,3 +195,39 @@ def test_group_parent_admin(group, permissions, user):
parent2.admin_role.members.add(u) parent2.admin_role.members.add(u)
assert childA.accessible_by(u, permissions['admin']) assert childA.accessible_by(u, permissions['admin'])
@pytest.mark.django_db
def test_access_admin(organization, inventory, user):
a = user('admin', False)
inventory.organization = organization
organization.admin_role.members.add(a)
access = InventoryAccess(a)
assert access.can_read(inventory)
assert access.can_add(None)
assert access.can_add({'organization': organization.id})
assert access.can_change(inventory, None)
assert access.can_change(inventory, {'organization': organization.id})
assert access.can_admin(inventory, None)
assert access.can_admin(inventory, {'organization': organization.id})
assert access.can_delete(inventory)
assert access.can_run_ad_hoc_commands(inventory)
@pytest.mark.django_db
def test_access_auditor(organization, inventory, user):
u = user('admin', False)
inventory.organization = organization
organization.auditor_role.members.add(u)
access = InventoryAccess(u)
assert access.can_read(inventory)
assert not access.can_add(None)
assert not access.can_add({'organization': organization.id})
assert not access.can_change(inventory, None)
assert not access.can_change(inventory, {'organization': organization.id})
assert not access.can_admin(inventory, None)
assert not access.can_admin(inventory, {'organization': organization.id})
assert not access.can_delete(inventory)
assert not access.can_run_ad_hoc_commands(inventory)

View File

@@ -57,27 +57,27 @@ def test_organization_access_superuser(cl, organization, user):
def test_organization_access_admin(cl, organization, user): def test_organization_access_admin(cl, organization, user):
'''can_change because I am an admin of that org''' '''can_change because I am an admin of that org'''
a = user('admin', False) a = user('admin', False)
organization.admins.add(a) organization.admin_role.members.add(a)
organization.users.add(user('user', False)) organization.member_role.members.add(user('user', False))
access = OrganizationAccess(a) access = OrganizationAccess(a)
assert access.can_change(organization, None) assert access.can_change(organization, None)
assert access.can_delete(organization) assert access.can_delete(organization)
org = access.get_queryset()[0] org = access.get_queryset()[0]
assert len(org.admins.all()) == 1 assert len(org.admin_role.members.all()) == 1
assert len(org.users.all()) == 1 assert len(org.member_role.members.all()) == 1
@mock.patch.object(BaseAccess, 'check_license', return_value=None) @mock.patch.object(BaseAccess, 'check_license', return_value=None)
@pytest.mark.django_db @pytest.mark.django_db
def test_organization_access_user(cl, organization, user): def test_organization_access_user(cl, organization, user):
access = OrganizationAccess(user('user', False)) access = OrganizationAccess(user('user', False))
organization.users.add(user('user', False)) organization.member_role.members.add(user('user', False))
assert not access.can_change(organization, None) assert not access.can_change(organization, None)
assert not access.can_delete(organization) assert not access.can_delete(organization)
org = access.get_queryset()[0] org = access.get_queryset()[0]
assert len(org.admins.all()) == 0 assert len(org.admin_role.members.all()) == 0
assert len(org.users.all()) == 1 assert len(org.member_role.members.all()) == 1