Skip to content

Commit

Permalink
[#7028] Disable CSRF protection when authenticating via header
Browse files Browse the repository at this point in the history
  • Loading branch information
amercader committed Sep 22, 2022
1 parent 5591055 commit 7d6f191
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ckan/config/middleware/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,10 @@ def load_user_from_request(request): # type: ignore
This callback function is called whenever a user could not be
authenticated via the session cookie, so we fall back to the API token.
"""
g.login_via_request = True

user = _get_user_for_apitoken()

return user

# Update the main CKAN config object with the Flask specific keys
Expand Down Expand Up @@ -410,6 +413,11 @@ def ckan_before_request() -> Optional[Response]:
# Sets g.user and g.userobj for extensions
response = identify_user()

# Disable CSRF protection if user was logged in via the Authorization
# header from the request
if g.get("login_via_request"):
csrf.exempt(f"ckan.views.{request.endpoint}")

# Set the csrf_field_name so we can use it in our templates
g.csrf_field_name = config.get_value("WTF_CSRF_FIELD_NAME")

Expand Down
35 changes: 35 additions & 0 deletions ckan/tests/controllers/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,38 @@ def test_cookie_based_auth_disabled(app):
res = app.get(url, environ_overrides=env)

assert res.status_code == 200


@pytest.mark.usefixtures("clean_db")
def test_header_based_auth_default(app):

sysadmin = factories.SysadminWithToken()
org = factories.Organization()
dataset = factories.Dataset(private=True, owner_org=org["id"])

url = url_for("api.action", ver=3, logic_function="package_show", id=dataset["id"])

env = {"Authorization": sysadmin["token"]}

res = app.get(url, environ_overrides=env)

assert res.status_code == 200

@pytest.mark.usefixtures("clean_db")
def test_header_based_auth_default_post(app):

sysadmin = factories.SysadminWithToken()
org = factories.Organization()
dataset = factories.Dataset(private=True, owner_org=org["id"])

url = url_for("api.action", ver=3, logic_function="package_patch")

env = {"Authorization": sysadmin["token"]}

data = {
"id": dataset["id"],
"notes": "updated",
}
res = app.post(url, environ_overrides=env, data=data)

assert res.status_code == 200

0 comments on commit 7d6f191

Please sign in to comment.