105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
import json
|
|
from typing import Union
|
|
|
|
from cryptojwt.jwk.jwk import key_from_jwk_dict
|
|
from django.core.exceptions import ValidationError
|
|
from django.utils.translation import gettext as _
|
|
from spid_cie_oidc.provider.settings import (
|
|
OIDCFED_DEFAULT_PROVIDER_PROFILE,
|
|
OIDCFED_PROVIDER_PROFILES
|
|
)
|
|
from spid_cie_oidc.relying_party.settings import (
|
|
RP_DEFAULT_PROVIDER_PROFILES,
|
|
RP_PROVIDER_PROFILES
|
|
)
|
|
|
|
from .jwks import serialize_key
|
|
from .settings import (
|
|
ENCRYPTION_ALG_VALUES_SUPPORTED,
|
|
ENCRYPTION_ENC_SUPPORTED,
|
|
ENTITY_TYPES,
|
|
SIGNING_ALG_VALUES_SUPPORTED
|
|
)
|
|
|
|
|
|
def validate_public_jwks(values: Union[dict, list]):
|
|
if isinstance(values, dict):
|
|
values = [values]
|
|
try:
|
|
for jwk_dict in values:
|
|
_k = key_from_jwk_dict(jwk_dict)
|
|
if _k.private_key():
|
|
_pub = serialize_key(_k.public_key())
|
|
raise ValidationError(
|
|
f"This JWK is is private {json.dumps(jwk_dict)}. "
|
|
f"It MUST be public instead, like this: {json.dumps([_pub])}."
|
|
)
|
|
except Exception as e:
|
|
raise ValidationError(f"Not valid: {e}")
|
|
|
|
|
|
def validate_metadata_algs(metadata: dict):
|
|
amap = dict(
|
|
id_token_signing_alg_values_supported = SIGNING_ALG_VALUES_SUPPORTED,
|
|
id_token_encryption_alg_values_supported = ENCRYPTION_ALG_VALUES_SUPPORTED,
|
|
id_token_encryption_enc_values_supported = ENCRYPTION_ENC_SUPPORTED,
|
|
token_endpoint_auth_signing_alg_values_supported = SIGNING_ALG_VALUES_SUPPORTED,
|
|
userinfo_encryption_alg_values_supported = ENCRYPTION_ALG_VALUES_SUPPORTED,
|
|
userinfo_encryption_enc_values_supported = ENCRYPTION_ENC_SUPPORTED,
|
|
userinfo_signing_alg_values_supported = SIGNING_ALG_VALUES_SUPPORTED,
|
|
request_object_encryption_alg_values_supported = ENCRYPTION_ALG_VALUES_SUPPORTED,
|
|
request_object_encryption_enc_values_supported = ENCRYPTION_ENC_SUPPORTED,
|
|
request_object_signing_alg_values_supported = SIGNING_ALG_VALUES_SUPPORTED,
|
|
)
|
|
if metadata.get("openid_provider", None):
|
|
md = metadata["openid_provider"]
|
|
for k, v in amap.items():
|
|
if k in md:
|
|
for alg in md[k]:
|
|
if alg not in v:
|
|
raise ValidationError(
|
|
f"{k} has an unsupported value {alg}. "
|
|
f"Supported algs are {v}"
|
|
)
|
|
|
|
|
|
def validate_entity_metadata(value):
|
|
status = False
|
|
for i in ENTITY_TYPES:
|
|
if i in value:
|
|
status = True
|
|
if not status:
|
|
raise ValidationError(
|
|
_(f'Need to specify one of {", ".join(ENTITY_TYPES)}')
|
|
)
|
|
if "openid_provider" in value:
|
|
schema = OIDCFED_PROVIDER_PROFILES[OIDCFED_DEFAULT_PROVIDER_PROFILE]
|
|
try:
|
|
schema["op_metadata"](**value["openid_provider"])
|
|
except Exception as e:
|
|
raise ValidationError(
|
|
f"OP metadata fail {e}. "
|
|
)
|
|
if "openid_relying_party" in value:
|
|
schema = RP_PROVIDER_PROFILES[RP_DEFAULT_PROVIDER_PROFILES]
|
|
try:
|
|
schema["rp_metadata"](**value["openid_relying_party"])
|
|
except Exception as e:
|
|
raise ValidationError(
|
|
f"RP metadata fail {e}. "
|
|
)
|
|
|
|
# TODO - add wallet_provider and wallet_relying_party once standardized
|
|
|
|
|
|
def validate_private_jwks(values: Union[dict, list]):
|
|
if isinstance(values, dict):
|
|
values = [values]
|
|
try:
|
|
for jwk_dict in values:
|
|
_k = key_from_jwk_dict(jwk_dict)
|
|
if not _k.private_key():
|
|
raise ValidationError(f"Can't extract a private JWK from {jwk_dict}")
|
|
except Exception as e:
|
|
raise ValidationError(f"Not valid: {e}")
|