Commit f651d0e9 authored by Élodie Thiéblin's avatar Élodie Thiéblin
Browse files

fix(urlpublisher): raise a 404 when a URL rewrite with rql has no rset

fix #199
parent 580b4af3476e
......@@ -340,6 +340,8 @@ class CubicWebPublisher(object):
try:
# standard processing of the request
try:
# The process function update the req according rewrites rules.
# It stores in req._rql_rewritten if the rql comes from the endUser.
ctrlid, rset = self.url_resolver.process(req, path)
try:
controller = self.vreg['controllers'].select(ctrlid, req,
......@@ -347,6 +349,8 @@ class CubicWebPublisher(object):
except NoSelectableObject:
raise Unauthorized(req._('not authorized'))
req.update_search_state()
# In case of rewritten rql, controller.publish directly raises
# notFound if the rset is empty.
result = controller.publish(rset=rset)
except Redirect as ex:
# Redirect may be raised by edit controller when everything went
......
......@@ -758,6 +758,20 @@ class ApplicationTC(CubicWebTC):
req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
self.app_handle_request(req)
def test_notfound_raised_on_empty_underlying_rset(self):
"""tests URLs that are rewritten with an underlying rqlquery.
If the rql query is empty, a NotFound error should be raised."""
with self.new_access('anon').web_request('schema/CWUser') as req:
self.app_handle_request(req)
self.assertEqual(req.status_out, 200)
# There is an underlying rql to fetch the schema of cwetype.
# As there is no entity «pouet», it should raise NotFound.
with self.new_access('anon').web_request('schema/pouet') as req:
self.app_handle_request(req)
self.assertEqual(req.status_out, 404)
if __name__ == '__main__':
unittest_main()
......@@ -27,7 +27,7 @@ from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
from cubicweb.utils import json_dumps
from cubicweb.predicates import (authenticated_user, anonymous_user,
match_form_params)
from cubicweb.web import Redirect
from cubicweb.web import Redirect, NotFound
from cubicweb.web.controller import Controller
from cubicweb.web.views import vid_from_rset
from cubicweb._exceptions import NotAnEntity
......@@ -84,8 +84,13 @@ class ViewController(Controller):
template = 'main-template'
def publish(self, rset=None):
"""publish a request, returning an encoded string"""
"""publish a request, returning an encoded string.
:raise NotFound: if the rql has been rewritten (rewrite rules) and the
resulting rset is empty"""
view, rset = self._select_view_and_rset(rset)
if not rset and getattr(self._cw, '_rql_rewritten', False):
raise NotFound
view.set_http_cache_headers()
if self._cw.is_client_cache_valid():
return b''
......
......@@ -130,7 +130,8 @@ class URLPublisherComponent(component.Component):
lang = req.negotiated_language()
if lang:
req.set_language(lang)
if req.form.get('rql'):
origin_rql = req.form.get('rql')
if origin_rql:
if parts[0] in self.vreg['controllers']:
return parts[0], None
return 'view', None
......@@ -142,6 +143,13 @@ class URLPublisherComponent(component.Component):
continue
else:
raise NotFound(path)
# Store if the final rql (changed by evaluator.evaluate_path) comes from
# the end user (?rql=Any X Where is CWUser) or comes from a rewrite rule
# such as SimpleReqRewriter.
new_rql = req.form.get("rql")
req._rql_rewritten = origin_rql != new_rql
if pmid is None:
pmid = self.default_method
return pmid, rset
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment