Skip to content

Commit 67b1064

Browse files
authored
Merge pull request ome#6420 from sbesson/login_json_tests
OMERO.web:test login requests with JSON
2 parents eed3452 + 695282b commit 67b1064

File tree

1 file changed

+85
-35
lines changed

1 file changed

+85
-35
lines changed

components/tools/OmeroWeb/test/integration/test_api_login.py

Lines changed: 85 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,24 @@
2222
"""
2323

2424
import pytest
25-
from omeroweb.testlib import IWebTest, get_json, _response, post
25+
from omeroweb.testlib import IWebTest, get_json
2626
from django.urls import reverse, NoReverseMatch
2727
from omeroweb.api import api_settings
2828
from django.test import Client
29+
from django.test.client import MULTIPART_CONTENT
2930
from omero_marshal import OME_SCHEMA_URL
30-
import json
3131

3232

3333
class TestLogin(IWebTest):
3434
"""
3535
Tests login workflow: getting url, csfv tokens etc.
3636
"""
3737

38+
def get_login_url(self):
39+
# test the most recent version
40+
version = api_settings.API_VERSIONS[-1]
41+
return reverse('api_login', kwargs={'api_version': version})
42+
3843
def test_versions(self):
3944
"""
4045
Start at the base url, get versions
@@ -52,7 +57,6 @@ def test_base_url(self):
5257
Tests that the base url for a given version provides other urls
5358
"""
5459
django_client = self.django_root_client
55-
# test the most recent version
5660
version = api_settings.API_VERSIONS[-1]
5761
request_url = reverse('api_base', kwargs={'api_version': version})
5862
rsp = get_json(django_client, request_url)
@@ -79,29 +83,61 @@ def test_login_get(self):
7983
Tests that we get a suitable message if we try to GET login_url
8084
"""
8185
django_client = self.django_root_client
82-
version = api_settings.API_VERSIONS[-1]
83-
request_url = reverse('api_login', kwargs={'api_version': version})
84-
rsp = get_json(django_client, request_url, status_code=405)
86+
rsp = get_json(django_client, self.get_login_url(), status_code=405)
8587
assert (rsp['message'] ==
8688
"POST only with username, password, server and csrftoken")
8789

88-
def test_login_csrf(self):
90+
def test_login_csrf_cookie_not_set(self):
91+
"""
92+
Test POST with missing CSRF cookie
93+
8994
"""
90-
Tests that we can only login with CSRF
95+
django_client = Client(enforce_csrf_checks=True)
96+
rsp = django_client.post(self.get_login_url())
97+
assert rsp.status_code == 403
98+
assert rsp.json()['message'] == (
99+
"CSRF Failed: CSRF cookie not set.")
100+
101+
def test_login_missing_csrf_token(self):
91102
"""
92-
django_client = self.django_root_client
93-
# test the most recent version
94-
version = api_settings.API_VERSIONS[-1]
95-
request_url = reverse('api_login', kwargs={'api_version': version})
96-
# POST without adding CSRF token
97-
rsp = _response(django_client, request_url, method='post',
98-
status_code=403)
99-
rsp = json.loads(rsp.content)
100-
assert (rsp['message'] ==
101-
("CSRF Error. You need to include valid CSRF tokens for any"
102-
" POST, PUT, PATCH or DELETE operations."
103-
" You have to include CSRF token in the POST data or"
104-
" add the token to the HTTP header."))
103+
Test POST with missing CSRF token
104+
105+
"""
106+
django_client = Client(enforce_csrf_checks=True)
107+
django_client.get(reverse("weblogin"))
108+
rsp = django_client.post(self.get_login_url())
109+
assert rsp.status_code == 403
110+
assert rsp.json()['message'] == (
111+
"CSRF Failed: CSRF token missing.")
112+
113+
def test_login_empty_csrf_token(self):
114+
"""
115+
Test POST with empty CSRF token
116+
"""
117+
django_client = Client(enforce_csrf_checks=True)
118+
django_client.get(reverse("weblogin"))
119+
data = {'username': 'root', 'password': 'omero', 'server': 1}
120+
rsp = django_client.post(
121+
self.get_login_url(), data, headers={"X-CSRFToken": ""})
122+
assert rsp.status_code == 403
123+
assert rsp.json()['message'] == (
124+
"CSRF Failed: "
125+
"CSRF token from the 'X-Csrftoken' HTTP header has incorrect "
126+
"length.")
127+
128+
def test_login_invalid_csrf_token(self):
129+
"""
130+
Test POST with invalid CSRF token
131+
"""
132+
django_client = Client(enforce_csrf_checks=True)
133+
django_client.get(reverse("weblogin"))
134+
data = {'username': 'root', 'password': 'omero', 'server': 1}
135+
rsp = django_client.post(
136+
self.get_login_url(), data, headers={"X-CSRFToken": "0" * 64})
137+
assert rsp.status_code == 403
138+
assert rsp.json()['message'] == (
139+
"CSRF Failed: "
140+
"CSRF token from the 'X-Csrftoken' HTTP header incorrect.")
105141

106142
@pytest.mark.parametrize("credentials", [
107143
[{'username': 'guest', 'password': 'fake', 'server': 1},
@@ -114,24 +150,35 @@ def test_login_csrf(self):
114150
"Server: This field is required.")],
115151
[{'username': 'nobody', 'password': 'fake', 'server': 1},
116152
("Connection not available, "
117-
"please check your user name and password.")]
153+
"please check your user name and password.")],
154+
[{'user': 1},
155+
("Username: This field is required. "
156+
"Password: This field is required. "
157+
"Server: This field is required.")]
118158
])
119-
def test_login_errors(self, credentials):
159+
@pytest.mark.parametrize("content_type", (
160+
MULTIPART_CONTENT, "application/json"))
161+
def test_login_errors(self, credentials, content_type):
120162
"""
121163
Tests that we get expected form validation errors if try to login
122164
without required fields, as 'guest' or with invalid username/password.
123165
"""
124-
django_client = self.django_root_client
125-
# test the most recent version
126-
version = api_settings.API_VERSIONS[-1]
127-
request_url = reverse('api_login', kwargs={'api_version': version})
166+
client = Client(enforce_csrf_checks=True)
167+
client.get(reverse("weblogin"))
168+
csrf_token = client.cookies["csrftoken"].value
128169
data = credentials[0]
129170
message = credentials[1]
130-
rsp = post(django_client, request_url, data, status_code=403)
131-
rsp = json.loads(rsp.content)
132-
assert rsp['message'] == message
171+
rsp = client.post(
172+
self.get_login_url(),
173+
data,
174+
headers={"X-CSRFToken": csrf_token},
175+
content_type=content_type)
176+
assert rsp.status_code == 403
177+
assert rsp.json()['message'] == message
133178

134-
def test_login_example(self):
179+
@pytest.mark.parametrize("content_type", (
180+
MULTIPART_CONTENT, "application/json"))
181+
def test_login_example(self, content_type):
135182
"""
136183
Example of successful login as user would do for real,
137184
starting at base url and getting all other urls and info from there.
@@ -179,10 +226,13 @@ def test_login_example(self):
179226
'server': server_id,
180227
# 'csrfmiddlewaretoken': token,
181228
}
182-
login_rsp = django_client.post(login_url, data)
183-
login_json = json.loads(login_rsp.content)
184-
assert login_json['success']
185-
event_context = login_json['eventContext']
229+
login_rsp = django_client.post(
230+
login_url,
231+
data,
232+
content_type=content_type)
233+
assert login_rsp.status_code == 200
234+
assert login_rsp.json()['success']
235+
event_context = login_rsp.json()['eventContext']
186236
# eventContext gives a bunch of info
187237
member_of_groups = event_context['memberOfGroups']
188238
current_group = event_context['groupId']

0 commit comments

Comments
 (0)