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

Commit d779aa6

Browse files
authored
Merge pull request #57 from IdentityPython/dir_attributes
Configuration attributes that points to directories.
2 parents 65dd682 + 6636b47 commit d779aa6

File tree

11 files changed

+110
-161
lines changed

11 files changed

+110
-161
lines changed

doc/source/add_on/pkce.rst

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ Proof Key for Code Exchange
88
Introduction
99
------------
1010

11-
12-
1311
OAuth 2.0 public clients utilizing the Authorization Code Grant are
1412
susceptible to the authorization code interception attack. `RFC7636`_
1513
describes the attack as well as a technique to mitigate

example/flask_rp/wsgi.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import os
44
import sys
55

6+
from oidcmsg.configure import create_from_config_file
7+
68
from oidcrp.configure import Configuration
79
from oidcrp.configure import RPConfiguration
8-
from oidcrp.configure import create_from_config_file
910
from oidcrp.util import create_context
1011

1112
try:

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def run_tests(self):
7474
"Programming Language :: Python :: 3.9",
7575
"Topic :: Software Development :: Libraries :: Python Modules"],
7676
install_requires=[
77-
'oidcmsg>=1.5.3',
77+
'oidcmsg==1.5.4',
7878
'pyyaml>=5.1.2',
7979
'responses'
8080
],

src/oidcrp/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
__author__ = 'Roland Hedberg'
4-
__version__ = '2.1.1'
4+
__version__ = '2.1.2'
55

66
logger = logging.getLogger(__name__)
77

src/oidcrp/configure.py

+43-133
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from typing import List
88
from typing import Optional
99

10+
from oidcmsg.configure import Base
11+
1012
from oidcrp.logging import configure_logging
1113
from oidcrp.util import load_yaml_config
1214
from oidcrp.util import lower_or_upper
@@ -16,89 +18,6 @@
1618
except ImportError:
1719
from cryptojwt import rndstr as rnd_token
1820

19-
DEFAULT_FILE_ATTRIBUTE_NAMES = ['server_key', 'server_cert', 'filename', 'template_dir',
20-
'private_path', 'public_path', 'db_file']
21-
22-
23-
def add_base_path(conf: dict, base_path: str, file_attributes: List[str]):
24-
for key, val in conf.items():
25-
if key in file_attributes:
26-
if val.startswith("/"):
27-
continue
28-
elif val == "":
29-
conf[key] = "./" + val
30-
else:
31-
conf[key] = os.path.join(base_path, val)
32-
if isinstance(val, dict):
33-
conf[key] = add_base_path(val, base_path, file_attributes)
34-
35-
return conf
36-
37-
38-
def set_domain_and_port(conf: dict, uris: List[str], domain: str, port: int):
39-
for key, val in conf.items():
40-
if key in uris:
41-
if not val:
42-
continue
43-
44-
if isinstance(val, list):
45-
_new = [v.format(domain=domain, port=port) for v in val]
46-
else:
47-
_new = val.format(domain=domain, port=port)
48-
conf[key] = _new
49-
elif isinstance(val, dict):
50-
conf[key] = set_domain_and_port(val, uris, domain, port)
51-
return conf
52-
53-
54-
class Base:
55-
""" Configuration base class """
56-
57-
def __init__(self,
58-
conf: Dict,
59-
base_path: str = '',
60-
file_attributes: Optional[List[str]] = None,
61-
):
62-
63-
if file_attributes is None:
64-
file_attributes = DEFAULT_FILE_ATTRIBUTE_NAMES
65-
66-
if base_path and file_attributes:
67-
# this adds a base path to all paths in the configuration
68-
add_base_path(conf, base_path, file_attributes)
69-
70-
def __getitem__(self, item):
71-
if item in self.__dict__:
72-
return self.__dict__[item]
73-
else:
74-
raise KeyError
75-
76-
def get(self, item, default=None):
77-
return getattr(self, item, default)
78-
79-
def __contains__(self, item):
80-
return item in self.__dict__
81-
82-
def items(self):
83-
for key in self.__dict__:
84-
if key.startswith('__') and key.endswith('__'):
85-
continue
86-
yield key, getattr(self, key)
87-
88-
def extend(self, entity_conf, conf, base_path, file_attributes, domain, port):
89-
for econf in entity_conf:
90-
_path = econf.get("path")
91-
_cnf = conf
92-
if _path:
93-
for step in _path:
94-
_cnf = _cnf[step]
95-
_attr = econf["attr"]
96-
_cls = econf["class"]
97-
setattr(self, _attr,
98-
_cls(_cnf, base_path=base_path, file_attributes=file_attributes,
99-
domain=domain, port=port))
100-
101-
10221
URIS = [
10322
"redirect_uris", 'post_logout_redirect_uris', 'frontchannel_logout_uri',
10423
'backchannel_logout_uri', 'issuer', 'base_url']
@@ -112,23 +31,17 @@ def __init__(self,
11231
domain: Optional[str] = "127.0.0.1",
11332
port: Optional[int] = 80,
11433
file_attributes: Optional[List[str]] = None,
34+
dir_attributes: Optional[List[str]] = None,
11535
):
11636

117-
Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes)
118-
119-
_keys_conf = lower_or_upper(conf, 'rp_keys')
120-
if _keys_conf is None:
121-
_keys_conf = lower_or_upper(conf, 'oidc_keys') # legacy
122-
123-
self.keys = _keys_conf
37+
Base.__init__(self, conf,
38+
base_path=base_path,
39+
domain=domain,
40+
port=port,
41+
file_attributes=file_attributes,
42+
dir_attributes=dir_attributes)
12443

125-
if not domain:
126-
domain = conf.get("domain", "127.0.0.1")
127-
128-
if not port:
129-
port = conf.get("port", 80)
130-
131-
conf = set_domain_and_port(conf, URIS, domain, port)
44+
self.key_conf = lower_or_upper(conf, 'rp_keys') or lower_or_upper(conf, 'oidc_keys')
13245
self.clients = lower_or_upper(conf, "clients")
13346

13447
hash_seed = lower_or_upper(conf, 'hash_seed')
@@ -155,8 +68,10 @@ def __init__(self,
15568
file_attributes: Optional[List[str]] = None,
15669
domain: Optional[str] = "",
15770
port: Optional[int] = 0,
71+
dir_attributes: Optional[List[str]] = None,
15872
):
159-
Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes)
73+
Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes,
74+
dir_attributes=dir_attributes)
16075

16176
log_conf = conf.get('logging')
16277
if log_conf:
@@ -166,40 +81,35 @@ def __init__(self,
16681

16782
self.web_conf = lower_or_upper(conf, "webserver")
16883

169-
# entity info
170-
if not domain:
171-
domain = conf.get("domain", "127.0.0.1")
172-
173-
if not port:
174-
port = conf.get("port", 80)
175-
17684
if entity_conf:
17785
self.extend(entity_conf=entity_conf, conf=conf, base_path=base_path,
178-
file_attributes=file_attributes, domain=domain, port=port)
179-
180-
181-
def create_from_config_file(cls,
182-
filename: str,
183-
base_path: Optional[str] = '',
184-
entity_conf: Optional[List[dict]] = None,
185-
file_attributes: Optional[List[str]] = None,
186-
domain: Optional[str] = "",
187-
port: Optional[int] = 0):
188-
if filename.endswith(".yaml"):
189-
"""Load configuration as YAML"""
190-
_cnf = load_yaml_config(filename)
191-
elif filename.endswith(".json"):
192-
_str = open(filename).read()
193-
_cnf = json.loads(_str)
194-
elif filename.endswith(".py"):
195-
head, tail = os.path.split(filename)
196-
tail = tail[:-3]
197-
module = importlib.import_module(tail)
198-
_cnf = getattr(module, "CONFIG")
199-
else:
200-
raise ValueError("Unknown file type")
201-
202-
return cls(_cnf,
203-
entity_conf=entity_conf,
204-
base_path=base_path, file_attributes=file_attributes,
205-
domain=domain, port=port)
86+
file_attributes=file_attributes, domain=domain, port=port,
87+
dir_attributes=dir_attributes)
88+
89+
90+
# def create_from_config_file(cls,
91+
# filename: str,
92+
# base_path: Optional[str] = '',
93+
# entity_conf: Optional[List[dict]] = None,
94+
# file_attributes: Optional[List[str]] = None,
95+
# dir_attributes: Optional[List[str]] = None,
96+
# domain: Optional[str] = "",
97+
# port: Optional[int] = 0):
98+
# if filename.endswith(".yaml"):
99+
# """Load configuration as YAML"""
100+
# _cnf = load_yaml_config(filename)
101+
# elif filename.endswith(".json"):
102+
# _str = open(filename).read()
103+
# _cnf = json.loads(_str)
104+
# elif filename.endswith(".py"):
105+
# head, tail = os.path.split(filename)
106+
# tail = tail[:-3]
107+
# module = importlib.import_module(tail)
108+
# _cnf = getattr(module, "CONFIG")
109+
# else:
110+
# raise ValueError("Unknown file type")
111+
#
112+
# return cls(_cnf,
113+
# entity_conf=entity_conf,
114+
# base_path=base_path, file_attributes=file_attributes,
115+
# domain=domain, port=port, dir_attributes=dir_attributes)

src/oidcrp/rp_handler.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from oidcmsg.oidc import OpenIDSchema
2222
from oidcmsg.oidc import RegistrationRequest
2323
from oidcmsg.oidc.session import BackChannelLogoutRequest
24-
from oidcmsg.time_util import time_sans_frac
24+
from oidcmsg.time_util import utc_time_sans_frac
2525

2626
from . import oidc
2727
from .defaults import DEFAULT_CLIENT_CONFIGS
@@ -836,7 +836,7 @@ def has_active_authentication(self, state):
836836
['auth_response', 'token_response', 'refresh_token_response'])
837837

838838
if _arg:
839-
_now = time_sans_frac()
839+
_now = utc_time_sans_frac()
840840
exp = _arg['__verified_id_token']['exp']
841841
return _now < exp
842842
else:
@@ -854,7 +854,7 @@ def get_valid_access_token(self, state):
854854
exp = 0
855855
token = None
856856
indefinite = []
857-
now = time_sans_frac()
857+
now = utc_time_sans_frac()
858858

859859
client = self.get_client_from_session_key(state)
860860
_context = client.client_get("service_context")

tests/pub_client.jwks

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"keys": [{"kty": "RSA", "use": "sig", "kid": "SUswNi1MRFlDT0Y2YjU1Z1RfQlo2S3dEa3FTTkV3LThFcnhDTHF5elk2VQ", "e": "AQAB", "n": "0UkUx2ewKyc-XJ1o0ToyGjws_JybAMZj2oYjsPyyvQ_T5dhZ2VmRRRkhsaVJ2xE_GGc7mSG0IjmGFyXp5y0w4mJBcsAEE5-8eBTvQdYIryjW74r3jt6Fi4Hlm1yFMTie3apv8mw79BUj-jT0kh3_m-FiKKUvLsq45DcLtTJ4cx7Ize37dl1sFSpQcoYMk7eiUEM8fiNboiVwvBYNAWVMkUM-LnVUPm3UjvKp0LihYEkZFWOxmuQmj2x25SFUkjus38ERrRqJQBZduxdBHFrWtWg8yOA53BkMU0FFg_r0H3ctl-5GaKw-BWlogU4qXnsq85xy0EoenRk7FPV8g_ulJw"}, {"kty": "EC", "use": "sig", "kid": "NC1pdGRQN002bWM3bk1xX2R0SktscElqbFdtN29ITDV2WVd2b0hOYzREVQ", "crv": "P-256", "x": "kK7Qp1woSerI7rUOAwW_4sU6ZmwV3wwXKX3VU-v2fMI", "y": "iPWd_Pjq6EjxYy08KNFZ3PxhEwgWHgAQTTknlKMKJA0"}]}
1+
{"keys": [{"kty": "RSA", "use": "sig", "kid": "SUswNi1MRFlDT0Y2YjU1Z1RfQlo2S3dEa3FTTkV3LThFcnhDTHF5elk2VQ", "n": "0UkUx2ewKyc-XJ1o0ToyGjws_JybAMZj2oYjsPyyvQ_T5dhZ2VmRRRkhsaVJ2xE_GGc7mSG0IjmGFyXp5y0w4mJBcsAEE5-8eBTvQdYIryjW74r3jt6Fi4Hlm1yFMTie3apv8mw79BUj-jT0kh3_m-FiKKUvLsq45DcLtTJ4cx7Ize37dl1sFSpQcoYMk7eiUEM8fiNboiVwvBYNAWVMkUM-LnVUPm3UjvKp0LihYEkZFWOxmuQmj2x25SFUkjus38ERrRqJQBZduxdBHFrWtWg8yOA53BkMU0FFg_r0H3ctl-5GaKw-BWlogU4qXnsq85xy0EoenRk7FPV8g_ulJw", "e": "AQAB"}, {"kty": "EC", "use": "sig", "kid": "NC1pdGRQN002bWM3bk1xX2R0SktscElqbFdtN29ITDV2WVd2b0hOYzREVQ", "crv": "P-256", "x": "kK7Qp1woSerI7rUOAwW_4sU6ZmwV3wwXKX3VU-v2fMI", "y": "iPWd_Pjq6EjxYy08KNFZ3PxhEwgWHgAQTTknlKMKJA0"}]}

0 commit comments

Comments
 (0)