Skip to content
This repository was archived by the owner on Jun 23, 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
150 changes: 79 additions & 71 deletions src/oidcop/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ def add_base_path(conf: Union[dict, str], base_path: str, file_attributes: List[
return conf


URIS = ["issuer", "base_url"]


def set_domain_and_port(conf: dict, uris: List[str], domain: str, port: int):
for key, val in conf.items():
if key in uris:
Expand Down Expand Up @@ -154,42 +151,59 @@ def create_from_config_file(
)


class Base:
class Base(dict):
""" Configuration base class """

parameter = {}

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

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 __getattr__(self, item):
return self[item]

def __contains__(self, item):
return item in self.__dict__
def __setattr__(self, key, value):
if key in self:
raise KeyError('{} has already been set'.format(key))
super(Base, self).__setitem__(key, value)

def items(self):
for key in self.__dict__:
if key.startswith("__") and key.endswith("__"):
continue
yield key, getattr(self, key)
def __setitem__(self, key, value):
if key in self:
raise KeyError('{} has already been set'.format(key))
super(Base, self).__setitem__(key, value)


class EntityConfiguration(Base):
default_config = AS_DEFAULT_CONFIG
uris = ["issuer", "base_url"]
parameter = {
"add_on": None,
"authz": None,
"authentication": None,
"base_url": "",
"capabilities": None,
"claims_interface": None,
"cookie_handler": None,
"endpoint": {},
"httpc_params": {},
"issuer": "",
"keys": None,
"session_key": None,
"template_dir": None,
"token_handler_args": {},
"userinfo": None,
"password": None,
"salt": None,
}

def __init__(
self,
Expand All @@ -204,72 +218,64 @@ def __init__(
conf = copy.deepcopy(conf)
Base.__init__(self, conf, base_path, file_attributes)

self.add_on = None
self.authz = None
self.authentication = None
self.base_url = ""
self.capabilities = None
self.claims_interface = None
self.cookie_handler = None
self.endpoint = {}
self.httpc_params = {}
self.issuer = ""
self.keys = None
self.template_dir = None
self.token_handler_args = {}
self.userinfo = None
self.session_params = None

if file_attributes is None:
file_attributes = DEFAULT_FILE_ATTRIBUTE_NAMES

for key in self.__dict__.keys():
if not domain:
domain = conf.get("domain", "127.0.0.1")

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

for key in self.parameter.keys():
_val = conf.get(key)
if not _val:
if key in self.default_config:
_dc = copy.deepcopy(self.default_config[key])
add_base_path(_dc, base_path, file_attributes)
_val = _dc
_val = copy.deepcopy(self.default_config[key])
self.format(_val, base_path=base_path, file_attributes=file_attributes,
domain=domain, port=port)
else:
continue
setattr(self, key, _val)

if self.template_dir is None:
self.template_dir = os.path.abspath("templates")
else:
self.template_dir = os.path.abspath(self.template_dir)
if key == "template_dir":
_val = os.path.abspath(_val)

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

if not port:
port = conf.get("port", 80)
setattr(self, key, _val)

set_domain_and_port(conf, URIS, domain=domain, port=port)
# try:
# _dir = self.template_dir
# except AttributeError:
# self.template_dir = os.path.abspath("templates")
# else:
# self.template_dir =

def format(self, conf, base_path, file_attributes, domain, port):
"""
Formats parts of the configuration. That includes replacing the strings {domain} and {port}
with the used domain and port and making references to files and directories absolute
rather then relative. The formatting is done in place.

:param conf: The configuration part
:param base_path: The base path used to make file/directory refrences absolute
:param file_attributes: Attribute names that refer to files or directories.
:param domain: The domain name
:param port: The port used
"""
add_base_path(conf, base_path, file_attributes)
if isinstance(conf, dict):
set_domain_and_port(conf, self.uris, domain=domain, port=port)


class OPConfiguration(EntityConfiguration):
"Provider configuration"
default_config = OP_DEFAULT_CONFIG

def __init__(
self,
conf: Dict,
base_path: Optional[str] = "",
entity_conf: Optional[List[dict]] = None,
domain: Optional[str] = "",
port: Optional[int] = 0,
file_attributes: Optional[List[str]] = None,
):
# OP special
self.id_token = None
self.login_hint2acrs = {}
self.login_hint_lookup = None

EntityConfiguration.__init__(self, conf=conf, base_path=base_path,
entity_conf=entity_conf, domain=domain, port=port,
file_attributes=file_attributes)

parameter = EntityConfiguration.parameter.copy()
parameter.update({
"id_token": None,
"login_hint2acrs": {},
"login_hint_lookup": None,
"sub_func": {}
})

class ASConfiguration(EntityConfiguration):
"Authorization server configuration"
Expand All @@ -290,6 +296,7 @@ def __init__(

class Configuration(Base):
"""Server Configuration"""
uris = ["issuer", "base_url"]

def __init__(
self,
Expand All @@ -316,7 +323,7 @@ def __init__(
if not port:
port = conf.get("port", 80)

set_domain_and_port(conf, URIS, domain=domain, port=port)
set_domain_and_port(conf, self.uris, domain=domain, port=port)

if entity_conf:
for econf in entity_conf:
Expand Down Expand Up @@ -511,7 +518,8 @@ def __init__(
"login_hint2acrs": {
"class": "oidcop.login_hint.LoginHint2Acrs",
"kwargs": {
"scheme_map": {"email": ["urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword"]}
"scheme_map": {
"email": ["urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword"]}
},
},
"template_dir": "templates",
Expand Down
8 changes: 7 additions & 1 deletion tests/test_12_user_authn.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ def create_endpoint_context(self):
"password": "mycket hemligt",
"grant_expires_in": 300,
"verify_ssl": False,
"endpoint": {},
"endpoint": {
"authorization": {
"path": "{}/authorization",
"class": 'oidcop.oidc.authorization.Authorization',
"kwargs": {},
}
},
"keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS},
"authentication": {
"user": {
Expand Down
8 changes: 7 additions & 1 deletion tests/test_24_oidc_authorization_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,13 @@ def create_endpoint_context(self):
"grant_expires_in": 300,
"refresh_token_expires_in": 86400,
"verify_ssl": False,
"endpoint": {},
"endpoint": {
"authorization": {
"path": "{}/authorization",
"class": Authorization,
"kwargs": {},
}
},
"keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS},
"authentication": {
"user": {
Expand Down