diff --git a/pycsw/core/repository.py b/pycsw/core/repository.py index 59093fb53..85fe53cbb 100644 --- a/pycsw/core/repository.py +++ b/pycsw/core/repository.py @@ -43,6 +43,7 @@ from sqlalchemy import create_engine, func, __version__, select from sqlalchemy.exc import OperationalError from sqlalchemy.sql import text +from sqlalchemy.sql.elements import Grouping from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import create_session @@ -418,7 +419,7 @@ def query(self, constraint, sortby=None, typenames=None, if 'where' in constraint: # GetRecords with constraint LOGGER.debug('constraint detected') query = self.session.query(self.dataset).filter( - text(constraint['where'])).params(self._create_values(constraint['values'])) + _safe_text(constraint['where'])).params(self._create_values(constraint['values'])) else: # GetRecords sans constraint LOGGER.debug('No constraint detected') query = self.session.query(self.dataset) @@ -512,14 +513,14 @@ def update(self, record=None, recprops=None, constraint=None): self.session.rollback() raise RuntimeError('property not found for XPath %s' % rpu['rp']['name']) rows += self._get_repo_filter(self.session.query(self.dataset)).filter( - text(constraint['where'])).params(self._create_values(constraint['values'])).update({ + _safe_text(constraint['where'])).params(self._create_values(constraint['values'])).update({ getattr(self.dataset, rpu['rp']['dbcol']): rpu['value'], 'xml': func.update_xpath(str(self.context.namespaces), getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:XML']), str(rpu)), }, synchronize_session='fetch') # then update anytext tokens rows2 += self._get_repo_filter(self.session.query(self.dataset)).filter( - text(constraint['where'])).params(self._create_values(constraint['values'])).update({ + _safe_text(constraint['where'])).params(self._create_values(constraint['values'])).update({ 'anytext': func.get_anytext(getattr( self.dataset, self.context.md_core_model['mappings']['pycsw:XML'])) }, synchronize_session='fetch') @@ -539,7 +540,7 @@ def delete(self, constraint): try: self.session.begin() rows = self._get_repo_filter(self.session.query(self.dataset)).filter( - text(constraint['where'])).params(self._create_values(constraint['values'])) + _safe_text(constraint['where'])).params(self._create_values(constraint['values'])) parentids = [] for row in rows: # get ids @@ -579,9 +580,11 @@ def exists(self): def _get_repo_filter(self, query): ''' Apply repository wide side filter / mask query ''' if self.filter is not None: - return query.filter(text(self.filter)) + return query.filter(_safe_text(self.filter)) return query +def _safe_text(target): + return Grouping(text(target)) def create_custom_sql_functions(connection): """Register custom functions on the database connection.""" diff --git a/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml new file mode 100644 index 000000000..2497d87f6 --- /dev/null +++ b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml new file mode 100644 index 000000000..3afb0eb08 --- /dev/null +++ b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml @@ -0,0 +1,37 @@ + + + + + + + urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 + http://purl.org/dc/dcmitype/Dataset + Physiography-Landforms + FI-ES + Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. + + + urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 + http://purl.org/dc/dcmitype/Dataset + Mauris sed neque + Vegetation-Cropland + Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. + 2006-03-26 + + 47.595 -4.097 + 51.217 0.889 + + + + urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc + http://purl.org/dc/dcmitype/Dataset + Ñunç elementum + Hydrography-Oceanographic + 2005-10-24 + + 44.792 -6.171 + 51.126 -2.228 + + + + diff --git a/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml b/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml new file mode 100644 index 000000000..6270c5e75 --- /dev/null +++ b/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml @@ -0,0 +1,24 @@ + + + + full + + + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + + + + diff --git a/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml b/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml new file mode 100644 index 000000000..5674af1de --- /dev/null +++ b/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml @@ -0,0 +1,24 @@ + + + + full + + + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + dc:type + http://purl.org/dc/dcmitype/Dataset + + + + + +