Fixed org auditor visibility of team credentials

And by fix, I mean prevent us from getting into the situation that was
causing the asymetric visiblity by brining us into alignment with the
original intention and spec for how credentials were supposed behave.

 #3081
This commit is contained in:
Akita Noek
2016-08-16 14:00:45 -04:00
parent db87e3cb30
commit 30451f230b
5 changed files with 214 additions and 43 deletions

View File

@@ -1716,21 +1716,21 @@ class CredentialSerializerCreate(CredentialSerializer):
attrs.pop(field)
if not owner_fields:
raise serializers.ValidationError({"detail": "Missing 'user', 'team', or 'organization'."})
elif len(owner_fields) > 1:
raise serializers.ValidationError({"detail": "Expecting exactly one of 'user', 'team', or 'organization'."})
return super(CredentialSerializerCreate, self).validate(attrs)
def create(self, validated_data):
user = validated_data.pop('user', None)
team = validated_data.pop('team', None)
if team:
validated_data['organization'] = team.organization
credential = super(CredentialSerializerCreate, self).create(validated_data)
if user:
credential.admin_role.members.add(user)
if team:
if not credential.organization or team.organization.id != credential.organization.id:
raise serializers.ValidationError({"detail": "Credential organization must be set and match before assigning to a team"})
credential.admin_role.parents.add(team.admin_role)
credential.use_role.parents.add(team.member_role)
return credential

View File

@@ -879,11 +879,18 @@ class TeamRolesList(SubListCreateAttachDetachAPIView):
return Response(data, status=status.HTTP_400_BAD_REQUEST)
role = get_object_or_400(Role, pk=sub_id)
content_type = ContentType.objects.get_for_model(Organization)
if role.content_type == content_type:
org_content_type = ContentType.objects.get_for_model(Organization)
if role.content_type == org_content_type:
data = dict(msg="You cannot assign an Organization role as a child role for a Team.")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
team = get_object_or_404(Team, pk=self.kwargs['pk'])
credential_content_type = ContentType.objects.get_for_model(Credential)
if role.content_type == credential_content_type:
if not role.content_object.organization or role.content_object.organization.id != team.organization.id:
data = dict(msg="You cannot grant credential access to a team when the Organization field isn't set, or belongs to a different organization")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
return super(TeamRolesList, self).post(request, *args, **kwargs)
class TeamObjectRolesList(SubListAPIView):
@@ -1209,11 +1216,23 @@ class UserRolesList(SubListCreateAttachDetachAPIView):
if sub_id == self.request.user.admin_role.pk:
raise PermissionDenied('You may not perform any action with your own admin_role.')
user = get_object_or_400(User, pk=self.kwargs['pk'])
role = get_object_or_400(Role, pk=sub_id)
user_content_type = ContentType.objects.get_for_model(User)
if role.content_type == user_content_type:
raise PermissionDenied('You may not change the membership of a users admin_role')
credential_content_type = ContentType.objects.get_for_model(Credential)
if role.content_type == credential_content_type:
if role.content_object.organization and user not in role.content_object.organization.member_role:
data = dict(msg="You cannot grant credential access to a user not in the credentials' organization")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
if not role.content_object.organization and not request.user.is_superuser:
data = dict(msg="You cannot grant private credential access to another user")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
return super(UserRolesList, self).post(request, *args, **kwargs)
def check_parent_access(self, parent=None):
@@ -3656,6 +3675,7 @@ class RoleUsersList(SubListCreateAttachDetachAPIView):
data = dict(msg="User 'id' field is missing.")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
user = get_object_or_400(User, pk=sub_id)
role = self.get_parent_object()
if role == self.request.user.admin_role:
raise PermissionDenied('You may not perform any action with your own admin_role.')
@@ -3664,6 +3684,16 @@ class RoleUsersList(SubListCreateAttachDetachAPIView):
if role.content_type == user_content_type:
raise PermissionDenied('You may not change the membership of a users admin_role')
credential_content_type = ContentType.objects.get_for_model(Credential)
if role.content_type == credential_content_type:
if role.content_object.organization and user not in role.content_object.organization.member_role:
data = dict(msg="You cannot grant credential access to a user not in the credentials' organization")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
if not role.content_object.organization and not request.user.is_superuser:
data = dict(msg="You cannot grant private credential access to another user")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
return super(RoleUsersList, self).post(request, *args, **kwargs)
@@ -3688,13 +3718,20 @@ class RoleTeamsList(SubListAPIView):
data = dict(msg="Team 'id' field is missing.")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
team = get_object_or_400(Team, pk=sub_id)
role = Role.objects.get(pk=self.kwargs['pk'])
content_type = ContentType.objects.get_for_model(Organization)
if role.content_type == content_type:
organization_content_type = ContentType.objects.get_for_model(Organization)
if role.content_type == organization_content_type:
data = dict(msg="You cannot assign an Organization role as a child role for a Team.")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
team = get_object_or_400(Team, pk=sub_id)
credential_content_type = ContentType.objects.get_for_model(Credential)
if role.content_type == credential_content_type:
if not role.content_object.organization or role.content_object.organization.id != team.organization.id:
data = dict(msg="You cannot grant credential access to a team when the Organization field isn't set, or belongs to a different organization")
return Response(data, status=status.HTTP_400_BAD_REQUEST)
action = 'attach'
if request.data.get('disassociate', None):
action = 'unattach'