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
2 changes: 1 addition & 1 deletion testsuite/gateway/exposers.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class LoadBalancerServiceExposer(Exposer):
"""Exposer using Load Balancer service for Gateway"""

def expose_hostname(self, name, gateway: Gateway) -> Hostname:
hostname = f"{name}.{self.base_domain}"
hostname = f"{name}-{self.cluster.project}.{self.base_domain}"

@crstrn13 crstrn13 Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenShiftExposer creates Routes and the resulting hostname is {name}.{cluster.apps_url}, which naturally includes the project context since Routes are namespace-scoped. On Kind, the LoadBalancerServiceExposer was just doing {name}.test.com — no project/namespace in the hostname at all. Adding cluster.project makes the Kind hostname format mirror what OpenShift produces, so tests don't break when switching between the two environments.

return StaticLocalHostname(
hostname, gateway.external_ip, lambda: gateway.get_tls_cert(hostname), force_https=self.passthrough
)
Expand Down
38 changes: 38 additions & 0 deletions testsuite/oidc/keycloak/objects.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
"""Object wrappers for Keycloak resources"""

from dataclasses import dataclass, field
from functools import cached_property
from typing import List

from keycloak import KeycloakOpenID, KeycloakAdmin


@dataclass
class ClientConfig: # pylint: disable=too-many-instance-attributes
"""Configuration for creating OIDC test clients"""

client_id: str
redirect_uris: list[str]
web_origins: list[str]
root_url: str
public_client: bool = False
standard_flow_enabled: bool = True
service_accounts_enabled: bool = False
direct_access_grants_enabled: bool = True
default_client_scopes: list[str] = field(default_factory=lambda: ["openid", "profile", "email"])
optional_client_scopes: list[str] = field(default_factory=lambda: ["offline_access", "microprofile-jwt"])

def to_keycloak_payload(self):
"""Convert to Keycloak client creation payload"""
return {
"name": self.client_id,
"clientId": self.client_id,
"publicClient": self.public_client,
"standardFlowEnabled": self.standard_flow_enabled,
"serviceAccountsEnabled": self.service_accounts_enabled,
"protocol": "openid-connect",
"redirectUris": self.redirect_uris,
"webOrigins": self.web_origins,
"directAccessGrantsEnabled": self.direct_access_grants_enabled,
"rootUrl": self.root_url,
"defaultClientScopes": self.default_client_scopes,
"optionalClientScopes": self.optional_client_scopes,
"attributes": {
"backchannel.logout.session.required": "true",
"use.refresh.tokens": "true",
},
}


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

Expand Down
172 changes: 0 additions & 172 deletions testsuite/oidc/test_client.py

This file was deleted.

47 changes: 26 additions & 21 deletions testsuite/tests/singlecluster/extensions/oidc_policy/conftest.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
"""Shared pytest fixtures for OIDC policy testing.

This module provides shared fixtures for testing OIDC (OpenID Connect) policy functionality,
including gateway setup and policy management. Client-specific fixtures are now located
in their respective test files.
"""
"""Shared pytest fixtures for OIDC policy testing. Client-specific fixtures are in each test file."""

from contextlib import contextmanager

import pytest

from testsuite.gateway import Gateway, GatewayListener
from testsuite.gateway.gateway_api.gateway import KuadrantGateway
from testsuite.kuadrant.extensions.oidc_policy import OIDCPolicy
from testsuite.kuadrant.extensions.oidc_policy import OIDCPolicy, Provider
from testsuite.oidc import Token


@pytest.fixture(scope="module")
def gateway(request, domain_name, base_domain, cluster, blame, label) -> Gateway:
"""Create and configure the test Gateway."""
fqdn = f"{domain_name}-kuadrant.{base_domain}"
fqdn = f"{domain_name}-{cluster.project}.{base_domain}"
gw = KuadrantGateway.create_instance(cluster, blame("gw"), {"app": label})
gw.add_listener(GatewayListener(hostname=fqdn))
request.addfinalizer(gw.delete)
Expand All @@ -25,35 +22,43 @@ def gateway(request, domain_name, base_domain, cluster, blame, label) -> Gateway
return gw


# JWT Cookie Helper fixture
@contextmanager
def set_jwt_cookie(client, token_value: str):
"""Context manager for setting JWT cookies with automatic cleanup"""
"""Context manager for setting JWT cookies with automatic cleanup."""
client.cookies.set("jwt", token_value)
try:
yield
finally:
client.cookies.clear()


# OIDC Policy fixtures - these are shared and will be overridden in individual test files
@pytest.fixture(scope="module")
def oidc_policy_provider_config(oidc_provider, test_client):
def oidc_policy_provider_config(oidc_provider, keycloak_client):
"""Create Provider configuration for the OIDC policy."""
return test_client.create_provider_config(oidc_provider)
return Provider(
issuerURL=oidc_provider.well_known["issuer"],
clientID=keycloak_client.client_id,
authorizationEndpoint=oidc_provider.well_known["authorization_endpoint"],
tokenEndpoint=oidc_provider.well_known["token_endpoint"],
)


@pytest.fixture(scope="module")
def oidc_policy(cluster, blame, oidc_policy_provider_config, gateway):
"""Create OIDC policy instance for testing.
"""Create OIDC policy instance targeting the gateway."""
return OIDCPolicy.create_instance(cluster, blame("oidc-policy"), gateway, provider=oidc_policy_provider_config)

Note: This fixture depends on 'provider' which should be defined in each test file
with the appropriate client-specific configuration.
"""
oidc_policy = OIDCPolicy.create_instance(
cluster, blame("oidc-policy"), gateway, provider=oidc_policy_provider_config
)
return oidc_policy

@pytest.fixture(scope="module")
def auth(keycloak_client, keycloak):
"""Get a Token for the test user via password grant."""

def _refresh(refresh_token):
data = keycloak_client.refresh_token(refresh_token)
return Token(data["access_token"], _refresh, data.get("refresh_token", ""))

data = keycloak_client.token(keycloak.test_username, keycloak.test_password)
return Token(data["access_token"], _refresh, data.get("refresh_token", ""))


@pytest.fixture(scope="module", autouse=True)
Expand Down
Loading
Loading