canaille-globuzma/tests/oidc/conftest.py
2024-12-06 15:09:25 +01:00

178 lines
5 KiB
Python

import datetime
import os
import uuid
import pytest
from authlib.oidc.core.grants.util import generate_id_token
from werkzeug.security import gen_salt
from canaille.app import models
from canaille.oidc.installation import generate_keypair
from canaille.oidc.oauth import generate_user_info
from canaille.oidc.oauth import get_jwt_config
@pytest.fixture
# For some reason all the params from the overridden fixture must be present here
# https://github.com/pytest-dev/pytest/issues/11075
def app(app, configuration, backend):
os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "true"
yield app
@pytest.fixture(scope="session")
def keypair():
return generate_keypair()
@pytest.fixture
def configuration(configuration, keypair):
private_key, public_key = keypair
configuration["CANAILLE_OIDC"] = {
"JWT": {
"PUBLIC_KEY": public_key,
"PRIVATE_KEY": private_key,
"ISS": "https://auth.mydomain.test",
}
}
return configuration
@pytest.fixture
def client(testclient, trusted_client, backend):
c = models.Client(
client_id=gen_salt(24),
client_name="Some client",
contacts=["contact@mydomain.test"],
client_uri="https://mydomain.test",
redirect_uris=[
"https://mydomain.test/redirect1",
"https://mydomain.test/redirect2",
],
logo_uri="https://mydomain.test/logo.webp",
client_id_issued_at=datetime.datetime.now(datetime.timezone.utc),
client_secret=gen_salt(48),
grant_types=[
"password",
"authorization_code",
"implicit",
"hybrid",
"refresh_token",
"client_credentials",
],
response_types=["code", "token", "id_token"],
scope=["openid", "email", "profile", "groups", "address", "phone"],
tos_uri="https://mydomain.test/tos",
policy_uri="https://mydomain.test/policy",
jwks_uri="https://mydomain.test/jwk",
token_endpoint_auth_method="client_secret_basic",
post_logout_redirect_uris=["https://mydomain.test/disconnected"],
)
backend.save(c)
c.audience = [c, trusted_client]
backend.save(c)
yield c
backend.delete(c)
@pytest.fixture
def trusted_client(testclient, backend):
c = models.Client(
client_id=gen_salt(24),
client_name="Some other client",
contacts=["contact@myotherdomain.test"],
client_uri="https://myotherdomain.test",
redirect_uris=[
"https://myotherdomain.test/redirect1",
"https://myotherdomain.test/redirect2",
],
logo_uri="https://myotherdomain.test/logo.webp",
client_id_issued_at=datetime.datetime.now(datetime.timezone.utc),
client_secret=gen_salt(48),
grant_types=[
"password",
"authorization_code",
"implicit",
"hybrid",
"refresh_token",
"client_credentials",
],
response_types=["code", "token", "id_token"],
scope=["openid", "profile", "groups"],
tos_uri="https://myotherdomain.test/tos",
policy_uri="https://myotherdomain.test/policy",
jwks_uri="https://myotherdomain.test/jwk",
token_endpoint_auth_method="client_secret_basic",
post_logout_redirect_uris=["https://myotherdomain.test/disconnected"],
preconsent=True,
)
backend.save(c)
c.audience = [c]
backend.save(c)
yield c
backend.delete(c)
@pytest.fixture
def authorization(testclient, user, client, backend):
a = models.AuthorizationCode(
authorization_code_id=gen_salt(48),
code="my-code",
client=client,
subject=user,
redirect_uri="https://foobar.test/callback",
response_type="code",
scope=["openid", "profile"],
nonce="nonce",
issue_date=datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc),
lifetime=3600,
challenge="challenge",
challenge_method="method",
)
backend.save(a)
yield a
backend.delete(a)
@pytest.fixture
def token(testclient, client, user, backend):
t = models.Token(
token_id=gen_salt(48),
access_token=gen_salt(48),
audience=[client],
client=client,
subject=user,
refresh_token=gen_salt(48),
scope=["openid", "profile"],
issue_date=datetime.datetime.now(datetime.timezone.utc),
lifetime=3600,
)
backend.save(t)
yield t
backend.delete(t)
@pytest.fixture
def id_token(testclient, client, user, backend):
return generate_id_token(
{},
generate_user_info(user, client.scope),
aud=client.client_id,
**get_jwt_config(None),
)
@pytest.fixture
def consent(testclient, client, user, backend):
t = models.Consent(
consent_id=str(uuid.uuid4()),
client=client,
subject=user,
scope=["openid", "profile"],
issue_date=datetime.datetime.now(datetime.timezone.utc),
)
backend.save(t)
yield t
backend.delete(t)