mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Rewrite auth tests in a more clean way, now using webtest to run the API
This commit is contained in:
parent
9fda7f4716
commit
53ab4709d1
4 changed files with 41 additions and 60 deletions
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
|
||||||
|
|
1
tox.ini
1
tox.ini
|
@ -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}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue