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

Commit 85d09e4

Browse files
committed
Added more tests.
As a consequence some code changes was made.
1 parent 9997f59 commit 85d09e4

10 files changed

Lines changed: 359 additions & 133 deletions

File tree

chrp/rp.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
#!/usr/bin/env python3
2+
import cherrypy
23
import importlib
3-
import json
44
import logging
55
import os
66
import sys
77

8-
import cherrypy
9-
10-
from oidcmsg.key_jar import build_keyjar, init_key_jar
11-
from oidcmsg.key_jar import KeyJar
8+
from cryptojwt.key_jar import init_key_jar
129

1310
from oidcrp import RPHandler
1411

@@ -22,6 +19,7 @@
2219
logger.addHandler(hdlr)
2320
logger.setLevel(logging.DEBUG)
2421

22+
2523
SIGKEY_NAME = 'sigkey.jwks'
2624

2725

src/oidcrp/__init__.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ def load_registration_response(client):
7070
7171
:param client: A :py:class:`oidcservice.oidc.Client` instance
7272
"""
73-
try:
74-
_client_reg = client.service_context.config['registration_response']
75-
except KeyError:
73+
if not client.service_context.client_id:
7674
try:
7775
response = client.do_request('registration')
7876
except KeyError:
@@ -83,8 +81,6 @@ def load_registration_response(client):
8381
else:
8482
if 'error' in response:
8583
raise OidcServiceError(response.to_json())
86-
else:
87-
client.service_context.registration_info = _client_reg
8884

8985

9086
def dynamic_provider_info_discovery(client):
@@ -114,7 +110,7 @@ class RPHandler(object):
114110
def __init__(self, base_url='', hash_seed="", keyjar=None, verify_ssl=True,
115111
services=None, service_factory=None, client_configs=None,
116112
client_authn_factory=None, client_cls=None,
117-
state_db=None, **kwargs):
113+
state_db=None, http_lib=None, **kwargs):
118114
self.base_url = base_url
119115
self.hash_seed = as_bytes(hash_seed)
120116
self.verify_ssl = verify_ssl
@@ -143,6 +139,7 @@ def __init__(self, base_url='', hash_seed="", keyjar=None, verify_ssl=True,
143139
# keep track on which RP instance that serves with OP
144140
self.issuer2rp = {}
145141
self.hash2issuer = {}
142+
self.httplib = http_lib
146143

147144
def supports_webfinger(self):
148145
"""
@@ -209,7 +206,9 @@ def init_client(self, issuer):
209206
state_db=self.state_db,
210207
client_authn_factory=self.client_authn_factory,
211208
verify_ssl=self.verify_ssl, services=_services,
212-
service_factory=self.service_factory, config=_cnf)
209+
service_factory=self.service_factory, config=_cnf,
210+
httplib=self.httplib
211+
)
213212
except Exception as err:
214213
logger.error('Failed initiating client: {}'.format(err))
215214
message = traceback.format_exception(*sys.exc_info())
@@ -413,7 +412,7 @@ def begin(self, issuer_id='', user_id=''):
413412

414413
try:
415414
res = self.init_authorization(client)
416-
except Exception as err:
415+
except Exception:
417416
message = traceback.format_exception(*sys.exc_info())
418417
logger.error(message)
419418
raise

src/oidcrp/http.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import copy
22
import logging
3+
import requests
4+
35
from http.cookiejar import FileCookieJar
46
from http.cookies import CookieError
57
from http.cookies import SimpleCookie
68

7-
import requests
8-
9-
from cryptojwt.key_jar import KeyJar
10-
119
from oidcservice import sanitize
1210
from oidcservice.exception import NonFatalException
1311

@@ -19,23 +17,19 @@
1917

2018

2119
class HTTPLib(object):
22-
def __init__(self, ca_certs=None, verify_ssl=True, keyjar=None,
23-
client_cert=None):
20+
def __init__(self, ca_certs=None, verify_ssl=True, client_cert=None):
2421
"""
2522
A base class for OAuth2 clients and servers
2623
2724
:param ca_certs: the path to a CA_BUNDLE file or directory with
2825
certificates of trusted CAs
2926
:param verify_ssl: If True then the server SSL certificate is not
3027
verfied
31-
:param keyjar: A place to keep keys for signing/encrypting messages
3228
:param client_cert: local cert to use as client side certificate, as a
3329
single file (containing the private key and the certificate) or as
3430
a tuple of both file's path
3531
"""
3632

37-
self.keyjar = keyjar or KeyJar(verify_ssl=verify_ssl)
38-
3933
self.request_args = {"allow_redirects": False}
4034

4135
self.cookiejar = FileCookieJar()
@@ -143,11 +137,3 @@ def send(self, url, method="GET", **kwargs):
143137
:return: Request response
144138
"""
145139
return self(url, method, **kwargs)
146-
147-
def load_cookies_from_file(self, filename, ignore_discard=False,
148-
ignore_expires=False):
149-
self.cookiejar.load(filename, ignore_discard, ignore_expires)
150-
151-
def save_cookies_to_file(self, filename, ignore_discard=False,
152-
ignore_expires=False):
153-
self.cookiejar.save(filename, ignore_discard, ignore_expires)

src/oidcrp/oauth2/__init__.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import cherrypy
44

55
from cryptojwt.key_jar import KeyJar
6+
from oidcmsg.exception import FormatError
67

78
from oidcservice.client_auth import factory as ca_factory
89
from oidcservice.exception import OidcServiceError
@@ -65,8 +66,7 @@ def __init__(self, state_db, ca_certs=None, client_authn_factory=None,
6566
self.session_interface = StateInterface(state_db)
6667
self.http = httplib or HTTPLib(ca_certs=ca_certs,
6768
verify_ssl=verify_ssl,
68-
client_cert=client_cert,
69-
keyjar=keyjar)
69+
client_cert=client_cert)
7070

7171
if not keyjar:
7272
keyjar = KeyJar()
@@ -90,16 +90,6 @@ def __init__(self, state_db, ca_certs=None, client_authn_factory=None,
9090

9191
self.verify_ssl = verify_ssl
9292

93-
def construct(self, request_type, request_args=None, extra_args=None,
94-
**kwargs):
95-
try:
96-
self.service[request_type]
97-
except KeyError:
98-
raise NotImplemented(request_type)
99-
100-
method = getattr(self, 'construct_{}_request'.format(request_type))
101-
return method(self.service_context, request_args, extra_args, **kwargs)
102-
10393
def do_request(self, request_type, response_body_type="", request_args=None,
10494
**kwargs):
10595

@@ -222,12 +212,12 @@ def parse_request_response(self, service, reqresp, response_body_type='',
222212

223213
try:
224214
err_resp = service.parse_response(reqresp.text, _deser_method)
225-
except OidcServiceError:
215+
except FormatError:
226216
if _deser_method != response_body_type:
227217
try:
228218
err_resp = service.parse_response(reqresp.text,
229219
response_body_type)
230-
except OidcServiceError:
220+
except (OidcServiceError, FormatError):
231221
raise cherrypy.HTTPError("HTTP ERROR: %s [%s] on %s" % (
232222
reqresp.text, reqresp.status_code, reqresp.url))
233223
else:

src/oidcrp/util.py

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -122,25 +122,6 @@ def set_cookie(cookiejar, kaka):
122122
cookiejar.set_cookie(new_cookie)
123123

124124

125-
def get_response_body_type(response):
126-
try:
127-
_ctype = response.headers["content-type"]
128-
except KeyError:
129-
raise ValueError('Missing Content-type specification')
130-
131-
body_type = ''
132-
133-
if match_to_("application/json", _ctype) or match_to_(
134-
'application/jrd+json', _ctype):
135-
body_type = 'json'
136-
elif match_to_("application/jwt", _ctype):
137-
body_type = "jwt"
138-
elif match_to_(URL_ENCODED, _ctype):
139-
body_type = 'urlencoded'
140-
141-
return body_type
142-
143-
144125
def verify_header(reqresp, body_type):
145126
"""
146127
@@ -215,7 +196,7 @@ def get_deserialization_method(reqresp):
215196
try:
216197
_ctype = reqresp.headers["content-type"]
217198
except KeyError:
218-
return 'txt' # reasonable default ??
199+
return 'urlencoded' # reasonable default ??
219200

220201
if match_to_("application/json", _ctype) or match_to_(
221202
'application/jrd+json', _ctype):
@@ -232,21 +213,21 @@ def get_deserialization_method(reqresp):
232213
return deser_method
233214

234215

235-
SORT_ORDER = {'RS': 0, 'ES': 1, 'HS': 2, 'PS': 3, 'no': 4}
236-
237-
238-
def sort_sign_alg(alg1, alg2):
239-
if SORT_ORDER[alg1[0:2]] < SORT_ORDER[alg2[0:2]]:
240-
return -1
241-
elif SORT_ORDER[alg1[0:2]] > SORT_ORDER[alg2[0:2]]:
242-
return 1
243-
else:
244-
if alg1 < alg2:
245-
return -1
246-
elif alg1 > alg2:
247-
return 1
248-
else:
249-
return 0
216+
# SORT_ORDER = {'RS': 0, 'ES': 1, 'HS': 2, 'PS': 3, 'no': 4}
217+
#
218+
#
219+
# def sort_sign_alg(alg1, alg2):
220+
# if SORT_ORDER[alg1[0:2]] < SORT_ORDER[alg2[0:2]]:
221+
# return -1
222+
# elif SORT_ORDER[alg1[0:2]] > SORT_ORDER[alg2[0:2]]:
223+
# return 1
224+
# else:
225+
# if alg1 < alg2:
226+
# return -1
227+
# elif alg1 > alg2:
228+
# return 1
229+
# else:
230+
# return 0
250231

251232

252233
def get_value_type(http_response, body_type):

tests/test_01_base.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from oidcrp import add_path
2+
from oidcrp import load_registration_response
3+
from oidcrp.oidc import RP
4+
5+
6+
class DB(object):
7+
def __init__(self):
8+
self.db = {}
9+
10+
def set(self, key, value):
11+
self.db[key] = value
12+
13+
def get(self, item):
14+
return self.db[item]
15+
16+
17+
def test_add_path():
18+
assert add_path('https://example.com/', '/usr') == 'https://example.com/usr'
19+
assert add_path('https://example.com/', 'usr') == 'https://example.com/usr'
20+
assert add_path('https://example.com', '/usr') == 'https://example.com/usr'
21+
assert add_path('https://example.com', 'usr') == 'https://example.com/usr'
22+
23+
24+
def test_load_registration_response():
25+
conf = {
26+
'redirect_uris': ['https://example.com/cli/authz_cb'],
27+
'client_id': 'client_1',
28+
'client_secret': 'abcdefghijklmnop',
29+
'registration_response': {'issuer': 'https://example.com'}
30+
}
31+
client = RP(DB(), config=conf)
32+
33+
# test static
34+
load_registration_response(client)
35+
assert True

tests/test_03_util.py

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from urllib.parse import parse_qs
77
from urllib.parse import urlparse
88

9-
9+
from oidcrp.util import get_deserialization_method, URL_ENCODED
1010
from oidcservice.exception import WrongContentType
1111

1212
from oidcrp import util
@@ -101,12 +101,13 @@ def test_match_to():
101101
assert not util.match_to_(str3, list_of_str)
102102

103103

104-
def test_verify_header():
105-
class FakeResponse():
106-
def __init__(self, header):
107-
self.headers = {"content-type": header}
108-
self.text = "TEST_RESPONSE"
104+
class FakeResponse():
105+
def __init__(self, header):
106+
self.headers = {"content-type": header}
107+
self.text = "TEST_RESPONSE"
108+
109109

110+
def test_verify_header():
110111
json_header = "application/json"
111112
jwt_header = "application/jwt"
112113
default_header = util.DEFAULT_POST_CONTENT_TYPE
@@ -120,6 +121,15 @@ def __init__(self, header):
120121
"urlencoded") == "urlencoded"
121122
assert util.verify_header(FakeResponse(plain_text_header),
122123
"urlencoded") == "urlencoded"
124+
assert util.verify_header(FakeResponse('text/html'), 'txt')
125+
assert util.verify_header(FakeResponse('text/plain'), 'txt')
126+
127+
assert util.verify_header(FakeResponse(json_header), "") == "json"
128+
assert util.verify_header(FakeResponse(jwt_header), "") == "jwt"
129+
assert util.verify_header(FakeResponse(jwt_header), "") == "jwt"
130+
assert util.verify_header(FakeResponse(default_header), "") == "urlencoded"
131+
assert util.verify_header(FakeResponse(plain_text_header), "") == "txt"
132+
assert util.verify_header(FakeResponse('text/html'), '') == 'txt'
123133

124134
with pytest.raises(WrongContentType):
125135
util.verify_header(FakeResponse(json_header), "urlencoded")
@@ -130,3 +140,38 @@ def __init__(self, header):
130140

131141
with pytest.raises(ValueError):
132142
util.verify_header(FakeResponse(json_header), "undefined")
143+
144+
145+
def test_get_deserialization_method_json():
146+
resp = FakeResponse("application/json")
147+
assert get_deserialization_method(resp) == 'json'
148+
149+
resp = FakeResponse("application/json; charset=utf-8")
150+
assert get_deserialization_method(resp) == 'json'
151+
152+
resp.headers["content-type"] = "application/jrd+json"
153+
assert get_deserialization_method(resp) == 'json'
154+
155+
156+
def test_get_deserialization_method_jwt():
157+
resp = FakeResponse("application/jwt")
158+
assert get_deserialization_method(resp) == 'jwt'
159+
160+
161+
def test_get_deserialization_method_urlencoded():
162+
resp = FakeResponse(URL_ENCODED)
163+
assert get_deserialization_method(resp) == 'urlencoded'
164+
165+
166+
def test_get_deserialization_method_text():
167+
resp = FakeResponse('text/html')
168+
assert get_deserialization_method(resp) == ''
169+
170+
resp = FakeResponse('text/plain')
171+
assert get_deserialization_method(resp) == ''
172+
173+
174+
def test_verify_no_content_type():
175+
resp = FakeResponse('text/html')
176+
del resp.headers['content-type']
177+
assert util.verify_header(resp, 'txt') == 'txt'

0 commit comments

Comments
 (0)