Skip to content

Commit

Permalink
Merge pull request #94 from IdentityPython/read_only_list
Browse files Browse the repository at this point in the history
Added a class that implements read only of a file.
  • Loading branch information
rohe authored Feb 27, 2024
2 parents f20b465 + 11cbbb3 commit 506b1d0
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 145 deletions.
2 changes: 1 addition & 1 deletion example/flask_op/static/jwks.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"keys": [{"kty": "RSA", "use": "sig", "kid": "bXNmZXROQ3N2dDI2SWY5VlNWTG5yOXZqYlpLenVsalhwUWR5RW9BMHNCaw", "n": "uGVI-b6qr-OTc2knp7bpmDtiCQoWFXZ8mUV-SX0rCMtcc_IRmc_J7AfNEfnYk3dv0cKQK_Dgv3vicoeuf4KQ9ZZY-xI3bnRl9_HnhRpz_cJScDirkNKlsv8aQuYBO_gIiHp8B32YC0nx3BUQV5I6QGEiyG-lZT9PmXsUO1uKPPhny_vtQ6cUpvtuLySBu2ZYpaTDQqCv5Y6EKC49NYWhBB4B6f6TNKCoQTaxA8ZoM3lh7kFbu5DPEXKFAtuNiOtUNP7Ei9KfBtyBYSaZQBY8VkwAm1yKCA2sfv1mBwx0dT53MPJlNkoltf89mv1NM2OJPQAgGE6ygwGS2fyBLAn_bQ", "e": "AQAB"}, {"kty": "EC", "use": "sig", "kid": "U0pLNmFBRE4waDYyZG9ZdjNPb2pTZXAwZzdrbmpZdG0ya3lpaFJwZU9ncw", "crv": "P-256", "x": "DYUyBfiD53SEtUuKLjFCFpIkqyhbmBppAMjOat9qiY0", "y": "-SUSvVeOv7EA84qHLLEkDP24iZree-fomICuA4baeeA"}]}
{"keys": [{"kty": "RSA", "use": "sig", "kid": "bXNmZXROQ3N2dDI2SWY5VlNWTG5yOXZqYlpLenVsalhwUWR5RW9BMHNCaw", "e": "AQAB", "n": "uGVI-b6qr-OTc2knp7bpmDtiCQoWFXZ8mUV-SX0rCMtcc_IRmc_J7AfNEfnYk3dv0cKQK_Dgv3vicoeuf4KQ9ZZY-xI3bnRl9_HnhRpz_cJScDirkNKlsv8aQuYBO_gIiHp8B32YC0nx3BUQV5I6QGEiyG-lZT9PmXsUO1uKPPhny_vtQ6cUpvtuLySBu2ZYpaTDQqCv5Y6EKC49NYWhBB4B6f6TNKCoQTaxA8ZoM3lh7kFbu5DPEXKFAtuNiOtUNP7Ei9KfBtyBYSaZQBY8VkwAm1yKCA2sfv1mBwx0dT53MPJlNkoltf89mv1NM2OJPQAgGE6ygwGS2fyBLAn_bQ"}, {"kty": "EC", "use": "sig", "kid": "U0pLNmFBRE4waDYyZG9ZdjNPb2pTZXAwZzdrbmpZdG0ya3lpaFJwZU9ncw", "crv": "P-256", "x": "DYUyBfiD53SEtUuKLjFCFpIkqyhbmBppAMjOat9qiY0", "y": "-SUSvVeOv7EA84qHLLEkDP24iZree-fomICuA4baeeA"}]}
5 changes: 1 addition & 4 deletions src/idpyoidc/client/claims/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ class Claims(claims.Claims):
def get_base_url(self, configuration: dict, entity_id: Optional[str] = ""):
_base = configuration.get("base_url")
if not _base:
if entity_id:
_base = entity_id
else:
_base = configuration.get("client_id")
_base = configuration.get("client_id", configuration.get("entity_id"))

return _base

Expand Down
56 changes: 33 additions & 23 deletions src/idpyoidc/client/client_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,27 +490,29 @@ def _get_signing_key(self, algorithm, keyjar, key_types, kid=None):
return signing_key

def _get_audience_and_algorithm(self, context, keyjar, **kwargs):
algorithm = None

# audience for the signed JWT depends on which endpoint
# we're talking to.
if "authn_endpoint" in kwargs and kwargs["authn_endpoint"] in ["token_endpoint"]:
algorithm = context.get_usage("token_endpoint_auth_signing_alg")
if algorithm is None:
_pi = context.provider_info
try:
algs = _pi["token_endpoint_auth_signing_alg_values_supported"]
except KeyError:
algorithm = "RS256" # default
else:
for alg in algs: # pick the first one I support and have keys for
if alg in SIGNER_ALGS and self.get_signing_key_from_keyjar(alg, keyjar):
algorithm = alg
break

audience = context.provider_info.get("token_endpoint")
else:
audience = context.provider_info["issuer"]
algorithm = kwargs.get("algorithm", None)
audience = kwargs.get("audience", None)

if not audience:
# audience for the signed JWT depends on which endpoint
# we're talking to.
if "authn_endpoint" in kwargs and kwargs["authn_endpoint"] in ["token_endpoint"]:
algorithm = context.get_usage("token_endpoint_auth_signing_alg")
if algorithm is None:
_pi = context.provider_info
try:
algs = _pi["token_endpoint_auth_signing_alg_values_supported"]
except KeyError:
algorithm = "RS256" # default
else:
for alg in algs: # pick the first one I support and have keys for
if alg in SIGNER_ALGS and self.get_signing_key_from_keyjar(alg, keyjar):
algorithm = alg
break

audience = context.provider_info.get("token_endpoint")
else:
audience = context.provider_info["issuer"]

if not algorithm:
algorithm = self.choose_algorithm(**kwargs)
Expand All @@ -519,6 +521,9 @@ def _get_audience_and_algorithm(self, context, keyjar, **kwargs):
def _construct_client_assertion(self, service, **kwargs):
_context = service.upstream_get("context")
_entity = service.upstream_get("entity")
if _entity is None:
_entity = service.upstream_get("unit")

_keyjar = service.upstream_get("attribute", "keyjar")
audience, algorithm = self._get_audience_and_algorithm(_context, _keyjar, **kwargs)

Expand All @@ -527,7 +532,11 @@ def _construct_client_assertion(self, service, **kwargs):
algorithm, _keyjar, _context.kid["sig"], kid=kwargs["kid"]
)
else:
signing_key = self._get_signing_key(algorithm, _keyjar, _context.kid["sig"])
_key_type = _context.kid.get("sig", None)
if _key_type:
signing_key = self._get_signing_key(algorithm, _keyjar, _key_type)
else:
signing_key = self.get_signing_key_from_keyjar(algorithm, _keyjar)

if not signing_key:
raise UnsupportedAlgorithm(algorithm)
Expand Down Expand Up @@ -570,7 +579,8 @@ def modify_request(self, request, service, **kwargs):
pass

# If client_id is not required to be present, remove it.
if not request.c_param["client_id"][VREQUIRED]:
_cid_spec = request.c_param.get("client_id", None)
if _cid_spec and not _cid_spec[VREQUIRED]:
try:
del request["client_id"]
except KeyError:
Expand Down
62 changes: 32 additions & 30 deletions src/idpyoidc/client/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,28 @@
from typing import Union
from urllib.parse import urlparse

from cryptojwt.exception import IssuerNotFound
from cryptojwt.jwe.jwe import factory as jwe_factory
from cryptojwt.jws.jws import factory as jws_factory
from cryptojwt.jwt import JWT
from idpyoidc.exception import MissingSigningKey

from idpyoidc.client.exception import Unsupported
from idpyoidc.exception import MissingSigningKey
from idpyoidc.impexp import ImpExp
from idpyoidc.item import DLDict
from idpyoidc.message import Message
from idpyoidc.message.oauth2 import ResponseMessage
from idpyoidc.message.oauth2 import is_error_message
from idpyoidc.message.oauth2 import ResponseMessage
from idpyoidc.util import importer

from ..constant import JOSE_ENCODED
from ..constant import JSON_ENCODED
from ..constant import URL_ENCODED
from .client_auth import client_auth_setup
from .client_auth import method_to_item
from .client_auth import single_authn_setup
from .configure import Configuration
from .exception import ResponseError
from .util import get_http_body
from .util import get_http_url
from ..constant import JOSE_ENCODED
from ..constant import JSON_ENCODED
from ..constant import URL_ENCODED

__author__ = "Roland Hedberg"

Expand Down Expand Up @@ -79,7 +77,7 @@ class Service(ImpExp):
_callback_path = {}

def __init__(
self, upstream_get: Callable, conf: Optional[Union[dict, Configuration]] = None, **kwargs
self, upstream_get: Callable, conf: Optional[Union[dict, Configuration]] = None, **kwargs
):
ImpExp.__init__(self)

Expand Down Expand Up @@ -333,7 +331,7 @@ def get_endpoint(self):
return self.upstream_get("context").provider_info[self.endpoint_name]

def get_authn_header(
self, request: Union[dict, Message], authn_method: Optional[str] = "", **kwargs
self, request: Union[dict, Message], authn_method: Optional[str] = "", **kwargs
) -> dict:
"""
Construct an authorization specification to be sent in the
Expand Down Expand Up @@ -364,12 +362,15 @@ def get_authn_method(self) -> str:
"""
return self.default_authn_method

def get_headers_args(self):
return {}

def get_headers(
self,
request: Union[dict, Message],
http_method: str,
authn_method: Optional[str] = "",
**kwargs,
self,
request: Union[dict, Message],
http_method: str,
authn_method: Optional[str] = "",
**kwargs,
) -> dict:
"""
Expand Down Expand Up @@ -404,7 +405,7 @@ def get_headers(
return _headers

def get_request_parameters(
self, request_args=None, method="", request_body_type="", authn_method="", **kwargs
self, request_args=None, method="", request_body_type="", authn_method="", **kwargs
) -> dict:
"""
Builds the request message and constructs the HTTP headers.
Expand Down Expand Up @@ -445,6 +446,7 @@ def get_request_parameters(

# Client authentication by usage of the Authorization HTTP header
# or by modifying the request object
_args.update(self.get_headers_args())
_headers = self.get_headers(request, http_method=method, authn_method=authn_method, **_args)

# Find out where to send this request
Expand Down Expand Up @@ -506,7 +508,7 @@ def post_parse_response(self, response, **kwargs):
return response

def gather_verify_arguments(
self, response: Optional[Union[dict, Message]] = None, behaviour_args: Optional[dict] = None
self, response: Optional[Union[dict, Message]] = None, behaviour_args: Optional[dict] = None
):
"""
Need to add some information before running verify()
Expand Down Expand Up @@ -542,7 +544,7 @@ def _do_jwt(self, info):
def _do_response(self, info, sformat, **kwargs):
_context = self.upstream_get("context")

if isinstance(info, list): # Don't have support for sformat=list
if isinstance(info, list): # Don't have support for sformat=list
return info

try:
Expand All @@ -566,13 +568,13 @@ def _do_response(self, info, sformat, **kwargs):
return resp

def parse_response(
self,
info,
sformat: Optional[str] = "",
state: Optional[str] = "",
behaviour_args: Optional[dict] = None,
**kwargs,
) :
self,
info,
sformat: Optional[str] = "",
state: Optional[str] = "",
behaviour_args: Optional[dict] = None,
**kwargs,
):
"""
This the start of a pipeline that will:
Expand Down Expand Up @@ -707,12 +709,12 @@ def get_uri(base_url, path, hex):
return f"{base_url}/{path}/{hex}"

def construct_uris(
self,
base_url: str,
hex: bytes,
context: OidcContext,
targets: Optional[List[str]] = None,
response_types: Optional[list] = None,
self,
base_url: str,
hex: bytes,
context: OidcContext,
targets: Optional[List[str]] = None,
response_types: Optional[list] = None,
):
if not targets:
targets = self._callback_path.keys()
Expand Down
Loading

0 comments on commit 506b1d0

Please sign in to comment.