Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OMERO.web: improve the CSRF tests coverage #6419

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
76 changes: 56 additions & 20 deletions components/tools/OmeroWeb/test/integration/test_api_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"""

import pytest
from omeroweb.testlib import IWebTest, get_json, _response, post
from omeroweb.testlib import IWebTest, get_json, post
from django.urls import reverse, NoReverseMatch
from omeroweb.api import api_settings
from django.test import Client
Expand All @@ -35,6 +35,11 @@ class TestLogin(IWebTest):
Tests login workflow: getting url, csfv tokens etc.
"""

def get_login_url(self):
# test the most recent version
version = api_settings.API_VERSIONS[-1]
return reverse('api_login', kwargs={'api_version': version})

def test_versions(self):
"""
Start at the base url, get versions
Expand All @@ -52,7 +57,6 @@ def test_base_url(self):
Tests that the base url for a given version provides other urls
"""
django_client = self.django_root_client
# test the most recent version
version = api_settings.API_VERSIONS[-1]
request_url = reverse('api_base', kwargs={'api_version': version})
rsp = get_json(django_client, request_url)
Expand All @@ -79,29 +83,61 @@ def test_login_get(self):
Tests that we get a suitable message if we try to GET login_url
"""
django_client = self.django_root_client
version = api_settings.API_VERSIONS[-1]
request_url = reverse('api_login', kwargs={'api_version': version})
rsp = get_json(django_client, request_url, status_code=405)
rsp = get_json(django_client, self.get_login_url(), status_code=405)
assert (rsp['message'] ==
"POST only with username, password, server and csrftoken")

def test_login_csrf(self):
def test_login_csrf_cookie_not_set(self):
"""
Tests that we can only login with CSRF
Test POST with missing CSRF cookie

"""
django_client = self.django_root_client
# test the most recent version
version = api_settings.API_VERSIONS[-1]
request_url = reverse('api_login', kwargs={'api_version': version})
# POST without adding CSRF token
rsp = _response(django_client, request_url, method='post',
status_code=403)
rsp = json.loads(rsp.content)
assert (rsp['message'] ==
("CSRF Error. You need to include valid CSRF tokens for any"
" POST, PUT, PATCH or DELETE operations."
" You have to include CSRF token in the POST data or"
" add the token to the HTTP header."))
django_client = Client(enforce_csrf_checks=True)
rsp = django_client.post(self.get_login_url())
assert rsp.status_code == 403
assert rsp.json()['message'] == (
"CSRF Failed: CSRF cookie not set.")

def test_login_missing_csrf_token(self):
"""
Test POST with missing CSRF token

"""
django_client = Client(enforce_csrf_checks=True)
django_client.get(reverse("weblogin"))
rsp = django_client.post(self.get_login_url())
assert rsp.status_code == 403
assert rsp.json()['message'] == (
"CSRF Failed: CSRF token missing.")

def test_login_empty_csrf_token(self):
"""
Test POST with empty CSRF token
"""
django_client = Client(enforce_csrf_checks=True)
django_client.get(reverse("weblogin"))
data = {'username': 'root', 'password': 'omero', 'server': 1}
rsp = django_client.post(
self.get_login_url(), data, headers={"X-CSRFToken": ""})
assert rsp.status_code == 403
assert rsp.json()['message'] == (
"CSRF Failed: "
"CSRF token from the 'X-Csrftoken' HTTP header has incorrect "
"length.")

def test_login_invalid_csrf_token(self):
"""
Test POST with invalid CSRF token
"""
django_client = Client(enforce_csrf_checks=True)
django_client.get(reverse("weblogin"))
data = {'username': 'root', 'password': 'omero', 'server': 1}
rsp = django_client.post(
self.get_login_url(), data, headers={"X-CSRFToken": "0" * 64})
assert rsp.status_code == 403
assert rsp.json()['message'] == (
"CSRF Failed: "
"CSRF token from the 'X-Csrftoken' HTTP header incorrect.")

@pytest.mark.parametrize("credentials", [
[{'username': 'guest', 'password': 'fake', 'server': 1},
Expand Down