Skip to content

Commit

Permalink
adjust and test WPS POST body parsing (fix #157)
Browse files Browse the repository at this point in the history
  • Loading branch information
fmigneault committed Oct 23, 2020
1 parent 39352c0 commit aeaad22
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Bug Fixes
the targeted ``Resource`` is actually missing, the *closest* parent permissions with ``Scope.RECURSIVE`` will still
take effect. Same fix applied for ``ServiceTHREDDS`` for corresponding directory and file typed ``Resource``.
* Propagate SSL verify option of generated service definition if provided to `Twitcher` obtained from ``MagpieAdapter``.
* Adjust and validate parsing of ``ServiceWPS`` request using ``POST`` XML body
(fixes `157 <https://github.com/Ouranosinc/Magpie/issues/157>`_).

`3.0.0 <https://github.com/Ouranosinc/Magpie/tree/3.0.0>`_ (2020-10-19)
------------------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions magpie/owsrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def _get_param_value(self, param):
return self.document.attrib[param].lower()
if param == "request":
return self.document.tag.lower()
for section in self.document:
if param == section.tag.lower():
return section.text.strip()
return None


Expand Down
6 changes: 3 additions & 3 deletions magpie/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ class ServiceWPS(ServiceOWS):
params_expected = [
"service",
"request",
"version"
# "identifier" not used because not required when requesting capabilities
"version",
"identifier",
]

resource_types_permissions = {
Expand All @@ -418,7 +418,7 @@ def resource_requested(self):
return self.service, True
if wps_request in [Permission.DESCRIBE_PROCESS, Permission.EXECUTE]:
wps_id = self.service.resource_id
proc_id = self.request.params.get("identifier")
proc_id = self.parser.params["identifier"]
if not proc_id:
return self.service, False
proc = models.find_children_by_name(proc_id, parent_id=wps_id, db_session=self.request.db)
Expand Down
53 changes: 48 additions & 5 deletions tests/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@ def test_ServiceWPS_effective_permissions(self):
wps2_name = "unittest-service-wps-2"
svc_type = ServiceWPS.service_type
proc_type = models.Process.resource_type_name
for svc_name in [wps1_name, wps2_name]:
utils.TestSetup.delete_TestService(self, override_service_name=svc_name)
body = utils.TestSetup.create_TestService(self, override_service_name=wps1_name, override_service_type=svc_type)
info = utils.TestSetup.get_ResourceInfo(self, override_body=body)
wps1_id = info["resource_id"]
Expand Down Expand Up @@ -727,7 +729,7 @@ def test_ServiceWPS_effective_permissions(self):
# of corresponding enums to validate the request query parameters are parsed correctly with combinations that
# are actually handled by the real WPS service.

# Service1 calls
# Service1 GET requests
path = "/ows/proxy/{}".format(wps1_name)
params = {"service": "WPS", "request": "GetCapabilities"}
req = self.mock_request(path, method="GET", params=params)
Expand All @@ -739,7 +741,7 @@ def test_ServiceWPS_effective_permissions(self):
req = self.mock_request(path, method="GET", params=params)
utils.check_raises(lambda: self.ows.check_request(req), OWSAccessForbidden)

# Process1 calls
# Process1 GET requests
path = "/ows/proxy/{}".format(wps1_name)
params = {"service": "WPS", "request": "GetCapabilities", "identifier": proc1_name} # see docstring notes
req = self.mock_request(path, method="GET", params=params)
Expand All @@ -751,7 +753,7 @@ def test_ServiceWPS_effective_permissions(self):
req = self.mock_request(path, method="GET", params=params)
utils.check_no_raise(lambda: self.ows.check_request(req))

# Service2 calls
# Service2 GET requests
path = "/ows/proxy/{}".format(wps2_name)
params = {"service": "WPS", "request": "GetCapabilities"}
req = self.mock_request(path, method="GET", params=params)
Expand All @@ -763,7 +765,7 @@ def test_ServiceWPS_effective_permissions(self):
req = self.mock_request(path, method="GET", params=params)
utils.check_raises(lambda: self.ows.check_request(req), OWSAccessForbidden)

# Process2 calls
# Process2 GET requests
path = "/ows/proxy/{}".format(wps2_name)
params = {"service": "WPS", "request": "GETCAPABILITIES", "identifier": proc2_name} # see docstring notes
req = self.mock_request(path, method="GET", params=params)
Expand All @@ -775,7 +777,7 @@ def test_ServiceWPS_effective_permissions(self):
req = self.mock_request(path, method="GET", params=params)
utils.check_no_raise(lambda: self.ows.check_request(req))

# Process3 calls
# Process3 GET requests
path = "/ows/proxy/{}".format(wps2_name)
params = {"service": "WPS", "request": "GETCAPABILITIES", "identifier": proc3_name} # see docstring notes
req = self.mock_request(path, method="GET", params=params)
Expand All @@ -787,6 +789,47 @@ def test_ServiceWPS_effective_permissions(self):
req = self.mock_request(path, method="GET", params=params)
utils.check_raises(lambda: self.ows.check_request(req), OWSAccessForbidden)

# evaluate parsing of POST-formatted Execute requests
# (source: https://docs.geoserver.org/stable/en/user/services/wps/operations.html)
wps_xml_post_body_template = inspect.cleandoc("""
<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute version="1.0.0" service="WPS"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0"
xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0"
xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml"
xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0
http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"
>
<ows:Identifier>{process}</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>geom</ows:Identifier>
<wps:Data>
<wps:ComplexData mimeType="application/wkt"><![CDATA[POINT(0 0)]]></wps:ComplexData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="application/gml-3.1.1">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
""")

# Process2 POST Execute
path = "/ows/proxy/{}".format(wps2_name)
body = wps_xml_post_body_template.format(process=proc2_name).encode()
req = self.mock_request(path, method="POST", body=body, params=None)
utils.check_no_raise(lambda: self.ows.check_request(req))

# Process3 POST Execute
path = "/ows/proxy/{}".format(wps2_name)
body = wps_xml_post_body_template.format(process=proc3_name).encode()
req = self.mock_request(path, method="POST", body=body, params=None)
utils.check_raises(lambda: self.ows.check_request(req), OWSAccessForbidden)

@utils.mock_get_settings
def test_ServiceAccess_effective_permissions(self):
"""
Expand Down

0 comments on commit aeaad22

Please sign in to comment.