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

Commit 5128963

Browse files
committed
Honor scopes_supported.
1 parent c522ce0 commit 5128963

File tree

2 files changed

+133
-40
lines changed

2 files changed

+133
-40
lines changed

src/oidcendpoint/userinfo.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def by_schema(cls, **kwa):
103103

104104

105105
def collect_user_info(
106-
endpoint_context, session, userinfo_claims=None, scope_to_claims=None
106+
endpoint_context, session, userinfo_claims=None, scope_to_claims=None
107107
):
108108
"""
109109
Collect information about a user.
@@ -118,8 +118,11 @@ def collect_user_info(
118118
if scope_to_claims is None:
119119
scope_to_claims = endpoint_context.scope2claims
120120

121+
supported_scopes = [s for s in authn_req["scope"] if
122+
s in endpoint_context.provider_info["scopes_supported"]]
123+
121124
if userinfo_claims is None:
122-
uic = scope2claims(authn_req["scope"], map=scope_to_claims)
125+
uic = scope2claims(supported_scopes, map=scope_to_claims)
123126

124127
# Get only keys allowed by user and update the dict if such info
125128
# is stored in session

tests/test_07_userinfo.py

Lines changed: 128 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import json
22
import os
33

4+
import pytest
5+
46
from oidcendpoint.authn_event import create_authn_event
57
from oidcendpoint.endpoint_context import EndpointContext
8+
from oidcendpoint.oidc.authorization import Authorization
9+
from oidcendpoint.oidc.provider_config import ProviderConfiguration
10+
from oidcendpoint.oidc.registration import Registration
611
from oidcendpoint.user_authn.authn_context import INTERNETPROTOCOLPASSWORD
712
from oidcendpoint.user_info import SCOPE2CLAIMS
813
from oidcendpoint.user_info import UserInfo
@@ -39,6 +44,17 @@
3944
claims=CLAIMS,
4045
)
4146

47+
RESPONSE_TYPES_SUPPORTED = [
48+
["code"],
49+
["token"],
50+
["id_token"],
51+
["code", "token"],
52+
["code", "id_token"],
53+
["id_token", "token"],
54+
["code", "token", "id_token"],
55+
["none"],
56+
]
57+
4258
BASEDIR = os.path.abspath(os.path.dirname(__file__))
4359

4460

@@ -193,44 +209,118 @@ def test_by_schema():
193209
]
194210

195211

196-
def test_collect_user_info():
197-
_session_info = {"authn_req": OIDR}
198-
session = _session_info.copy()
199-
session["sub"] = "doe"
200-
session["uid"] = "diana"
201-
session["authn_event"] = create_authn_event("diana", "salt")
202-
203-
endpoint_context = EndpointContext(
204-
{
205-
"userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_DB}},
206-
"password": "we didn't start the fire",
207-
"issuer": "https://example.com/op",
208-
"token_expires_in": 900,
209-
"grant_expires_in": 600,
210-
"refresh_token_expires_in": 86400,
211-
"endpoint": {},
212-
"jwks": {
213-
"public_path": "jwks.json",
214-
"key_defs": KEYDEFS,
215-
"uri_path": "static/jwks.json",
216-
},
217-
"authentication": {
218-
"anon": {
219-
"acr": INTERNETPROTOCOLPASSWORD,
220-
"class": "oidcendpoint.user_authn.user.NoAuthn",
221-
"kwargs": {"user": "diana"},
222-
}
223-
},
224-
"template_dir": "template",
212+
class TestCollectUserInfo:
213+
@pytest.fixture(autouse=True)
214+
def create_endpoint_context(self):
215+
self.endpoint_context = EndpointContext(
216+
{
217+
"userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_DB}},
218+
"password": "we didn't start the fire",
219+
"issuer": "https://example.com/op",
220+
"token_expires_in": 900,
221+
"grant_expires_in": 600,
222+
"refresh_token_expires_in": 86400,
223+
"endpoint": {
224+
"provider_config": {
225+
"path": "{}/.well-known/openid-configuration",
226+
"class": ProviderConfiguration,
227+
"kwargs": {},
228+
},
229+
"registration": {
230+
"path": "{}/registration",
231+
"class": Registration,
232+
"kwargs": {},
233+
},
234+
"authorization": {
235+
"path": "{}/authorization",
236+
"class": Authorization,
237+
"kwargs": {
238+
"response_types_supported": [
239+
" ".join(x) for x in RESPONSE_TYPES_SUPPORTED
240+
],
241+
"response_modes_supported": ["query", "fragment", "form_post"],
242+
"claims_parameter_supported": True,
243+
"request_parameter_supported": True,
244+
"request_uri_parameter_supported": True,
245+
},
246+
},
247+
},
248+
"jwks": {
249+
"public_path": "jwks.json",
250+
"key_defs": KEYDEFS,
251+
"uri_path": "static/jwks.json",
252+
},
253+
"authentication": {
254+
"anon": {
255+
"acr": INTERNETPROTOCOLPASSWORD,
256+
"class": "oidcendpoint.user_authn.user.NoAuthn",
257+
"kwargs": {"user": "diana"},
258+
}
259+
},
260+
"template_dir": "template",
261+
}
262+
)
263+
264+
def test_collect_user_info(self):
265+
_session_info = {"authn_req": OIDR}
266+
session = _session_info.copy()
267+
session["sub"] = "doe"
268+
session["uid"] = "diana"
269+
session["authn_event"] = create_authn_event("diana", "salt")
270+
271+
res = collect_user_info(self.endpoint_context, session)
272+
273+
assert res == {
274+
"given_name": "Diana",
275+
"nickname": "Dina",
276+
"sub": "doe",
277+
"email": "diana@example.org",
278+
"email_verified": False,
279+
}
280+
281+
def test_collect_user_info_2(self):
282+
_req = OIDR.copy()
283+
_req["scope"] = "openid email"
284+
del _req["claims"]
285+
286+
_session_info = {"authn_req": _req}
287+
session = _session_info.copy()
288+
session["sub"] = "doe"
289+
session["uid"] = "diana"
290+
session["authn_event"] = create_authn_event("diana", "salt")
291+
292+
self.endpoint_context.provider_info["scopes_supported"] = [
293+
"openid", "email", "offline_access"
294+
]
295+
res = collect_user_info(self.endpoint_context, session)
296+
297+
assert res == {
298+
"sub": "doe",
299+
"email": "diana@example.org",
300+
"email_verified": False,
301+
}
302+
303+
def test_collect_user_info_scope_not_supported(self):
304+
_req = OIDR.copy()
305+
_req["scope"] = "openid email address"
306+
del _req["claims"]
307+
308+
_session_info = {"authn_req": _req}
309+
session = _session_info.copy()
310+
session["sub"] = "doe"
311+
session["uid"] = "diana"
312+
session["authn_event"] = create_authn_event("diana", "salt")
313+
314+
# Scope address not supported
315+
self.endpoint_context.provider_info["scopes_supported"] = [
316+
"openid", "email", "offline_access"
317+
]
318+
res = collect_user_info(self.endpoint_context, session)
319+
320+
assert res == {
321+
"sub": "doe",
322+
"email": "diana@example.org",
323+
"email_verified": False,
225324
}
226-
)
227325

228-
res = collect_user_info(endpoint_context, session)
229326

230-
assert res == {
231-
"given_name": "Diana",
232-
"nickname": "Dina",
233-
"sub": "doe",
234-
"email": "diana@example.org",
235-
"email_verified": False,
236-
}

0 commit comments

Comments
 (0)