import tempfile from unittest.mock import MagicMock import pytest from social_core.utils import setting_name from galaxy.authnz.managers import AuthnzManager from galaxy.util import asbool @pytest.fixture def mock_app(): yield MagicMock() OIDC_BACKEND_CONFIG_TEMPLATE = """ {url} {client_id} {client_secret} $galaxy_url/authnz/keycloak/callback {enable_idp_logout} {require_create_confirmation} {accepted_audiences} {username_key} """ OIDC_CONFIG_TEMPLATE = """ {extra_properties} """ def create_oidc_config(extra_properties: str = "") -> tuple[str, str]: contents = OIDC_CONFIG_TEMPLATE.format(extra_properties=extra_properties) file = tempfile.NamedTemporaryFile(mode="w", delete=False) file.write(contents) return contents, file.name def create_backend_config( provider_name="oidc", url="https://example.com", client_id="client_id", client_secret="client_secret", enable_idp_logout="true", require_create_confirmation="false", accepted_audiences="https://audience.example.com", username_key="custom_username", ) -> tuple[str, str]: contents = OIDC_BACKEND_CONFIG_TEMPLATE.format( provider_name=provider_name, url=url, client_id=client_id, client_secret=client_secret, enable_idp_logout=enable_idp_logout, require_create_confirmation=require_create_confirmation, accepted_audiences=accepted_audiences, username_key=username_key, ) file = tempfile.NamedTemporaryFile(mode="w", delete=False) file.write(contents) return contents, file.name def test_parse_backend_config(mock_app): config_values = { "url": "https://example.com", "client_id": "example_app", "client_secret": "abcd1234", "enable_idp_logout": "true", "require_create_confirmation": "false", "accepted_audiences": "https://audience.example.com", "username_key": "custom_username", } oidc_contents, oidc_path = create_oidc_config() backend_contents, backend_path = create_backend_config(provider_name="oidc", **config_values) manager = AuthnzManager(app=mock_app, oidc_config_file=oidc_path, oidc_backends_config_file=backend_path) assert isinstance(manager.oidc_backends_config["oidc"], dict) parsed = manager.oidc_backends_config["oidc"] assert parsed["url"] == config_values["url"] assert parsed["client_id"] == config_values["client_id"] assert parsed["client_secret"] == config_values["client_secret"] assert parsed["accepted_audiences"] == config_values["accepted_audiences"] assert parsed["username_key"] == config_values["username_key"] # Boolean values should be parsed into bools assert parsed["enable_idp_logout"] == asbool(config_values["enable_idp_logout"]) assert parsed["require_create_confirmation"] == asbool(config_values["require_create_confirmation"]) def test_psa_authnz_config(mock_app): """ Test config values are set correctly in PSAAuthnz """ config_values = { "url": "https://example.com", "client_id": "example_app", "client_secret": "abcd1234", "enable_idp_logout": "true", "require_create_confirmation": "false", "accepted_audiences": "https://audience.example.com", "username_key": "custom_username", } oidc_contents, oidc_path = create_oidc_config() backend_contents, backend_path = create_backend_config(provider_name="oidc", **config_values) manager = AuthnzManager(app=mock_app, oidc_config_file=oidc_path, oidc_backends_config_file=backend_path) from galaxy.authnz.psa_authnz import PSAAuthnz psa_authnz = PSAAuthnz( provider="oidc", oidc_config=manager.oidc_config, oidc_backend_config=manager.oidc_backends_config["oidc"], app_config=mock_app.config, ) assert psa_authnz.config[setting_name("USERNAME_KEY")] == config_values["username_key"]