def test_no_active(self):
     result = serialize(
         self._get_org_members()[0],
         self.user_2,
         OrganizationMemberSCIMSerializer(),
     )
     assert "active" not in result
 def test_simple(self):
     result = serialize(
         self._get_org_members()[0],
         self.user_2,
         OrganizationMemberSCIMSerializer(expand=["active"]),
     )
     assert "active" in result
Beispiel #3
0
    def post(self, request, organization):
        # TODO: confirm mixed case emails get converted to lowercase
        serializer = OrganizationMemberSerializer(
            data={
                "email": request.data.get("userName"),
                "role": roles.get(organization.default_role).id,
            },
            context={
                "organization": organization,
                "allowed_roles": [roles.get(organization.default_role)],
                "allow_existing_invite_request": True,
            },
        )

        if not serializer.is_valid():
            if "email" in serializer.errors and any(
                ("is already a member" in error)
                    for error in serializer.errors["email"]):
                # we include conflict logic in the serializer, check to see if that was
                # our error and if so, return a 409 so the scim IDP knows how to handle
                raise ConflictError(detail=SCIM_409_USER_EXISTS)
            return Response(serializer.errors, status=400)

        result = serializer.validated_data
        with transaction.atomic():
            member = OrganizationMember(
                organization=organization,
                email=result["email"],
                role=result["role"],
                inviter=request.user,
            )
            self.create_audit_entry(
                request=request,
                organization_id=organization.id,
                target_object=member.id,
                data=member.get_audit_log_data(),
                event=AuditLogEntryEvent.MEMBER_INVITE
                if settings.SENTRY_ENABLE_INVITES else
                AuditLogEntryEvent.MEMBER_ADD,
            )
            # TODO: are invite tokens needed for SAML orgs?
            if settings.SENTRY_ENABLE_INVITES:
                member.token = member.generate_token()
            member.save()

        if settings.SENTRY_ENABLE_INVITES and result.get("sendInvite"):
            member.send_invite_email()
            member_invited.send_robust(
                member=member,
                user=request.user,
                sender=self,
                referrer=request.data.get("referrer"),
            )

        context = serialize(member,
                            serializer=OrganizationMemberSCIMSerializer())
        return Response(context, status=201)
Beispiel #4
0
def _scim_member_serializer_with_expansion(organization):
    """
    For our Azure SCIM integration, we don't want to return the `active`
    flag since we don't support soft deletes. Other integrations don't
    care about this and rely on the behavior of setting "active" to false
    to delete a member.
    """
    auth_provider = AuthProvider.objects.get(organization=organization)
    expand = ["active"]

    if auth_provider.provider == ACTIVE_DIRECTORY_PROVIDER_NAME:
        expand = []
    return OrganizationMemberSCIMSerializer(expand=expand)
Beispiel #5
0
    def patch(self, request, organization, member):
        operations = request.data.get("Operations", [])
        if len(operations) > 100:
            return Response(SCIM_400_TOO_MANY_PATCH_OPS_ERROR, status=400)
        for operation in operations:
            # we only support setting active to False which deletes the orgmember
            if self._should_delete_member(operation):
                self._delete_member(request, organization, member)
                return Response(status=204)
            else:
                return Response(SCIM_400_INVALID_PATCH, status=400)

        context = serialize(member,
                            serializer=OrganizationMemberSCIMSerializer())
        return Response(context)
Beispiel #6
0
 def get(self, request, organization, member):
     context = serialize(member,
                         serializer=OrganizationMemberSCIMSerializer())
     return Response(context)
Beispiel #7
0
 def on_results(results):
     results = serialize(results, None,
                         OrganizationMemberSCIMSerializer())
     return self.list_api_format(request, queryset.count(), results)