Skip to content

Commit

Permalink
Test id token
Browse files Browse the repository at this point in the history
Note, the current mock setup delivers different handlers (for ingesting
sample users) depending on whether id tokens are intended to be supplied.
The fixtures (for preparing a mock client and preconfigured authenticator)
thus need specialisation depending on whether the id token is being used.
However, the current mock also requires that tests individually manage the
packaging of the id token when loading into the mock client's handler;
the handler syntax is different between the two cases. This means that to
test that JWT id tokens and JSON userinfo endpoints provide equivalent
behaviour requires changes in both the test (in the preamble) and in
fixtures (compared to unmodified tests). This has led to some code
duplication, which would be a target for future refactoring.
  • Loading branch information
benjimin committed Feb 13, 2024
1 parent 657b433 commit a108d23
Showing 1 changed file with 44 additions and 4 deletions.
48 changes: 44 additions & 4 deletions oauthenticator/tests/test_generic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import jwt
from functools import partial

from pytest import fixture, mark
Expand All @@ -18,6 +19,11 @@ def user_model(username, **kwargs):
}


@fixture(params=[True, False])
def userdata_from_id_token(request):
return request.param


@fixture
def generic_client(client):
setup_oauth_mock(
Expand All @@ -29,6 +35,18 @@ def generic_client(client):
return client


@fixture
def generic_client_variant(client, userdata_from_id_token):
setup_oauth_mock(
client,
host='generic.horse',
access_token_path='/oauth/access_token',
user_path='/oauth/userinfo',
token_request_style='jwt' if userdata_from_id_token else 'post',
)
return client


def _get_authenticator(**kwargs):
return GenericOAuthenticator(
token_url='https://generic.horse/oauth/access_token',
Expand All @@ -37,6 +55,14 @@ def _get_authenticator(**kwargs):
)


def _get_authenticator_for_id_token(**kwargs):
return GenericOAuthenticator(
token_url='https://generic.horse/oauth/access_token',
userdata_from_id_token=True,
**kwargs,
)


@fixture
def get_authenticator(generic_client):
"""
Expand All @@ -45,6 +71,17 @@ def get_authenticator(generic_client):
return partial(_get_authenticator, http_client=generic_client)


@fixture
def get_authenticator_variant(generic_client, userdata_from_id_token):
"""
http_client can't be configured, only passed as argument to the constructor.
"""
return partial(
_get_authenticator_for_id_token if userdata_from_id_token else _get_authenticator,
http_client=generic_client
)


@mark.parametrize(
"test_variation_id,class_config,expect_allowed,expect_admin",
[
Expand Down Expand Up @@ -163,24 +200,27 @@ def get_authenticator(generic_client):
],
)
async def test_generic(
get_authenticator,
generic_client,
get_authenticator_variant,
generic_client_variant,
test_variation_id,
class_config,
expect_allowed,
expect_admin,
userdata_from_id_token,
):
print(f"Running test variation id {test_variation_id}")
c = Config()
c.GenericOAuthenticator = Config(class_config)
c.GenericOAuthenticator.username_claim = "username"
authenticator = get_authenticator(config=c)
authenticator = get_authenticator_variant(config=c)
manage_groups = False
if "manage_groups" in class_config:
manage_groups = authenticator.manage_groups

handled_user_model = user_model("user1")
handler = generic_client.handler_for_user(handled_user_model)
if userdata_from_id_token:
handled_user_model = dict(id_token=jwt.encode(handled_user_model, key="foo"))
handler = generic_client_variant.handler_for_user(handled_user_model)
auth_model = await authenticator.get_authenticated_user(handler, None)

if expect_allowed:
Expand Down

0 comments on commit a108d23

Please sign in to comment.