예제 #1
0
    def handle(self, request, organization, project):
        form = self.get_form(request)

        if form.is_valid():
            client.delete('/projects/{}/{}/'.format(organization.slug,
                                                    project.slug),
                          request=request,
                          is_sudo=True)

            is_internal = features.has(
                'organizations:internal-catchall',
                organization,
                actor=request.user,
            )
            project_name = (project.slug
                            if is_internal else project.name).encode('utf-8')
            messages.add_message(
                request, messages.SUCCESS,
                _(u'The project %r was scheduled for deletion.') %
                (project_name, ))

            return HttpResponseRedirect(
                reverse('sentry-organization-home', args=[organization.slug]))

        context = {
            'form': form,
        }

        return self.respond('sentry/projects/remove.html', context)
예제 #2
0
    def handle(self, request, organization, project):
        form = self.get_form(request)

        if form.is_valid():
            client.delete(
                '/projects/{}/{}/'.format(organization.slug, project.slug),
                request=request,
                is_sudo=True
            )

            has_new_teams = features.has(
                'organizations:new-teams',
                organization,
                actor=request.user,
            )
            project_name = (project.slug if has_new_teams else project.name).encode('utf-8')
            messages.add_message(
                request, messages.SUCCESS,
                _(u'The project %r was scheduled for deletion.') % (project_name, )
            )

            return HttpResponseRedirect(
                reverse('sentry-organization-home', args=[organization.slug])
            )

        context = {
            'form': form,
        }

        return self.respond('sentry/projects/remove.html', context)
예제 #3
0
    def handle(self, request):
        org_list = Organization.objects.filter(
            member_set__role=roles.get_top_dog().id,
            member_set__user=request.user,
        )
        org_results = []
        for org in sorted(org_list, key=lambda x: x.name):
            # O(N) query
            org_results.append({
                'organization': org,
                'single_owner': org.has_single_owner(),
            })

        form = self.get_form(request)
        if form.is_valid():
            avail_org_slugs = set([
                o['organization'].slug for o in org_results
            ])
            orgs_to_remove = set(
                request.POST.getlist('oID')
            ).intersection(avail_org_slugs)
            for result in org_results:
                if result['single_owner']:
                    orgs_to_remove.add(result['organization'].slug)

            logging.getLogger('sentry.deletions').info(
                'User (id=%s) removal requested by self',
                request.user.id)

            for org_slug in orgs_to_remove:
                client.delete('/organizations/{}/'.format(org_slug),
                              request.user, is_sudo=True)

            remaining_org_ids = [
                o.id for o in org_list
                if o.slug in avail_org_slugs.difference(orgs_to_remove)
            ]

            if remaining_org_ids:
                OrganizationMember.objects.filter(
                    organization__in=remaining_org_ids,
                    user=request.user,
                ).delete()

            User.objects.filter(
                id=request.user.id,
            ).update(
                is_active=False,
            )

            logout(request)

            return self.respond('sentry/post-remove-account.html')

        context = {
            'form': form,
            'organization_results': org_results,
        }

        return self.respond('sentry/remove-account.html', context)
    def handle(self, request):
        org_list = Organization.objects.filter(
            member_set__role=roles.get_top_dog().id,
            member_set__user=request.user,
            status=OrganizationStatus.VISIBLE,
        )
        org_results = []
        for org in sorted(org_list, key=lambda x: x.name):
            # O(N) query
            org_results.append({
                'organization': org,
                'single_owner': org.has_single_owner(),
            })

        form = self.get_form(request)
        if form.is_valid():
            avail_org_slugs = set(
                [o['organization'].slug for o in org_results])
            orgs_to_remove = set(
                request.POST.getlist('oID')).intersection(avail_org_slugs)
            for result in org_results:
                if result['single_owner']:
                    orgs_to_remove.add(result['organization'].slug)

            delete_logger.info('user.deactivate',
                               extra={
                                   'actor_id': request.user.id,
                                   'ip_address': request.META['REMOTE_ADDR'],
                               })

            for org_slug in orgs_to_remove:
                client.delete('/organizations/{}/'.format(org_slug),
                              request=request,
                              is_sudo=True)

            remaining_org_ids = [
                o.id for o in org_list
                if o.slug in avail_org_slugs.difference(orgs_to_remove)
            ]

            if remaining_org_ids:
                OrganizationMember.objects.filter(
                    organization__in=remaining_org_ids,
                    user=request.user,
                ).delete()

            User.objects.filter(id=request.user.id, ).update(is_active=False, )

            logout(request)

            return self.respond('sentry/post-remove-account.html')

        context = {
            'form': form,
            'page': 'remove_account',
            'organization_results': org_results,
        }

        return self.respond('sentry/remove-account.html', context)
예제 #5
0
    def handle(self, request):
        org_list = Organization.objects.filter(
            member_set__type=OrganizationMemberType.OWNER,
            member_set__user=request.user,
            member_set__has_global_access=True,
        )
        org_results = []
        for org in sorted(org_list, key=lambda x: x.name):
            # O(N) query
            org_results.append({
                'organization': org,
                'single_owner': org.has_single_owner(),
            })

        form = self.get_form(request)
        if form.is_valid():
            avail_org_slugs = set(
                [o['organization'].slug for o in org_results])
            orgs_to_remove = set(
                request.POST.getlist('oID')).intersection(avail_org_slugs)
            for result in org_results:
                if result['single_owner']:
                    orgs_to_remove.add(result['organization'].slug)

            logging.getLogger('sentry.deletions').info(
                'User (id=%s) removal requested by self', request.user.id)

            for org_slug in orgs_to_remove:
                client.delete('/organizations/{}/'.format(org_slug),
                              request.user,
                              is_sudo=True)

            remaining_org_ids = [
                o.id for o in org_list
                if o.slug in avail_org_slugs.difference(orgs_to_remove)
            ]

            if remaining_org_ids:
                OrganizationMember.objects.filter(
                    organization__in=remaining_org_ids,
                    user=request.user,
                ).delete()

            User.objects.filter(id=request.user.id, ).update(is_active=False, )

            logout(request)

            return self.respond('sentry/post-remove-account.html')

        context = {
            'form': form,
            'organization_results': org_results,
        }

        return self.respond('sentry/remove-account.html', context)
예제 #6
0
    def post(self, request, organization):
        op = request.POST.get('op')
        team = request.POST.get('team')

        om = OrganizationMember.objects.get(
            user=request.user,
            organization=organization,
        )

        if op == 'leave':
            try:
                client.delete('/organizations/{}/members/{}/teams/{}/'.format(
                    organization.slug, om.id, team,
                ), request.user)
            except client.ApiError as exc:
                self.logger.exception('Unable to remove member from team: %s', unicode(exc))
                messages.add_message(
                    request, messages.ERROR,
                    'We were unable to remove you from the team.',
                )
            else:
                messages.add_message(
                    request, messages.SUCCESS,
                    'Your team membership has been deactivated.',
                )
        elif op == 'join':
            try:
                resp = client.post('/organizations/{}/members/{}/teams/{}/'.format(
                    organization.slug, om.id, team,
                ), request.user)
            except client.ApiError as exc:
                self.logger.exception('Unable to add member from team: %s', unicode(exc))
                messages.add_message(
                    request, messages.ERROR,
                    'We were unable to join the team.',
                )
            else:
                if resp.status_code == 202:
                    messages.add_message(
                        request, messages.SUCCESS,
                        'A request has been sent to join the team.',
                    )
                else:
                    messages.add_message(
                        request, messages.SUCCESS,
                        'Your team membership has been activated.',
                    )
        return HttpResponseRedirect(request.path)
예제 #7
0
    def post(self, request, organization):
        op = request.POST.get('op')
        team = request.POST.get('team')

        om = OrganizationMember.objects.get(
            user=request.user,
            organization=organization,
        )

        if op == 'leave':
            try:
                client.delete('/organizations/{}/members/{}/teams/{}/'.format(
                    organization.slug, om.id, team,
                ), request.user)
            except client.ApiError as exc:
                self.logger.exception('Unable to remove member from team: %s', unicode(exc))
                messages.add_message(
                    request, messages.ERROR,
                    'We were unable to remove you from the team.',
                )
            else:
                messages.add_message(
                    request, messages.SUCCESS,
                    'Your team membership has been deactivated.',
                )
        elif op == 'join':
            try:
                resp = client.post('/organizations/{}/members/{}/teams/{}/'.format(
                    organization.slug, om.id, team,
                ), request.user)
            except client.ApiError as exc:
                self.logger.exception('Unable to add member from team: %s', unicode(exc))
                messages.add_message(
                    request, messages.ERROR,
                    'We were unable to join the team.',
                )
            else:
                if resp.status_code == 202:
                    messages.add_message(
                        request, messages.SUCCESS,
                        'A request has been sent to join the team.',
                    )
                else:
                    messages.add_message(
                        request, messages.SUCCESS,
                        'Your team membership has been activated.',
                    )
        return HttpResponseRedirect(request.path)
예제 #8
0
    def handle(self, request, organization, team, project):
        form = self.get_form(request)

        if form.is_valid():
            client.delete('/projects/{}/{}/'.format(organization.slug, project.slug),
                          request=request, is_sudo=True)

            messages.add_message(
                request, messages.SUCCESS,
                _(u'The project %r was scheduled for deletion.') % (project.name.encode('utf-8'),))

            return HttpResponseRedirect(reverse('sentry-organization-home', args=[team.organization.slug]))

        context = {
            'form': form,
        }

        return self.respond('sentry/projects/remove.html', context)
예제 #9
0
    def handle(self, request, organization, team):
        form = self.get_form(request)

        if form.is_valid():
            client.delete('/teams/{}/{}/'.format(organization.slug, team.slug),
                          request.user, is_sudo=True)

            messages.add_message(
                request, messages.SUCCESS,
                _(u'The team %r was scheduled for deletion.') % (team.name.encode('utf-8'),))

            return HttpResponseRedirect(reverse('sentry'))

        context = {
            'form': form,
        }

        return self.respond('sentry/teams/remove.html', context)
예제 #10
0
    def handle(self, request, organization, team, project):
        form = self.get_form(request)

        if form.is_valid():
            client.delete('/projects/{}/{}/'.format(organization.slug, project.slug),
                          request.user, is_sudo=True)

            messages.add_message(
                request, messages.SUCCESS,
                _(u'The project %r was scheduled for deletion.') % (project.name.encode('utf-8'),))

            return HttpResponseRedirect(reverse('sentry-organization-home', args=[team.organization.slug]))

        context = {
            'form': form,
        }

        return self.respond('sentry/projects/remove.html', context)
예제 #11
0
    def handle(self, request, organization, team):
        form = self.get_form(request)

        if form.is_valid():
            client.delete('/teams/{}/{}/'.format(organization.slug, team.slug),
                          request=request,
                          is_sudo=True)

            messages.add_message(
                request, messages.SUCCESS,
                _(u'The team %r was scheduled for deletion.') %
                (team.name.encode('utf-8'), ))

            return HttpResponseRedirect(reverse('sentry'))

        context = {
            'form': form,
        }

        return self.respond('sentry/teams/remove.html', context)
예제 #12
0
    def delete(self, request, user):
        """
        Delete User Account

        Also removes organizations if they are an owner
        :pparam string user_id: user id
        :param boolean hard_delete: Completely remove the user from the database (requires super user)
        :param list organizations: List of organization ids to remove
        :auth required:
        """

        serializer = DeleteUserSerializer(data=request.data)

        if not serializer.is_valid():
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # from `frontend/remove_account.py`
        org_list = Organization.objects.filter(
            member_set__role__in=[x.id for x in roles.with_scope("org:admin")],
            member_set__user=user,
            status=OrganizationStatus.VISIBLE,
        )

        org_results = []
        for org in org_list:
            org_results.append({
                "organization": org,
                "single_owner": org.has_single_owner()
            })

        avail_org_slugs = {o["organization"].slug for o in org_results}
        orgs_to_remove = set(serializer.validated_data.get(
            "organizations")).intersection(avail_org_slugs)

        for result in org_results:
            if result["single_owner"]:
                orgs_to_remove.add(result["organization"].slug)

        for org_slug in orgs_to_remove:
            client.delete(path=f"/organizations/{org_slug}/",
                          request=request,
                          is_sudo=True)

        remaining_org_ids = [
            o.id for o in org_list
            if o.slug in avail_org_slugs.difference(orgs_to_remove)
        ]

        if remaining_org_ids:
            OrganizationMember.objects.filter(
                organization__in=remaining_org_ids, user=user).delete()

        logging_data = {
            "actor_id": request.user.id,
            "ip_address": request.META["REMOTE_ADDR"],
            "user_id": user.id,
        }

        hard_delete = serializer.validated_data.get("hardDelete", False)

        # Only active superusers can hard delete accounts
        if hard_delete and not is_active_superuser(request):
            return Response(
                {"detail": "Only superusers may hard delete a user account"},
                status=status.HTTP_403_FORBIDDEN,
            )

        is_current_user = request.user.id == user.id

        if hard_delete:
            user.delete()
            delete_logger.info("user.removed", extra=logging_data)
        else:
            User.objects.filter(id=user.id).update(is_active=False)
            delete_logger.info("user.deactivate", extra=logging_data)

        # if the user deleted their own account log them out
        if is_current_user:
            logout(request)

        return Response(status=status.HTTP_204_NO_CONTENT)
예제 #13
0
    def delete(self, request, user):
        """
        Delete User Account

        Also removes organizations if they are an owner
        :pparam string user_id: user id
        :param list organizations: List of organization ids to remove
        :auth required:
        """

        serializer = OrganizationsSerializer(data=request.DATA)

        if not serializer.is_valid():
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # from `frontend/remove_account.py`
        org_list = Organization.objects.filter(
            member_set__role__in=[x.id for x in roles.with_scope('org:admin')],
            member_set__user=user,
            status=OrganizationStatus.VISIBLE,
        )

        org_results = []
        for org in org_list:
            org_results.append({
                'organization': org,
                'single_owner': org.has_single_owner(),
            })

        avail_org_slugs = set([o['organization'].slug for o in org_results])
        orgs_to_remove = set(serializer.object.get(
            'organizations')).intersection(avail_org_slugs)

        for result in org_results:
            if result['single_owner']:
                orgs_to_remove.add(result['organization'].slug)

        delete_logger.info('user.deactivate',
                           extra={
                               'actor_id': request.user.id,
                               'ip_address': request.META['REMOTE_ADDR'],
                           })

        for org_slug in orgs_to_remove:
            client.delete(path='/organizations/{}/'.format(org_slug),
                          request=request,
                          is_sudo=True)

        remaining_org_ids = [
            o.id for o in org_list
            if o.slug in avail_org_slugs.difference(orgs_to_remove)
        ]

        if remaining_org_ids:
            OrganizationMember.objects.filter(
                organization__in=remaining_org_ids,
                user=request.user,
            ).delete()

        User.objects.filter(id=request.user.id, ).update(is_active=False, )

        logout(request)

        return Response(status=status.HTTP_204_NO_CONTENT)
예제 #14
0
    def delete(self, request, user):
        """
        Delete User Account

        Also removes organizations if they are an owner
        :pparam string user_id: user id
        :param list organizations: List of organization ids to remove
        :auth required:
        """

        serializer = OrganizationsSerializer(data=request.DATA)

        if not serializer.is_valid():
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # from `frontend/remove_account.py`
        org_list = Organization.objects.filter(
            member_set__role__in=[x.id for x in roles.with_scope('org:admin')],
            member_set__user=user,
            status=OrganizationStatus.VISIBLE,
        )

        org_results = []
        for org in org_list:
            org_results.append({
                'organization': org,
                'single_owner': org.has_single_owner(),
            })

        avail_org_slugs = set([o['organization'].slug for o in org_results])
        orgs_to_remove = set(serializer.object.get('organizations')).intersection(avail_org_slugs)

        for result in org_results:
            if result['single_owner']:
                orgs_to_remove.add(result['organization'].slug)

        delete_logger.info(
            'user.deactivate',
            extra={
                'actor_id': request.user.id,
                'ip_address': request.META['REMOTE_ADDR'],
            }
        )

        for org_slug in orgs_to_remove:
            client.delete(
                path='/organizations/{}/'.format(org_slug),
                request=request,
                is_sudo=True)

        remaining_org_ids = [
            o.id for o in org_list if o.slug in avail_org_slugs.difference(orgs_to_remove)
        ]

        if remaining_org_ids:
            OrganizationMember.objects.filter(
                organization__in=remaining_org_ids,
                user=request.user,
            ).delete()

        User.objects.filter(
            id=request.user.id,
        ).update(
            is_active=False,
        )

        logout(request)

        return Response(status=status.HTTP_204_NO_CONTENT)