def get(self, request, organization):
        """
        List an Organization's saved searches
        `````````````````````````````````````
        Retrieve a list of saved searches for a given Organization. For custom
        saved searches, return them for all projects even if we have duplicates.
        For default searches, just return one of each search

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get('type', 0)))
        except ValueError as e:
            return Response(
                {'detail': 'Invalid input for `type`. Error: %s' % six.text_type(e)},
                status=400,
            )

        if request.GET.get('use_org_level') == '1':
            org_searches_q = Q(
                Q(owner=request.user) | Q(owner__isnull=True),
                organization=organization,
            )
            global_searches_q = Q(is_global=True)
            saved_searches = list(SavedSearch.objects.filter(
                org_searches_q | global_searches_q,
                type=search_type,
            ).extra(
                select={'has_owner': 'owner_id is not null', 'name__upper': 'UPPER(name)'},
                order_by=['-has_owner', 'name__upper'],
            ))
            results = []
            if saved_searches:
                pinned_search = None
                # If the saved search has an owner then it's the user's pinned
                # search. The user can only have one pinned search.
                results.append(saved_searches[0])
                if saved_searches[0].is_pinned:
                    pinned_search = saved_searches[0]
                for saved_search in saved_searches[1:]:
                    # If a search has the same query as the pinned search we
                    # want to use that search as the pinned search
                    if pinned_search and saved_search.query == pinned_search.query:
                        saved_search.is_pinned = True
                        results[0] = saved_search
                    else:
                        results.append(saved_search)
        else:
            org_searches = Q(
                Q(owner=request.user) | Q(owner__isnull=True),
                ~Q(query__in=DEFAULT_SAVED_SEARCH_QUERIES),
                project__in=self.get_projects(request, organization),
            )
            global_searches = Q(is_global=True)
            results = list(SavedSearch.objects.filter(
                org_searches | global_searches
            ).order_by('name', 'project'))

        return Response(serialize(results, request.user))
Example #2
0
    def post(self, request, organization):
        serializer = OrganizationSearchSerializer(data=request.data)

        if serializer.is_valid():
            result = serializer.validated_data
            # Prevent from creating duplicate queries
            if SavedSearch.objects.filter(
                    Q(is_global=True)
                    | Q(organization=organization, owner__isnull=True),
                    query=result["query"],
            ).exists():
                return Response(
                    {
                        "detail": "Query {} already exists".format(
                            result["query"])
                    },
                    status=400)

            saved_search = SavedSearch.objects.create(
                organization=organization,
                type=result["type"],
                name=result["name"],
                query=result["query"],
                sort=result["sort"],
            )
            analytics.record(
                "organization_saved_search.created",
                search_type=SearchType(saved_search.type).name,
                org_id=organization.id,
                query=saved_search.query,
            )
            return Response(serialize(saved_search, request.user))
        return Response(serializer.errors, status=400)
Example #3
0
    def delete(self, request, organization, search_id):
        """
        Delete a saved search

        Permanently remove a saved search.

            {method} {path}

        """
        try:
            search = SavedSearch.objects.get(
                owner__isnull=True,
                organization=organization,
                id=search_id,
            )
        except SavedSearch.DoesNotExist:
            raise ResourceDoesNotExist

        search.delete()
        analytics.record(
            'organization_saved_search.deleted',
            search_type=SearchType(search.type).name,
            org_id=organization.id,
            query=search.query,
        )
        return Response(status=204)
Example #4
0
    def get(self, request, organization):
        """
        List recent searches for a User within an Organization
        ``````````````````````````````````````````````````````
        Returns recent searches for a user in a given Organization.

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get("type", 0)))
        except ValueError as e:
            return Response({"detail": "Invalid input for `type`. Error: %s" % str(e)}, status=400)

        try:
            limit = int(request.GET.get("limit", 3))
        except ValueError as e:
            return Response({"detail": "Invalid input for `limit`. Error: %s" % str(e)}, status=400)

        query_kwargs = {"organization": organization, "user": request.user, "type": search_type}

        if "query" in request.GET:
            query_kwargs["query__icontains"] = request.GET["query"]

        recent_searches = list(
            RecentSearch.objects.filter(**query_kwargs).order_by("-last_seen")[:limit]
        )

        return Response(serialize(recent_searches, request.user))
Example #5
0
    def post(self, request, organization):
        serializer = OrganizationSearchSerializer(data=request.DATA)

        if serializer.is_valid():
            result = serializer.object
            # Prevent from creating duplicate queries
            if SavedSearch.objects.filter(
                    Q(is_global=True)
                    | Q(organization=organization, owner__isnull=True),
                    query=result['query'],
            ).exists():
                return Response(
                    {
                        'detail':
                        u'Query {} already exists'.format(result['query'])
                    },
                    status=400,
                )

            saved_search = SavedSearch.objects.create(
                organization=organization,
                type=result['type'],
                name=result['name'],
                query=result['query'],
            )
            analytics.record(
                'organization_saved_search.created',
                search_type=SearchType(saved_search.type).name,
                org_id=organization.id,
                query=saved_search.query,
            )
            return Response(serialize(saved_search, request.user))
        return Response(serializer.errors, status=400)
Example #6
0
 def delete(self, request, organization):
     try:
         search_type = SearchType(int(request.data.get("type", 0)))
     except ValueError as e:
         return Response({"detail": "Invalid input for `type`. Error: %s" % str(e)}, status=400)
     SavedSearch.objects.filter(
         organization=organization, owner=request.user, type=search_type.value
     ).delete()
     return Response(status=204)
 def delete(self, request, organization):
     try:
         search_type = SearchType(int(request.data.get('type', 0)))
     except ValueError as e:
         return Response(
             {'detail': 'Invalid input for `type`. Error: %s' % six.text_type(e)},
             status=400,
         )
     SavedSearch.objects.filter(
         organization=organization,
         owner=request.user,
         type=search_type.value,
     ).delete()
     return Response(status=204)
Example #8
0
    def get(self, request, organization):
        """
        List an Organization's saved searches
        `````````````````````````````````````
        Retrieve a list of saved searches for a given Organization. For custom
        saved searches, return them for all projects even if we have duplicates.
        For default searches, just return one of each search

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get("type", 0)))
        except ValueError as e:
            return Response(
                {
                    "detail":
                    "Invalid input for `type`. Error: %s" % six.text_type(e)
                },
                status=400)
        org_searches_q = Q(Q(owner=request.user) | Q(owner__isnull=True),
                           organization=organization)
        global_searches_q = Q(is_global=True)
        saved_searches = list(
            SavedSearch.objects.filter(
                org_searches_q | global_searches_q, type=search_type).extra(
                    select={
                        "has_owner": "owner_id is not null",
                        "name__upper": "UPPER(name)"
                    },
                    order_by=["-has_owner", "name__upper"],
                ))
        results = []
        if saved_searches:
            pinned_search = None
            # If the saved search has an owner then it's the user's pinned
            # search. The user can only have one pinned search.
            results.append(saved_searches[0])
            if saved_searches[0].is_pinned:
                pinned_search = saved_searches[0]
            for saved_search in saved_searches[1:]:
                # If a search has the same query as the pinned search we
                # want to use that search as the pinned search
                if pinned_search and saved_search.query == pinned_search.query:
                    saved_search.is_pinned = True
                    results[0] = saved_search
                else:
                    results.append(saved_search)

        return Response(serialize(results, request.user))
    def get(self, request, organization):
        """
        List recent searches for a User within an Organization
        ``````````````````````````````````````````````````````
        Returns recent searches for a user in a given Organization.

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get('type', 0)))
        except ValueError as e:
            return Response(
                {
                    'detail':
                    'Invalid input for `type`. Error: %s' % six.text_type(e)
                },
                status=400,
            )

        try:
            limit = int(request.GET.get('limit', 3))
        except ValueError as e:
            return Response(
                {
                    'detail':
                    'Invalid input for `limit`. Error: %s' % six.text_type(e)
                },
                status=400,
            )

        query_kwargs = {
            'organization': organization,
            'user': request.user,
            'type': search_type,
        }

        if 'query' in request.GET:
            query_kwargs['query__icontains'] = request.GET['query']

        recent_searches = list(
            RecentSearch.objects.filter(
                **query_kwargs).order_by('-last_seen')[:limit])

        return Response(serialize(recent_searches, request.user))
Example #10
0
    def get(self, request, organization):
        """
        List recent searches for a User within an Organization
        ``````````````````````````````````````````````````````
        Returns recent searches for a user in a given Organization.

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get('type', 0)))
        except ValueError as e:
            return Response(
                {
                    'detail':
                    'Invalid input for `type`. Error: %s' % six.text_type(e)
                },
                status=400,
            )

        try:
            limit = int(request.GET.get('limit', 3))
        except ValueError as e:
            return Response(
                {
                    'detail':
                    'Invalid input for `limit`. Error: %s' % six.text_type(e)
                },
                status=400,
            )

        recent_searches = list(
            RecentSearch.objects.filter(
                organization=organization,
                user=request.user,
                type=search_type,
            ).order_by('-last_seen')[:limit])

        return Response(serialize(recent_searches, request.user))
Example #11
0
    def get(self, request, organization):
        """
        List an Organization's saved searches
        `````````````````````````````````````
        Retrieve a list of saved searches for a given Organization. For custom
        saved searches, return them for all projects even if we have duplicates.
        For default searches, just return one of each search

        :auth: required

        """
        try:
            search_type = SearchType(int(request.GET.get("type", 0)))
        except ValueError as e:
            return Response(
                {"detail": "Invalid input for `type`. Error: %s" % six.text_type(e)}, status=400
            )

        if request.GET.get("use_org_level") == "1":
            org_searches_q = Q(
                Q(owner=request.user) | Q(owner__isnull=True), organization=organization
            )
            global_searches_q = Q(is_global=True)
            saved_searches = list(
                SavedSearch.objects.filter(
                    org_searches_q | global_searches_q, type=search_type
                ).extra(
                    select={"has_owner": "owner_id is not null", "name__upper": "UPPER(name)"},
                    order_by=["-has_owner", "name__upper"],
                )
            )
            results = []
            if saved_searches:
                pinned_search = None
                # If the saved search has an owner then it's the user's pinned
                # search. The user can only have one pinned search.
                results.append(saved_searches[0])
                if saved_searches[0].is_pinned:
                    pinned_search = saved_searches[0]
                for saved_search in saved_searches[1:]:
                    # If a search has the same query as the pinned search we
                    # want to use that search as the pinned search
                    if pinned_search and saved_search.query == pinned_search.query:
                        saved_search.is_pinned = True
                        results[0] = saved_search
                    else:
                        results.append(saved_search)
        else:
            with sentry_sdk.push_scope() as scope:
                scope.level = "warning"
                sentry_sdk.capture_message("Deprecated project saved search used")

            org_searches = Q(
                Q(owner=request.user) | Q(owner__isnull=True),
                ~Q(query__in=DEFAULT_SAVED_SEARCH_QUERIES),
                project__in=self.get_projects(request, organization),
            )
            global_searches = Q(is_global=True)
            results = list(
                SavedSearch.objects.filter(org_searches | global_searches).order_by(
                    "name", "project"
                )
            )

        return Response(serialize(results, request.user))
Example #12
0
 def validate_type(self, value):
     try:
         SearchType(value)
     except ValueError as e:
         raise serializers.ValidationError(str(e))
     return value
 def validate_type(self, attrs, source):
     try:
         SearchType(attrs[source])
     except ValueError as e:
         raise serializers.ValidationError(six.text_type(e))
     return attrs