def handle_delete(self, request, organization):
        """
        This method exists as a way for getsentry to override this endpoint with less duplication.
        """
        if not request.user.is_authenticated:
            return self.respond({"detail": ERR_NO_USER}, status=401)
        if organization.is_default:
            return self.respond({"detail": ERR_DEFAULT_ORG}, status=400)

        with transaction.atomic():
            updated = Organization.objects.filter(
                id=organization.id, status=OrganizationStatus.VISIBLE).update(
                    status=OrganizationStatus.PENDING_DELETION)
            if updated:
                organization.status = OrganizationStatus.PENDING_DELETION
                schedule = ScheduledDeletion.schedule(organization,
                                                      days=1,
                                                      actor=request.user)
                entry = self.create_audit_entry(
                    request=request,
                    organization=organization,
                    target_object=organization.id,
                    event=AuditLogEntryEvent.ORG_REMOVE,
                    data=organization.get_audit_log_data(),
                    transaction_id=schedule.guid,
                )
                organization.send_delete_confirmation(entry, ONE_DAY)
        context = serialize(
            organization,
            request.user,
            org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(
            ),
            access=request.access,
        )
        return self.respond(context, status=202)
Esempio n. 2
0
    def put(self, request, organization):
        """
        Update an Organization
        ``````````````````````

        Update various attributes and configurable settings for the given
        organization.

        :pparam string organization_slug: the slug of the organization the
                                          team should be created for.
        :param string name: an optional new name for the organization.
        :param string slug: an optional new slug for the organization.  Needs
                            to be available and unique.
        :auth: required
        """
        if request.access.has_scope("org:admin"):
            serializer_cls = OwnerOrganizationSerializer
        else:
            serializer_cls = OrganizationSerializer

        was_pending_deletion = organization.status in DELETION_STATUSES

        serializer = serializer_cls(
            data=request.data,
            partial=True,
            context={"organization": organization, "user": request.user, "request": request},
        )
        if serializer.is_valid():
            organization, changed_data = serializer.save()

            if was_pending_deletion:
                self.create_audit_entry(
                    request=request,
                    organization=organization,
                    target_object=organization.id,
                    event=AuditLogEntryEvent.ORG_RESTORE,
                    data=organization.get_audit_log_data(),
                )
                delete_logger.info(
                    "object.delete.canceled",
                    extra={"object_id": organization.id, "model": Organization.__name__},
                )
            elif changed_data:
                self.create_audit_entry(
                    request=request,
                    organization=organization,
                    target_object=organization.id,
                    event=AuditLogEntryEvent.ORG_EDIT,
                    data=changed_data,
                )

            context = serialize(
                organization,
                request.user,
                org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(),
                access=request.access,
            )

            return self.respond(context)
        return self.respond(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Esempio n. 3
0
 def handle_delete(self, request, organization):
     """
     This method exists as a way for getsentry to override this endpoint with less duplication.
     """
     if not request.user.is_authenticated:
         return self.respond({"detail": ERR_NO_USER}, status=401)
     if organization.is_default:
         return self.respond({"detail": ERR_DEFAULT_ORG}, status=400)
     updated = Organization.objects.filter(
         id=organization.id, status=OrganizationStatus.VISIBLE).update(
             status=OrganizationStatus.PENDING_DELETION)
     if updated:
         transaction_id = uuid4().hex
         countdown = 86400
         entry = self.create_audit_entry(
             request=request,
             organization=organization,
             target_object=organization.id,
             event=AuditLogEntryEvent.ORG_REMOVE,
             data=organization.get_audit_log_data(),
             transaction_id=transaction_id,
         )
         organization.send_delete_confirmation(entry, countdown)
         delete_organization.apply_async(
             kwargs={
                 "object_id": organization.id,
                 "transaction_id": transaction_id,
                 "actor_id": request.user.id,
             },
             countdown=countdown,
         )
         delete_logger.info(
             "object.delete.queued",
             extra={
                 "object_id": organization.id,
                 "transaction_id": transaction_id,
                 "model": Organization.__name__,
             },
         )
     context = serialize(
         organization,
         request.user,
         org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(
         ),
         access=request.access,
     )
     return self.respond(context, status=202)
Esempio n. 4
0
    def delete(self, request, organization):
        """
        Delete an Organization
        ``````````````````````

        Schedules an organization for deletion.  This API endpoint cannot
        be invoked without a user context for security reasons.  This means
        that at present an organization can only be deleted from the
        Sentry UI.

        Deletion happens asynchronously and therefor is not immediate.
        However once deletion has begun the state of a project changes and
        will be hidden from most public views.

        :pparam string organization_slug: the slug of the organization the
                                          team should be created for.
        :auth: required, user-context-needed
        """
        if not request.user.is_authenticated():
            return self.respond({'detail': ERR_NO_USER}, status=401)

        if organization.is_default:
            return self.respond({'detail': ERR_DEFAULT_ORG}, status=400)

        updated = Organization.objects.filter(
            id=organization.id,
            status=OrganizationStatus.VISIBLE,
        ).update(status=OrganizationStatus.PENDING_DELETION)
        if updated:
            transaction_id = uuid4().hex
            countdown = 86400

            entry = self.create_audit_entry(
                request=request,
                organization=organization,
                target_object=organization.id,
                event=AuditLogEntryEvent.ORG_REMOVE,
                data=organization.get_audit_log_data(),
                transaction_id=transaction_id,
            )

            organization.send_delete_confirmation(entry, countdown)

            delete_organization.apply_async(
                kwargs={
                    'object_id': organization.id,
                    'transaction_id': transaction_id,
                    'actor_id': request.user.id,
                },
                countdown=countdown,
            )

            delete_logger.info('object.delete.queued',
                               extra={
                                   'object_id': organization.id,
                                   'transaction_id': transaction_id,
                                   'model': Organization.__name__,
                               })

        context = serialize(
            organization,
            request.user,
            org_serializers.DetailedOrganizationSerializerWithProjectsAndTeams(
            ),
            access=request.access,
        )
        return self.respond(context, status=202)