1010from pydantic import Json
1111from six import string_types
1212from sortedcontainers import SortedSet
13- from sqlalchemy import Table , and_ , desc , func , not_ , or_ , orm
13+ from sqlalchemy import Table , and_ , desc , func , not_ , or_ , orm , exists
1414from sqlalchemy .exc import InvalidRequestError , ProgrammingError
1515from sqlalchemy .orm import mapperlib , Query as SQLAlchemyQuery
1616from sqlalchemy_filters import apply_pagination , apply_sort
@@ -591,6 +591,7 @@ def common_parameters(
591591 sort_by : list [str ] = Query ([], alias = "sortBy[]" ),
592592 descending : list [bool ] = Query ([], alias = "descending[]" ),
593593 role : UserRoles = Depends (get_current_role ),
594+ security_event_only : bool = Query (None , alias = "security_event_only" ),
594595):
595596 return {
596597 "db_session" : db_session ,
@@ -602,11 +603,15 @@ def common_parameters(
602603 "descending" : descending ,
603604 "current_user" : current_user ,
604605 "role" : role ,
606+ "security_event_only" : security_event_only ,
605607 }
606608
607609
608610CommonParameters = Annotated [
609- dict [str , int | CurrentUser | DbSession | QueryStr | Json | list [str ] | list [bool ] | UserRoles ],
611+ dict [
612+ str ,
613+ int | CurrentUser | DbSession | QueryStr | Json | list [str ] | list [bool ] | UserRoles | bool ,
614+ ],
610615 Depends (common_parameters ),
611616]
612617
@@ -676,6 +681,7 @@ def search_filter_sort_paginate(
676681 descending : list [bool ] = None ,
677682 current_user : DispatchUser = None ,
678683 role : UserRoles = UserRoles .member ,
684+ security_event_only : bool = None ,
679685):
680686 """Common functionality for searching, filtering, sorting, and pagination."""
681687 model_cls = get_class_by_tablename (model )
@@ -712,6 +718,11 @@ def search_filter_sort_paginate(
712718 else :
713719 query = apply_filters (query , filter_spec , model_cls )
714720
721+ # Handle security_event_only filter for Case model
722+ if model == "Case" and security_event_only :
723+ # Use NOT EXISTS to find cases that do NOT have signal instances
724+ query = query .filter (~ exists ().where (SignalInstance .case_id == Case .id ))
725+
715726 # Apply tag_all filters using intersect only when necessary
716727 for filter in tag_all_filters :
717728 query = query .intersect (filter )
0 commit comments