Resource server: read the required scope in access token
All checks were successful
/ build (push) Successful in 15s
/ test (push) Successful in 5s

This commit is contained in:
phil 2025-01-30 20:40:04 +01:00
parent f910834736
commit b3e19b3e40
4 changed files with 129 additions and 37 deletions

View file

@ -1,21 +1,76 @@
from datetime import datetime
import logging
from httpx import AsyncClient
from fastapi import HTTPException, status
from jwt import ExpiredSignatureError, InvalidKeyError, decode
from .models import User
from .auth_utils import oidc_providers_settings
from .settings import settings
logger = logging.getLogger(__name__)
async def get_resource(id: str, user: User) -> dict:
pname = getattr(user.oidc_provider, "name", "?")
resp = {
"hello" : f"Hi {user.name} from an OAuth resource provider.",
"comment": f"I received a request for '{id}' with an access token signed by {pname}."
"hello": f"Hi {user.name} from an OAuth resource provider.",
"comment": f"I received a request for '{id}' with an access token signed by {pname}.",
}
if id == "time":
resp["time"] = datetime.now().strftime("%c")
elif id == "bs":
async with AsyncClient() as client:
bs = await client.get("https://corporatebs-generator.sameerkumar.website/")
resp['bs'] = bs.json().get("phrase", "Sorry, i am out of BS today.")
scope = f"get:{id}"
user_scopes = user.userinfo["scope"].split(" ")
if scope in user_scopes:
if id == "time":
resp["time"] = datetime.now().strftime("%c")
elif id == "bs":
async with AsyncClient() as client:
bs = await client.get(
"https://corporatebs-generator.sameerkumar.website/"
)
resp["bs"] = bs.json().get("phrase", "Sorry, i am out of BS today.")
else:
resp["sorry"] = f"I don't known how to give '{id}' but i know corporate bs."
else:
resp['sorry'] = f"I don't known how to give '{id}' but i know corporate bs."
resp["sorry"] = (
f"I don't serve the ressource {id} to you because"
"there is no scope {scope} in the access token,"
)
return resp
# assert user.oidc_provider is not None
### Get some info (TODO: refactor)
# if (auth_provider_id := user.oidc_provider.name) is None:
# raise HTTPException(
# status.HTTP_401_UNAUTHORIZED,
# "Request headers must have a 'auth_provider' field",
# )
# if (
# auth_provider_settings := oidc_providers_settings.get(auth_provider_id)
# ) is None:
# raise HTTPException(
# status.HTTP_401_UNAUTHORIZED, f"Unknown auth provider '{auth_provider_id}'"
# )
# if (key := auth_provider_settings.get_public_key()) is None:
# raise HTTPException(
# status.HTTP_401_UNAUTHORIZED,
# f"Key for provider '{auth_provider_id}' unknown",
# )
# logger.warn(f"refresh with scope {scope}")
# breakpoint()
# refreshed_auth_info = await user.oidc_provider.fetch_access_token(scope=scope)
### Decode the new token
# try:
# payload = decode(
# refreshed_auth_info["access_token"],
# key=key,
# algorithms=["RS256"],
# audience="account",
# options={"verify_signature": not settings.insecure.skip_verify_signature},
# )
# except ExpiredSignatureError as err:
# logger.info(f"Expired signature: {err}")
# raise HTTPException(
# status.HTTP_401_UNAUTHORIZED,
# "Expired signature (refresh not implemented yet)",
# )