feat: link local library

This commit is contained in:
gabdevele
2026-06-17 20:43:56 +02:00 Unverified
parent 9a770a2af0
commit db59882f33
327 changed files with 22274 additions and 1 deletions
@@ -0,0 +1,12 @@
from typing import List
from pydantic import BaseModel, HttpUrl, EmailStr
class FAMetadata(BaseModel):
contacts: List[EmailStr]
federation_fetch_endpoint: HttpUrl
federation_resolve_endpoint: HttpUrl
federation_list_endpoint: HttpUrl
homepage_uri: HttpUrl
organization_name: str
@@ -0,0 +1,72 @@
from typing import List, Literal, Optional
from pydantic import BaseModel, validator
class Jwk(BaseModel):
kid: str # Base64url-encoded thumbprint string
kty: Literal["EC", "RSA"]
# TODO: verify if is optional
alg: Optional[
Literal[
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512",
"PS256",
"PS384",
"PS512",
"RSA-OAEP",
"RSA-OAEP-256",
"ECDH-ES",
"ECDH-ES+A128KW",
"ECDH-ES+A256KW"
]
]
use: Optional[Literal["sig", "enc"]]
n: Optional[str] # Base64urlUInt-encoded
e: Optional[str] # Base64urlUInt-encoded
def check_value_for_rsa(value, name, values):
if "EC" == values.get("kty") and value:
raise ValueError(f"{name} must be present only for kty = RSA")
def check_value_for_ec(value, name, values):
if "RSA" == values.get("kty") and value:
raise ValueError(f"{name} must be present only for kty = EC")
@validator("n")
def validate_n(cls, n_value, values):
cls.check_value_for_rsa(n_value, "n", values)
@validator("e")
def validate_e(cls, e_value, values):
cls.check_value_for_rsa(e_value, "e", values)
class JwkCie(Jwk):
x: Optional[str] # Base64url-encoded
y: Optional[str] # Base64url-encoded
crv: Optional[Literal["P-256", "P-384", "P-521"]]
@validator("x")
def validate_x(cls, x_value, values):
cls.check_value_for_ec(x_value, "x", values)
@validator("y")
def validate_y(cls, y_value, values):
cls.check_value_for_ec(y_value, "y", values)
@validator("crv")
def validate_crv(cls, crv_value, values):
cls.check_value_for_ec(crv_value, "crv", values)
class JwksCie(BaseModel):
keys: List[JwkCie]
class JwksSpid(BaseModel):
keys: List[Jwk]
@@ -0,0 +1,138 @@
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, HttpUrl, root_validator
from .jwks import JwksCie
class ScopeSupported(str, Enum):
openid = "openid"
offline_access = "offline_access"
profile = "profile"
email = "email"
class ResponseModesSupported(str, Enum):
form_post = ("form_post",)
query = "query"
class GrantTypeSupported(str, Enum):
refresh_token = "refresh_token" # nosec - B105
authorization_code = "authorization_code"
class AcrValuesSupported(str, Enum):
spid_l1 = "https://www.spid.gov.it/SpidL1"
spid_l2 = "https://www.spid.gov.it/SpidL2"
spid_l3 = "https://www.spid.gov.it/SpidL3"
class SigningAlgValuesSupported(str, Enum):
es256 = "ES256"
es384 = "ES384"
es512 = "ES512"
rs256 = "RS256"
rs384 = "RS384"
rs512 = "RS512"
# TODO: to be confirmed
# ps256 = "PS256"
# ps384 = "PS384"
# ps512 = "PS512"
class EncryptionAlgValuesSupported(str, Enum):
rsa_oaep = "RSA-OAEP"
ras_oaep_256 = "RSA-OAEP-256"
class EncryptionEncValuesSupported(str, Enum):
a128cbc_hs256 = "A128CBC-HS256"
a192cbc_hs384 = "A192CBC-HS384"
a256cbc_hs512 = "A256CBC-HS512"
a128gcm = "A128GCM"
a192gcm = "A192GCM"
a256gcm = "A256GCM"
rsa_oaep_256 = "RSA-OAEP-256"
class ClaimsSupported(str, Enum):
given_name = "given_name"
family_name = "family_name"
email = "email"
email_verified = "email_verified"
gender = "gender"
birthdate = "birthdate"
phone_number = "phone_number"
phone_number_verified = "phone_number_verified"
place_of_birth = "place_of_birth"
address = "address"
document_details = "document_details"
https_attributes_eid_gov_it_e_delivery_service = (
"https://attributes.eid.gov.it/e_delivery_service"
)
https_attributes_eid_gov_it_fiscal_number = (
"https://attributes.eid.gov.it/fiscal_number"
)
https_attributes_eid_gov_it_idANPR = "https://attributes.eid.gov.it/idANPR"
https_attributes_eid_gov_it_physical_phone_number = (
"https://attributes.eid.gov.it/physical_phone_number"
)
class OPMetadata(BaseModel):
organization_name: str
issuer: HttpUrl
authorization_endpoint: HttpUrl
token_endpoint: HttpUrl
userinfo_endpoint: HttpUrl
introspection_endpoint: HttpUrl
revocation_endpoint: HttpUrl
token_endpoint_auth_signing_alg_values_supported: List[SigningAlgValuesSupported]
id_token_encryption_alg_values_supported: List[EncryptionAlgValuesSupported]
id_token_encryption_enc_values_supported: List[EncryptionEncValuesSupported]
userinfo_encryption_alg_values_supported: List[EncryptionAlgValuesSupported]
userinfo_encryption_enc_values_supported: List[EncryptionEncValuesSupported]
request_object_encryption_alg_values_supported: List[EncryptionAlgValuesSupported]
request_object_encryption_enc_values_supported: List[EncryptionEncValuesSupported]
id_token_signing_alg_values_supported: List[SigningAlgValuesSupported]
userinfo_signing_alg_values_supported: List[SigningAlgValuesSupported]
request_object_signing_alg_values_supported: List[SigningAlgValuesSupported]
token_endpoint_auth_methods_supported = ["private_key_jwt"]
subject_types_supported = ["pairwise"]
request_parameter_supported = True
acr_values_supported: List[AcrValuesSupported]
signed_jwks_uri: Optional[HttpUrl]
jwks_uri: Optional[HttpUrl]
jwks: Optional[JwksCie]
@root_validator(pre=False)
def validate(cls, values):
jwks_there = False
for i in ("jwks_uri", "jwks", "signed_jwks_uri"):
if values.get(i):
jwks_there = True
break
if not jwks_there:
raise ValueError(
"one of signed_jwks_uri or jwks_uri or jwks must be set"
)
return values
class OPMetadataCie(OPMetadata):
scopes_supported: List[ScopeSupported]
response_types_supported = ["code"]
response_modes_supported: List[ResponseModesSupported]
grant_types_supported: List[GrantTypeSupported]
claims_supported: List[ClaimsSupported]
claims_parameter_supported = True
tls_client_certificate_bound_access_tokens = True
authorization_response_iss_parameter_supported = True
class OPMetadataSpid(OPMetadata):
op_name: Optional[str]
op_uri: Optional[str]
@@ -0,0 +1,53 @@
from typing import List, Literal, Optional
from pydantic import BaseModel, HttpUrl, constr
class ResolveResponse(BaseModel):
jose: constr(regex=r"^[a-zA-Z\_\-0-9]+\.[a-zA-Z\_\-0-9]+\.[a-zA-Z\_\-0-9]+") # noqa: F722
class ResolveErrorResponse(BaseModel):
operation: Optional[str]
error: Literal[
"invalid_request",
"invalid_subject",
"invalid_trust_anchor",
"invalid_trust_chain",
"invalid_metadata",
"not_found",
"server_error",
"temporarily_unavailable",
"unsupported_parameter",
]
error_description: str
class ResolveRequest(BaseModel):
sub: HttpUrl
trust_anchor: HttpUrl
# OpenID Federation 8.3.1: entity_type OPTIONAL, may occur multiple times
entity_type: Optional[List[str]] = None
format: Optional[Literal["json", "jose"]] = None
def example(): # pragma: no cover
return ResolveRequest(
sub="http://127.0.0.1:8000/oidc/rp",
trust_anchor="http://127.0.0.1:8000",
format="json",
)
# class ResolveResponse(BaseModel):
# iss : HttpUrl
# sub : HttpUrl
# iat : int
# exp: int
# trust_marks : Json
# metadata: Json
# trust_chain: List
class ResolveHeader(BaseModel):
Authorization : Optional[str]
@@ -0,0 +1,46 @@
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, HttpUrl, root_validator
from .jwks import JwksSpid
class GrantTypeSupported(str, Enum):
refresh_token = "refresh_token" # nosec - B105
authorization_code = "authorization_code"
class RPMetadata(BaseModel):
organization_name: str
redirect_uris: List[HttpUrl]
response_types = ["code"]
grant_types: List[GrantTypeSupported]
client_id: HttpUrl
# TODO: Could be specified in multiple languages
client_name: str
signed_jwks_uri: Optional[HttpUrl]
jwks_uri: Optional[HttpUrl]
jwks: Optional[JwksSpid]
@root_validator(pre=False)
def validate(cls, values):
jwks_there = False
for i in ("jwks_uri", "jwks", "signed_jwks_uri"):
if values.get(i):
jwks_there = True
break
if not jwks_there:
raise ValueError(
"one of signed_jwks_uri or jwks_uri or jwks must be set"
)
return values
class RPMetadataSpid(RPMetadata):
pass
class RPMetadataCie(RPMetadataSpid):
application_type = "web"
tls_client_certificate_bound_access_tokens: Optional[bool]