88from qwc_services_core .database import DatabaseEngine
99from qwc_services_core .permissions_reader import PermissionsReader
1010from qwc_services_core .runtime_config import RuntimeConfig
11- from sqlalchemy .sql import text as sql_text
11+ from sqlalchemy .sql import text as sql_text , literal
1212
1313from search_resources import SearchResources
1414
@@ -57,6 +57,12 @@ def __init__(self, tenant, logger):
5757 self .layer_query_template = config .get ('trgm_layer_query_template' )
5858 self .similarity_threshold = config .get ('trgm_similarity_threshold' , 0.3 )
5959
60+ def sql_escape (self , string ):
61+ return str (literal (str (string )).compile (
62+ dialect = self .db_engine .db_engine (self .db_url ).dialect ,
63+ compile_kwargs = {"literal_binds" : True }
64+ ))[1 :- 1 ]
65+
6066 def search (self , identity , searchtext , searchfilter , limit ):
6167 (filterword , tokens ) = self .tokenize (searchtext )
6268 if not tokens :
@@ -65,13 +71,13 @@ def search(self, identity, searchtext, searchfilter, limit):
6571 searchfilter = [self .filterwords .get (filterword )]
6672
6773 # Determine permitted facets and dataproducts
68- solr_facets = self .resources .solr_facets (identity )
74+ search_facets = self .resources .solr_facets (identity )
6975 permitted_dataproducts = self .resources .dataproducts (identity )
7076 if not searchfilter :
7177 # use all permitted facets if filter is empty
72- search_facets = list (solr_facets .keys ())
78+ search_facets = list (search_facets .keys ())
7379 else :
74- search_facets = [facet for facet in searchfilter if facet in solr_facets ]
80+ search_facets = [facet for facet in searchfilter if facet in search_facets ]
7581
7682 search_ds = list (filter (lambda facet : facet not in ["foreground" , "background" ], search_facets ))
7783 search_dp = list (filter (lambda facet : facet in ["foreground" , "background" ], search_facets ))
@@ -85,7 +91,9 @@ def search(self, identity, searchtext, searchfilter, limit):
8591 layer_query = self .layer_query
8692 if self .layer_query_template :
8793 layer_query = Template (self .layer_query_template ).render (
88- searchtext = searchtext , words = tokens , facets = search_dp
94+ searchtext = self .sql_escape (searchtext ),
95+ words = list (map (self .sql_escape , tokens )),
96+ facets = search_dp
8997 )
9098 self .logger .debug ("Generated layer query from template" )
9199
@@ -94,7 +102,10 @@ def search(self, identity, searchtext, searchfilter, limit):
94102 # NOTE: facet_search_limit + 1: we limit results to facet_search_limit below, but pass + 1 here to
95103 # be able to detect whether there were actually more results than facet_search_limit
96104 feature_query = Template (self .feature_query_template ).render (
97- searchtext = searchtext , words = tokens , facets = search_ds , facetlimit = self .facet_search_limit + 1
105+ searchtext = self .sql_escape (searchtext ),
106+ words = list (map (self .sql_escape , tokens )),
107+ facets = search_ds ,
108+ facetlimit = self .facet_search_limit + 1
98109 )
99110 self .logger .debug ("Generated feature query from template" )
100111
0 commit comments