import copy from urllib.parse import urlparse from django.conf import settings from saml2.config import SPConfig from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT def is_relative(url): absolute = bool(urlparse(url).netloc) return not absolute def absolutize(path, default_base): if is_absolute(path): return path else: return default_base + path SAML_CONFIG = settings.SAML_CONFIG _idp_configs = {} _relative_paths = [] def relative_config_loader(request=None): host = request.get_host() if host in _idp_configs: return _idp_configs[host] base = request.scheme + "://" + request.get_host() config = copy.deepcopy(settings.SAML_CONFIG) endpoints = config['service']['sp']['endpoints'] if not _relative_paths: if is_relative(config['entityid']): _relative_paths.append('entityid') if is_relative(endpoints['assertion_consumer_service'][0]): _relative_paths.append('assertion_consumer_service') if is_relative(endpoints['single_logout_service'][0][0]): _relative_paths.append('single_logout_service') if 'single_logout_service' in _relative_paths: absolute_rdir = base + endpoints['single_logout_service'][0][0] absolute_post = base + endpoints['single_logout_service'][1][0] sls_endpoint = [ (absolute_rdir, BINDING_HTTP_REDIRECT), (absolute_post, BINDING_HTTP_POST) ] config['service']['sp']['endpoints']['single_logout_service'] = sls_endpoint if 'assertion_consumer_service' in _relative_paths: acs = base + endpoints['assertion_consumer_service'][0] config['service']['sp']['endpoints']['assertion_consumer_service'][0] = acs if 'entityid' in _relative_paths: config['entityid'] = base + config['entityid'] conf = SPConfig() conf.load(config) _idp_configs[host] = conf return conf