Fix auth provider resources
All checks were successful
/ build (push) Successful in 5s
/ test (push) Successful in 5s

This commit is contained in:
phil 2025-02-20 21:16:43 +01:00
parent 3f945310a4
commit 347c395394
3 changed files with 56 additions and 23 deletions

View file

@ -108,7 +108,6 @@ async def home(
"show_token": settings.show_token,
"user": user,
"now": datetime.now(),
"auth_provider": provider,
}
if provider is None or token is None:
context["providers"] = providers
@ -117,26 +116,28 @@ async def home(
context["access_token_parsed"] = None
context["refresh_token_parsed"] = None
context["resources"] = None
context["auth_provider"] = None
else:
context["auth_provider"] = provider
context["access_token"] = token["access_token"]
try:
access_token_parsed = provider.decode(token["access_token"], verify_signature=False)
context["access_token_parsed"] = access_token_parsed
except PyJWTError as err:
access_token_parsed = {"Cannot parse": err.__class__.__name__}
try:
context["access_token_scope"] = access_token_parsed["scope"]
except KeyError:
context["access_token_scope"] = None
context["id_token_parsed"] = provider.decode(token["id_token"], verify_signature=False)
context["access_token_parsed"] = access_token_parsed
id_token_parsed = provider.decode(token["id_token"], verify_signature=False)
context["id_token_parsed"] = id_token_parsed
except PyJWTError as err:
id_token_parsed = {"Cannot parse": err.__class__.__name__}
try:
refresh_token_parsed = provider.decode(token["refresh_token"], verify_signature=False)
context["refresh_token_parsed"] = refresh_token_parsed
except PyJWTError as err:
refresh_token_parsed = {"Cannot parse": err.__class__.__name__}
context["access_token_scope"] = access_token_parsed.get("scope")
context["resources"] = registry.resources
context["resource_providers"] = provider.resource_providers
try:
context["refresh_token_parsed"] = provider.decode(
token["refresh_token"], verify_signature=False
)
except PyJWTError as err:
context["refresh_token_parsed"] = {"Cannot parse": err.__class__.__name__}
return templates.TemplateResponse(name="home.html", request=request, context=context)

View file

@ -1,9 +1,10 @@
from typing import Annotated, Any
import logging
from json import JSONDecodeError
from authlib.oauth2.rfc6749 import OAuth2Token
from httpx import AsyncClient
from jwt.exceptions import ExpiredSignatureError, InvalidTokenError
from httpx import AsyncClient, HTTPError
from jwt.exceptions import DecodeError, ExpiredSignatureError, InvalidTokenError
from fastapi import FastAPI, HTTPException, Depends, Request, status
from fastapi.middleware.cors import CORSMiddleware
@ -84,6 +85,10 @@ async def get_resource(
"auth_provider": user.auth_provider_id,
},
)
except HTTPError as err:
raise HTTPException(
status.HTTP_503_SERVICE_UNAVAILABLE, err.__class__.__name__
)
except Exception as err:
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR, err.__class__.__name__
@ -151,7 +156,7 @@ async def get_auth_provider_resource(
) -> ProcessResult:
if token is None:
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "No auth token")
access_token = token["access_token"]
access_token = token
async with AsyncClient() as client:
resp = await client.get(
url=provider.get_resource_url(resource_name),
@ -165,9 +170,19 @@ async def get_auth_provider_resource(
# Only a demo, real application would really process the response
resp_length = len(resp.text)
if resp_length > 1024:
return ProcessResult(msg=f"The resource is too long ({resp_length} bytes) to show here")
return ProcessResult(
msg=f"The resource is too long ({resp_length} bytes) to show in this demo, here is just the begining in raw format",
start=resp.text[:100] + "...",
)
else:
try:
resp_json = resp.json()
except JSONDecodeError:
return ProcessResult(msg="The resource is not formatted in JSON", text=resp.text)
if isinstance(resp_json, dict):
return ProcessResult(**resp.json())
elif isinstance(resp_json, list):
return ProcessResult(**{str(i): line for i, line in enumerate(resp_json)})
# @resource_server.get("/public")

View file

@ -66,12 +66,8 @@
{% endif %}
<hr>
<div class="content">
<!--
-->
{% if resources %}
<p>
This application provides all these resources, eventually protected with scope or roles:
</p>
<p>This application provides all these resources, eventually protected with scope or roles:</p>
<div class="links-to-check">
{% for name, resource in resources.items() %}
{% if resource.default_resource_id %}
@ -91,8 +87,29 @@
{% endfor %}
</div>
{% endif %}
{% if auth_provider.resources %}
<p>{{ auth_provider.name }} is also defined as a provider for these resources:</p>
<div class="links-to-check">
{% for resource in auth_provider.resources %}
{% if resource.default_resource_id %}
<button resource-name="{{ resource.resource_name }}"
resource-id="{{ resource.default_resource_id }}"
onclick="get_resource('{{ resource.resource_name }}', '{{ access_token }}', '{{ auth_provider.id }}', '{{ resource.default_resource_id }}')"
>
{{ resource.name }}
</button>
{% else %}
<button resource-name="{{ resource.name }}"
onclick="get_resource('{{ resource.resource_name }}', '{{ access_token }}', '{{ auth_provider.id }}')"
>
{{ resource.name }}
</button>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if resource_providers %}
<p>{{ auth_provider.name }} allows this applicaiton to request resources from third party resource providers:</p>
<p>{{ auth_provider.name }} allows this application to request resources from third party resource providers:</p>
{% for resource_provider in resource_providers %}
<div class="links-to-check">
{{ resource_provider.name }}