Skip to content

Commit cfd0b6e

Browse files
schlenkMichael Schlenker
andauthored
Repair some oauth_examples and get rid of the outdated jquery file (CZ-NIC#857)
* More cleanup * Add oauth_example to quality checks Signed-off-by: Michael Schlenker <michael.schlenker@contact-software.com> * Update CHANGELOG.md --------- Signed-off-by: Michael Schlenker <michael.schlenker@contact-software.com> Co-authored-by: Michael Schlenker <michael.schlenker@contact-software.com>
1 parent 444bd68 commit cfd0b6e

15 files changed

Lines changed: 242 additions & 314 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ oidc_example/op1/client_db.db
4747
oidc_example/op1/oc_config.py
4848
oidc_example/rp3/conf.py
4949
oidc_example/rp3/modules/
50+
oauth_example/rp/modules/
51+
oauth_example/as/modules/
52+
oauth_example/as/static/jwks.json
53+
oauth_example/as/client_db.*
5054
update

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ The format is based on the [KeepAChangeLog] project.
1313
- [#847] Using pydantic for settings instead of custom class
1414
- [#851], [#852] Add `authn_method` to `Consumer.complete`
1515

16+
## Fixed
17+
- [#857] Made oauth_example less broken
18+
1619
[#847]: https://github.com/CZ-NIC/pyoidc/pull/847
1720
[#851]: https://github.com/CZ-NIC/pyoidc/issues/851
1821
[#852]: https://github.com/CZ-NIC/pyoidc/pull/852
22+
[#857]: https://github.com/CZ-NIC/pyoidc/pull/857
1923

2024
## 1.5.0 [2022-12-14]
2125

Makefile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ BUILDDIR = doc/_build
77
DOCDIR = doc/
88
OICDIR = src/oic
99
TESTDIR = tests
10+
OAUTH_EXAMPLE = oauth_example
11+
1012

1113
help:
1214
@echo "Please use \`make <target>' where <target> is one of"
@@ -43,25 +45,25 @@ test:
4345
.PHONY: test
4446

4547
isort:
46-
@pipenv run isort $(OICDIR) $(TESTDIR)
48+
@pipenv run isort $(OICDIR) $(TESTDIR) $(OAUTH_EXAMPLE)
4749

4850
check-isort:
49-
@pipenv run isort --diff --check-only $(OICDIR) $(TESTDIR)
51+
@pipenv run isort --diff --check-only $(OICDIR) $(TESTDIR) $(OAUTH_EXAMPLE)
5052
.PHONY: isort check-isort
5153

5254
blacken:
53-
@pipenv run black src/ tests/
55+
@pipenv run black src/ tests/ oauth_example/
5456

5557
check-black:
56-
@pipenv run black src/ tests/ --check
58+
@pipenv run black src/ tests/ oauth_example/ --check
5759
.PHONY: blacken check-black
5860

5961
bandit:
6062
@pipenv run bandit -a file -r src/ oauth_example/ oidc_example/
6163
.PHONY: bandit
6264

6365
check-pylama:
64-
@pipenv run pylama $(OICDIR) $(TESTDIR)
66+
@pipenv run pylama $(OICDIR) $(TESTDIR) $(OAUTH_EXAMPLE)
6567
.PHONY: check-pylama
6668

6769
release:

oauth_example/as/as.py

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"""
55
import json
66
import logging
7+
import os
78
import re
89
import sys
910
import traceback
1011

12+
import cherrypy
1113
from authn_setup import authn_setup
12-
from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter
13-
from otest import as_unicode
1414
from requests.packages import urllib3
1515

1616
from oic.extension.provider import IntrospectionEndpoint
@@ -30,23 +30,22 @@
3030

3131
urllib3.disable_warnings()
3232

33-
__author__ = 'roland'
33+
__author__ = "roland"
3434

3535
# ============================================================================
3636
# First define how logging is supposed to be done
3737
# ============================================================================
3838

3939
LOGGER = logging.getLogger("")
40-
LOGFILE_NAME = 'oauth2_as.log'
40+
LOGFILE_NAME = "oauth2_as.log"
4141
hdlr = logging.FileHandler(LOGFILE_NAME)
42-
base_formatter = logging.Formatter(
43-
"%(asctime)s %(name)s:%(levelname)s %(message)s")
42+
base_formatter = logging.Formatter("%(asctime)s %(name)s:%(levelname)s %(message)s")
4443

4544
hdlr.setFormatter(base_formatter)
4645
LOGGER.addHandler(hdlr)
4746
LOGGER.setLevel(logging.INFO)
4847

49-
JWKS_FILE_NAME = "static/jwks.json"
48+
JWKS_FILE_NAME = os.path.join(os.path.dirname(__file__), "static/jwks.json")
5049

5150

5251
# ---------------------------------------------------------------------------
@@ -57,20 +56,21 @@ def static(environ, start_response, path):
5756
LOGGER.info("[static]sending: %s" % (path,))
5857

5958
try:
60-
text = open(path, 'rb').read()
59+
with open(path, "rb") as fd:
60+
content = fd.read()
6161
if path.endswith(".ico"):
62-
start_response('200 OK', [('Content-Type', "image/x-icon")])
62+
start_response("200 OK", [("Content-Type", "image/x-icon")])
6363
elif path.endswith(".html"):
64-
start_response('200 OK', [('Content-Type', 'text/html')])
64+
start_response("200 OK", [("Content-Type", "text/html")])
6565
elif path.endswith(".json"):
66-
start_response('200 OK', [('Content-Type', 'application/json')])
66+
start_response("200 OK", [("Content-Type", "application/json")])
6767
elif path.endswith(".txt"):
68-
start_response('200 OK', [('Content-Type', 'text/plain')])
68+
start_response("200 OK", [("Content-Type", "text/plain")])
6969
elif path.endswith(".css"):
70-
start_response('200 OK', [('Content-Type', 'text/css')])
70+
start_response("200 OK", [("Content-Type", "text/css")])
7171
else:
72-
start_response('200 OK', [('Content-Type', "text/xml")])
73-
return [text]
72+
start_response("200 OK", [("Content-Type", "text/xml")])
73+
return [content]
7474
except IOError:
7575
resp = NotFound()
7676
return resp(environ, start_response)
@@ -90,12 +90,12 @@ def __init__(self, oas):
9090
TokenEndpoint(self.token),
9191
RegistrationEndpoint(self.registration),
9292
IntrospectionEndpoint(self.introspection),
93-
RevocationEndpoint(self.revocation)
93+
RevocationEndpoint(self.revocation),
9494
]
9595

9696
self.urls = [
97-
(r'^verify', self.verify),
98-
(r'.well-known/openid-configuration', self.config)
97+
(r"^verify", self.verify),
98+
(r".well-known/openid-configuration", self.config),
9999
]
100100

101101
for endp in self.endpoints:
@@ -111,28 +111,23 @@ def token(self, environ, start_response):
111111

112112
# noinspection PyUnusedLocal
113113
def authorization(self, environ, start_response):
114-
return wsgi_wrapper(environ, start_response,
115-
self.oas.authorization_endpoint)
114+
return wsgi_wrapper(environ, start_response, self.oas.authorization_endpoint)
116115

117116
# noinspection PyUnusedLocal
118117
def config(self, environ, start_response):
119-
return wsgi_wrapper(environ, start_response,
120-
self.oas.providerinfo_endpoint)
118+
return wsgi_wrapper(environ, start_response, self.oas.providerinfo_endpoint)
121119

122120
# noinspection PyUnusedLocal
123121
def registration(self, environ, start_response):
124-
return wsgi_wrapper(environ, start_response,
125-
self.oas.registration_endpoint)
122+
return wsgi_wrapper(environ, start_response, self.oas.registration_endpoint)
126123

127124
# noinspection PyUnusedLocal
128125
def introspection(self, environ, start_response):
129-
return wsgi_wrapper(environ, start_response,
130-
self.oas.introspection_endpoint)
126+
return wsgi_wrapper(environ, start_response, self.oas.introspection_endpoint)
131127

132128
# noinspection PyUnusedLocal
133129
def revocation(self, environ, start_response):
134-
return wsgi_wrapper(environ, start_response,
135-
self.oas.revocation_endpoint)
130+
return wsgi_wrapper(environ, start_response, self.oas.revocation_endpoint)
136131

137132
def application(self, environ, start_response):
138133
"""
@@ -149,8 +144,7 @@ def application(self, environ, start_response):
149144
:return: The response as a list of lines
150145
"""
151146

152-
# user = environ.get("REMOTE_USER", "")
153-
path = environ.get('PATH_INFO', '').lstrip('/')
147+
path = environ.get("PATH_INFO", "").lstrip("/")
154148

155149
LOGGER.info("path: %s" % path)
156150
if path == "robots.txt":
@@ -163,9 +157,9 @@ def application(self, environ, start_response):
163157
match = re.search(regex, path)
164158
if match is not None:
165159
try:
166-
environ['oic.url_args'] = match.groups()[0]
160+
environ["oic.url_args"] = match.groups()[0]
167161
except IndexError:
168-
environ['oic.url_args'] = path
162+
environ["oic.url_args"] = path
169163

170164
LOGGER.debug("callback: %s" % callback)
171165
try:
@@ -191,24 +185,23 @@ def application(self, environ, start_response):
191185

192186
if __name__ == "__main__":
193187
import argparse
194-
import shelve # nosec
195188
import importlib
196-
197-
from cherrypy import wsgiserver
189+
import shelve # nosec
198190

199191
# This is where session information is stored
200192
# This serve is stateful.
201193
from oic import rndstr
202-
from oic.utils.sdb import SessionDB, DefaultToken
194+
from oic.utils.sdb import DefaultToken
195+
from oic.utils.sdb import SessionDB
203196

204197
# Parse the command arguments
205198
parser = argparse.ArgumentParser()
206-
parser.add_argument('-d', dest='debug', action='store_true')
207-
parser.add_argument('-k', dest='insecure', action='store_true')
208-
parser.add_argument('-p', dest='port', default=80, type=int)
199+
parser.add_argument("-d", dest="debug", action="store_true")
200+
parser.add_argument("-k", dest="insecure", action="store_true")
201+
parser.add_argument("-p", dest="port", default=80, type=int)
209202
# Who it should report as being responsible for the authentication
210-
parser.add_argument('-A', dest='authn_as', default="")
211-
parser.add_argument('-c', dest='conf_path')
203+
parser.add_argument("-A", dest="authn_as", default="")
204+
parser.add_argument("-c", dest="conf_path")
212205
parser.add_argument(dest="config")
213206
args = parser.parse_args()
214207

@@ -247,47 +240,67 @@ def application(self, environ, start_response):
247240
capabilities = None
248241

249242
if args.insecure:
250-
kwargs = {'verify_ssl': False}
243+
kwargs = {"verify_ssl": False}
251244
else:
252245
kwargs = {}
253246

254247
# Initiate the Provider
255-
oas = Provider(config.issuer, None, cdb, broker, authz,
256-
baseurl=config.issuer, client_authn=verify_client,
257-
symkey=config.SYM_KEY, hostname=config.HOST,
258-
capabilities=capabilities,
259-
behavior=config.BEHAVIOR, **kwargs)
248+
oas = Provider(
249+
config.issuer,
250+
None,
251+
cdb,
252+
broker,
253+
authz,
254+
baseurl=config.issuer,
255+
client_authn=verify_client,
256+
symkey=config.SYM_KEY,
257+
hostname=config.HOST,
258+
capabilities=capabilities,
259+
behavior=config.BEHAVIOR,
260+
**kwargs
261+
)
260262

261263
try:
262264
jwks = keyjar_init(oas, config.keys, kid_template="op%d")
263265
except Exception as err:
264266
LOGGER.error("Key setup failed: {}".format(err))
265267
print("Key setup failed: {}".format(err))
266268
exit()
267-
# oas.key_setup("static", sig={"format": "jwk", "alg": "rsa"})
268269
else:
269270
jwks_file_name = JWKS_FILE_NAME
270-
f = open(jwks_file_name, "w")
271271

272-
for key in jwks["keys"]:
273-
for k in key.keys():
274-
key[k] = as_unicode(key[k])
272+
with open(jwks_file_name, "w") as f:
273+
for key in jwks["keys"]:
274+
for k in key.keys():
275+
key[k] = key[k]
276+
f.write(json.dumps(jwks))
275277

276-
f.write(json.dumps(jwks))
277-
f.close()
278278
oas.jwks_uri = "{}/{}".format(oas.baseurl, jwks_file_name)
279279

280280
# Initiate the SessionDB
281-
_code = DefaultToken(rndstr(32), rndstr(32), typ='A', lifetime=600)
282-
_token = JWTToken('T', oas.keyjar, {'code': 3600, 'token': 900},
283-
iss=config.issuer, sign_alg='RS256')
284-
_refresh_token = JWTToken('R', oas.keyjar, {'': 86400}, iss=config.issuer,
285-
sign_alg='RS256')
286-
oas.sdb = SessionDB(config.SERVICE_URL,
287-
db={},
288-
code_factory=_code,
289-
token_factory=_token,
290-
refresh_token_factory=_refresh_token)
281+
_code = DefaultToken(rndstr(32), rndstr(32), typ="A", lifetime=600)
282+
_token = JWTToken(
283+
"T",
284+
oas.keyjar,
285+
{"code": 3600, "token": 900},
286+
iss=config.issuer,
287+
sign_alg="RS256",
288+
)
289+
_refresh_token = JWTToken(
290+
"R",
291+
oas.keyjar,
292+
{"": 86400},
293+
iss=config.issuer,
294+
sign_alg="RS256",
295+
token_storage={},
296+
)
297+
oas.sdb = SessionDB(
298+
config.SERVICE_URL,
299+
db={},
300+
code_factory=_code,
301+
token_factory=_token,
302+
refresh_token_factory=_refresh_token,
303+
)
291304

292305
# set some parameters
293306
try:
@@ -324,32 +337,34 @@ def application(self, environ, start_response):
324337
pass
325338
else:
326339
for ent in extern:
327-
iss = ent['iss']
340+
iss = ent["iss"]
328341
kb = KeyBundle()
329-
kb.imp_jwks = json.load(open(ent['jwks']))
330-
kb.do_keys(kb.imp_jwks['keys'])
342+
kb.imp_jwks = json.load(open(ent["jwks"]))
343+
kb.do_keys(kb.imp_jwks["keys"])
331344
oas.keyjar.add_kb(iss, kb)
332345

346+
# Initiate the web server
347+
cherrypy.config.update({"server.socket_port": args.port})
348+
333349
_app = Application(oas)
350+
cherrypy.tree.graft(_app.application, "/")
334351

335-
# Initiate the web server
336-
SRV = wsgiserver.CherryPyWSGIServer(('0.0.0.0', args.port), _app.application) # nosec
337-
338352
https = ""
339353
if config.SERVICE_URL.startswith("https"):
340354
https = " using HTTPS"
341-
# SRV.ssl_adapter = ssl_pyopenssl.pyOpenSSLAdapter(
342-
# config.SERVER_CERT, config.SERVER_KEY, config.CERT_CHAIN)
343-
SRV.ssl_adapter = BuiltinSSLAdapter(config.SERVER_CERT,
344-
config.SERVER_KEY,
345-
config.CERT_CHAIN)
355+
cherrypy.config.update(
356+
{
357+
"cherrypy.server.ssl_certificate": config.SERVER_CERT,
358+
"cherrypy.server.ssl_private_key": config.SERVER_KEY,
359+
}
360+
)
346361

347362
_info = START_MESG.format(args.port, config.HOST)
348363
if https:
349364
_info += https
350365
LOGGER.info(_info)
351366
print(_info)
352367
try:
353-
SRV.start()
368+
cherrypy.engine.start()
354369
except KeyboardInterrupt:
355-
SRV.stop()
370+
pass

0 commit comments

Comments
 (0)