kanidm/pykanidm/tests/test_authenticate.py

192 lines
6.5 KiB
Python
Raw Normal View History

""" testing auth things """
import logging
import os
import pytest
from pytest_mock import MockerFixture
# pylint: disable=unused-import
from testutils import client, client_configfile, MockResponse
from kanidm import KanidmClient
from kanidm.exceptions import AuthCredFailed, AuthInitFailed
from kanidm.types import AuthBeginResponse
2022-09-29 02:08:15 +02:00
from kanidm.tokens import TokenStore
logging.basicConfig(level=logging.DEBUG)
@pytest.mark.network
@pytest.mark.asyncio
async def test_auth_init(client_configfile: KanidmClient) -> None:
"""tests the auth init step"""
print("Starting client...")
print(f"Doing auth_init for {client_configfile.config.username}")
if client_configfile.config.username is None:
2022-09-29 02:08:15 +02:00
pytest.skip("Can't run auth test without a username/password")
result = await client_configfile.auth_init(client_configfile.config.username)
print(f"{result=}")
print(result.dict())
assert result.sessionid
@pytest.mark.network
@pytest.mark.asyncio
async def test_auth_begin(client_configfile: KanidmClient) -> None:
"""tests the auth begin step"""
print(f"Doing auth_init for {client_configfile.config.username}")
2022-09-29 02:08:15 +02:00
if client_configfile.config.username is None:
pytest.skip("Can't run auth test without a username/password")
result = await client_configfile.auth_init(client_configfile.config.username)
print(f"{result=}")
print("Result dict:")
print(result.dict())
assert result.sessionid
print(f"Doing auth_begin for {client_configfile.config.username}")
if result.response is None:
raise ValueError("Failed to get response")
sessionid = result.response.headers["x-kanidm-auth-session-id"]
begin_result = await client_configfile.auth_begin(
sessionid=sessionid,
method="password",
)
print(f"{begin_result=}")
print(begin_result.data)
retval = begin_result.data
2022-09-29 02:08:15 +02:00
if retval is None:
raise pytest.fail("Failed to do begin_result")
2022-09-29 02:08:15 +02:00
retval["response"] = begin_result
2022-09-29 02:08:15 +02:00
assert AuthBeginResponse.parse_obj(retval)
@pytest.mark.network
@pytest.mark.asyncio
async def test_authenticate_flow(client_configfile: KanidmClient) -> None:
"""tests the authenticate() flow"""
2022-09-29 02:08:15 +02:00
if (
client_configfile.config.username is None
or client_configfile.config.password is None
):
pytest.skip(
"Can't run this without a username and password set in the config file"
)
client_configfile.config.auth_token = None
print(f"Doing client.authenticate for {client_configfile.config.username}")
result = await client_configfile.authenticate_password()
print(result)
@pytest.mark.network
@pytest.mark.asyncio
async def test_authenticate_flow_fail(client_configfile: KanidmClient) -> None:
2022-09-29 02:08:15 +02:00
"""tests the authenticate() flow with a valid (hopefully) username and invalid password"""
if not bool(os.getenv("RUN_SCARY_TESTS", None)):
pytest.skip(reason="Skipping because env var RUN_SCARY_TESTS isn't set")
print("Starting client...")
if (
client_configfile.config.uri is None
or client_configfile.config.username is None
or client_configfile.config.password is None
):
pytest.skip("Please ensure you have a username, password and uri in the config")
print(f"Doing client.authenticate for {client_configfile.config.username}")
2022-09-29 02:08:15 +02:00
client_configfile.config.auth_token = None
with pytest.raises((AuthCredFailed, AuthInitFailed)):
result = await client_configfile.authenticate_password(
username=client_configfile.config.username,
password="cheese",
)
print(result)
# TODO: mock a call to auth_init when a 200 response is not returned, raises AuthInitFailed
# TODO: mock a call to auth_init when "x-kanidm-auth-session-id" not in response.headers, raises ValueError
# TODO: mock a call to auth_begin when a 200 response is not returned, raises AuthBeginFailed
# TODO: mock a call to auth_step_password when a 200 response is not returned, raises AuthCredFailed
@pytest.mark.asyncio
async def test_authenticate_inputs_validation(
client: KanidmClient, mocker: MockerFixture
) -> None:
"""tests if you pass username but not password and password but not username"""
resp = MockResponse("crabs are cool", 200)
mocker.patch("aiohttp.ClientSession.post", return_value=resp)
2022-09-29 02:08:15 +02:00
with pytest.raises(ValueError):
await client.authenticate_password(username="cheese")
with pytest.raises(ValueError):
await client.authenticate_password(password="cheese")
client.config.password = None
client.config.username = "crabby"
with pytest.raises(ValueError):
await client.authenticate_password()
client.config.password = "cR4bzR0ol"
client.config.username = None
with pytest.raises(ValueError):
await client.authenticate_password()
client.config.username = None
client.config.password = None
with pytest.raises(ValueError):
await client.authenticate_password()
@pytest.mark.network
@pytest.mark.asyncio
async def test_auth_step_password(client: KanidmClient) -> None:
"""tests things"""
with pytest.raises(ValueError):
2022-09-29 02:08:15 +02:00
await client.auth_step_password(sessionid="asdf")
@pytest.mark.network
@pytest.mark.asyncio
async def test_authenticate_with_token(client_configfile: KanidmClient) -> None:
"""tests auth with a token, needs to have a valid token in your local cache"""
if "KANIDM_TEST_USERNAME" in os.environ:
test_username: str = os.environ["KANIDM_TEST_USERNAME"]
print(f"Using username {test_username} from KANIDM_TEST_USERNAME env var")
else:
test_username = "idm_admin"
print(
f"Using username {test_username} by default - set KANIDM_TEST_USERNAME env var if you want to change this."
)
tokens = TokenStore()
tokens.load()
if test_username not in tokens:
print(f"Can't find {test_username} user in token store")
raise pytest.skip(f"Can't find {test_username} user in token store")
test_token: str = tokens[test_username]
if not await client_configfile.check_token_valid(test_token):
print(f"Token for {test_username} isn't valid")
pytest.skip(f"Token for {test_username} isn't valid")
else:
print("Token was noted as valid, so auth works!")
# tests the "we set a token and well it works."
client_configfile.config.auth_token = tokens[test_username]
result = await client_configfile.call_get("/v1/self")
print(result)
assert result.status_code == 200