Change the config module, resulted in changes in many files

This commit is contained in:
Roland Hedberg
2011-03-18 13:04:36 +01:00
parent 411dfb4c89
commit a62476cde3
6 changed files with 148 additions and 54 deletions

View File

@@ -34,11 +34,8 @@ from repoze.who.interfaces import IChallenger, IIdentifier, IAuthenticator
from repoze.who.interfaces import IMetadataProvider
from repoze.who.plugins.form import FormPluginBase
from saml2 import BINDING_HTTP_REDIRECT
from saml2.client import Saml2Client
from saml2.config import SPConfig
from saml2.s_utils import sid
from saml2.virtual_org import VirtualOrg
#from saml2.population import Population
#from saml2.attribute_resolver import AttributeResolver
@@ -417,13 +414,10 @@ def make_plugin(rememberer_name=None, # plugin for remember
raise ValueError(
'must include rememberer_name in configuration')
config = SPConfig()
config.load_file(saml_conf)
scl = Saml2Client(config, identity_cache=identity_cache,
scl = Saml2Client(config_file=saml_conf, identity_cache=identity_cache,
virtual_organization=virtual_organization)
plugin = SAML2Plugin(rememberer_name, config, scl, wayf, cache, debug,
plugin = SAML2Plugin(rememberer_name, scl.config, scl, wayf, cache, debug,
sid_store)
return plugin

View File

@@ -40,7 +40,7 @@ from saml2.binding import send_using_soap, http_redirect_message
from saml2.binding import http_post_message
from saml2.population import Population
from saml2.virtual_org import VirtualOrg
from saml2.config import SPConfig
from saml2.config import config_factory
#from saml2.response import authn_response
from saml2.response import response_factory
@@ -72,9 +72,9 @@ class LogoutError(Exception):
class Saml2Client(object):
""" The basic pySAML2 service provider class """
def __init__(self, config=None, debug=0,
def __init__(self, config=None, debug=0,
identity_cache=None, state_cache=None,
virtual_organization=None):
virtual_organization=None, config_file=""):
"""
:param config: A saml2.config.Config instance
:param debug: Whether debugging should be done even if the
@@ -96,11 +96,14 @@ class Saml2Client(object):
self.sec = None
if config:
self.config = config
self.metadata = config.metadata
self.sec = security_context(config)
elif config_file:
self.config = config_factory("sp", config_file)
else:
self.config = SPConfig()
raise Exception("Missing configuration")
self.metadata = self.config.metadata
self.sec = security_context(config)
if virtual_organization:
self.vorg = VirtualOrg(self, virtual_organization)
else:
@@ -464,12 +467,15 @@ class Saml2Client(object):
log.info("No response")
return None
def construct_logout_request(self, subject_id, destination, entity_id,
def construct_logout_request(self, subject_id, destination,
issuer_entity_id,
reason=None, expire=None):
""" Constructs a LogoutRequest
:param subject_id: The identifier of the subject
:param destination:
:param destination:
:param issuer_entity_id: The entity ID of the IdP the request is
target at.
:param reason: An indication of the reason for the logout, in the
form of a URI reference.
:param expire: The time at which the request expires,
@@ -480,7 +486,8 @@ class Saml2Client(object):
session_id = sid()
# create NameID from subject_id
name_id = saml.NameID(
text = self.users.get_entityid(subject_id, entity_id, False))
text = self.users.get_entityid(subject_id, issuer_entity_id,
False))
request = samlp.LogoutRequest(
id=session_id,

View File

@@ -2,65 +2,135 @@
__author__ = 'rolandh'
import sys
from importlib import import_module
from saml2 import BINDING_SOAP, BINDING_HTTP_REDIRECT
from saml2 import metadata
from saml2.attribute_converter import ac_factory
from saml2.assertion import Policy
SIMPLE_ARGS = ["entityid", "xmlsec_binary", "debug", "key_file", "cert_file",
"secret", "accepted_time_diff", "virtual_organization", "name",
"description", "endpoints", "required_attributes",
"optional_attributes", "idp", "sp", "aa", "subject_data",
"want_assertions_signed", "authn_requests_signed", "type",
"organization", "contact_person",
"want_authn_requests_signed", "name_form"]
COMMON_ARGS = ["entityid", "xmlsec_binary", "debug", "key_file", "cert_file",
"secret", "accepted_time_diff", "name",
"description",
"organization",
"contact_person",
"name_form",
"virtual_organization",
]
COMPLEX_ARGS = ["metadata", "attribute_converters", "policy"]
SP_ARGS = [
"required_attributes",
"optional_attributes",
"idp",
"subject_data",
"want_assertions_signed",
"authn_requests_signed",
"name_form",
"endpoints",
]
AA_IDP_ARGS = ["want_authn_requests_signed",
"provided_attributes",
"subject_data",
"sp",
"endpoints",
"metadata"]
COMPLEX_ARGS = ["attribute_converters", "metadata", "policy"]
ALL = COMMON_ARGS + SP_ARGS + AA_IDP_ARGS + COMPLEX_ARGS
SPEC = {
"": COMMON_ARGS + COMPLEX_ARGS,
"sp": COMMON_ARGS + COMPLEX_ARGS + SP_ARGS,
"idp": COMMON_ARGS + COMPLEX_ARGS + AA_IDP_ARGS,
"aa": COMMON_ARGS + COMPLEX_ARGS + AA_IDP_ARGS,
}
class Config(object):
def __init__(self):
self._attr = {}
def_context = ""
def __init__(self):
self._attr = {"": {}, "sp": {}, "idp": {}, "aa": {}}
self.context = ""
def serves(self):
return [t for t in ["sp", "idp", "aa"] if self._attr[t]]
def __getattribute__(self, item):
if item in SIMPLE_ARGS or item in COMPLEX_ARGS:
if item == "context":
return object.__getattribute__(self, item)
_context = self.context
if item in ALL:
try:
return self._attr[item]
return self._attr[_context][item]
except KeyError:
if _context:
try:
return self._attr[""][item]
except KeyError:
pass
return None
else:
return object.__getattribute__(self, item)
def load(self, cnf):
for arg in SIMPLE_ARGS:
def load_special(self, cnf, typ):
for arg in SPEC[typ]:
try:
self._attr[arg] = cnf[arg]
self._attr[typ][arg] = cnf[arg]
except KeyError:
pass
self.context = typ
self.load_complex(cnf, typ)
self.context = self.def_context
def load_complex(self, cnf, typ=""):
try:
self._attr["policy"] = Policy(cnf["policy"])
self._attr[typ]["policy"] = Policy(cnf["policy"])
except KeyError:
pass
try:
acs = ac_factory(cnf["attribute_map_dir"])
try:
self._attr["attribute_converters"].extend(acs)
self._attr[typ]["attribute_converters"].extend(acs)
except KeyError:
self._attr["attribute_converters"] = acs
self._attr[typ]["attribute_converters"] = acs
except KeyError:
pass
try:
self._attr["metadata"] = self.load_metadata(cnf["metadata"])
self._attr[typ]["metadata"] = self.load_metadata(cnf["metadata"])
except KeyError:
pass
def load(self, cnf):
for arg in COMMON_ARGS:
try:
self._attr[""][arg] = cnf[arg]
except KeyError:
pass
if "service" in cnf:
for typ in ["aa", "idp", "sp"]:
try:
self.load_special(cnf["service"][typ], typ)
except KeyError:
pass
self.load_complex(cnf)
self.context = self.def_context
return self
def load_file(self, config_file):
return self.load(eval(open(config_file).read()))
if sys.path[0] != ".":
sys.path.insert(0, ".")
mod = import_module(config_file)
#return self.load(eval(open(config_file).read()))
return self.load(mod.CONFIG)
def load_metadata(self, metadata_conf):
""" Loads metadata into an internal structure """
@@ -110,6 +180,8 @@ class Config(object):
return None
class SPConfig(Config):
def_context = "sp"
def __init__(self):
Config.__init__(self)
@@ -167,6 +239,8 @@ class SPConfig(Config):
return self.metadata.idps()
class IdPConfig(Config):
def_context = "idp"
def __init__(self):
Config.__init__(self)
@@ -190,3 +264,15 @@ class IdPConfig(Config):
return [s[binding] for s in acs]
return []
def config_factory(typ, file):
if typ == "sp":
conf = SPConfig().load_file(file)
conf.context = typ
elif typ in ["aa", "idp"]:
conf = IdPConfig().load_file(file)
conf.context = typ
else:
conf = Config().load_file(file)
conf.context = typ
return conf

View File

@@ -719,6 +719,7 @@ def do_requested_attribute(attributes, acs, is_required="false"):
for key in attr.keyswv():
args[key] = getattr(attr, key)
args["is_required"] = is_required
args["name_format"] = NAME_FORMAT_URI
lista.append(md.RequestedAttribute(**args))
return lista
@@ -917,16 +918,18 @@ def entity_descriptor(confd, valid_for):
if confd.contact_person is not None:
entd.contact_person = do_contact_person_info(confd.contact_person)
if confd.type == "sp":
entd.spsso_descriptor = do_sp_sso_descriptor(confd, mycert)
elif confd.type == "idp":
entd.idpsso_descriptor = do_idp_sso_descriptor(confd, mycert)
elif confd.type == "aa":
entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert)
else:
serves = confd.serves()
if not serves:
raise Exception(
'No service type ("sp","idp","aa") provided in the configuration')
if "sp" in serves:
entd.spsso_descriptor = do_sp_sso_descriptor(confd, mycert)
if "idp" in serves:
entd.idpsso_descriptor = do_idp_sso_descriptor(confd, mycert)
if "aa" in serves:
entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert)
return entd
def entities_descriptor(eds, valid_for, name, ident, sign, secc):

View File

@@ -56,7 +56,7 @@ def for_me(condition, myself ):
return False
def authn_response(conf, entity_id, return_addr, outstanding_queries=None,
def authn_response(conf, return_addr, outstanding_queries=None,
log=None, timeslack=0, debug=0):
sec = security_context(conf)
if not timeslack:
@@ -65,12 +65,12 @@ def authn_response(conf, entity_id, return_addr, outstanding_queries=None,
except TypeError:
timeslack = 0
return AuthnResponse(sec, conf.attribute_converters, entity_id,
return AuthnResponse(sec, conf.attribute_converters, conf.entityid,
return_addr, outstanding_queries, log, timeslack,
debug)
# comes in over SOAP so synchronous
def attribute_response(conf, entity_id, return_addr, log=None, timeslack=0,
def attribute_response(conf, return_addr, log=None, timeslack=0,
debug=0):
sec = security_context(conf)
if not timeslack:
@@ -79,7 +79,7 @@ def attribute_response(conf, entity_id, return_addr, log=None, timeslack=0,
except TypeError:
timeslack = 0
return AttributeResponse(sec, conf.attribute_converters, entity_id,
return AttributeResponse(sec, conf.attribute_converters, conf.entityid,
return_addr, log, timeslack, debug)
class StatusResponse(object):

View File

@@ -50,7 +50,7 @@ from saml2.binding import http_post_message
from saml2.sigver import security_context
from saml2.sigver import signed_instance_factory
from saml2.sigver import pre_signature_part
from saml2.config import IdPConfig
from saml2.config import config_factory
from saml2.assertion import Assertion, Policy
class UnknownVO(Exception):
@@ -212,6 +212,8 @@ class Server(object):
self.load_config(config_file)
elif config:
self.conf = config
else:
raise Exception("Missing configuration")
self.metadata = self.conf.metadata
self.sec = security_context(self.conf, log)
@@ -228,8 +230,7 @@ class Server(object):
:param config_file: The name of the configuration file
"""
self.conf = IdPConfig()
self.conf.load_file(config_file)
self.conf = config_factory("idp", config_file)
try:
# subject information is store in database
# default database is a shelve database which is OK in some setups
@@ -593,7 +594,10 @@ class Server(object):
self.log.info("enpoints: %s" % (self.conf.endpoints,))
self.log.info("binding wanted: %s" % (binding,))
raise
if not slo:
raise Exception("No single_logout_server for that binding")
if self.log:
self.log.info("Endpoint: %s" % slo)
req = LogoutRequest(self.sec, slo)