Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions doc/source/add_on/pkce.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Proof Key for Code Exchange
Introduction
------------



OAuth 2.0 public clients utilizing the Authorization Code Grant are
susceptible to the authorization code interception attack. `RFC7636`_
describes the attack as well as a technique to mitigate
Expand Down
3 changes: 2 additions & 1 deletion example/flask_rp/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import os
import sys

from oidcmsg.configure import create_from_config_file

from oidcrp.configure import Configuration
from oidcrp.configure import RPConfiguration
from oidcrp.configure import create_from_config_file
from oidcrp.util import create_context

try:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def run_tests(self):
"Programming Language :: Python :: 3.9",
"Topic :: Software Development :: Libraries :: Python Modules"],
install_requires=[
'oidcmsg>=1.5.3',
'oidcmsg==1.5.4',
'pyyaml>=5.1.2',
'responses'
],
Expand Down
2 changes: 1 addition & 1 deletion src/oidcrp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

__author__ = 'Roland Hedberg'
__version__ = '2.1.1'
__version__ = '2.1.2'

logger = logging.getLogger(__name__)

Expand Down
176 changes: 43 additions & 133 deletions src/oidcrp/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from typing import List
from typing import Optional

from oidcmsg.configure import Base

from oidcrp.logging import configure_logging
from oidcrp.util import load_yaml_config
from oidcrp.util import lower_or_upper
Expand All @@ -16,89 +18,6 @@
except ImportError:
from cryptojwt import rndstr as rnd_token

DEFAULT_FILE_ATTRIBUTE_NAMES = ['server_key', 'server_cert', 'filename', 'template_dir',
'private_path', 'public_path', 'db_file']


def add_base_path(conf: dict, base_path: str, file_attributes: List[str]):
for key, val in conf.items():
if key in file_attributes:
if val.startswith("/"):
continue
elif val == "":
conf[key] = "./" + val
else:
conf[key] = os.path.join(base_path, val)
if isinstance(val, dict):
conf[key] = add_base_path(val, base_path, file_attributes)

return conf


def set_domain_and_port(conf: dict, uris: List[str], domain: str, port: int):
for key, val in conf.items():
if key in uris:
if not val:
continue

if isinstance(val, list):
_new = [v.format(domain=domain, port=port) for v in val]
else:
_new = val.format(domain=domain, port=port)
conf[key] = _new
elif isinstance(val, dict):
conf[key] = set_domain_and_port(val, uris, domain, port)
return conf


class Base:
""" Configuration base class """

def __init__(self,
conf: Dict,
base_path: str = '',
file_attributes: Optional[List[str]] = None,
):

if file_attributes is None:
file_attributes = DEFAULT_FILE_ATTRIBUTE_NAMES

if base_path and file_attributes:
# this adds a base path to all paths in the configuration
add_base_path(conf, base_path, file_attributes)

def __getitem__(self, item):
if item in self.__dict__:
return self.__dict__[item]
else:
raise KeyError

def get(self, item, default=None):
return getattr(self, item, default)

def __contains__(self, item):
return item in self.__dict__

def items(self):
for key in self.__dict__:
if key.startswith('__') and key.endswith('__'):
continue
yield key, getattr(self, key)

def extend(self, entity_conf, conf, base_path, file_attributes, domain, port):
for econf in entity_conf:
_path = econf.get("path")
_cnf = conf
if _path:
for step in _path:
_cnf = _cnf[step]
_attr = econf["attr"]
_cls = econf["class"]
setattr(self, _attr,
_cls(_cnf, base_path=base_path, file_attributes=file_attributes,
domain=domain, port=port))


URIS = [
"redirect_uris", 'post_logout_redirect_uris', 'frontchannel_logout_uri',
'backchannel_logout_uri', 'issuer', 'base_url']
Expand All @@ -112,23 +31,17 @@ def __init__(self,
domain: Optional[str] = "127.0.0.1",
port: Optional[int] = 80,
file_attributes: Optional[List[str]] = None,
dir_attributes: Optional[List[str]] = None,
):

Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes)

_keys_conf = lower_or_upper(conf, 'rp_keys')
if _keys_conf is None:
_keys_conf = lower_or_upper(conf, 'oidc_keys') # legacy

self.keys = _keys_conf
Base.__init__(self, conf,
base_path=base_path,
domain=domain,
port=port,
file_attributes=file_attributes,
dir_attributes=dir_attributes)

if not domain:
domain = conf.get("domain", "127.0.0.1")

if not port:
port = conf.get("port", 80)

conf = set_domain_and_port(conf, URIS, domain, port)
self.key_conf = lower_or_upper(conf, 'rp_keys') or lower_or_upper(conf, 'oidc_keys')
self.clients = lower_or_upper(conf, "clients")

hash_seed = lower_or_upper(conf, 'hash_seed')
Expand All @@ -155,8 +68,10 @@ def __init__(self,
file_attributes: Optional[List[str]] = None,
domain: Optional[str] = "",
port: Optional[int] = 0,
dir_attributes: Optional[List[str]] = None,
):
Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes)
Base.__init__(self, conf, base_path=base_path, file_attributes=file_attributes,
dir_attributes=dir_attributes)

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

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

# entity info
if not domain:
domain = conf.get("domain", "127.0.0.1")

if not port:
port = conf.get("port", 80)

if entity_conf:
self.extend(entity_conf=entity_conf, conf=conf, base_path=base_path,
file_attributes=file_attributes, domain=domain, port=port)


def create_from_config_file(cls,
filename: str,
base_path: Optional[str] = '',
entity_conf: Optional[List[dict]] = None,
file_attributes: Optional[List[str]] = None,
domain: Optional[str] = "",
port: Optional[int] = 0):
if filename.endswith(".yaml"):
"""Load configuration as YAML"""
_cnf = load_yaml_config(filename)
elif filename.endswith(".json"):
_str = open(filename).read()
_cnf = json.loads(_str)
elif filename.endswith(".py"):
head, tail = os.path.split(filename)
tail = tail[:-3]
module = importlib.import_module(tail)
_cnf = getattr(module, "CONFIG")
else:
raise ValueError("Unknown file type")

return cls(_cnf,
entity_conf=entity_conf,
base_path=base_path, file_attributes=file_attributes,
domain=domain, port=port)
file_attributes=file_attributes, domain=domain, port=port,
dir_attributes=dir_attributes)


# def create_from_config_file(cls,
# filename: str,
# base_path: Optional[str] = '',
# entity_conf: Optional[List[dict]] = None,
# file_attributes: Optional[List[str]] = None,
# dir_attributes: Optional[List[str]] = None,
# domain: Optional[str] = "",
# port: Optional[int] = 0):
# if filename.endswith(".yaml"):
# """Load configuration as YAML"""
# _cnf = load_yaml_config(filename)
# elif filename.endswith(".json"):
# _str = open(filename).read()
# _cnf = json.loads(_str)
# elif filename.endswith(".py"):
# head, tail = os.path.split(filename)
# tail = tail[:-3]
# module = importlib.import_module(tail)
# _cnf = getattr(module, "CONFIG")
# else:
# raise ValueError("Unknown file type")
#
# return cls(_cnf,
# entity_conf=entity_conf,
# base_path=base_path, file_attributes=file_attributes,
# domain=domain, port=port, dir_attributes=dir_attributes)
6 changes: 3 additions & 3 deletions src/oidcrp/rp_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from oidcmsg.oidc import OpenIDSchema
from oidcmsg.oidc import RegistrationRequest
from oidcmsg.oidc.session import BackChannelLogoutRequest
from oidcmsg.time_util import time_sans_frac
from oidcmsg.time_util import utc_time_sans_frac

from . import oidc
from .defaults import DEFAULT_CLIENT_CONFIGS
Expand Down Expand Up @@ -836,7 +836,7 @@ def has_active_authentication(self, state):
['auth_response', 'token_response', 'refresh_token_response'])

if _arg:
_now = time_sans_frac()
_now = utc_time_sans_frac()
exp = _arg['__verified_id_token']['exp']
return _now < exp
else:
Expand All @@ -854,7 +854,7 @@ def get_valid_access_token(self, state):
exp = 0
token = None
indefinite = []
now = time_sans_frac()
now = utc_time_sans_frac()

client = self.get_client_from_session_key(state)
_context = client.client_get("service_context")
Expand Down
2 changes: 1 addition & 1 deletion tests/pub_client.jwks
Original file line number Diff line number Diff line change
@@ -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"}]}
{"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"}]}
Loading