Skip to content
This repository was archived by the owner on Jun 12, 2021. It is now read-only.

Commit 32a2b18

Browse files
committed
With support for reading client registration result on the OP side
we need server support on the client side.
1 parent 68363ea commit 32a2b18

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import logging
2+
3+
from oidcmsg import oidc
4+
from oidcmsg.message import Message
5+
from oidcmsg.oauth2 import ResponseMessage
6+
7+
from oidcservice.service import Service
8+
9+
10+
LOGGER = logging.getLogger(__name__)
11+
12+
13+
class RegistrationRead(Service):
14+
msg_type = Message
15+
response_cls = oidc.RegistrationResponse
16+
error_msg = ResponseMessage
17+
synchronous = True
18+
service_name = 'registration_read'
19+
http_method = 'GET'
20+
default_authn_method = 'client_secret_basic'
21+
22+
def get_endpoint(self):
23+
try:
24+
return self.service_context.registration_response["registration_client_uri"]
25+
except KeyError:
26+
return ''
27+
28+
def get_authn_header(self, request, authn_method, **kwargs):
29+
"""
30+
Construct an authorization specification to be sent in the
31+
HTTP header.
32+
33+
:param request: The service request
34+
:param authn_method: Which authentication/authorization method to use
35+
:param kwargs: Extra keyword arguments
36+
:return: A set of keyword arguments to be sent in the HTTP header.
37+
"""
38+
headers = {}
39+
40+
if authn_method == "client_secret_basic":
41+
LOGGER.debug("Client authn method: %s", authn_method)
42+
headers["Authorization"] = "Bearer {}".format(
43+
self.service_context.registration_response["registration_access_token"]
44+
)
45+
46+
return headers

tests/test_17_read_registration.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import json
2+
import time
3+
4+
import pytest
5+
import requests
6+
import responses
7+
from cryptojwt.utils import as_bytes
8+
from oidcmsg.oidc import RegistrationResponse
9+
10+
from oidcservice.service_context import ServiceContext
11+
from oidcservice.service_factory import service_factory
12+
13+
ISS = "https://example.com"
14+
RP_BASEURL = "https://example.com/rp"
15+
16+
17+
class TestRegistrationRead(object):
18+
@pytest.fixture(autouse=True)
19+
def create_request(self):
20+
self._iss = ISS
21+
client_config = {
22+
"redirect_uris": ["https://example.com/cli/authz_cb"],
23+
"issuer": self._iss, "requests_dir": "requests",
24+
"base_url": "https://example.com/cli/",
25+
"client_preferences": {
26+
"application_type": "web",
27+
"response_types": ["code"],
28+
"contacts": ["[email protected]"],
29+
"jwks_uri": "https://example.com/rp/static/jwks.json",
30+
"redirect_uris": ["{}/authz_cb".format(RP_BASEURL)],
31+
"token_endpoint_auth_method": "client_secret_basic",
32+
"grant_types": ["authorization_code"]
33+
}
34+
}
35+
service_context = ServiceContext(config=client_config)
36+
self.reg_service = service_factory("Registration", ["oidc"], state_db=None,
37+
service_context=service_context)
38+
self.read_service = service_factory("RegistrationRead", ["oidc"], state_db=None,
39+
service_context=service_context)
40+
41+
def test_construct(self):
42+
self.reg_service.endpoint = "{}/registration".format(ISS)
43+
44+
_param = self.reg_service.get_request_parameters()
45+
46+
now = int(time.time())
47+
48+
_client_registration_response = json.dumps({
49+
"client_id": "zls2qhN1jO6A",
50+
"client_secret": "c8434f28cf9375d9a7",
51+
"registration_access_token": "NdGrGR7LCuzNtixvBFnDphGXv7wRcONn",
52+
"registration_client_uri": "{}/registration_api?client_id=zls2qhN1jO6A".format(ISS),
53+
"client_secret_expires_at": now + 3600,
54+
"client_id_issued_at": now,
55+
"application_type": "web",
56+
"response_types": ["code"],
57+
"contacts": ["[email protected]"],
58+
"redirect_uris": ["{}/authz_cb".format(RP_BASEURL)],
59+
"token_endpoint_auth_method": "client_secret_basic",
60+
"grant_types": ["authorization_code"]
61+
})
62+
63+
with responses.RequestsMock() as rsps:
64+
rsps.add(_param["method"], _param["url"], body=_client_registration_response, status=200)
65+
_resp = requests.request(
66+
_param["method"], _param["url"],
67+
data=as_bytes(_param["body"]),
68+
headers=_param["headers"],
69+
verify=False
70+
)
71+
72+
resp = self.reg_service.parse_response(_resp.text)
73+
self.reg_service.update_service_context(resp)
74+
75+
assert resp
76+
77+
_read_param = self.read_service.get_request_parameters()
78+
with responses.RequestsMock() as rsps:
79+
rsps.add(_param["method"], _param["url"], body=_client_registration_response,
80+
adding_headers={"Content-Type": "application/json"}, status=200)
81+
_resp = requests.request(
82+
_param["method"],
83+
_param["url"],
84+
headers=_param["headers"],
85+
verify=False
86+
)
87+
88+
read_resp = self.reg_service.parse_response(_resp.text)
89+
assert isinstance(read_resp, RegistrationResponse)

0 commit comments

Comments
 (0)