Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions pycsw/core/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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')
Expand All @@ -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
Expand Down Expand Up @@ -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."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- PYCSW_VERSION -->
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
<csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
<csw:SearchResults numberOfRecordsMatched="0" numberOfRecordsReturned="0" nextRecord="0" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"/>
</csw:GetRecordsResponse>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- PYCSW_VERSION -->
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
<csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
<csw:SearchResults numberOfRecordsMatched="3" numberOfRecordsReturned="3" nextRecord="0" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
<csw:Record>
<dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
<dc:subject scheme="http://www.digest.org/2.1">Physiography-Landforms</dc:subject>
<dct:spatial>FI-ES</dct:spatial>
<dct:abstract>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</dct:abstract>
</csw:Record>
<csw:Record>
<dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
<dc:title>Mauris sed neque</dc:title>
<dc:subject scheme="http://www.digest.org/2.1">Vegetation-Cropland</dc:subject>
<dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
<dc:date>2006-03-26</dc:date>
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
<ows:LowerCorner>47.595 -4.097</ows:LowerCorner>
<ows:UpperCorner>51.217 0.889</ows:UpperCorner>
</ows:BoundingBox>
</csw:Record>
<csw:Record>
<dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
<dc:title>Ñunç elementum</dc:title>
<dc:subject scheme="http://www.digest.org/2.1">Hydrography-Oceanographic</dc:subject>
<dc:date>2005-10-24</dc:date>
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
<ows:LowerCorner>44.792 -6.171</ows:LowerCorner>
<ows:UpperCorner>51.126 -2.228</ows:UpperCorner>
</ows:BoundingBox>
</csw:Record>
</csw:SearchResults>
</csw:GetRecordsResponse>
24 changes: 24 additions & 0 deletions tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<csw:GetRecords xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" service="CSW" version="2.0.2" resultType="results" startPosition="1" maxRecords="5" outputFormat="application/xml" outputSchema="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
<csw:Query typeNames="csw:Record">
<csw:ElementSetName>full</csw:ElementSetName>
<csw:Constraint version="1.1.0">
<Filter xmlns="http://www.opengis.net/ogc">
<Or>
<ogc:PropertyIsNotEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsNotEqualTo>
<ogc:PropertyIsNotEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsNotEqualTo>
<ogc:PropertyIsNotEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsNotEqualTo>
</Or>
</Filter>
</csw:Constraint>
</csw:Query>
</csw:GetRecords>
24 changes: 24 additions & 0 deletions tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<csw:GetRecords xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" service="CSW" version="2.0.2" resultType="results" startPosition="1" maxRecords="5" outputFormat="application/xml" outputSchema="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
<csw:Query typeNames="csw:Record">
<csw:ElementSetName>full</csw:ElementSetName>
<csw:Constraint version="1.1.0">
<Filter xmlns="http://www.opengis.net/ogc">
<Or>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsEqualTo>
<ogc:PropertyIsNotEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsNotEqualTo>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>dc:type</ogc:PropertyName>
<ogc:Literal>http://purl.org/dc/dcmitype/Dataset</ogc:Literal>
</ogc:PropertyIsEqualTo>
</Or>
</Filter>
</csw:Constraint>
</csw:Query>
</csw:GetRecords>