Rewrite auth tests in a more clean way, now using webtest to run the API

This commit is contained in:
Alexandre Aubin 2019-11-19 21:06:55 +01:00
parent 9fda7f4716
commit 53ab4709d1
4 changed files with 41 additions and 60 deletions

View file

@ -17,7 +17,7 @@ class Authenticator(BaseAuthenticator):
vendor = 'dummy' vendor = 'dummy'
def __init__(self, name, vendor, parameters, extra): def __init__(self, name, vendor, parameters, extra):
logger.debug("initialize authenticator '%s") logger.debug("initialize authenticator dummy")
super(Authenticator, self).__init__(name) super(Authenticator, self).__init__(name)
def authenticate(self, password): def authenticate(self, password):

View file

@ -1,7 +1,5 @@
"""Pytest fixtures for testing.""" """Pytest fixtures for testing."""
from multiprocessing import Process
import time
import json import json
import os import os
import shutil import shutil
@ -121,19 +119,25 @@ def moulinette(tmp_path_factory):
return moulinette return moulinette
@pytest.fixture(scope='session') @pytest.fixture
def moulinette_webapi(moulinette): def moulinette_webapi(moulinette):
namespace = "moulitest" from webtest import TestApp
from webtest.app import CookiePolicy
api_thread = Process(target=moulinette.api, # Dirty hack needed, otherwise cookies ain't reused between request .. not
args=([namespace],), # sure why :|
kwargs={"host": "localhost", "port": 12342, "use_websocket": False}) def return_true(self, cookie, request):
api_thread.start() return True
time.sleep(0.5) CookiePolicy.return_ok_secure = return_true
assert api_thread.is_alive()
yield "http://localhost:12342" moulinette_webapi = moulinette.core.init_interface(
api_thread.terminate() 'api',
kwargs={'routes': {}, 'use_websocket': False},
actionsmap={'namespaces': ["moulitest"], 'use_cache': True}
)
return TestApp(moulinette_webapi._app)
@pytest.fixture @pytest.fixture

View file

@ -1,46 +1,36 @@
import os import os
import requests
def login(webapi, cookies=None, csrf=False, profile=None): def login(webapi, csrf=False, profile=None, status=200):
data = {"password": "Yoloswag"} data = {"password": "Yoloswag"}
if profile: if profile:
data["profile"] = profile data["profile"] = profile
return requests.post(webapi + "/login", return webapi.post("/login", data,
cookies=cookies, status=status,
data=data,
headers=None if csrf else {"X-Requested-With": ""}) headers=None if csrf else {"X-Requested-With": ""})
def test_request_no_auth_needed(moulinette_webapi): def test_request_no_auth_needed(moulinette_webapi):
r = requests.get(moulinette_webapi + "/test-auth/none") assert moulinette_webapi.get("/test-auth/none", status=200).text == '"some_data_from_none"'
assert r.status_code == 200
assert r.text == '"some_data_from_none"'
def test_request_with_auth_but_not_logged(moulinette_webapi): def test_request_with_auth_but_not_logged(moulinette_webapi):
r = requests.get(moulinette_webapi + "/test-auth/default") assert moulinette_webapi.get("/test-auth/default", status=401).text == "Authentication required"
assert r.status_code == 401
assert r.text == "Authentication required"
def test_login(moulinette_webapi): def test_login(moulinette_webapi):
r = login(moulinette_webapi) assert login(moulinette_webapi).text == "Logged in"
assert r.status_code == 200 assert "session.id" in moulinette_webapi.cookies
assert r.text == "Logged in" assert "session.tokens" in moulinette_webapi.cookies
assert "session.id" in r.cookies
assert "session.tokens" in r.cookies
cache_session_default = os.environ['MOULINETTE_CACHE_DIR'] + "/session/default/" cache_session_default = os.environ['MOULINETTE_CACHE_DIR'] + "/session/default/"
assert r.cookies["session.id"] + ".asc" in os.listdir(cache_session_default) assert moulinette_webapi.cookies["session.id"] + ".asc" in os.listdir(cache_session_default)
def test_login_csrf_attempt(moulinette_webapi): def test_login_csrf_attempt(moulinette_webapi):
@ -49,51 +39,37 @@ def test_login_csrf_attempt(moulinette_webapi):
# https://security.stackexchange.com/a/58308 # https://security.stackexchange.com/a/58308
# https://stackoverflow.com/a/22533680 # https://stackoverflow.com/a/22533680
r = login(moulinette_webapi, csrf=True) assert "CSRF protection" in login(moulinette_webapi, csrf=True, status=403).text
assert not any(c.name == "session.id" for c in moulinette_webapi.cookiejar)
assert r.status_code == 403 assert not any(c.name == "session.tokens" for c in moulinette_webapi.cookiejar)
assert "session.id" not in r.cookies
assert "session.tokens" not in r.cookies
assert "CSRF protection" in r.text
def test_login_then_legit_request_without_cookies(moulinette_webapi): def test_login_then_legit_request_without_cookies(moulinette_webapi):
login(moulinette_webapi) login(moulinette_webapi)
r = requests.get(moulinette_webapi + "/test-auth/default") moulinette_webapi.cookiejar.clear()
assert r.status_code == 401 moulinette_webapi.get("/test-auth/default", status=401)
assert r.text == "Authentication required"
def test_login_then_legit_request(moulinette_webapi): def test_login_then_legit_request(moulinette_webapi):
r_login = login(moulinette_webapi) login(moulinette_webapi)
r = requests.get(moulinette_webapi + "/test-auth/default", #for cookie in moulinette_webapi.cookiejar:
cookies={"session.id": r_login.cookies["session.id"], # cookie.domain = "localhost"
"session.tokens": r_login.cookies["session.tokens"], })
assert r.status_code == 200 assert moulinette_webapi.get("/test-auth/default", status=200).text == '"some_data_from_default"'
assert r.text == '"some_data_from_default"'
def test_login_then_logout(moulinette_webapi): def test_login_then_logout(moulinette_webapi):
r_login = login(moulinette_webapi) login(moulinette_webapi)
r = requests.get(moulinette_webapi + "/logout", moulinette_webapi.get("/logout", status=200)
cookies={"session.id": r_login.cookies["session.id"],
"session.tokens": r_login.cookies["session.tokens"], })
assert r.status_code == 200
cache_session_default = os.environ['MOULINETTE_CACHE_DIR'] + "/session/default/" cache_session_default = os.environ['MOULINETTE_CACHE_DIR'] + "/session/default/"
assert not r_login.cookies["session.id"] + ".asc" in os.listdir(cache_session_default) assert not moulinette_webapi.cookies["session.id"] + ".asc" in os.listdir(cache_session_default)
r = requests.get(moulinette_webapi + "/test-auth/default", assert moulinette_webapi.get("/test-auth/default", status=401).text == "Authentication required"
cookies={"session.id": r_login.cookies["session.id"],
"session.tokens": r_login.cookies["session.tokens"], })
assert r.status_code == 401
assert r.text == "Authentication required"

View file

@ -18,6 +18,7 @@ deps =
toml >= 0.10, < 0.11 toml >= 0.10, < 0.11
gevent-websocket gevent-websocket
bottle >= 0.12 bottle >= 0.12
WebTest >= 2.0, < 2.1
commands = commands =
pytest {posargs} pytest {posargs}