Commit fe469a24 authored by Simon Chabot's avatar Simon Chabot
Browse files

feat: requires the NO-CSRF-CHECK header to bypass CSRF check

BREAKING CHANGE: the NO-CSRF-CHECK is not required
parent 21601a37af3e
Pipeline #77692 failed with stages
in 1 minute and 35 seconds
......@@ -16,7 +16,7 @@ web = "http://www.cubicweb.org/project/%s" % distname
__depends__ = {
"cubicweb": ">= 3.32.2",
}
__recommends__ = {}
__recommends__ = {"cubicweb-signedrequest": None}
classifiers = [
"Environment :: Web Environment",
......
......@@ -24,8 +24,6 @@ from cubicweb.predicates import (
ExpectedValuePredicate,
match_form_params,
match_http_method,
anonymous_user,
authenticated_user,
)
from cubicweb.uilib import exc_message
from cubicweb.utils import json_dumps
......@@ -35,9 +33,6 @@ from cubicweb.web.views.urlrewrite import rgx_action, SchemaBasedRewriter
from cubicweb import Binary
from cubicweb_rqlcontroller.rql_schema_holder import RqlIOSchemaHolder
from cubicweb_rqlcontroller.predicates import match_all_http_headers
ARGRE = re.compile(r"__r(?P<ref>\d+)$")
DATARE = re.compile(r"__f(?P<ref>.+)$")
......@@ -114,9 +109,12 @@ class BaseRqlIOController(Controller):
"""
__abstract__ = True
__regid__ = "rqlio"
__select__ = match_http_method("POST") & match_form_params("version")
__select__ = (
match_http_method("POST")
& match_form_params("version")
)
require_csrf = False
def json(self):
contenttype = self._cw.get_header("Content-Type", raw=False)
......@@ -147,6 +145,14 @@ class BaseRqlIOController(Controller):
self._cw.ajax_request = True
self._cw.set_content_type("application/json")
has_no_csrf_check_header = self._cw.get_header("NO-CSRF-CHECK", False)
if not has_no_csrf_check_header:
raise RemoteCallFailed(
"Since RQLController 0.9.0 requires a NO-CSRF-CHECK header "
"to prove that you are not using a form. Please upgrade "
"to cwclientlib >= 1.2.0 or cwclientlibjs >= 0.2.6."
)
version = self._cw.form["version"]
if version not in ("1.0", "2.0"):
raise RemoteCallFailed("unknown rqlio version %r", version)
......@@ -184,49 +190,6 @@ class BaseRqlIOController(Controller):
return output
class JsonRqlIOController(BaseRqlIOController):
"""RqlIOController with csrf desactivated for application/json because
application/json can't be sent through a form
"""
__select__ = BaseRqlIOController.__select__ & match_request_content_type(
"application/json", mode="any"
)
require_csrf = False
class MultipartRqlIOController(BaseRqlIOController):
"""RqlIOController with csrf activated for cookie authenticated user
and multipart/form-data.
To have csrf deactivated with multipart/form-data, install
cubicweb-signedrequest and use an authentication method.
"""
__select__ = (
BaseRqlIOController.__select__
& ~match_all_http_headers("Authorization") # no Authorization == cookie
& match_request_content_type("multipart/form-data", mode="any")
& authenticated_user()
)
class AnonMultipartRqlIOController(BaseRqlIOController):
"""RqlIOController with csrf desactivated for anonymous_user.
This allows public usage of the route.
It is expected anonymous user should have only read auhorization.
"""
__select__ = (
BaseRqlIOController.__select__
& ~match_all_http_headers("Authorization")
& match_request_content_type("multipart/form-data", mode="any")
& anonymous_user()
)
require_csrf = False
class RQLIORewriter(SchemaBasedRewriter):
rules = [
(re.compile("/rqlio/schema"), rgx_action(controller="rqlio_schema")),
......
Supports Markdown
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