def _can_access(self, request, member, organization): """ Conditions where user can modify the requested resource: * If they are an active superuser * If they are modifying their own membership * If the user's role is higher than the targeted user's role (e.g. "admin" can't modify "owner") * If the user is an "admin" and they are modifying a team they are a member of """ if is_active_superuser(request): return True if not request.user.is_authenticated(): return False if request.user.id == member.user_id: return True acting_member = OrganizationMember.objects.get( organization=organization, user__id=request.user.id, user__is_active=True ) if roles.get(acting_member.role).is_global and roles.can_manage( acting_member.role, member.role ): return True return False
def delete(self, request: Request, organization, member_id) -> Response: """ Remove an organization member. """ try: om = self._get_member(request, organization, member_id) except OrganizationMember.DoesNotExist: raise ResourceDoesNotExist if request.user.is_authenticated and not is_active_superuser(request): try: acting_member = OrganizationMember.objects.get( organization=organization, user=request.user) except OrganizationMember.DoesNotExist: return Response({"detail": ERR_INSUFFICIENT_ROLE}, status=400) else: if acting_member != om: if not request.access.has_scope("member:admin"): return Response({"detail": ERR_INSUFFICIENT_SCOPE}, status=400) elif not roles.can_manage(acting_member.role, om.role): return Response({"detail": ERR_INSUFFICIENT_ROLE}, status=400) # TODO(dcramer): do we even need this check? elif not request.access.has_scope("member:admin"): return Response({"detail": ERR_INSUFFICIENT_SCOPE}, status=400) if self.is_only_owner(om): return Response({"detail": ERR_ONLY_OWNER}, status=403) audit_data = om.get_audit_log_data() with transaction.atomic(): AuthIdentity.objects.filter( user=om.user, auth_provider__organization=organization).delete() # Delete instances of `UserOption` that are scoped to the projects within the # organization when corresponding member is removed from org proj_list = Project.objects.filter( organization=organization).values_list("id", flat=True) uo_list = UserOption.objects.filter(user=om.user, project_id__in=proj_list, key="mail:email") for uo in uo_list: uo.delete() om.delete() self.create_audit_entry( request=request, organization=organization, target_object=om.id, target_user=om.user, event=AuditLogEntryEvent.MEMBER_REMOVE, data=audit_data, ) return Response(status=204)
def delete(self, request, organization, member_id): try: om = self._get_member(request, organization, member_id) except OrganizationMember.DoesNotExist: raise ResourceDoesNotExist if request.user.is_authenticated( ) and not is_active_superuser(request): try: acting_member = OrganizationMember.objects.get( organization=organization, user=request.user, ) except OrganizationMember.DoesNotExist: return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400) else: if acting_member != om: if not request.access.has_scope('member:admin'): return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400) elif not roles.can_manage(acting_member.role, om.role): return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400) # TODO(dcramer): do we even need this check? elif not request.access.has_scope('member:admin'): return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400) if self._is_only_owner(om): return Response({'detail': ERR_ONLY_OWNER}, status=403) audit_data = om.get_audit_log_data() with transaction.atomic(): AuthIdentity.objects.filter( user=om.user, auth_provider__organization=organization, ).delete() om.delete() self.create_audit_entry( request=request, organization=organization, target_object=om.id, target_user=om.user, event=AuditLogEntryEvent.MEMBER_REMOVE, data=audit_data, ) return Response(status=204)
def delete(self, request, organization, member_id): try: om = self._get_member(request, organization, member_id) except OrganizationMember.DoesNotExist: raise ResourceDoesNotExist if request.user.is_authenticated() and not request.is_superuser(): try: acting_member = OrganizationMember.objects.get( organization=organization, user=request.user, ) except OrganizationMember.DoesNotExist: return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400) else: if acting_member != om: if not request.access.has_scope('member:admin'): return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400) elif not roles.can_manage(acting_member.role, om.role): return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400) # TODO(dcramer): do we even need this check? elif not request.access.has_scope('member:admin'): return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400) if self._is_only_owner(om): return Response({'detail': ERR_ONLY_OWNER}, status=403) audit_data = om.get_audit_log_data() with transaction.atomic(): AuthIdentity.objects.filter( user=om.user, auth_provider__organization=organization, ).delete() om.delete() self.create_audit_entry( request=request, organization=organization, target_object=om.id, target_user=om.user, event=AuditLogEntryEvent.MEMBER_REMOVE, data=audit_data, ) return Response(status=204)
def _can_access(self, request, member, organization): if is_active_superuser(request): return True if not request.user.is_authenticated(): return False if request.user.id == member.user_id: return True acting_member = OrganizationMember.objects.get( organization=organization, user__id=request.user.id, user__is_active=True, ) if roles.get(acting_member.role).is_global and \ roles.can_manage(acting_member.role, member.role): return True return False
def can_manage_member(self, member): return roles.can_manage(self.role, member.role)