Skip to content
Snippets Groups Projects
Verified Commit fa523d66 authored by Antoine R. Dumont's avatar Antoine R. Dumont
Browse files

keycloak: Open from_config* method to instantiate KeycloakOpenIDConnect

Related to T3079
parent bd3d8437
No related branches found
No related tags found
1 merge request!41keycloak: Open from_config* method to instantiate KeycloakOpenIDConnect
...@@ -8,6 +8,8 @@ from urllib.parse import urlencode ...@@ -8,6 +8,8 @@ from urllib.parse import urlencode
from keycloak import KeycloakOpenID from keycloak import KeycloakOpenID
from swh.core.config import load_from_envvar
class KeycloakOpenIDConnect: class KeycloakOpenIDConnect:
""" """
...@@ -158,3 +160,43 @@ class KeycloakOpenIDConnect: ...@@ -158,3 +160,43 @@ class KeycloakOpenIDConnect:
A dictionary fillled with user information A dictionary fillled with user information
""" """
return self._keycloak.userinfo(access_token) return self._keycloak.userinfo(access_token)
@classmethod
def from_config(cls, **kwargs: Any) -> "KeycloakOpenIDConnect":
"""Instantiate a KeycloakOpenIDConnect class from a configuration dict.
Args:
kwargs: configuration dict for the instance, with one keycloak key, whose
value is a Dict with the following keys:
- server_url: URL of the Keycloak server
- realm_name: The realm name
- client_id: The OpenID Connect client identifier
Returns:
the KeycloakOpenIDConnect instance
"""
cfg = kwargs["keycloak"]
return cls(
server_url=cfg["server_url"],
realm_name=cfg["realm_name"],
client_id=cfg["client_id"],
)
@classmethod
def from_configfile(cls, **kwargs: Any) -> "KeycloakOpenIDConnect":
"""Instantiate a KeycloakOpenIDConnect class from the configuration loaded from the
SWH_CONFIG_FILENAME envvar, with potential extra keyword arguments if their
value is not None.
Args:
kwargs: kwargs passed to instantiation call
Returns:
the KeycloakOpenIDConnect instance
"""
config = dict(load_from_envvar()).get("keycloak", {})
config.update({k: v for k, v in kwargs.items() if v is not None})
return cls.from_config(keycloak=config)
...@@ -4,11 +4,14 @@ ...@@ -4,11 +4,14 @@
# See top-level LICENSE file for more information # See top-level LICENSE file for more information
from copy import copy from copy import copy
import os
from urllib.parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from keycloak.exceptions import KeycloakError from keycloak.exceptions import KeycloakError
import pytest import pytest
import yaml
from swh.auth.keycloak import KeycloakOpenIDConnect
from swh.auth.pytest_plugin import keycloak_mock_factory from swh.auth.pytest_plugin import keycloak_mock_factory
from swh.auth.tests.sample_data import ( from swh.auth.tests.sample_data import (
CLIENT_ID, CLIENT_ID,
...@@ -18,6 +21,7 @@ from swh.auth.tests.sample_data import ( ...@@ -18,6 +21,7 @@ from swh.auth.tests.sample_data import (
SERVER_URL, SERVER_URL,
USER_INFO, USER_INFO,
) )
from swh.core.config import read
# Make keycloak fixture to use for tests below. # Make keycloak fixture to use for tests below.
keycloak_mock = keycloak_mock_factory( keycloak_mock = keycloak_mock_factory(
...@@ -98,3 +102,63 @@ def test_keycloak_decode_token(keycloak_mock): ...@@ -98,3 +102,63 @@ def test_keycloak_decode_token(keycloak_mock):
def test_keycloak_login(keycloak_mock): def test_keycloak_login(keycloak_mock):
actual_response = keycloak_mock.login("username", "password") actual_response = keycloak_mock.login("username", "password")
assert actual_response == OIDC_PROFILE assert actual_response == OIDC_PROFILE
@pytest.fixture
def auth_config():
return {
"keycloak": {
"server_url": "https://auth.swh.org/SWHTest",
"realm_name": "SWHTest",
"client_id": "client_id",
}
}
@pytest.fixture
def auth_config_path(tmp_path, monkeypatch, auth_config):
conf_path = os.path.join(tmp_path, "auth.yml")
with open(conf_path, "w") as f:
f.write(yaml.dump(auth_config))
monkeypatch.setenv("SWH_CONFIG_FILENAME", conf_path)
return conf_path
def test_auth_KeycloakOpenIDConnect_from_config(auth_config):
"""Instantiating keycloak client out of configuration dict is possible
"""
client = KeycloakOpenIDConnect.from_config(**auth_config)
assert client.server_url == auth_config["keycloak"]["server_url"]
assert client.realm_name == auth_config["keycloak"]["realm_name"]
assert client.client_id == auth_config["keycloak"]["client_id"]
def test_auth_KeycloakOpenIDConnect_from_configfile(auth_config_path, monkeypatch):
"""Instantiating keycloak client out of environment variable is possible
"""
client = KeycloakOpenIDConnect.from_configfile()
auth_config = read(auth_config_path)
assert client.server_url == auth_config["keycloak"]["server_url"]
assert client.realm_name == auth_config["keycloak"]["realm_name"]
assert client.client_id == auth_config["keycloak"]["client_id"]
def test_auth_KeycloakOpenIDConnect_from_configfile_override(
auth_config_path, monkeypatch
):
"""Instantiating keycloak client out of environment variable is possible
And caller can override the configuration at calling
"""
client = KeycloakOpenIDConnect.from_configfile(client_id="foobar")
auth_config = read(auth_config_path)
assert client.server_url == auth_config["keycloak"]["server_url"]
assert client.realm_name == auth_config["keycloak"]["realm_name"]
assert client.client_id == "foobar"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment