Skip to content

Commit

Permalink
chore: some additional logs
Browse files Browse the repository at this point in the history
  • Loading branch information
peppelinux committed Jan 2, 2024
1 parent 31b2d41 commit dec981c
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 58 deletions.
7 changes: 4 additions & 3 deletions pyeudiw/federation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from pyeudiw.federation.schemas.entity_configuration import EntityStatementPayload, EntityConfigurationPayload


def is_es(payload: dict) -> bool:
"""
Determines if payload dict is an Entity Statement
Determines if payload dict is a Subordinate Entity Statement
:param payload: the object to determine if is an Entity Statement
:param payload: the object to determine if is a Subordinate Entity Statement
:type payload: dict
:returns: True if is an Entity Statement and False otherwise
Expand Down Expand Up @@ -34,4 +35,4 @@ def is_ec(payload: dict) -> bool:
EntityConfigurationPayload(**payload)
return True
except Exception as e:
return False
return False
15 changes: 2 additions & 13 deletions pyeudiw/federation/statements.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import annotations

from copy import deepcopy
from pyeudiw.federation.exceptions import (
UnknownKid,
Expand All @@ -13,22 +11,15 @@
EntityConfigurationHeader,
EntityStatementPayload
)
from pydantic import ValidationError
from pyeudiw.jwt.utils import decode_jwt_payload, decode_jwt_header
from pyeudiw.jwt import JWSHelper
from pyeudiw.tools.utils import get_http_url
from pydantic import ValidationError

from pyeudiw.jwk import find_jwk
from pyeudiw.tools.utils import get_http_url

import json
import logging

try:
pass
except ImportError: # pragma: no cover
pass


OIDCFED_FEDERATION_WELLKNOWN_URL = ".well-known/openid-federation"
logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -67,7 +58,6 @@ def get_federation_jwks(jwt_payload: dict) -> list[dict]:

jwks = jwt_payload.get("jwks", {})
keys = jwks.get("keys", [])

return keys


Expand All @@ -87,7 +77,6 @@ def get_entity_statements(urls: list[str] | str, httpc_params: dict, http_async:
"""

urls = urls if isinstance(urls, list) else [urls]

for url in urls:
logger.debug(f"Starting Entity Statement Request to {url}")

Expand Down
26 changes: 21 additions & 5 deletions pyeudiw/federation/trust_chain_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,27 @@ def validate(self) -> bool:
)

if not ta_jwk:
logger.error(
f"Trust chain validation error: TA jwks not found."
)
return False

# Validate the last statement with ta_jwk
jwsh = JWSHelper(ta_jwk)

if not jwsh.verify(last_element):
logger.error(
f"Trust chain signature validation error: {last_element} using {ta_jwk}"
)
return False

# then go ahead with other checks
self.exp = es_payload["exp"]

if self._check_expired(self.exp):
logger.error(
f"Trust chain validation error, statement expired: {es_payload}"
)
return False

fed_jwks = es_payload["jwks"]["keys"]
Expand All @@ -160,10 +169,16 @@ def validate(self) -> bool:
st_header.get("kid", None), fed_jwks
)
except (KidNotFoundError, InvalidKid):
logger.error(
f"Trust chain validation KidNotFoundError: {st_header} not in {fed_jwks}"
)
return False

jwsh = JWSHelper(jwk)
if not jwsh.verify(st):
logger.error(
f"Trust chain signature validation error: {st} using {jwk}"
)
return False
else:
fed_jwks = st_payload["jwks"]["keys"]
Expand All @@ -184,8 +199,9 @@ def _retrieve_ec(self, iss: str) -> str:
"""
jwt = get_entity_configurations(iss, self.httpc_params)
if not jwt:
raise HttpError(
f"Cannot get the Entity Configuration from {iss}")
_msg = f"Cannot get the Entity Configuration from {iss}"
logger.error(_msg)
raise HttpError(_msg)

# is something weird these will raise their Exceptions
return jwt[0]
Expand All @@ -204,9 +220,9 @@ def _retrieve_es(self, download_url: str, iss: str) -> str:
"""
jwt = get_entity_statements(download_url, self.httpc_params)
if not jwt:
logger.warning(
f"Cannot fast refresh Entity Statement {iss}"
)
_msg = f"Cannot fast refresh Entity Statement {iss}"
logger.warning(_msg)
raise HttpError(_msg)
if isinstance(jwt, list) and jwt:
return jwt[0]
return jwt
Expand Down
2 changes: 2 additions & 0 deletions pyeudiw/oauth2/dpop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def __init__(
"Jwk validation error, "
f"{e.__class__.__name__}: {e}"
)
raise ValueError("JWK schema validation error during DPoP init")

# If the jwt is invalid, this will raise an exception
try:
decode_jwt_header(http_header_dpop)
Expand Down
32 changes: 22 additions & 10 deletions pyeudiw/openid4vp/direct_post_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from pyeudiw.openid4vp.vp import Vp
from pydantic import ValidationError


class DirectPostResponse:
"""
Helper class for generate Direct Post Response.
Expand Down Expand Up @@ -90,8 +91,10 @@ def _validate_vp(self, vp: dict) -> bool:
)
VPTokenPayload(**vp.payload)
VPTokenHeader(**vp.headers)
except ValidationError:
return False
except ValidationError as e:
raise InvalidVPToken(
f"VP is not valid, {e}: {vp.headers}.{vp.payload}"
)
return True


Expand All @@ -102,12 +105,19 @@ def validate(self) -> bool:
:returns: True if all VP are valid, False otherwhise.
:rtype: bool
"""

all_valid = None
for vp in self.get_presentation_vps():
if not self._validate_vp(vp):
return False

return True
try:
self._validate_vp(vp)
if all_valid == None:
all_valid = True
except Exception as e:
logger.error(

)
all_valid = False

return all_valid

def get_presentation_vps(self) -> list[Vp]:
"""
Expand All @@ -125,16 +135,18 @@ def get_presentation_vps(self) -> list[Vp]:
vps = [_vps] if isinstance(_vps, str) else _vps

if not vps:
raise VPNotFound(f"Vps are empty for response with nonce \"{self.nonce}\"")
raise VPNotFound(
f'Vps are empty for response with nonce "{self.nonce}"'
)

for vp in vps:
# TODO - add an exception handling here
_vp = Vp(vp)
self._vps.append(_vp)

cred_iss = _vp.credential_payload['iss']
if not self.credentials_by_issuer.get(cred_iss, None):
self.credentials_by_issuer[cred_iss] = []

self.credentials_by_issuer[cred_iss].append(_vp.payload['vp'])

return self._vps
Expand All @@ -151,4 +163,4 @@ def payload(self) -> dict:
"""Returns the decoded payload of presentation"""
if not self._payload:
self._decode_payload()
return self._payload
return self._payload
13 changes: 9 additions & 4 deletions pyeudiw/satosa/dpop.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from pyeudiw.tools.base_logger import BaseLogger
from .base_http_error_handler import BaseHTTPErrorHandler


class BackendDPoP(BaseHTTPErrorHandler, BaseLogger):
"""
Backend DPoP class.
Expand Down Expand Up @@ -50,9 +51,13 @@ def _request_endpoint_dpop(self, context: Context, *args) -> Union[JsonResponse,
try:
WalletInstanceAttestationPayload(**wia)
except ValidationError as e:
self._log_warning(context, message=f"[FOUND WIA] Invalid WIA: {wia}! \nValidation error: {e}")
_msg = f"[FOUND WIA] Invalid WIA: {wia}! \nValidation error: {e}"
self._log_warning(context, message=_msg)
# return self._handle_401(context, _msg, e)
except Exception as e:
self._log_warning(context, message=f"[FOUND WIA] Invalid WIA: {wia}! \nUnexpected error: {e}")
_msg = f"[FOUND WIA] Invalid WIA: {wia}! \nUnexpected error: {e}"
self._log_warning(context, message=_msg)
# return self._handle_401(context, _msg, e)

try:
self._validate_trust(context, dpop_jws)
Expand Down Expand Up @@ -84,7 +89,7 @@ def _request_endpoint_dpop(self, context: Context, *args) -> Union[JsonResponse,

else:
_msg = (
"The Wallet Instance doesn't provide a valid Wallet Instance Attestation "
"The Wallet Instance doesn't provide a valid Wallet Attestation "
"a default set of capabilities and a low security level are applied."
)
self._log_warning(context, message=_msg)
self._log_warning(context, message=_msg)
29 changes: 15 additions & 14 deletions pyeudiw/satosa/trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from pyeudiw.tools.base_logger import BaseLogger


class BackendTrust(BaseLogger):
"""
Backend Trust class.
Expand All @@ -41,7 +42,10 @@ def init_trust_resources(self) -> None:
try:
self.get_backend_trust_chain()
except Exception as e:
self._log_critical("Backend Trust", f"Cannot fetch the trust anchor configuration: {e}")
self._log_critical(
"Backend Trust",
f"Cannot fetch the trust anchor configuration: {e}"
)

self.db_engine.close()
self._db_engine = None
Expand All @@ -57,10 +61,9 @@ def entity_configuration_endpoint(self, context: Context) -> Response:
:rtype: Response
"""

data = self.entity_configuration_as_dict
if context.qs_params.get('format', '') == 'json':
return Response(
json.dumps(data),
json.dumps(self.entity_configuration_as_dict),
status="200",
content="application/json"
)
Expand Down Expand Up @@ -101,21 +104,21 @@ def get_backend_trust_chain(self) -> list[str]:
"""
try:
trust_evaluation_helper = TrustEvaluationHelper.build_trust_chain_for_entity_id(
storage=self.db_engine,
entity_id=self.client_id,
entity_configuration=self.entity_configuration,
httpc_params=self.config['network']['httpc_params']
storage = self.db_engine,
entity_id = self.client_id,
entity_configuration = self.entity_configuration,
httpc_params = self.config['network']['httpc_params']
)
self.db_engine.add_or_update_trust_attestation(
entity_id=self.client_id,
attestation=trust_evaluation_helper.trust_chain,
exp=trust_evaluation_helper.exp
entity_id = self.client_id,
attestation = trust_evaluation_helper.trust_chain,
exp = trust_evaluation_helper.exp
)
return trust_evaluation_helper.trust_chain

except (DiscoveryFailedError, EntryNotFound, Exception) as e:
message = (
f"Error while building trust chain for client with id: {self.client_id}\n"
f"Error while building trust chain for client with id: {self.client_id}. "
f"{e.__class__.__name__}: {e}"
)
self._log_warning("Trust Chain", message)
Expand Down Expand Up @@ -154,7 +157,6 @@ def _validate_trust(self, context: Context, jws: str) -> TrustEvaluationHelper:
f"{trust_eval.entity_id}"
)
self._log_error(context, message)

raise NotTrustedFederationError(
f"{trust_eval.entity_id} not found for Trust evaluation."
)
Expand All @@ -164,7 +166,6 @@ def _validate_trust(self, context: Context, jws: str) -> TrustEvaluationHelper:
f"{trust_eval.entity_id}: {e}"
)
self._log_error(context, message)

raise NotTrustedFederationError(
f"{trust_eval.entity_id} is not trusted."
)
Expand Down Expand Up @@ -208,4 +209,4 @@ def entity_configuration(self) -> dict:
"typ": "entity-statement+jwt"
},
plain_dict=data
)
)
Loading

0 comments on commit dec981c

Please sign in to comment.