Skip to content

Commit

Permalink
Merge pull request Kuadrant#398 from pehala/rename_rhsso
Browse files Browse the repository at this point in the history
Rename RHSSO to Keycloak
  • Loading branch information
averevki authored May 21, 2024
2 parents 593f647 + 70074dc commit 840c1bb
Show file tree
Hide file tree
Showing 34 changed files with 209 additions and 206 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ podman run \
-v $HOME/.kube/config:/run/kubeconfig:z \
-e KUADRANT_SERVICE_PROTECTION__PROJECT=authorino \
-e KUADRANT_SERVICE_PROTECTION__PROJECT2=authorino2 \
-e KUADRANT_RHSSO__url="https://my-sso.net" \
-e KUADRANT_RHSSO__password="ADMIN_PASSWORD" \
-e KUADRANT_RHSSO__username="ADMIN_USERNAME" \
-e KUADRANT_KEYCLOAK__url="https://my-sso.net" \
-e KUADRANT_KEYCLOAK__password="ADMIN_PASSWORD" \
-e KUADRANT_KEYCLOAK__username="ADMIN_USERNAME" \
-e KUADRANT_AUTH0__url="AUTH0_URL" \
-e KUADRANT_AUTH0__client_id="AUTH0_CLIENT_ID" \
-e KUADRANT_AUTH0__client_secret="AUTH0_CLIENT_SECRET" \
Expand Down
8 changes: 4 additions & 4 deletions config/settings.local.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
# kubeconfig_path: "~/.kube/config" # Optional: Kubeconfig to use, if None the default one is used
# tools:
# project: "tools" # Optional: OpenShift project, where external tools are located
# rhsso:
# url: "SSO_URL"
# username: "SSO_ADMIN_USERNAME"
# password: "SSO_ADMIN_PASSWORD"
# keycloak:
# url: "KEYCLOAK_URL"
# username: "KEYCLOAK_ADMIN_USERNAME"
# password: "KEYCLOAK_ADMIN_PASSWORD"
# test_user:
# username: "testUser"
# password: "testPassword"
Expand Down
2 changes: 1 addition & 1 deletion config/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ default:
tools:
project: "tools"
cfssl: "cfssl"
rhsso:
keycloak:
username: "admin"
test_user:
username: "testUser"
Expand Down
4 changes: 2 additions & 2 deletions testsuite/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def __init__(self, name, default, **kwargs) -> None:
Validator("control_plane.managedzone", must_exist=True, ne=None),
Validator("control_plane.clusterissuer", must_exist=True, ne=None),
Validator("letsencrypt.clusterissuer", must_exist=True, ne=None),
DefaultValueValidator("rhsso.url", default=fetch_route("no-ssl-sso")),
DefaultValueValidator("rhsso.password", default=fetch_secret("credential-sso", "ADMIN_PASSWORD")),
DefaultValueValidator("keycloak.url", default=fetch_route("no-ssl-sso")),
DefaultValueValidator("keycloak.password", default=fetch_secret("credential-sso", "ADMIN_PASSWORD")),
DefaultValueValidator("mockserver.url", default=fetch_route("mockserver", force_http=True)),
],
validate_only=["authorino", "kuadrant", "default_exposer", "control_plane"],
Expand Down
4 changes: 2 additions & 2 deletions testsuite/httpx/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from httpx import Auth, Request, URL, Response

from testsuite.oidc.rhsso import User
from testsuite.oidc.keycloak import User
from testsuite.oidc import Token

TokenType = Union[Token, Callable[[], Token]]
Expand All @@ -22,7 +22,7 @@ def __init__(self, token: TokenType, location="authorization", username: str = N

@classmethod
def from_user(cls, token: TokenType, user: User, location="authorization"):
"""Creates Auth from RHSSO User object"""
"""Creates Auth from Keycloak User object"""
return cls(token, location, user.username, user.password)

@cached_property
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Objects for RHSSO"""
"""Keycloak OIDCProvider"""

from functools import cached_property
from urllib.parse import urlparse
Expand All @@ -11,9 +11,9 @@


# pylint: disable=too-many-instance-attributes
class RHSSO(OIDCProvider, LifecycleObject):
class Keycloak(OIDCProvider, LifecycleObject):
"""
OIDCProvider implementation for RHSSO. It creates Realm, client and user.
OIDCProvider implementation using Keycloak. It creates Realm, Client and single User.
"""

def __init__(
Expand All @@ -37,7 +37,7 @@ def __init__(
self.client = None

try:
self.master = KeycloakAdmin(
self.master_realm = KeycloakAdmin(
server_url=server_url,
username=username,
password=password,
Expand All @@ -49,7 +49,7 @@ def __init__(
# Older Keycloaks versions (and RHSSO) needs requires url to be pointed at auth/ endpoint
# pylint: disable=protected-access
self.server_url = urlparse(server_url)._replace(path="auth/").geturl()
self.master = KeycloakAdmin(
self.master_realm = KeycloakAdmin(
server_url=self.server_url,
username=username,
password=password,
Expand All @@ -59,8 +59,8 @@ def __init__(

def create_realm(self, name: str, **kwargs) -> Realm:
"""Creates new realm"""
self.master.create_realm(payload={"realm": name, "enabled": True, "sslRequired": "None", **kwargs})
return Realm(self.master, name)
self.master_realm.create_realm(payload={"realm": name, "enabled": True, "sslRequired": "None", **kwargs})
return Realm(self.master_realm, name)

def commit(self):
self.realm: Realm = self.create_realm(self.realm_name, accessTokenLifespan=24 * 60 * 60)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Object wrappers of RHSSO resources"""
"""Object wrappers for Keycloak resources"""

from functools import cached_property
from typing import List
Expand All @@ -7,7 +7,7 @@


class Realm:
"""Helper class for RHSSO realm manipulation"""
"""Helper class for Keycloak realm manipulation"""

def __init__(self, master: KeycloakAdmin, name) -> None:
self.admin = KeycloakAdmin(
Expand Down Expand Up @@ -63,7 +63,7 @@ def oidc_client(self, client_id, client_secret):


class Client:
"""Helper class for RHSSO client manipulation"""
"""Helper class for Keycloak client manipulation"""

def __init__(self, realm: Realm, client_id) -> None:
self.admin = realm.admin
Expand All @@ -79,7 +79,7 @@ def assign_role(self, role_name):

@cached_property
def auth_id(self):
"""Note This is different clientId (clientId) than self.client_id (Id), because RHSSO"""
"""Note This is different clientId (clientId) than self.client_id (Id), because Keycloak"""
return self.admin.get_client(self.client_id)["clientId"]

@property
Expand All @@ -105,7 +105,7 @@ def create_uma_resource(self, name, uris: List[str], owner=None):


class User:
"""Wrapper object for User object in RHSSO"""
"""Wrapper object for User object in Keycloak"""

def __init__(self, realm: Realm, user_id, username, password) -> None:
super().__init__()
Expand Down
18 changes: 9 additions & 9 deletions testsuite/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from testsuite.mockserver import Mockserver
from testsuite.oidc import OIDCProvider
from testsuite.oidc.auth0 import Auth0Provider
from testsuite.oidc.rhsso import RHSSO
from testsuite.oidc.keycloak import Keycloak
from testsuite.openshift.kuadrant import KuadrantCR
from testsuite.tracing import TracingClient
from testsuite.utils import randomize, _whoami
Expand Down Expand Up @@ -150,17 +150,17 @@ def openshift2(testconfig, skip_or_fail):


@pytest.fixture(scope="session")
def rhsso(request, testconfig, blame, skip_or_fail):
"""RHSSO OIDC Provider fixture"""
def keycloak(request, testconfig, blame, skip_or_fail):
"""Keycloak OIDC Provider fixture"""
try:
testconfig.validators.validate(only="rhsso")
cnf = testconfig["rhsso"]
info = RHSSO(
testconfig.validators.validate(only="keycloak")
cnf = testconfig["keycloak"]
info = Keycloak(
cnf["url"],
cnf["username"],
cnf["password"],
blame("realm"),
blame("client"),
"base-client",
cnf["test_user"]["username"],
cnf["test_user"]["password"],
)
Expand Down Expand Up @@ -217,9 +217,9 @@ def tracing(testconfig, skip_or_fail):


@pytest.fixture(scope="session")
def oidc_provider(rhsso) -> OIDCProvider:
def oidc_provider(keycloak) -> OIDCProvider:
"""Fixture which enables switching out OIDC providers for individual modules"""
return rhsso
return keycloak


@pytest.fixture(scope="session")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
pytestmark = [pytest.mark.authorino]


# pylint: disable=line-too-long
@pytest.fixture(scope="module")
def rego_policy(rhsso):
def rego_policy(keycloak):
"""
Complex OPA REGO policy that implements the UMA authorization flow.
See https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_uma_authorization_process
Expand All @@ -29,12 +30,12 @@ def rego_policy(rhsso):
under the used scope (HTTP GET) this REGO policy authorizes the request.
"""
return f"""\
pat := http.send({{"url":"{rhsso.server_url}realms/{rhsso.realm.name}/protocol/openid-connect/token",\
pat := http.send({{"url":"{keycloak.server_url}realms/{keycloak.realm.name}/protocol/openid-connect/token",\
"method": "post","headers":{{"Content-Type":"application/x-www-form-urlencoded"}},\
"raw_body":"grant_type=client_credentials&client_id={rhsso.client_name}&client_secret={rhsso.client.secret}"}})\
"raw_body":"grant_type=client_credentials&client_id={keycloak.client_name}&client_secret={keycloak.client.secret}"}})\
.body.access_token
resource_id := http.send({{"url":concat("",["{rhsso.server_url}realms/{rhsso.realm.name}/authz/protection/\
resource_id := http.send({{"url":concat("",["{keycloak.server_url}realms/{keycloak.realm.name}/authz/protection/\
resource_set?uri=",input.context.request.http.path]),"method":"get", "headers":\
{{"Authorization":concat(" ",["Bearer ",pat])}}}}).body[0]
Expand All @@ -44,12 +45,12 @@ def rego_policy(rhsso):
rpt = access_token {{ object.get(input.auth.identity, "authorization", {{}}).permissions }}
else = rpt_str {{
ticket := http.send({{"url":"{rhsso.server_url}realms/{rhsso.realm.name}/authz/protection/permission",\
ticket := http.send({{"url":"{keycloak.server_url}realms/{keycloak.realm.name}/authz/protection/permission",\
"method":"post","headers":{{"Authorization":concat(" ",["Bearer ",pat]),"Content-Type":"application/json"}},\
"raw_body":concat("",["[{{\\"resource_id\\":\\"",resource_id,"\\",\\"resource_scopes\\":[\\"",scope,"\\"]}}]"\
])}}).body.ticket
rpt_str := object.get(http.send({{"url":"{rhsso.server_url}realms/{rhsso.realm.name}/protocol/openid-connect/token",\
rpt_str := object.get(http.send({{"url":"{keycloak.server_url}realms/{keycloak.realm.name}/protocol/openid-connect/token",\
"method":"post","headers":{{"Authorization":concat(" ",\
["Bearer ",access_token]),"Content-Type":"application/x-www-form-urlencoded"}},"raw_body":concat("",\
["grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&ticket=",ticket,"&submit_request=true"])}})\
Expand Down Expand Up @@ -84,34 +85,34 @@ def authorization(authorization, rego_policy):


@pytest.fixture(scope="module")
def resource_owner_auth(rhsso):
def resource_owner_auth(keycloak):
"""
Auth for user who owns the protected resource, a.k.a. "owner" user.
The "uma_protection" client role is assigned to the user so that they are allowed to create protected resources.
"""
owner = rhsso.realm.create_user("owner", "owner")
role = rhsso.realm.admin.get_client_role(client_id=rhsso.client.client_id, role_name="uma_protection")
rhsso.realm.admin.assign_client_role(user_id=owner.user_id, client_id=rhsso.client.client_id, roles=[role])
return HttpxOidcClientAuth.from_user(rhsso.get_token(owner.username, owner.password), owner)
owner = keycloak.realm.create_user("owner", "owner")
role = keycloak.realm.admin.get_client_role(client_id=keycloak.client.client_id, role_name="uma_protection")
keycloak.realm.admin.assign_client_role(user_id=owner.user_id, client_id=keycloak.client.client_id, roles=[role])
return HttpxOidcClientAuth.from_user(keycloak.get_token(owner.username, owner.password), owner)


@pytest.fixture(scope="module")
def requester_auth(rhsso):
def requester_auth(keycloak):
"""Auth for user who requests the access to the protected resource, a.k.a. "requester" user"""
requester = rhsso.realm.create_user("requester", "requester")
return HttpxOidcClientAuth.from_user(rhsso.get_token(requester.username, requester.password), requester)
requester = keycloak.realm.create_user("requester", "requester")
return HttpxOidcClientAuth.from_user(keycloak.get_token(requester.username, requester.password), requester)


@pytest.fixture(scope="module")
def owner_uma(rhsso, resource_owner_auth):
def owner_uma(keycloak, resource_owner_auth):
"""UMA client used to create a protected resource and assign permissions for "requester" to access it."""
keycloak_connection = KeycloakOpenIDConnection(
server_url=rhsso.server_url,
client_id=rhsso.client_name,
client_secret_key=rhsso.client.secret,
server_url=keycloak.server_url,
client_id=keycloak.client_name,
client_secret_key=keycloak.client.secret,
username=resource_owner_auth.username,
password=resource_owner_auth.password,
realm_name=rhsso.realm_name,
realm_name=keycloak.realm_name,
)
return KeycloakUMA(keycloak_connection)

Expand Down
6 changes: 3 additions & 3 deletions testsuite/tests/kuadrant/authorino/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ def authorino(authorino, openshift, blame, request, testconfig, label) -> Author
# pylint: disable=unused-argument
@pytest.fixture(scope="module")
def authorization(authorization, oidc_provider, route, authorization_name, openshift, label) -> AuthConfig:
"""In case of Authorino, AuthC onfig used for authorization"""
"""In case of Authorino, AuthConfig used for authorization"""
if authorization is None:
authorization = AuthConfig.create_instance(openshift, authorization_name, route, labels={"testRun": label})
authorization.identity.add_oidc("rhsso", oidc_provider.well_known["issuer"])
authorization.identity.add_oidc("default", oidc_provider.well_known["issuer"])
return authorization


@pytest.fixture(scope="module")
def auth(oidc_provider):
"""Returns RHSSO authentication object for HTTPX"""
"""Returns authentication object for HTTPX"""
return HttpxOidcClientAuth(oidc_provider.get_token, "authorization")


Expand Down
Loading

0 comments on commit 840c1bb

Please sign in to comment.