Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/reference/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,17 @@ components:
description: Client ID
title: Client Id
type: string
issuer:
description: URL of OIDC provider
title: Issuer
type: string
logout_redirect_endpoint:
default: ''
description: The oidc endpoint required to logout
title: Logout Redirect Endpoint
type: string
well_known_url:
description: URL to fetch OIDC config from the provider
title: Well Known Url
type: string
required:
- well_known_url
- issuer
- client_id
title: OIDCConfig
type: object
Expand Down Expand Up @@ -377,7 +377,7 @@ info:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
title: BlueAPI Control
version: 1.1.2
version: 1.2.0
openapi: 3.1.0
paths:
/config/oidc:
Expand Down
8 changes: 4 additions & 4 deletions helm/blueapi/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,9 @@
"OIDCConfig": {
"additionalProperties": false,
"properties": {
"well_known_url": {
"description": "URL to fetch OIDC config from the provider",
"title": "Well Known Url",
"issuer": {
"description": "URL of OIDC provider",
"title": "Issuer",
"type": "string"
},
"client_id": {
Expand All @@ -323,7 +323,7 @@
}
},
"required": [
"well_known_url",
"issuer",
"client_id"
],
"title": "OIDCConfig",
Expand Down
12 changes: 6 additions & 6 deletions helm/blueapi/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@
"title": "OIDCConfig",
"type": "object",
"required": [
"well_known_url",
"issuer",
"client_id"
],
"properties": {
Expand All @@ -739,16 +739,16 @@
"description": "Client ID",
"type": "string"
},
"issuer": {
"title": "Issuer",
"description": "URL of OIDC provider",
"type": "string"
},
"logout_redirect_endpoint": {
"title": "Logout Redirect Endpoint",
"description": "The oidc endpoint required to logout",
"default": "",
"type": "string"
},
"well_known_url": {
"title": "Well Known Url",
"description": "URL to fetch OIDC config from the provider",
"type": "string"
}
},
"additionalProperties": false
Expand Down
12 changes: 4 additions & 8 deletions src/blueapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,7 @@ class ScratchConfig(BlueapiBaseModel):


class OIDCConfig(BlueapiBaseModel):
well_known_url: str = Field(
description="URL to fetch OIDC config from the provider"
)
issuer: str = Field(description="URL of OIDC provider")
client_id: str = Field(description="Client ID")
client_audience: str = Field(description="Client Audience(s)", default="blueapi")
logout_redirect_endpoint: str = Field(
Expand All @@ -217,7 +215,9 @@ class OIDCConfig(BlueapiBaseModel):

@cached_property
def _config_from_oidc_url(self) -> dict[str, Any]:
response: requests.Response = requests.get(self.well_known_url)
response: requests.Response = requests.get(
self.issuer + "/.well-known/openid-configuration"
)
response.raise_for_status()
return response.json()

Expand All @@ -231,10 +231,6 @@ def device_authorization_endpoint(self) -> str:
def token_endpoint(self) -> str:
return cast(str, self._config_from_oidc_url.get("token_endpoint"))

@cached_property
def issuer(self) -> str:
return cast(str, self._config_from_oidc_url.get("issuer"))

@cached_property
def authorization_endpoint(self) -> str:
return cast(str, self._config_from_oidc_url.get("authorization_endpoint"))
Expand Down
2 changes: 1 addition & 1 deletion src/blueapi/service/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from .runner import WorkerDispatcher

#: API version to publish in OpenAPI schema
REST_API_VERSION = "1.1.2"
REST_API_VERSION = "1.2.0"

LICENSE_INFO: dict[str, str] = {
"name": "Apache 2.0",
Expand Down
22 changes: 9 additions & 13 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,12 @@ def exporter() -> JsonObjectSpanExporter:
return exporter


@pytest.fixture
def oidc_url() -> str:
return (
"https://auth.example.com/realms/master/oidc/.well-known/openid-configuration"
)
ISSUER = "https://auth.example.com/realms/master"


@pytest.fixture
def oidc_config(oidc_url: str) -> OIDCConfig:
return OIDCConfig(
well_known_url=oidc_url, client_id="blueapi-cli", client_audience="blueapi"
)
def oidc_config() -> OIDCConfig:
return OIDCConfig(issuer=ISSUER, client_id="blueapi-cli", client_audience="blueapi")


CACHE_FILE = "blueapi_cache"
Expand All @@ -88,7 +82,7 @@ def oidc_well_known() -> dict[str, Any]:
"device_authorization_endpoint": "https://example.com/device_authorization",
"authorization_endpoint": "https://example.com/authorization",
"token_endpoint": "https://example.com/token",
"issuer": "https://example.com",
"issuer": ISSUER,
"jwks_uri": "https://example.com/realms/master/protocol/openid-connect/certs",
"end_session_endpoint": "https://example.com/end_session",
"id_token_signing_alg_values_supported": ["RS256"],
Expand All @@ -112,14 +106,15 @@ def _make_token(
rsa_private_key: str,
jwt_access_token: bool = False,
valid_audience: bool = True,
issuer: str = ISSUER,
) -> dict[str, str]:
now = time.time()

dummy_token = {
"aud": "blueapi" if valid_audience else "invalid_audience",
"exp": now + expires_in,
"iat": now + issued_in,
"iss": "https://example.com",
"iss": issuer,
"sub": "jd1",
"name": "Jane Doe",
"fedid": "jd1",
Expand Down Expand Up @@ -244,7 +239,6 @@ def device_code() -> str:

@pytest.fixture
def mock_authn_server(
oidc_url: str,
oidc_well_known: dict[str, Any],
oidc_config: OIDCConfig,
valid_token: dict[str, Any],
Expand All @@ -258,7 +252,9 @@ def mock_authn_server(
json=oidc_config.model_dump(),
)
# Fetch well-known OIDC flow URLs from server
requests_mock.get(oidc_url, json=oidc_well_known)
requests_mock.get(
ISSUER + "/.well-known/openid-configuration", json=oidc_well_known
)
# When device flow begins, return a device_code
requests_mock.post(
oidc_well_known["device_authorization_endpoint"],
Expand Down
2 changes: 1 addition & 1 deletion tests/system_tests/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ tiled:
enabled: true
url: http://localhost:8407/api/v1
oidc:
well_known_url: "http://localhost:8081/realms/master/.well-known/openid-configuration"
issuer: "http://localhost:8081/realms/master"
client_id: "ixx-cli-blueapi"
client_audience: "blueapi"
7 changes: 3 additions & 4 deletions tests/system_tests/test_blueapi_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@
# This client will give tokens for alice
CLIENT_ID = "system-test-blueapi"
CLIENT_SECRET = "secret"
KEYCLOAK_BASE_URL = "http://localhost:8081/"
OIDC_TOKEN_ENDPOINT = KEYCLOAK_BASE_URL + "realms/master/protocol/openid-connect/token"
KEYCLOAK_BASE_URL = "http://localhost:8081/realms/master"
OIDC_TOKEN_ENDPOINT = KEYCLOAK_BASE_URL + "/protocol/openid-connect/token"


@pytest.fixture
Expand Down Expand Up @@ -226,8 +226,7 @@ def test_cannot_access_endpoints(

def test_can_get_oidc_config_without_auth(client_without_auth: BlueapiClient):
assert client_without_auth.get_oidc_config() == OIDCConfig(
well_known_url=KEYCLOAK_BASE_URL
+ "realms/master/.well-known/openid-configuration",
issuer=KEYCLOAK_BASE_URL,
client_id="ixx-cli-blueapi",
)

Expand Down
4 changes: 2 additions & 2 deletions tests/unit_tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ def test_login_success(
result = runner.invoke(main, ["-c", config_with_auth, "login"])
assert (
"Logging in\n"
"Please login from this URL:- https://example.com/verify\n"
"Please login from this URL:- https://auth.example.com/realms/master/verify\n"
"Logged in and cached new token\n" == result.output
)
assert result.exit_code == 0
Expand Down Expand Up @@ -1064,7 +1064,7 @@ def test_login_when_cached_token_decode_fails(
result = runner.invoke(main, ["-c", config_with_auth, "login"])
assert (
"Logging in\n"
"Please login from this URL:- https://example.com/verify\n"
"Please login from this URL:- https://auth.example.com/realms/master/verify\n"
"Logged in and cached new token\n" in result.output
)
assert result.exit_code == 0
Expand Down
7 changes: 3 additions & 4 deletions tests/unit_tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def test_config_yaml_parsed(temp_yaml_config_file):
},
"numtracker": None,
"oidc": {
"well_known_url": "https://auth.example.com/realms/sample/.well-known/openid-configuration",
"issuer": "https://auth.example.com/realms/sample",
"client_id": "blueapi-client",
"client_audience": "aud",
"logout_redirect_endpoint": "",
Expand Down Expand Up @@ -377,7 +377,7 @@ def test_config_yaml_parsed(temp_yaml_config_file):
},
"numtracker": None,
"oidc": {
"well_known_url": "https://auth.example.com/realms/sample/.well-known/openid-configuration",
"issuer": "https://auth.example.com/realms/sample",
"client_id": "blueapi-client",
"client_audience": "aud",
"logout_redirect_endpoint": "",
Expand Down Expand Up @@ -446,7 +446,7 @@ def test_config_yaml_parsed_complete(temp_yaml_config_file: dict):
"api": {"host": "0.0.0.0", "port": 8001, "protocol": "http"},
"numtracker": None,
"oidc": {
"well_known_url": "https://auth.example.com/realms/sample/.well-known/openid-configuration",
"issuer": "https://auth.example.com/realms/sample",
"client_id": "blueapi-client",
"client_audience": "aud",
},
Expand Down Expand Up @@ -498,7 +498,6 @@ def test_oauth_config_model_post_init(
oidc_config.authorization_endpoint == oidc_well_known["authorization_endpoint"]
)
assert oidc_config.token_endpoint == oidc_well_known["token_endpoint"]
assert oidc_config.issuer == oidc_well_known["issuer"]
assert oidc_config.jwks_uri == oidc_well_known["jwks_uri"]
assert oidc_config.end_session_endpoint == oidc_well_known["end_session_endpoint"]

Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/test_helm_chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
),
logging=LoggingConfig(level="CRITICAL"),
oidc=OIDCConfig(
well_known_url="foo.bar",
issuer="foo.bar",
client_id="blueapi2",
client_audience="blueapi++",
),
Expand Down