Skip to content

Commit

Permalink
Merge pull request #175 from oslokommune/url-serialization-fix
Browse files Browse the repository at this point in the history
Fix URL serialization in the ID-porten endpoint
  • Loading branch information
simenheg committed Apr 19, 2024
2 parents 6405698 + b3640fe commit 36effba
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 23 deletions.
10 changes: 6 additions & 4 deletions maskinporten_api/maskinporten_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,19 @@ def create_idporten_client(
"application_type": "web",
"authorization_lifetime": 0,
"client_name": self._make_client_name(team_name, provider, integration),
"client_uri": client_uri,
"client_uri": str(client_uri),
"description": self._make_client_description(
team_name, provider, integration
),
"code_challenge_method": "S256",
"frontchannel_logout_session_required": True,
"frontchannel_logout_uri": frontchannel_logout_uri,
"frontchannel_logout_uri": str(frontchannel_logout_uri),
"grant_types": ["authorization_code", "refresh_token"],
"integration_type": "idporten",
"post_logout_redirect_uris": post_logout_redirect_uris,
"redirect_uris": redirect_uris,
"post_logout_redirect_uris": [
str(u) for u in post_logout_redirect_uris
],
"redirect_uris": [str(u) for u in redirect_uris],
"refresh_token_lifetime": 0,
"refresh_token_usage": "ONETIME",
"scopes": ["openid", "profile"],
Expand Down
42 changes: 37 additions & 5 deletions test/resources/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def get_mock_user(principal_id):
return None


def generate_mock_client_response(
def maskinporten_client_response(
client_id,
client_name,
scopes=["folkeregister:deling/offentligmedhjemmel"],
Expand All @@ -84,6 +84,35 @@ def generate_mock_client_response(
}


def idporten_client_response(client_id, client_name):
return {
"client_name": client_name,
"client_uri": "http://localhost:8000",
"description": "Test client",
"scopes": ["openid", "profile"],
"redirect_uris": ["http://localhost:8000/auth/callback"],
"post_logout_redirect_uris": ["http://localhost:8000/"],
"authorization_lifetime": 0,
"access_token_lifetime": 0,
"refresh_token_lifetime": 0,
"refresh_token_usage": "ONETIME",
"frontchannel_logout_uri": "http://localhost:8000/auth/logout",
"frontchannel_logout_session_required": True,
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": ["authorization_code", "refresh_token"],
"integration_type": "idporten",
"application_type": "web",
"sso_disabled": False,
"code_challenge_method": "S256",
"last_updated": "2024-01-01T20:00:00.000Z",
"created": "2024-01-01T20:00:00.000Z",
"client_id": client_id,
"client_orgno": "123456789",
"active": True,
"jwks_uri": f"/clients/{client_id}/jwks",
}


@pytest.fixture
def maskinporten_create_client_body():
return {
Expand Down Expand Up @@ -113,15 +142,18 @@ def idporten_create_client_body():

@pytest.fixture
def maskinporten_create_client_response():
return generate_mock_client_response(
return maskinporten_client_response(
client_id="d1427568-1eba-1bf2-59ed-1c4af065f30e",
client_name="my-team-freg-testing",
)


@pytest.fixture
def idporten_create_client_response(maskinporten_create_client_response):
return maskinporten_create_client_response
def idporten_create_client_response():
return idporten_client_response(
client_id="1a7a504d-bb4c-239d-1469-61e220c3bcb6",
client_name="my-team-idporten-testing",
)


@pytest.fixture
Expand All @@ -134,7 +166,7 @@ def maskinporten_get_client_response(maskinporten_create_client_response):
def maskinporten_get_clients_response(maskinporten_get_client_response):
return [
maskinporten_get_client_response,
generate_mock_client_response(
maskinporten_client_response(
client_id="a70c6d97-51c2-4a08-83ce-50f44ebf8921",
client_name="another-client",
),
Expand Down
77 changes: 63 additions & 14 deletions test/resources/test_maskinporten.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from unittest.mock import Mock, patch
from unittest.mock import patch

import pytest
import requests_mock
Expand Down Expand Up @@ -101,24 +101,73 @@ def test_create_client_idporten(
idporten_create_client_response,
user_team_response,
mock_authorizer,
mock_aws,
mock_client,
mock_dynamodb,
mocker,
):
with requests_mock.Mocker(real_http=True) as rm:
mock_user = get_mock_user("janedoe")
mock_access_token_generation_requests(rm)
rm.get(f"{OKDATA_PERMISSION_API_URL}/teams/{team_id}", json=user_team_response)

with patch("resources.maskinporten.MaskinportenClient") as MaskinportenClient:
mocked_maskinporten_client = Mock()
MaskinportenClient.return_value = mocked_maskinporten_client
mocked_maskinporten_client.create_idporten_client.return_value.json.return_value = (
idporten_create_client_response
)
mock_client.post(
"/clients",
json=idporten_create_client_body,
headers={"Authorization": get_mock_user("janedoe").bearer_token},
)
mocked_maskinporten_client.create_idporten_client.assert_called_once()
rm.post(CLIENTS_ENDPOINT, json=idporten_create_client_response)

teams_api_matcher = rm.get(
f"{OKDATA_PERMISSION_API_URL}/teams/{team_id}",
json=user_team_response,
)
permissions_api_matcher = rm.post(
f"{OKDATA_PERMISSION_API_URL}/permissions",
)
audit_notify_matcher = rm.post(SLACK_WEBHOOK_URL)

created_client = mock_client.post(
"/clients",
json=idporten_create_client_body,
headers={"Authorization": mock_user.bearer_token},
).json()

client = {
"client_id": "1a7a504d-bb4c-239d-1469-61e220c3bcb6",
"client_name": "my-team-idporten-testing",
"description": "Test client",
"scopes": ["openid", "profile"],
"created": "2024-01-01T20:00:00+00:00",
"last_updated": "2024-01-01T20:00:00+00:00",
"active": True,
}
assert created_client == client

teams_request = teams_api_matcher.last_request
assert teams_request.headers["Authorization"] == f"Bearer {mock_user.access_token}"

permissions_request = permissions_api_matcher.last_request
assert (
permissions_request.headers["Authorization"] == f"Bearer {valid_client_token}"
)
resource_name = client_resource_name(
idporten_create_client_body["env"], client["client_id"]
)
assert permissions_request.json() == {
"owner": {
"user_id": user_team_response["name"],
"user_type": "team",
},
"resource_name": resource_name,
}

table = mock_dynamodb.Table("maskinporten-audit-trail")
audit_log_entry = table.query(KeyConditionExpression=Key("Id").eq(resource_name))[
"Items"
][0]
assert audit_log_entry["Action"] == "create"

assert audit_notify_matcher.last_request.json() == _slack_message_payload(
"Client created",
client["client_name"],
idporten_create_client_body["env"],
client["scopes"],
)


def test_create_client_rollback(
Expand Down

0 comments on commit 36effba

Please sign in to comment.