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))
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)
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)
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))
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)
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)
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))
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))
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))
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