From 6ac0cdff8541b80c31359df02899345c19fc228a Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Sun, 6 Jun 2021 09:19:57 +0200 Subject: [PATCH 1/7] Editorial changes. Removed unused parameters. Changed get_ophash_by_cb_uri to use the provided url. --- example/flask_rp/views.py | 11 ++++++----- src/oidcrp/oauth2/__init__.py | 5 ++--- src/oidcrp/oauth2/add_on/dpop.py | 7 ++----- src/oidcrp/rp_handler.py | 3 +-- tests/test_40_dpop.py | 10 +++------- 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/example/flask_rp/views.py b/example/flask_rp/views.py index 10b7b36..c909f04 100644 --- a/example/flask_rp/views.py +++ b/example/flask_rp/views.py @@ -1,6 +1,6 @@ import logging -import urllib from urllib.parse import parse_qs +from urllib.parse import splitquery from flask import Blueprint from flask import current_app @@ -67,7 +67,8 @@ def rp(): except Exception as err: return make_response('Something went wrong:{}'.format(err), 400) else: - return redirect(result['url'], 303) + response = redirect(result['url'], 303) + return response else: _providers = current_app.rp_config.clients.keys() return render_template('opbyuid.html', providers=_providers) @@ -150,10 +151,10 @@ def finalize(op_hash, request_args): return make_response(res['error'], 400) -def get_ophash_by_cb_uri(url:str): - uri = urllib.parse.splitquery(request.url)[0] +def get_ophash_by_cb_uri(url: str): + uri = splitquery(url)[0] clients = current_app.rp_config.clients - for k,v in clients.items(): + for k, v in clients.items(): for endpoint in ("redirect_uris", "post_logout_redirect_uris", "frontchannel_logout_uri", diff --git a/src/oidcrp/oauth2/__init__.py b/src/oidcrp/oauth2/__init__.py index 52fcf79..b195c8d 100755 --- a/src/oidcrp/oauth2/__init__.py +++ b/src/oidcrp/oauth2/__init__.py @@ -72,9 +72,7 @@ def __init__(self, client_authn_factory=None, keyjar=None, verify_ssl=True, conf # just ignore verify_ssl until it goes away self.verify_ssl = self.httpc_params.get("verify", True) - def do_request(self, request_type, response_body_type="", request_args=None, - **kwargs): - + def do_request(self, request_type, response_body_type="", request_args=None, **kwargs): _srv = self._service[request_type] _info = _srv.get_request_parameters(request_args=request_args, **kwargs) @@ -137,6 +135,7 @@ def service_request(self, service, url, method="GET", body=None, The method that sends the request and handles the response returned. This assumes that the response arrives in the HTTP response. + :param service: The Service instance :param url: The URL to which the request should be sent :param method: Which HTTP method to use :param body: A message body if any diff --git a/src/oidcrp/oauth2/add_on/dpop.py b/src/oidcrp/oauth2/add_on/dpop.py index 654db97..a13248f 100644 --- a/src/oidcrp/oauth2/add_on/dpop.py +++ b/src/oidcrp/oauth2/add_on/dpop.py @@ -85,20 +85,16 @@ def verify_header(self, dpop_header) -> Optional["DPoPProof"]: def dpop_header(service_context: ServiceContext, - request: Union[dict, Message], service_endpoint: str, http_method: str, headers: Optional[dict] = None, - authn_method: Optional[str] = "", **kwargs) -> dict: """ :param service_context: - :param request: :param service_endpoint: :param http_method: :param headers: - :param authn_method: :param kwargs: :return: """ @@ -156,7 +152,8 @@ def add_support(services, signing_algorithms: Optional[list] = None): """ _service = services["accesstoken"] - _service.client_get("service_context").add_on['dpop'] = { + _context = _service.client_get("service_context") + _context.add_on['dpop'] = { # "key": key_by_alg(signing_algorithm), "sign_algs": signing_algorithms } diff --git a/src/oidcrp/rp_handler.py b/src/oidcrp/rp_handler.py index 5dc6750..e359939 100644 --- a/src/oidcrp/rp_handler.py +++ b/src/oidcrp/rp_handler.py @@ -488,8 +488,7 @@ def get_access_token(self, state, client: Optional[Client] = None): try: tokenresp = client.do_request( 'accesstoken', request_args=req_args, - authn_method=self.get_client_authn_method(client, - "token_endpoint"), + authn_method=self.get_client_authn_method(client, "token_endpoint"), state=state ) except Exception as err: diff --git a/tests/test_40_dpop.py b/tests/test_40_dpop.py index 490182a..fb0955c 100644 --- a/tests/test_40_dpop.py +++ b/tests/test_40_dpop.py @@ -1,15 +1,11 @@ import os -import pytest from cryptojwt.jws.jws import factory from cryptojwt.key_jar import init_key_jar +import pytest -from oidcrp.client_auth import factory as ca_factory from oidcrp.oauth2 import Client from oidcrp.oauth2 import DEFAULT_OAUTH2_SERVICES -from oidcrp.oauth2.add_on import do_add_ons -from oidcrp.service import init_services -from oidcrp.service_context import ServiceContext _dirname = os.path.dirname(os.path.abspath(__file__)) @@ -43,14 +39,14 @@ def create_client(self): self.client = Client(keyjar=CLI_KEY, config=config, services=DEFAULT_OAUTH2_SERVICES) - self.client.client_get("service_context").provider_info= { + self.client.client_get("service_context").provider_info = { "authorization_endpoint": "https://example.com/auth", "token_endpoint": "https://example.com/token", "dpop_signing_alg_values_supported": ["RS256", "ES256"] } def test_add_header(self): - token_serv = self.client.client_get("service","accesstoken") + token_serv = self.client.client_get("service", "accesstoken") req_args = { "grant_type": "authorization_code", "code": "SplxlOBeZQQYbYS6WxSbIA", From 0a47f8a8c54efe68850478b595601e153af24d70 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Mon, 7 Jun 2021 11:01:45 +0200 Subject: [PATCH 2/7] Changed such that on can enter an issuer ID for an OP that supports dynamic provider info discovery instead of an user identifier or a static issuer ID. --- example/flask_rp/conf.json | 2 +- example/flask_rp/templates/opbyuid.html | 6 +- example/flask_rp/views.py | 86 ++++++++++++------------- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/example/flask_rp/conf.json b/example/flask_rp/conf.json index 2325f03..b7cd241 100644 --- a/example/flask_rp/conf.json +++ b/example/flask_rp/conf.json @@ -108,7 +108,7 @@ "client_secret_post" ] }, - "redirect_uris": "None", + "redirect_uris": [], "services": { "discovery": { "class": "oidcrp.oidc.provider_info_discovery.ProviderInfoDiscovery", diff --git a/example/flask_rp/templates/opbyuid.html b/example/flask_rp/templates/opbyuid.html index d2c766b..a91b6b9 100644 --- a/example/flask_rp/templates/opbyuid.html +++ b/example/flask_rp/templates/opbyuid.html @@ -16,9 +16,11 @@

OP by UID

Start sign in flow

By entering your unique identifier:

- + +

an issuer ID

+

Or you can chose one of the preconfigured OpenID Connect Providers

- {% for op in providers %} diff --git a/example/flask_rp/views.py b/example/flask_rp/views.py index c909f04..f368688 100644 --- a/example/flask_rp/views.py +++ b/example/flask_rp/views.py @@ -43,27 +43,24 @@ def index(): @oidc_rp_views.route('/rp') def rp(): - try: - iss = request.args['iss'] - except KeyError: - link = '' - else: - link = iss + iss = request.args['dyn_iss'] + if not iss: + iss = request.args['static_iss'] - try: + if not iss: uid = request.args['uid'] - except KeyError: + else: uid = '' - if link or uid: + if iss or uid: if uid: args = {'user_id': uid} else: args = {} - session['op_hash'] = link + session['op_identifier'] = iss try: - result = current_app.rph.begin(link, **args) + result = current_app.rph.begin(iss, **args) except Exception as err: return make_response('Something went wrong:{}'.format(err), 400) else: @@ -74,13 +71,16 @@ def rp(): return render_template('opbyuid.html', providers=_providers) -def get_rp(op_hash): +def get_rp(op_identifier): try: - _iss = current_app.rph.hash2issuer[op_hash] + _iss = current_app.rph.hash2issuer[op_identifier] except KeyError: - logger.error('Unkown issuer: {} not among {}'.format( - op_hash, list(current_app.rph.hash2issuer.keys()))) - return make_response("Unknown hash: {}".format(op_hash), 400) + try: + rp = current_app.rph.issuer2rp[op_identifier] + except KeyError: + logger.error('Unkown issuer: {} not among {}'.format( + op_identifier, list(current_app.rph.hash2issuer.keys()))) + return make_response("Unknown hash: {}".format(op_identifier), 400) else: try: rp = current_app.rph.issuer2rp[_iss] @@ -91,8 +91,8 @@ def get_rp(op_hash): return rp -def finalize(op_hash, request_args): - rp = get_rp(op_hash) +def finalize(op_identifier, request_args): + rp = get_rp(op_identifier) if hasattr(rp, 'status_code') and rp.status_code != 200: logger.error(rp.response[0].decode()) @@ -151,22 +151,22 @@ def finalize(op_hash, request_args): return make_response(res['error'], 400) -def get_ophash_by_cb_uri(url: str): +def get_op_identifier_by_cb_uri(url: str): uri = splitquery(url)[0] - clients = current_app.rp_config.clients - for k, v in clients.items(): + for k,v in current_app.rph.issuer2rp.items(): + _cntx = v.get_service_context() for endpoint in ("redirect_uris", "post_logout_redirect_uris", "frontchannel_logout_uri", "backchannel_logout_uri"): - if uri in clients[k].get(endpoint, []): + if uri in _cntx.get(endpoint, []): return k -@oidc_rp_views.route('/authz_cb/') -def authz_cb(op_hash): - op_hash = get_ophash_by_cb_uri(request.url) - return finalize(op_hash, request.args) +@oidc_rp_views.route('/authz_cb/') +def authz_cb(op_identifier): + op_identifier = get_op_identifier_by_cb_uri(request.url) + return finalize(op_identifier, request.args) @oidc_rp_views.errorhandler(werkzeug.exceptions.BadRequest) @@ -177,12 +177,12 @@ def handle_bad_request(e): @oidc_rp_views.route('/repost_fragment') def repost_fragment(): args = compact(parse_qs(request.args['url_fragment'])) - op_hash = request.args['op_hash'] - return finalize(op_hash, args) + op_identifier = request.args['op_identifier'] + return finalize(op_identifier, args) @oidc_rp_views.route('/ihf_cb') -def ihf_cb(self, op_hash='', **kwargs): +def ihf_cb(self, op_identifier='', **kwargs): logger.debug('implicit_hybrid_flow kwargs: {}'.format(kwargs)) return render_template('repost_fragment.html') @@ -191,11 +191,11 @@ def ihf_cb(self, op_hash='', **kwargs): def session_iframe(): # session management logger.debug('session_iframe request_args: {}'.format(request.args)) - _rp = get_rp(session['op_hash']) + _rp = get_rp(session['op_identifier']) _context = _rp.client_get("service_context") session_change_url = "{}/session_change".format(_context.base_url) - _issuer = current_app.rph.hash2issuer[session['op_hash']] + _issuer = current_app.rph.hash2issuer[session['op_identifier']] args = { 'client_id': session['client_id'], 'session_state': session['session_state'], @@ -209,8 +209,8 @@ def session_iframe(): # session management @oidc_rp_views.route('/session_change') def session_change(): - logger.debug('session_change: {}'.format(session['op_hash'])) - _rp = get_rp(session['op_hash']) + logger.debug('session_change: {}'.format(session['op_identifier'])) + _rp = get_rp(session['op_identifier']) # If there is an ID token send it along as a id_token_hint _aserv = _rp.client_get("service", 'authorization') @@ -228,10 +228,10 @@ def session_change(): # post_logout_redirect_uri -@oidc_rp_views.route('/session_logout/') -def session_logout(op_hash): - op_hash = get_ophash_by_cb_uri(request.url) - _rp = get_rp(op_hash) +@oidc_rp_views.route('/session_logout/') +def session_logout(op_identifier): + op_identifier = get_op_identifier_by_cb_uri(request.url) + _rp = get_rp(op_identifier) logger.debug('post_logout') return "Post logout from {}".format(_rp.client_get("service_context").issuer) @@ -245,9 +245,9 @@ def logout(): return redirect(_info['url'], 303) -@oidc_rp_views.route('/bc_logout/', methods=['GET', 'POST']) -def backchannel_logout(op_hash): - _rp = get_rp(op_hash) +@oidc_rp_views.route('/bc_logout/', methods=['GET', 'POST']) +def backchannel_logout(op_identifier): + _rp = get_rp(op_identifier) try: _state = rp_handler.backchannel_logout(_rp, request.data) except Exception as err: @@ -258,9 +258,9 @@ def backchannel_logout(op_hash): return "OK" -@oidc_rp_views.route('/fc_logout/', methods=['GET', 'POST']) -def frontchannel_logout(op_hash): - _rp = get_rp(op_hash) +@oidc_rp_views.route('/fc_logout/', methods=['GET', 'POST']) +def frontchannel_logout(op_identifier): + _rp = get_rp(op_identifier) sid = request.args['sid'] _iss = request.args['iss'] if _iss != _rp.client_get("service_context").get('issuer'): From 754171dea00ce24bd6ef7a56648d1d7920010fe7 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Mon, 7 Jun 2021 11:03:00 +0200 Subject: [PATCH 3/7] An example configuration for an RP that knows DPoP. Support the usage of DPoP for the user info endpoint. --- example/flask_rp/dpop_conf.json | 218 +++++++++++++++++++++++++++++++ src/oidcrp/oauth2/add_on/dpop.py | 5 + 2 files changed, 223 insertions(+) create mode 100644 example/flask_rp/dpop_conf.json diff --git a/example/flask_rp/dpop_conf.json b/example/flask_rp/dpop_conf.json new file mode 100644 index 0000000..f887487 --- /dev/null +++ b/example/flask_rp/dpop_conf.json @@ -0,0 +1,218 @@ +{ + "logging": { + "version": 1, + "disable_existing_loggers": false, + "root": { + "handlers": [ + "file" + ], + "level": "DEBUG" + }, + "loggers": { + "idp": { + "level": "DEBUG" + } + }, + "handlers": { + "file": { + "class": "logging.FileHandler", + "filename": "dpoop_debug.log", + "formatter": "default" + } + }, + "formatters": { + "default": { + "format": "%(asctime)s %(name)s %(levelname)s %(message)s" + } + } + }, + "port": 8090, + "domain": "127.0.0.1", + "base_url": "https://{domain}:{port}", + "httpc_params": { + "verify": false + }, + "rp_keys": { + "private_path": "private/jwks.json", + "key_defs": [ + { + "type": "RSA", + "key": "", + "use": [ + "sig" + ] + }, + { + "type": "EC", + "crv": "P-256", + "use": [ + "sig" + ] + } + ], + "public_path": "static/jwks.json", + "read_only": false + }, + "services": { + "discovery": { + "class": "oidcrp.oidc.provider_info_discovery.ProviderInfoDiscovery", + "kwargs": {} + }, + "registration": { + "class": "oidcrp.oidc.registration.Registration", + "kwargs": {} + }, + "authorization": { + "class": "oidcrp.oidc.authorization.Authorization", + "kwargs": {} + }, + "accesstoken": { + "class": "oidcrp.oidc.access_token.AccessToken", + "kwargs": {} + }, + "userinfo": { + "class": "oidcrp.oidc.userinfo.UserInfo", + "kwargs": {} + }, + "end_session": { + "class": "oidcrp.oidc.end_session.EndSession", + "kwargs": {} + } + }, + "clients": { + "": { + "client_preferences": { + "application_name": "rphandler", + "application_type": "web", + "contacts": [ + "ops@example.com" + ], + "response_types": [ + "code" + ], + "scope": [ + "openid", + "profile", + "email", + "address", + "phone" + ], + "token_endpoint_auth_method": [ + "client_secret_basic", + "client_secret_post" + ] + }, + "redirect_uris": [], + "services": { + "discovery": { + "class": "oidcrp.oidc.provider_info_discovery.ProviderInfoDiscovery", + "kwargs": {} + }, + "registration": { + "class": "oidcrp.oidc.registration.Registration", + "kwargs": {} + }, + "authorization": { + "class": "oidcrp.oidc.authorization.Authorization", + "kwargs": {} + }, + "accesstoken": { + "class": "oidcrp.oidc.access_token.AccessToken", + "kwargs": {} + }, + "userinfo": { + "class": "oidcrp.oidc.userinfo.UserInfo", + "kwargs": {} + }, + "end_session": { + "class": "oidcrp.oidc.end_session.EndSession", + "kwargs": {} + } + } + }, + "flask_provider": { + "client_preferences": { + "application_name": "rphandler", + "application_type": "web", + "contacts": [ + "ops@example.com" + ], + "response_types": [ + "code" + ], + "scope": [ + "openid", + "profile", + "email", + "address", + "phone" + ], + "token_endpoint_auth_method": [ + "client_secret_basic", + "client_secret_post" + ] + }, + "issuer": "https://127.0.0.1:5000/", + "redirect_uris": [ + "https://{domain}:{port}/authz_cb/local" + ], + "post_logout_redirect_uris": [ + "https://{domain}:{port}/session_logout/local" + ], + "frontchannel_logout_uri": "https://{domain}:{port}/fc_logout/local", + "frontchannel_logout_session_required": true, + "backchannel_logout_uri": "https://{domain}:{port}/bc_logout/local", + "backchannel_logout_session_required": true, + "services": { + "discovery": { + "class": "oidcrp.oidc.provider_info_discovery.ProviderInfoDiscovery", + "kwargs": {} + }, + "registration": { + "class": "oidcrp.oidc.registration.Registration", + "kwargs": {} + }, + "authorization": { + "class": "oidcrp.oidc.authorization.Authorization", + "kwargs": {} + }, + "accesstoken": { + "class": "oidcrp.oidc.access_token.AccessToken", + "kwargs": {} + }, + "userinfo": { + "class": "oidcrp.oidc.userinfo.UserInfo", + "kwargs": {} + }, + "end_session": { + "class": "oidcrp.oidc.end_session.EndSession", + "kwargs": {} + } + }, + "add_ons": { + "pkce": { + "function": "oidcrp.oauth2.add_on.pkce.add_support", + "kwargs": { + "code_challenge_length": 64, + "code_challenge_method": "S256" + } + }, + "dpop": { + "function": "oidcrp.oauth2.add_on.dpop.add_support", + "kwargs": { + "signing_algorithms": [ + "ES256", "ES384", "ES512" + ] + } + } + } + } + }, + "webserver": { + "port": 8090, + "domain": "127.0.0.1", + "server_cert": "certs/cert.pem", + "server_key": "certs/key.pem", + "debug": true + } +} diff --git a/src/oidcrp/oauth2/add_on/dpop.py b/src/oidcrp/oauth2/add_on/dpop.py index a13248f..6d3fa8b 100644 --- a/src/oidcrp/oauth2/add_on/dpop.py +++ b/src/oidcrp/oauth2/add_on/dpop.py @@ -151,6 +151,7 @@ def add_support(services, signing_algorithms: Optional[list] = None): :param signing_algorithms: """ + # Access token request should use DPoP header _service = services["accesstoken"] _context = _service.client_get("service_context") _context.add_on['dpop'] = { @@ -158,3 +159,7 @@ def add_support(services, signing_algorithms: Optional[list] = None): "sign_algs": signing_algorithms } _service.construct_extra_headers.append(dpop_header) + + # The same for userinfo requests + _service = services["userinfo"] + _service.construct_extra_headers.append(dpop_header) From 49e94831a40d438096e8ec8a186fd8ea26662e68 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Mon, 7 Jun 2021 17:02:46 +0200 Subject: [PATCH 4/7] Fixed test --- src/oidcrp/oauth2/add_on/dpop.py | 5 +- tests/test_40_dpop.py | 91 +++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/oidcrp/oauth2/add_on/dpop.py b/src/oidcrp/oauth2/add_on/dpop.py index 6d3fa8b..92bd575 100644 --- a/src/oidcrp/oauth2/add_on/dpop.py +++ b/src/oidcrp/oauth2/add_on/dpop.py @@ -161,5 +161,6 @@ def add_support(services, signing_algorithms: Optional[list] = None): _service.construct_extra_headers.append(dpop_header) # The same for userinfo requests - _service = services["userinfo"] - _service.construct_extra_headers.append(dpop_header) + _userinfo_service = services.get("userinfo") + if _userinfo_service: + _userinfo_service.construct_extra_headers.append(dpop_header) diff --git a/tests/test_40_dpop.py b/tests/test_40_dpop.py index fb0955c..ac893d3 100644 --- a/tests/test_40_dpop.py +++ b/tests/test_40_dpop.py @@ -19,7 +19,7 @@ key_defs=KEYSPEC, issuer_id='client_id') -class TestDPoP: +class TestDPoPWithoutUserinfo: @pytest.fixture(autouse=True) def create_client(self): config = { @@ -67,3 +67,92 @@ def test_add_header(self): assert _header["alg"] == "ES256" assert _header["jwk"]["kty"] == "EC" assert _header["jwk"]["crv"] == "P-256" + + +class TestDPoPWithUserinfo: + @pytest.fixture(autouse=True) + def create_client(self): + config = { + 'client_id': 'client_id', + 'client_secret': 'a longesh password', + 'redirect_uris': ['https://example.com/cli/authz_cb'], + 'behaviour': {'response_types': ['code']}, + 'add_ons': { + "dpop": { + "function": "oidcrp.oauth2.add_on.dpop.add_support", + "kwargs": { + "signing_algorithms": ["ES256", "ES512"] + } + } + } + } + + services = { + "discovery": { + 'class': 'oidcrp.oauth2.provider_info_discovery.ProviderInfoDiscovery' + }, + 'authorization': { + 'class': 'oidcrp.oauth2.authorization.Authorization' + }, + 'access_token': { + 'class': 'oidcrp.oauth2.access_token.AccessToken' + }, + 'refresh_access_token': { + 'class': 'oidcrp.oauth2.refresh_access_token.RefreshAccessToken' + }, + 'userinfo': { + 'class': 'oidcrp.oidc.userinfo.UserInfo' + } + } + self.client = Client(keyjar=CLI_KEY, config=config, services=services) + + self.client.client_get("service_context").provider_info = { + "authorization_endpoint": "https://example.com/auth", + "token_endpoint": "https://example.com/token", + "dpop_signing_alg_values_supported": ["RS256", "ES256"], + "userinfo_endpoint": "https://example.com/user", + } + + def test_add_header_token(self): + token_serv = self.client.client_get("service", "accesstoken") + req_args = { + "grant_type": "authorization_code", + "code": "SplxlOBeZQQYbYS6WxSbIA", + "redirect_uri": "https://client/example.com/cb" + } + headers = token_serv.get_headers(request=req_args, http_method="POST") + assert headers + assert "dpop" in headers + + # Now for the content of the DPoP proof + _jws = factory(headers["dpop"]) + _payload = _jws.jwt.payload() + assert _payload["htu"] == "https://example.com/token" + assert _payload["htm"] == "POST" + _header = _jws.jwt.headers + assert "jwk" in _header + assert _header["typ"] == "dpop+jwt" + assert _header["alg"] == "ES256" + assert _header["jwk"]["kty"] == "EC" + assert _header["jwk"]["crv"] == "P-256" + + def test_add_header_userinfo(self): + userinfo_serv = self.client.client_get("service", "userinfo") + req_args = {} + access_token = 'access.token.sign' + headers = userinfo_serv.get_headers(request=req_args, http_method="GET", + access_token=access_token) + assert headers + assert "dpop" in headers + + # Now for the content of the DPoP proof + _jws = factory(headers["dpop"]) + _payload = _jws.jwt.payload() + assert _payload["htu"] == "https://example.com/user" + assert _payload["htm"] == "GET" + _header = _jws.jwt.headers + assert "jwk" in _header + assert _header["typ"] == "dpop+jwt" + assert _header["alg"] == "ES256" + assert _header["jwk"]["kty"] == "EC" + assert _header["jwk"]["crv"] == "P-256" From 06e2e8d09e4003e2641a652cdbb1d0ffd41da916 Mon Sep 17 00:00:00 2001 From: peppelinux Date: Tue, 15 Jun 2021 09:49:03 +0200 Subject: [PATCH 5/7] fix: setup.py - oidcmsg version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 491527c..75a0fe5 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def run_tests(self): "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules"], install_requires=[ - 'oidcmsg==1.3.2', + 'oidcmsg==1.3.3-1', 'pyyaml>=5.1.2', 'responses' ], From 12b3ebc7c61235832a33703ceb1ce1e8aab7ce0a Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Tue, 22 Jun 2021 21:29:52 +0200 Subject: [PATCH 6/7] f string handling --- example/flask_rp/views.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/example/flask_rp/views.py b/example/flask_rp/views.py index f368688..5af68ae 100644 --- a/example/flask_rp/views.py +++ b/example/flask_rp/views.py @@ -80,13 +80,12 @@ def get_rp(op_identifier): except KeyError: logger.error('Unkown issuer: {} not among {}'.format( op_identifier, list(current_app.rph.hash2issuer.keys()))) - return make_response("Unknown hash: {}".format(op_identifier), 400) + return make_response(f"Unknown OP identifier: {op_identifier}", 400) else: try: rp = current_app.rph.issuer2rp[_iss] except KeyError: - return make_response("Couldn't find client for {}".format(_iss), - 400) + return make_response(f"Couldn't find client for issuer: '{_iss}'", 400) return rp From a5f4220c6dafe42bb8b6d299ee9fdf4af2537fa1 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Tue, 22 Jun 2021 21:33:40 +0200 Subject: [PATCH 7/7] Changed version --- src/oidcrp/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oidcrp/__init__.py b/src/oidcrp/__init__.py index 4d3b843..23161e0 100644 --- a/src/oidcrp/__init__.py +++ b/src/oidcrp/__init__.py @@ -1,7 +1,7 @@ import logging __author__ = 'Roland Hedberg' -__version__ = '2.0.0' +__version__ = '2.0.1' logger = logging.getLogger(__name__)