")
+ user: Annotated[User, Depends(UserWithRole("foorole"))],
+):
+ assert user is not None
+ return {"msg": "Only users with foorole can see this"}
@resource_server.get("/protected-by-barrole")
async def get_protected_by_barrole(
- user: Annotated[User, Depends(UserWithRole("barrole"))]
-) -> HTMLResponse:
- return HTMLResponse("
Protected by barrole
")
+ user: Annotated[User, Depends(UserWithRole("barrole"))],
+):
+ assert user is not None
+ return {"msg": "Protected by barrole"}
@resource_server.get("/protected-by-foorole-and-barrole")
async def get_protected_by_foorole_and_barrole(
user: Annotated[User, Depends(UserWithRole("foorole")), Depends(UserWithRole("barrole"))],
-) -> HTMLResponse:
+):
assert user is not None # Just to keep QA checks happy
- return HTMLResponse("
Only users with foorole and barrole can see this
")
+ return {"msg": "Only users with foorole and barrole can see this"}
@resource_server.get("/protected-by-foorole-or-barrole")
async def get_protected_by_foorole_or_barrole(
- user: Annotated[User, Depends(UserWithRole(["foorole", "barrole"]))]
-) -> HTMLResponse:
+ user: Annotated[User, Depends(UserWithRole(["foorole", "barrole"]))],
+):
assert user is not None # Just to keep QA checks happy
- return HTMLResponse("
Only users with foorole or barrole can see this
")
+ return {"msg": "Only users with foorole or barrole can see this"}
# @resource_server.get("/introspect")
@@ -118,9 +119,9 @@ async def get_resource_(
# oidc_provider: Annotated[StarletteOAuth2App, Depends(get_oidc_provider)],
# token: Annotated[OAuth2Token, Depends(get_token)],
user: Annotated[User, Depends(get_user_from_token)],
-) -> JSONResponse:
+):
"""Generic path for testing a resource provided by a provider"""
- return JSONResponse(await get_resource(id, user))
+ return await get_resource(id, user)
async def get_resource(resource_id: str, user: User) -> dict:
diff --git a/src/oidc_test/settings.py b/src/oidc_test/settings.py
index 2544bd7..b601739 100644
--- a/src/oidc_test/settings.py
+++ b/src/oidc_test/settings.py
@@ -43,9 +43,7 @@ class OIDCProvider(BaseModel):
info_url: str | None = (
None # Used eg. for Keycloak's public key (see https://stackoverflow.com/questions/54318633/getting-keycloaks-public-key)
)
- info: dict[str, str | int] | None = (
- None # Info fetched from info_url, eg. public key
- )
+ info: dict[str, str | int] | None = None # Info fetched from info_url, eg. public key
public_key: str | None = None
signature_alg: str = "RS256"
resource_provider_scopes: list[str] = []
@@ -62,25 +60,17 @@ class OIDCProvider(BaseModel):
def get_account_url(self, request: Request, user: User) -> str | None:
if self.account_url_template:
- if not (
- self.url.endswith("/") or self.account_url_template.startswith("/")
- ):
+ if not (self.url.endswith("/") or self.account_url_template.startswith("/")):
sep = "/"
else:
sep = ""
- return (
- self.url
- + sep
- + self.account_url_template.format(request=request, user=user)
- )
+ return self.url + sep + self.account_url_template.format(request=request, user=user)
else:
return None
def get_public_key(self) -> str:
"""Return the public key formatted for decoding token"""
- public_key = self.public_key or (
- self.info is not None and self.info["public_key"]
- )
+ public_key = self.public_key or (self.info is not None and self.info["public_key"])
if public_key is None:
raise AttributeError(f"Cannot get public key for {self.name}")
return f"""
@@ -91,17 +81,18 @@ class OIDCProvider(BaseModel):
def decode(self, token: str, verify_signature: bool = True) -> dict[str, Any]:
"""Decode the token with signature check"""
- decoded = decode(
- token,
- self.get_public_key(),
- algorithms=[self.signature_alg],
- audience=["account", "oidc-test", "oidc-test-web"],
- options={
- "verify_signature": False,
- "verify_aud": False,
- }, # not settings.insecure.skip_verify_signature},
- )
- logger.debug(str(decoded))
+ if settings.debug_token:
+ decoded = decode(
+ token,
+ self.get_public_key(),
+ algorithms=[self.signature_alg],
+ audience=["account", "oidc-test", "oidc-test-web"],
+ options={
+ "verify_signature": False,
+ "verify_aud": False,
+ }, # not settings.insecure.skip_verify_signature},
+ )
+ logger.debug(str(decoded))
return decode(
token,
self.get_public_key(),
@@ -143,6 +134,7 @@ class Settings(BaseSettings):
log: bool = False
insecure: Insecure = Insecure()
cors_origins: list[str] = []
+ debug_token: bool = False
@classmethod
def settings_customise_sources(
@@ -161,9 +153,7 @@ class Settings(BaseSettings):
settings_cls,
Path(
Path(
- environ.get(
- "OIDC_TEST_SETTINGS_FILE", Path.cwd() / "settings.yaml"
- ),
+ environ.get("OIDC_TEST_SETTINGS_FILE", Path.cwd() / "settings.yaml"),
)
),
),
diff --git a/src/oidc_test/static/styles.css b/src/oidc_test/static/styles.css
index 7e1260b..6262d79 100644
--- a/src/oidc_test/static/styles.css
+++ b/src/oidc_test/static/styles.css
@@ -171,11 +171,13 @@ hr {
gap: 0.5em;
flex-flow: wrap;
}
-.content .links-to-check a {
+.content .links-to-check button {
color: black;
padding: 5px 10px;
text-decoration: none;
border-radius: 8px;
+ border: none;
+ cursor: pointer;
}
.token {
@@ -183,12 +185,6 @@ hr {
font-family: monospace;
}
-.actions {
- display: flex;
- justify-content: center;
- gap: 0.5em;
-}
-
.resourceResult {
padding: 0.5em;
gap: 0.5em;
diff --git a/src/oidc_test/static/utils.js b/src/oidc_test/static/utils.js
index e6c4bfc..6ea8da2 100644
--- a/src/oidc_test/static/utils.js
+++ b/src/oidc_test/static/utils.js
@@ -1,6 +1,7 @@
async function checkHref(elem, token, authProvider) {
const msg = document.getElementById("msg")
- const resp = await fetch(elem.href, {
+ const url = `resource/${elem.getAttribute("resource-id")}`
+ const resp = await fetch(url, {
headers: new Headers({
"Content-type": "application/json",
"Authorization": `Bearer ${token}`,
diff --git a/src/oidc_test/templates/home.html b/src/oidc_test/templates/home.html
index 09c313f..92b7068 100644
--- a/src/oidc_test/templates/home.html
+++ b/src/oidc_test/templates/home.html
@@ -61,33 +61,30 @@
{% endif %}
- {% if user %}
-
- Fetch resources from the resource server with your authentication token:
-
-
-
-
-
-
-
-
-
-
- {% endif %}
-
- These links should get different response codes depending on the authorization:
+