diff options
author | Roland Hedberg <roland.hedberg@adm.umu.se> | 2012-06-27 07:50:13 +0200 |
---|---|---|
committer | Roland Hedberg <roland.hedberg@adm.umu.se> | 2012-06-27 07:50:13 +0200 |
commit | 2495375de47d0a4bb77aaac91d2ea9421a03bde4 (patch) | |
tree | 759721f6b72f4de534f813ff8543077306e255f6 | |
parent | ce1eb1502587d1b51fafca4caa36fd3e6c2db98c (diff) | |
download | pysaml2-2495375de47d0a4bb77aaac91d2ea9421a03bde4.tar.gz |
Changed logging setup
-rw-r--r-- | src/saml2/assertion.py | 2 | ||||
-rw-r--r-- | src/saml2/attribute_resolver.py | 9 | ||||
-rw-r--r-- | src/saml2/binding.py | 3 | ||||
-rw-r--r-- | src/saml2/cache.py | 3 | ||||
-rw-r--r-- | src/saml2/client.py | 228 | ||||
-rw-r--r-- | src/saml2/config.py | 4 | ||||
-rw-r--r-- | src/saml2/ecp.py | 22 | ||||
-rw-r--r-- | src/saml2/ecp_client.py | 24 | ||||
-rw-r--r-- | src/saml2/encdec.py | 3 | ||||
-rw-r--r-- | src/saml2/httplib2cookie.py | 3 | ||||
-rw-r--r-- | src/saml2/httputil.py | 4 | ||||
-rw-r--r-- | src/saml2/mcache.py | 2 | ||||
-rw-r--r-- | src/saml2/mdbcache.py | 3 | ||||
-rw-r--r-- | src/saml2/metadata.py | 21 | ||||
-rw-r--r-- | src/saml2/population.py | 10 | ||||
-rw-r--r-- | src/saml2/request.py | 54 | ||||
-rw-r--r-- | src/saml2/response.py | 5 | ||||
-rw-r--r-- | src/saml2/s_utils.py | 35 | ||||
-rw-r--r-- | src/saml2/server.py | 12 | ||||
-rw-r--r-- | src/saml2/sigver.py | 78 | ||||
-rw-r--r-- | src/saml2/soap.py | 21 | ||||
-rw-r--r-- | src/saml2/virtual_org.py | 27 |
22 files changed, 245 insertions, 328 deletions
diff --git a/src/saml2/assertion.py b/src/saml2/assertion.py index 845e011a..3105f12c 100644 --- a/src/saml2/assertion.py +++ b/src/saml2/assertion.py @@ -14,6 +14,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import logging import re import sys @@ -28,6 +29,7 @@ from saml2.s_utils import sid, MissingValue from saml2.s_utils import factory from saml2.s_utils import assertion_factory +logger = logging.getLogger(__name__) def _filter_values(vals, vlist=None, must=False): """ Removes values from *vals* that does not appear in vlist diff --git a/src/saml2/attribute_resolver.py b/src/saml2/attribute_resolver.py index f6d07334..786a22f6 100644 --- a/src/saml2/attribute_resolver.py +++ b/src/saml2/attribute_resolver.py @@ -21,6 +21,11 @@ to do attribute aggregation. """ import saml2 +import logging +from saml2.client import Saml2Client + +logger = logging.getLogger(__name__) + DEFAULT_BINDING = saml2.BINDING_SOAP class AttributeResolver(object): @@ -32,7 +37,7 @@ class AttributeResolver(object): self.saml2client = saml2client self.metadata = saml2client.config.metadata else: - self.saml2client = saml2.client.Saml2Client(config) + self.saml2client = Saml2Client(config) def extend(self, subject_id, issuer, vo_members, name_id_format=None, sp_name_qualifier=None, log=None, real_id=None): @@ -42,7 +47,7 @@ class AttributeResolver(object): :param issuer: Who am I the poses the query :param vo_members: The entity IDs of the IdP who I'm going to ask for extra attributes - :param nameid_format: Used to make the IdPs aware of what's going + :param name_id_format: Used to make the IdPs aware of what's going on here :param log: Where to log exciting information :return: A dictionary with all the collected information about the diff --git a/src/saml2/binding.py b/src/saml2/binding.py index acef290d..8fbd91a2 100644 --- a/src/saml2/binding.py +++ b/src/saml2/binding.py @@ -28,6 +28,9 @@ import base64 import urllib from saml2.s_utils import deflate_and_base64_encode from saml2.soap import SOAPClient, HTTPClient +import logging + +logger = logging.getLogger(__name__) try: from xml.etree import cElementTree as ElementTree diff --git a/src/saml2/cache.py b/src/saml2/cache.py index 62258dbe..fc7b57c4 100644 --- a/src/saml2/cache.py +++ b/src/saml2/cache.py @@ -2,6 +2,9 @@ import shelve from saml2 import time_util +import logging + +logger = logging.getLogger(__name__) # The assumption is that any subject may consist of data # gathered from several different sources, all with their own diff --git a/src/saml2/client.py b/src/saml2/client.py index 50c150c2..831c31ef 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -58,6 +58,9 @@ from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_SOAP from saml2 import BINDING_HTTP_POST from saml2 import BINDING_PAOS +import logging + +logger = logging.getLogger(__name__) SSO_BINDING = saml2.BINDING_HTTP_REDIRECT @@ -82,9 +85,8 @@ class LogoutError(Exception): class Saml2Client(object): """ The basic pySAML2 service provider class """ - def __init__(self, config=None, - identity_cache=None, state_cache=None, - virtual_organization=None, config_file="", logger=None): + def __init__(self, config=None, identity_cache=None, state_cache=None, + virtual_organization=None, config_file=""): """ :param config: A saml2.config.Config instance :param identity_cache: Where the class should store identity information @@ -110,18 +112,12 @@ class Saml2Client(object): self.metadata = self.config.metadata - if logger is None: - self.logger = self.config.setup_logger() - else: - self.logger = logger - # we copy the config.debug variable in an internal # field for convenience and because we may need to # change it during the tests self.debug = self.config.debug - self.sec = security_context(self.config, log=self.logger, - debug=self.debug) + self.sec = security_context(self.config) if virtual_organization: self.vorg = VirtualOrg(self, virtual_organization) @@ -173,8 +169,7 @@ class Saml2Client(object): try: return self.config.single_sign_on_services(entityid, binding)[0] except IndexError: - if self.logger: - self.logger.info("_sso_location: %s, %s" % (entityid, + logger.info("_sso_location: %s, %s" % (entityid, binding)) raise IdpUnspecified("No IdP to send to given the premises") @@ -205,15 +200,13 @@ class Saml2Client(object): else: return None - def response(self, post, outstanding, log=None, decode=True, - asynchop=True): + def response(self, post, outstanding, decode=True, asynchop=True): """ Deal with an AuthnResponse or LogoutResponse :param post: The reply as a dictionary :param outstanding: A dictionary with session IDs as keys and the original web request from the user before redirection as values. - :param log: where loggin should go. :param decode: Whether the response is Base64 encoded or not :param asynchop: Whether the response was return over a asynchronous connection. SOAP for instance is synchronous @@ -230,39 +223,33 @@ class Saml2Client(object): except KeyError: raise Exception("Missing entity_id specification") - if log is None: - log = self.logger - reply_addr = self.service_url() resp = None if saml_response: try: resp = response_factory(saml_response, self.config, - reply_addr, outstanding, log, - debug=self.debug, decode=decode, + reply_addr, outstanding, decode=decode, asynchop=asynchop, allow_unsolicited=self.allow_unsolicited) except Exception, exc: - if log: - log.error("%s" % exc) + logger.error("%s" % exc) return None - if log: - log.debug(">> %s", resp) + logger.debug(">> %s", resp) resp = resp.verify() if isinstance(resp, AuthnResponse): self.users.add_information_about_person(resp.session_info()) - if log: - log.info("--- ADDED person info ----") + logger.info("--- ADDED person info ----") elif isinstance(resp, LogoutResponse): - self.handle_logout_response(resp, log) - elif log: - log.error("Response type not supported: %s" % saml2.class_name(resp)) + self.handle_logout_response(resp) + else: + logger.error("Response type not supported: %s" % ( + saml2.class_name(resp),)) return resp def authn_request(self, query_id, destination, service_url, spentityid, - my_name="", vorg="", scoping=None, log=None, sign=None, + my_name="", vorg="", scoping=None, sign=None, binding=saml2.BINDING_HTTP_POST, nameid_format=saml.NAMEID_FORMAT_TRANSIENT): """ Creates an authentication request. @@ -274,7 +261,6 @@ class Saml2Client(object): :param my_name: The name of this service. :param vorg: The vitual organization the service belongs to. :param scoping: The scope of the request - :param log: A service to which logs should be written :param sign: Whether the request should be signed or not. :param binding: The protocol to use for the Response !! :return: <samlp:AuthnRequest> instance @@ -321,11 +307,7 @@ class Saml2Client(object): request.name_id_policy = name_id_policy request.issuer = self._issuer(spentityid) - if log is None: - log = self.logger - - if log: - log.info("REQUEST: %s" % request) + logger.info("REQUEST: %s" % request) return signed_instance_factory(request, self.sec, to_sign) @@ -357,16 +339,11 @@ class Saml2Client(object): my_name = self._my_name() - if log is None: - log = self.logger - - if log: - log.info("spentityid: %s" % spentityid) - log.info("service_url: %s" % service_url) - log.info("my_name: %s" % my_name) + logger.info("spentityid: %s\nservice_url: %s\nmy_name: %s" % ( + spentityid, service_url, my_name)) return self.authn_request(session_id, location, service_url, - spentityid, my_name, vorg, scoping, log, + spentityid, my_name, vorg, scoping, sign, binding=binding) def authenticate(self, entityid=None, relay_state="", @@ -471,7 +448,7 @@ class Saml2Client(object): def attribute_query(self, subject_id, destination, issuer_id=None, attribute=None, sp_name_qualifier=None, name_qualifier=None, - nameid_format=None, log=None, real_id=None): + nameid_format=None, real_id=None): """ Does a attribute request to an attribute authority, this is by default done over SOAP. Other bindings could be used but not supported right now. @@ -486,60 +463,49 @@ class Saml2Client(object): :param name_qualifier: The unique identifier of the identity provider that generated the identifier. :param nameid_format: The format of the name ID - :param log: Function to use for logging :param real_id: The identifier which is the key to this entity in the identity database :return: The attributes returned """ - if log is None: - log = self.logger - session_id = sid() issuer = self._issuer(issuer_id) request = self.create_attribute_query(session_id, subject_id, destination, issuer, attribute, sp_name_qualifier, name_qualifier, nameid_format=nameid_format) - - if log: - log.info("Request, created: %s" % request) + + logger.info("Request, created: %s" % request) soapclient = SOAPClient(destination, self.config.key_file, self.config.cert_file, ca_certs=self.config.ca_certs) - if log: - log.info("SOAP client initiated") + logger.info("SOAP client initiated") try: response = soapclient.send(request) except Exception, exc: - if log: - log.info("SoapClient exception: %s" % (exc,)) + logger.info("SoapClient exception: %s" % (exc,)) return None - if log: - log.info("SOAP request sent and got response: %s" % response) + logger.info("SOAP request sent and got response: %s" % response) # fil = open("response.xml", "w") # fil.write(response) # fil.close() if response: - if log: - log.info("Verifying response") + logger.info("Verifying response") try: # synchronous operation - aresp = attribute_response(self.config, issuer, log=log) + aresp = attribute_response(self.config, issuer) except Exception, exc: - if log: - log.error("%s", (exc,)) + logger.error("%s", (exc,)) return None _resp = aresp.loads(response, False, soapclient.response).verify() if _resp is None: - if log: - log.error("Didn't like the response") + logger.error("Didn't like the response") return None session_info = _resp.session_info() @@ -548,13 +514,11 @@ class Saml2Client(object): if real_id is not None: session_info["name_id"] = real_id self.users.add_information_about_person(session_info) - - if log: - log.info("session: %s" % session_info) + + logger.info("session: %s" % session_info) return session_info else: - if log: - log.info("No response") + logger.info("No response") return None def construct_logout_request(self, subject_id, destination, @@ -595,8 +559,8 @@ class Saml2Client(object): return request - def global_logout(self, subject_id, reason="", expire=None, - sign=None, log=None, return_to="/"): + def global_logout(self, subject_id, reason="", expire=None, sign=None, + return_to="/"): """ More or less a layer of indirection :-/ Bootstrapping the whole thing by finding all the IdPs that should be notified. @@ -607,7 +571,6 @@ class Saml2Client(object): :param expire: The latest the log out should happen. :param sign: Whether the request should be signed or not. This also depends on what binding is used. - :param log: A logging function :param return_to: Where to send the user after she has been logged out. :return: Depends on which binding is used: @@ -616,17 +579,13 @@ class Saml2Client(object): conversation. """ - if log is None: - log = self.logger - - if log: - log.info("logout request for: %s" % subject_id) + logger.info("logout request for: %s" % subject_id) # find out which IdPs/AAs I should notify entity_ids = self.users.issuers_of_info(subject_id) return self._logout(subject_id, entity_ids, reason, expire, - sign, log, return_to) + sign, return_to) def _logout(self, subject_id, entity_ids, reason, expire, sign=None, log=None, return_to="/"): @@ -640,8 +599,6 @@ class Saml2Client(object): # for all where I can use the SOAP binding, do those first not_done = entity_ids[:] response = False - if log is None: - log = self.logger for entity_id in entity_ids: response = False @@ -654,9 +611,8 @@ class Saml2Client(object): continue destination = destinations[0] - - if log: - log.info("destination to provider: %s" % destination) + + logger.info("destination to provider: %s" % destination) request = self.construct_logout_request(subject_id, destination, entity_id, reason, expire) @@ -670,9 +626,8 @@ class Saml2Client(object): request.signature = pre_signature_part(request.id, self.sec.my_cert, 1) to_sign = [(class_name(request), request.id)] - - if log: - log.info("REQUEST: %s" % request) + + logger.info("REQUEST: %s" % request) request = signed_instance_factory(request, self.sec, to_sign) @@ -683,17 +638,14 @@ class Saml2Client(object): log=log, ca_certs=self.config.ca_certs) if response: - if log: - log.info("Verifying response") + logger.info("Verifying response") response = self.logout_response(response, log) if response: not_done.remove(entity_id) - if log: - log.info("OK response from %s" % destination) + logger.info("OK response from %s" % destination) else: - if log: - log.info( + logger.info( "NOT OK response from %s" % destination) else: @@ -737,25 +689,19 @@ class Saml2Client(object): self.users.remove_person(subject_id) return True - def handle_logout_response(self, response, log): + def handle_logout_response(self, response): """ handles a Logout response :param response: A response.Response instance - :param log: A logging function :return: 4-tuple of (session_id of the last sent logout request, response message, response headers and message) """ - if log is None: - log = self.logger - if log: - log.info("state: %s" % (self.state,)) + logger.info("state: %s" % (self.state,)) status = self.state[response.in_response_to] - if log: - log.info("status: %s" % (status,)) + logger.info("status: %s" % (status,)) issuer = response.issuer() - if log: - log.info("issuer: %s" % issuer) + logger.info("issuer: %s" % issuer) del self.state[response.in_response_to] if status["entity_ids"] == [issuer]: # done self.local_logout(status["subject_id"]) @@ -766,14 +712,12 @@ class Saml2Client(object): status["entity_ids"], status["reason"], status["not_on_or_after"], - status["sign"], - log, ) + status["sign"]) - def logout_response(self, xmlstr, log=None, binding=BINDING_SOAP): + def logout_response(self, xmlstr, binding=BINDING_SOAP): """ Deal with a LogoutResponse :param xmlstr: The response as a xml string - :param log: logging function :param binding: What type of binding this message came through. :return: None if the reply doesn't contain a valid SAML LogoutResponse, otherwise the reponse if the logout was successful and None if it @@ -781,8 +725,6 @@ class Saml2Client(object): """ response = None - if log is None: - log = self.logger if xmlstr: try: @@ -790,16 +732,13 @@ class Saml2Client(object): return_addr = self.config.endpoint("single_logout_service", binding=binding)[0] except Exception: - if log: - log.info("Not supposed to handle this!") + logger.info("Not supposed to handle this!") return None try: - response = LogoutResponse(self.sec, return_addr, - debug=self.debug, log=log) + response = LogoutResponse(self.sec, return_addr) except Exception, exc: - if log: - log.info("%s" % exc) + logger.info("%s" % exc) return None if binding == BINDING_HTTP_REDIRECT: @@ -807,8 +746,7 @@ class Saml2Client(object): elif binding == BINDING_HTTP_POST: xmlstr = base64.b64decode(xmlstr) - if log: - log.debug("XMLSTR: %s" % xmlstr) + logger.debug("XMLSTR: %s" % xmlstr) response = response.loads(xmlstr, False) @@ -817,11 +755,10 @@ class Saml2Client(object): if not response: return None - - if log: - log.debug(response) - return self.handle_logout_response(response, log) + logger.debug(response) + + return self.handle_logout_response(response) return response @@ -836,8 +773,6 @@ class Saml2Client(object): """ headers = [] success = False - if log is None: - log = self.logger try: saml_request = get['SAMLRequest'] @@ -848,8 +783,7 @@ class Saml2Client(object): xml = decode_base64_and_inflate(saml_request) request = samlp.logout_request_from_string(xml) - if log: - log.debug(request) + logger.debug(request) if request.name_id.text == subject_id: status = samlp.STATUS_SUCCESS @@ -862,8 +796,7 @@ class Saml2Client(object): request.id, status) - if log: - log.info("RESPONSE: {0:>s}".format(response)) + logger.info("RESPONSE: {0:>s}".format(response)) if 'RelayState' in get: rstate = get['RelayState'] @@ -876,7 +809,7 @@ class Saml2Client(object): return headers, success - def logout_request(self, request, subject_id, log=None, + def logout_request(self, request, subject_id, binding=BINDING_HTTP_REDIRECT): """ Deal with a LogoutRequest @@ -885,11 +818,9 @@ class Saml2Client(object): :param subject_id: the id of the current logged user :return: What is returned also depends on which binding is used. """ - if log is None: - log = self.logger if binding == BINDING_HTTP_REDIRECT: - return self.http_redirect_logout_request(request, subject_id, log) + return self.http_redirect_logout_request(request, subject_id) def make_logout_response(self, idp_entity_id, request_id, status_code, binding=BINDING_HTTP_REDIRECT): @@ -951,7 +882,7 @@ class Saml2Client(object): action=None, resource=None, subject=None, binding=saml2.BINDING_HTTP_REDIRECT, - log=None, sign=False): + sign=False): """ Makes an authz decision query. :param entityid: The entity ID of the IdP to send the request to @@ -960,7 +891,6 @@ class Saml2Client(object): :param resource: :param subject: :param binding: Which binding to use for sending the request - :param log: Where to write log messages :param sign: Whether the request should be signed or not. :return: AuthzDecisionQuery instance """ @@ -977,13 +907,12 @@ class Saml2Client(object): _action, saml.Evidence(assertion=assertion), resource, subject, - binding, log, sign) + binding, sign) #noinspection PyUnusedLocal def authz_decision_query(self, entityid, action, evidence=None, resource=None, subject=None, - binding=saml2.BINDING_HTTP_REDIRECT, - log=None, sign=None): + binding=saml2.BINDING_HTTP_REDIRECT, sign=None): """ Creates an authz decision query. :param entityid: The entity ID of the IdP to send the request to @@ -992,7 +921,6 @@ class Saml2Client(object): :param resource: The resource you want to perform the action on :param subject: Who wants to do the thing :param binding: Which binding to use for sending the request - :param log: Where to write log messages :param sign: Whether the request should be signed or not. :return: AuthzDecisionQuery instance """ @@ -1001,14 +929,8 @@ class Saml2Client(object): service_url = self.service_url() my_name = self._my_name() - if log is None: - log = self.logger - - if log: - log.info("spentityid: %s" % spentityid) - log.info("service_url: %s" % service_url) - log.info("my_name: %s" % my_name) - + logger.info("spentityid: %s\nservice_url: %s\nmy_name: %s" % ( + spentityid, service_url, my_name)) # authen_req = self.authn_request(session_id, location, # service_url, spentityid, my_name, vorg, @@ -1026,13 +948,13 @@ class Saml2Client(object): #noinspection PyUnusedLocal - def authz_decision_query_response(self, response, log=None): + def authz_decision_query_response(self, response): """ Verify that the response is OK """ pass #noinspection PyUnusedLocal def do_authz_decision_query(self, entityid, assertion=None, - log=None, sign=False): + sign=False): authz_decision_query = self.authz_decision_query(entityid, assertion) @@ -1051,21 +973,17 @@ class Saml2Client(object): response = send_using_soap(authz_decision_query, destination, self.config.key_file, self.config.cert_file, - log=log, ca_certs=self.config.ca_certs) if response: - if log: - log.info("Verifying response") - response = self.authz_decision_query_response(response, log) + logger.info("Verifying response") + response = self.authz_decision_query_response(response) if response: #not_done.remove(entity_id) - if log: - log.info("OK response from %s" % destination) + logger.info("OK response from %s" % destination) return response else: - if log: - log.info("NOT OK response from %s" % destination) + logger.info("NOT OK response from %s" % destination) return None diff --git a/src/saml2/config.py b/src/saml2/config.py index 2b126314..98c5db28 100644 --- a/src/saml2/config.py +++ b/src/saml2/config.py @@ -18,6 +18,8 @@ from saml2.attribute_converter import ac_factory from saml2.assertion import Policy from saml2.sigver import get_xmlsec_binary +logger = logging.getLogger(__name__) + COMMON_ARGS = ["entityid", "xmlsec_binary", "debug", "key_file", "cert_file", "secret", "accepted_time_diff", "name", "ca_certs", "description", @@ -84,8 +86,6 @@ LOG_HANDLER = { } LOG_FORMAT = "%(asctime)s %(name)s: %(levelname)s %(message)s" -#LOG_FORMAT = "%(asctime)s %(name)s: %(levelname)s [%(sid)s][%(func)s] % -# (message)s" class ConfigurationError(Exception): pass diff --git a/src/saml2/ecp.py b/src/saml2/ecp.py index 0cc4b9bf..69fc999f 100644 --- a/src/saml2/ecp.py +++ b/src/saml2/ecp.py @@ -18,6 +18,7 @@ """ Contains classes used in the SAML ECP profile """ +import logging from saml2 import element_to_extension_element from saml2 import samlp @@ -35,6 +36,8 @@ from saml2.s_utils import sid from saml2.response import authn_response +logger = logging.getLogger(__name__) + SERVICE = "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp" def ecp_capable(headers): @@ -49,14 +52,12 @@ def ecp_capable(headers): ACTOR = "http://schemas.xmlsoap.org/soap/actor/next" #noinspection PyUnusedLocal -def ecp_auth_request(cls, entityid=None, relay_state="", - log=None, sign=False): +def ecp_auth_request(cls, entityid=None, relay_state="", sign=False): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. - :param log: Where to write log messages :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ @@ -111,13 +112,11 @@ def ecp_auth_request(cls, entityid=None, relay_state="", # <samlp:AuthnRequest> # ---------------------------------------- - if log: - log.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP)) + logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP)) location = cls._sso_location(entityid, binding=BINDING_SOAP) session_id = sid() - authn_req = cls.authn(location, session_id, log=log, - binding=BINDING_PAOS, + authn_req = cls.authn(location, session_id, binding=BINDING_PAOS, service_url_binding=BINDING_PAOS) body = soapenv.Body() @@ -144,9 +143,7 @@ def handle_ecp_authn_response(cls, soap_message, outstanding=None): item.c_namespace == ecp.NAMESPACE: _relay_state = item - response = authn_response(cls.config, cls.service_url(), - outstanding, log=cls.logger, - debug=cls.debug, + response = authn_response(cls.config, cls.service_url(), outstanding, allow_unsolicited=True) response.loads("%s" % rdict["body"], False, soap_message) @@ -182,9 +179,8 @@ class ECPServer(Server): TODO: Still tentative """ - def __init__(self, config_file="", config=None, _cache="", - log=None, debug=0): - Server.__init__(self, config_file, config, _cache, log, debug) + def __init__(self, config_file="", config=None, _cache=""): + Server.__init__(self, config_file, config, _cache) def parse_ecp_authn_query(self): pass diff --git a/src/saml2/ecp_client.py b/src/saml2/ecp_client.py index 2494b35e..d8bb938a 100644 --- a/src/saml2/ecp_client.py +++ b/src/saml2/ecp_client.py @@ -21,6 +21,7 @@ programs. """ import cookielib +import logging import sys from saml2 import soap @@ -37,11 +38,12 @@ from saml2.metadata import MetaData SERVICE = "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp" PAOS_HEADER_INFO = 'ver="%s";"%s"' % (paos.NAMESPACE, SERVICE) +logger = logging.getLogger(__name__) + class Client(object): def __init__(self, user, passwd, sp="", idp=None, metadata_file=None, xmlsec_binary=None, verbose=0, ca_certs="", - disable_ssl_certificate_validation=True, logger=None, - debug=False): + disable_ssl_certificate_validation=True): """ :param user: user name :param passwd: user password @@ -55,15 +57,11 @@ class Client(object): :param disable_ssl_certificate_validation: If disable_ssl_certificate_validation is true, SSL cert validation will not be performed. - :param logger: Somewhere to write logs to - :param debug: Whether debug output is needed """ self._idp = idp self._sp = sp self.user = user self.passwd = passwd - self.log = logger - self.debug = debug self._verbose = verbose if metadata_file: @@ -83,9 +81,7 @@ class Client(object): disable_ssl_certificate_validation=disable_ssl_certificate_validation) def _debug_info(self, text): - if self.debug: - if self.log: - self.log.debug(text) + logger.debug(text) if self._verbose: print >> sys.stderr, text @@ -104,8 +100,7 @@ class Client(object): binding=binding) if ssos: self._idp = ssos[0] - if self.debug: - self.log.debug("IdP endpoint: '%s'" % self._idp) + logger.debug("IdP endpoint: '%s'" % self._idp) return self._idp raise Exception("No suitable endpoint found for entity id '%s'" % ( @@ -244,8 +239,7 @@ class Client(object): self._debug_info("[P3] IdP response: %s" % response) self.done_ecp = True - if self.debug: - self.log.debug("Done ECP") + logger.debug("Done ECP") return None @@ -297,9 +291,7 @@ class Client(object): # header blocks may also be present try: respdict = soap.class_instances_from_soap_enveloped_saml_thingies( - response, - [paos, ecp, - samlp]) + response,[paos, ecp,samlp]) self.ecp_conversation(respdict, idp_entity_id) # should by now be authenticated so this should go smoothly response = op(**opargs) diff --git a/src/saml2/encdec.py b/src/saml2/encdec.py index 239f5449..9898bf83 100644 --- a/src/saml2/encdec.py +++ b/src/saml2/encdec.py @@ -1,3 +1,4 @@ +import logging import os import sys @@ -15,6 +16,8 @@ __author__ = 'rohe0002' import xmlenc as enc +logger = logging.getLogger(__name__) + #<EncryptedData # xmlns="http://www.w3.org/2001/04/xmlenc#" # Type="http://www.w3.org/2001/04/xmlenc#Element"> diff --git a/src/saml2/httplib2cookie.py b/src/saml2/httplib2cookie.py index 912523f9..a6742cc6 100644 --- a/src/saml2/httplib2cookie.py +++ b/src/saml2/httplib2cookie.py @@ -32,6 +32,7 @@ # CookieJar class with httplib2. # # +import logging import re import cookielib @@ -40,6 +41,8 @@ from httplib2 import Http import urllib import urllib2 +logger = logging.getLogger(__name__) + class DummyRequest(object): """Simulated urllib2.Request object for httplib2 diff --git a/src/saml2/httputil.py b/src/saml2/httputil.py index e29ccf1f..7a2a8e52 100644 --- a/src/saml2/httputil.py +++ b/src/saml2/httputil.py @@ -1,8 +1,12 @@ +import logging + __author__ = 'rohe0002' import cgi from urllib import quote +logger = logging.getLogger(__name__) + class Response(object): _template = None _status = '200 OK' diff --git a/src/saml2/mcache.py b/src/saml2/mcache.py index a94f06cd..d2c200aa 100644 --- a/src/saml2/mcache.py +++ b/src/saml2/mcache.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import logging import memcache from saml2 import time_util @@ -8,6 +9,7 @@ from saml2.cache import ToOld, CacheError # gathered from several different sources, all with their own # timeout time. +logger = logging.getLogger(__name__) def _key(prefix, name): return "%s_%s" % (prefix, name) diff --git a/src/saml2/mdbcache.py b/src/saml2/mdbcache.py index 28158973..d1347cca 100644 --- a/src/saml2/mdbcache.py +++ b/src/saml2/mdbcache.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import logging __author__ = 'rolandh' @@ -11,6 +12,8 @@ from saml2 import time_util from saml2.cache import ToOld from saml2.time_util import TIME_FORMAT +logger = logging.getLogger(__name__) + class Cache(object): def __init__(self, server=None, debug=0, db=None): if server: diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index df1384a9..e2526cac 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -18,6 +18,7 @@ """ Contains classes and functions to alleviate the handling of SAML metadata """ +import logging import httplib2 import sys @@ -57,6 +58,8 @@ from saml2.sigver import pem_format from saml2.validate import valid_instance, NotValid from saml2.country_codes import D_COUNTRIES +logger = logging.getLogger(__name__) + def metadata_extension_modules(): _pre = "saml2.extension" res = [] @@ -86,8 +89,7 @@ def keep_updated(func, self=None, entity_id=None, *args, **kwargs): class MetaData(object): """ A class to manage metadata information """ - def __init__(self, xmlsec_binary=None, attrconv=None, log=None): - self.log = log + def __init__(self, xmlsec_binary=None, attrconv=None): self.xmlsec_binary = xmlsec_binary self.attrconv = attrconv or [] self._loc_key = {} @@ -388,15 +390,9 @@ class MetaData(object): def do_entity_descriptor(self, entity_descr, source, valid_until=0): try: if not valid(entity_descr.valid_until): - if self.log: - self.log.info( - "Entity descriptor (entity id:%s) to old" % \ - entity_descr.entity_id) - else: - print >> sys.stderr, \ - "Entity descriptor (entity id:%s) to old" % \ - entity_descr.entity_id - return + logger.info("Entity descriptor (entity id:%s) to old" % ( + entity_descr.entity_id,)) + return except AttributeError: pass @@ -483,8 +479,7 @@ class MetaData(object): self.import_metadata(content, (url, cert)) return True else: - if self.log: - self.log.info("Response status: %s" % response.status) + logger.info("Response status: %s" % response.status) return False @keep_updated diff --git a/src/saml2/population.py b/src/saml2/population.py index 78233abb..58ee1cd4 100644 --- a/src/saml2/population.py +++ b/src/saml2/population.py @@ -1,6 +1,8 @@ - +import logging from saml2.cache import Cache +logger = logging.getLogger(__name__) + class Population(object): def __init__(self, cache=None): if cache: @@ -33,8 +35,10 @@ class Population(object): def issuers_of_info(self, subject_id): return self.cache.entities(subject_id) - def get_identity(self, subject_id, entities=None, check_not_on_or_after=True): - return self.cache.get_identity(subject_id, entities, check_not_on_or_after) + def get_identity(self, subject_id, entities=None, + check_not_on_or_after=True): + return self.cache.get_identity(subject_id, entities, + check_not_on_or_after) def get_info_from(self, subject_id, entity_id): return self.cache.get(subject_id, entity_id) diff --git a/src/saml2/request.py b/src/saml2/request.py index 6053beda..f5fa8028 100644 --- a/src/saml2/request.py +++ b/src/saml2/request.py @@ -1,4 +1,4 @@ -import sys +import logging from attribute_converter import to_local from saml2 import time_util @@ -9,20 +9,16 @@ from saml2.validate import valid_instance from saml2.validate import NotValid from saml2.response import IncorrectlySigned +logger = logging.getLogger(__name__) + def _dummy(_arg): return None class Request(object): - def __init__(self, sec_context, receiver_addrs, log=None, timeslack=0, - debug=0): + def __init__(self, sec_context, receiver_addrs, timeslack=0): self.sec = sec_context self.receiver_addrs = receiver_addrs self.timeslack = timeslack - self.log = log - self.debug = debug - if self.debug and not self.log: - self.debug = 0 - self.xmlstr = "" self.name_id = "" self.message = None @@ -38,40 +34,32 @@ class Request(object): def _loads(self, xmldata, decode=True): if decode: - if self.debug: - self.log.debug("Expected to decode and inflate xml data") + logger.debug("Expected to decode and inflate xml data") decoded_xml = s_utils.decode_base64_and_inflate(xmldata) else: decoded_xml = xmldata # own copy self.xmlstr = decoded_xml[:] - if self.debug: - self.log.info("xmlstr: %s" % (self.xmlstr,)) + logger.info("xmlstr: %s" % (self.xmlstr,)) try: self.message = self.signature_check(decoded_xml) except TypeError: raise except Exception, excp: - if self.log: - self.log.info("EXCEPTION: %s", excp) + logger.info("EXCEPTION: %s", excp) if not self.message: - if self.log: - self.log.error("Response was not correctly signed") - self.log.info(decoded_xml) + logger.error("Response was not correctly signed") + logger.info(decoded_xml) raise IncorrectlySigned() - - if self.debug: - self.log.info("request: %s" % (self.message,)) + + logger.info("request: %s" % (self.message,)) try: valid_instance(self.message) except NotValid, exc: - if self.log: - self.log.error("Not valid request: %s" % exc.args[0]) - else: - print >> sys.stderr, "Not valid request: %s" % exc.args[0] + logger.error("Not valid request: %s" % exc.args[0]) raise return self @@ -91,12 +79,8 @@ class Request(object): assert self.message.version == "2.0" if self.message.destination and \ self.message.destination not in self.receiver_addrs: - if self.log: - self.log.error("%s != %s" % (self.message.destination, + logger.error("%s != %s" % (self.message.destination, self.receiver_addrs)) - else: - print >> sys.stderr, "%s != %s" % (self.message.destination, - self.receiver_addrs) raise OtherError("Not destined for me!") assert self.issue_instant_ok() @@ -138,16 +122,14 @@ class Request(object): class LogoutRequest(Request): def __init__(self, sec_context, receiver_addrs, log=None, timeslack=0, debug=0): - Request.__init__(self, sec_context, receiver_addrs, log, timeslack, - debug) + Request.__init__(self, sec_context, receiver_addrs, timeslack) self.signature_check = self.sec.correctly_signed_logout_request class AttributeQuery(Request): def __init__(self, sec_context, receiver_addrs, log=None, timeslack=0, debug=0): - Request.__init__(self, sec_context, receiver_addrs, log, timeslack, - debug) + Request.__init__(self, sec_context, receiver_addrs, timeslack) self.signature_check = self.sec.correctly_signed_attribute_query def attribute(self): @@ -159,8 +141,7 @@ class AttributeQuery(Request): class AuthnRequest(Request): def __init__(self, sec_context, attribute_converters, receiver_addrs, log=None, timeslack=0, debug=0): - Request.__init__(self, sec_context, receiver_addrs, log, timeslack, - debug) + Request.__init__(self, sec_context, receiver_addrs, timeslack) self.attribute_converters = attribute_converters self.signature_check = self.sec.correctly_signed_authn_request @@ -172,8 +153,7 @@ class AuthnRequest(Request): class AuthzRequest(Request): def __init__(self, sec_context, receiver_addrs, log=None, timeslack=0, debug=0): - Request.__init__(self, sec_context, receiver_addrs, log, timeslack, - debug) + Request.__init__(self, sec_context, receiver_addrs, timeslack) self.signature_check = self.sec.correctly_signed_logout_request def action(self): diff --git a/src/saml2/response.py b/src/saml2/response.py index 8bfaea6f..6bf726b3 100644 --- a/src/saml2/response.py +++ b/src/saml2/response.py @@ -17,6 +17,7 @@ import calendar import base64 +import logging import sys from saml2 import samlp @@ -38,6 +39,8 @@ from saml2.validate import valid_instance from saml2.validate import valid_address from saml2.validate import NotValid +logger = logging.getLogger(__name__) + # --------------------------------------------------------------------------- class IncorrectlySigned(Exception): @@ -205,7 +208,7 @@ class StatusResponse(object): # print "issue_instant: %s" % self.response.issue_instant # print "%s < x < %s" % (lower, upper) issued_at = str_to_time(self.response.issue_instant) - return issued_at > lower and issued_at < upper + return lower < issued_at < upper def _verify(self): if self.request_id and self.in_response_to and \ diff --git a/src/saml2/s_utils.py b/src/saml2/s_utils.py index 971f5b75..289e2381 100644 --- a/src/saml2/s_utils.py +++ b/src/saml2/s_utils.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import logging import time import base64 @@ -22,6 +23,8 @@ except ImportError: from md5 import md5 import zlib +logger = logging.getLogger(__name__) + class VersionMismatch(Exception): pass @@ -304,3 +307,35 @@ def verify_signature(secret, parts): return True else: return False + + +FTICKS_FORMAT = "F-TICKS/SWAMID/2.0%s#" + +def fticks_log(sp, logf, idp_entity_id, user_id, secret, assertion): + """ + 'F-TICKS/' federationIdentifier '/' version *('#' attribute '=' value ) '#' + Allowed attributes: + TS the login time stamp + RP the relying party entityID + AP the asserting party entityID (typcially the IdP) + PN a sha256-hash of the local principal name and a unique key + AM the authentication method URN + + :param sp: Client instance + :param logf: The log function to use + :param idp_entity_id: IdP entity ID + :param user_id: The user identifier + :param secret: A salt to make the hash more secure + :param assertion: A SAML Assertion instance gotten from the IdP + """ + csum = hmac.new(secret, digestmod=hashlib.sha1) + csum.update(user_id) + + info = { + "TS": time.time(), + "RP": sp.entity_id, + "AP": idp_entity_id, + "PN": csum.hexdigest(), + "AM": assertion.AuthnStatement.AuthnContext.AuthnContextClassRef.text + } + logf.info(FTICKS_FORMAT % "#".join(["%s=%s" % (a,v) for a,v in info]))
\ No newline at end of file diff --git a/src/saml2/server.py b/src/saml2/server.py index 5b9f3938..9af44b00 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -18,6 +18,7 @@ """Contains classes and functions that a SAML2.0 Identity provider (IdP) or attribute authority (AA) may use to conclude its tasks. """ +import logging import shelve import sys @@ -57,20 +58,20 @@ from saml2.config import config_factory from saml2.assertion import Assertion, Policy +logger = logging.getLogger(__name__) + class UnknownVO(Exception): pass class Identifier(object): """ A class that handles identifiers of objects """ - def __init__(self, db, voconf=None, debug=0, log=None): + def __init__(self, db, voconf=None): if isinstance(db, basestring): self.map = shelve.open(db, writeback=True) else: self.map = db self.voconf = voconf - self.debug = debug - self.log = log - + def _store(self, typ, entity_id, local, remote): self.map["|".join([typ, entity_id, "f", local])] = remote self.map["|".join([typ, entity_id, "b", remote])] = local @@ -277,8 +278,7 @@ class Server(object): idb = addr if idb is not None: - self.ident = Identifier(idb, self.conf.virtual_organization, - self.debug, self.log) + self.ident = Identifier(idb, self.conf.virtual_organization) else: raise Exception("Couldn't open identity database: %s" % (dbspec,)) diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index 8c6d905c..2c26bc57 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -20,6 +20,7 @@ Based on the use of xmlsec1 binaries and not the python xmlsec module. """ import base64 +import logging import random import os import sys @@ -40,6 +41,8 @@ from saml2.time_util import instant from tempfile import NamedTemporaryFile from subprocess import Popen, PIPE +logger = logging.getLogger(__name__) + SIG = "{%s#}%s" % (ds.NAMESPACE, "Signature") def signed(item): @@ -321,9 +324,12 @@ def parse_xmlsec_output(output): __DEBUG = 0 +LOG_LINE = 60*"="+"\n%s\n"+60*"-"+"\n%s"+60*"=" +LOG_LINE_2 = 60*"="+"\n%s\n%s\n"+60*"-"+"\n%s"+60*"=" + def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem", node_name=NODE_NAME, debug=False, node_id=None, - log=None, id_attr=""): + id_attr=""): """ Verifies the signature of a XML document. :param enctext: The signed XML document @@ -374,12 +380,7 @@ def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem", print p_err verified = parse_xmlsec_output(p_err) except XmlsecError, exc: - if log: - log.error(60*"=") - log.error(p_out) - log.error(60*"-") - log.error("%s" % exc) - log.error(60*"=") + logger.error(LOG_LINE % (p_out, exc)) raise SignatureError("%s" % (exc,)) return verified @@ -421,12 +422,10 @@ def read_cert_from_file(cert_file, cert_type): data = open(cert_file).read() return base64.b64encode(str(data)) -def security_context(conf, log=None, debug=None): +def security_context(conf, debug=None): """ Creates a security context based on the configuration :param conf: The configuration - :param log: A logger if different from the one specified in the - configuration :return: A SecurityContext instance """ if not conf: @@ -443,12 +442,11 @@ def security_context(conf, log=None, debug=None): return SecurityContext(conf.xmlsec_binary, conf.key_file, cert_file=conf.cert_file, metadata=metadata, - log=log, debug=debug, - only_use_keys_in_metadata=_only_md) + debug=debug, only_use_keys_in_metadata=_only_md) class SecurityContext(object): def __init__(self, xmlsec_binary, key_file="", key_type= "pem", - cert_file="", cert_type="pem", metadata=None, log=None, + cert_file="", cert_type="pem", metadata=None, debug=False, template="", encrypt_key_type="des-192", only_use_keys_in_metadata=False): @@ -465,7 +463,6 @@ class SecurityContext(object): self.metadata = metadata self.only_use_keys_in_metadata = only_use_keys_in_metadata - self.log = log self.debug = debug if not template: @@ -476,12 +473,8 @@ class SecurityContext(object): self.key_type = encrypt_key_type - if self.debug and not self.log: - self.debug = 0 - def correctly_signed(self, xml, must=False): - if self.log: - self.log.info("verify correct signature") + logger.info("verify correct signature") return self.correctly_signed_response(xml, must) def encrypt(self, text, recv_key="", template="", key_type=""): @@ -501,8 +494,7 @@ class SecurityContext(object): if not template: template = self.template - if self.log: - self.log.info("input len: %d" % len(text)) + logger.info("input len: %d" % len(text)) _, fil = make_temp("%s" % text, decode=False) ntf = NamedTemporaryFile() @@ -513,8 +505,7 @@ class SecurityContext(object): "--output", ntf.name, template] - if self.debug: - self.log.debug("Encryption command: %s" % " ".join(com_list)) + logger.debug("Encryption command: %s" % " ".join(com_list)) pof = Popen(com_list, stderr=PIPE, stdout=PIPE) @@ -522,14 +513,8 @@ class SecurityContext(object): try: parse_xmlsec_output(p_err) except XmlsecError, exc: - if self.debug: - p_out = pof.stdout.read() - self.log.error(60*"=") - self.log.error(p_out) - self.log.error(p_err) - self.log.error(60*"-") - self.log.error("%s" % exc) - self.log.error(60*"=") + p_out = pof.stdout.read() + logger.error(LOG_LINE_2 % (p_out, p_err, exc)) raise DecryptError("%s" % (exc,)) ntf.seek(0) @@ -542,8 +527,7 @@ class SecurityContext(object): :return: The decrypted text """ - if self.log: - self.log.info("input len: %d" % len(enctext)) + logger.info("input len: %d" % len(enctext)) _, fil = make_temp("%s" % enctext, decode=False) ntf = NamedTemporaryFile() @@ -553,8 +537,7 @@ class SecurityContext(object): "--id-attr:%s" % ID_ATTR, ENC_KEY_CLASS, fil] - if self.debug: - self.log.debug("Decrypt command: %s" % " ".join(com_list)) + logger.debug("Decrypt command: %s" % " ".join(com_list)) pof = Popen(com_list, stderr=PIPE, stdout=PIPE) @@ -562,14 +545,8 @@ class SecurityContext(object): try: parse_xmlsec_output(p_err) except XmlsecError, exc: - if self.debug: - p_out = pof.stdout.read() - self.log.error(60*"=") - self.log.error(p_out) - self.log.error(p_err) - self.log.error(60*"-") - self.log.error("%s" % exc) - self.log.error(60*"=") + p_out = pof.stdout.read() + logger.error(LOG_LINE_2 % (p_out, p_err, exc)) raise DecryptError("%s" % (exc,)) ntf.seek(0) @@ -639,12 +616,10 @@ class SecurityContext(object): verified = True break except XmlsecError, exc: - if self.log: - self.log.error("check_sig: %s" % exc) + logger.error("check_sig: %s" % exc) pass except Exception, exc: - if self.log: - self.log.error("check_sig: %s" % exc) + logger.error("check_sig: %s" % exc) raise if not verified: @@ -776,21 +751,18 @@ class SecurityContext(object): # Try to find the signing cert in the assertion for assertion in response.assertion: if not assertion.signature: - if self.debug: - self.log.debug("unsigned") + logger.debug("unsigned") if must: raise SignatureError("Signature missing") continue else: - if self.debug: - self.log.debug("signed") + logger.debug("signed") try: self._check_signature(decoded_xml, assertion, class_name(assertion), origdoc) except Exception, exc: - if self.log: - self.log.error("correctly_signed_response: %s" % exc) + logger.error("correctly_signed_response: %s" % exc) raise return response diff --git a/src/saml2/soap.py b/src/saml2/soap.py index a1e0ea1b..27d85c6d 100644 --- a/src/saml2/soap.py +++ b/src/saml2/soap.py @@ -18,6 +18,7 @@ """ Suppport for the client part of the SAML2.0 SOAP binding. """ +import logging from httplib2 import Http @@ -37,6 +38,9 @@ except ImportError: #noinspection PyUnresolvedReferences from elementtree import ElementTree + +logger = logging.getLogger(__name__) + class XmlParseError(Exception): pass @@ -197,9 +201,8 @@ def soap_fault(message=None, actor=None, code=None, detail=None): class HTTPClient(object): """ For sending a message to a HTTP server using POST or GET """ - def __init__(self, path, keyfile=None, certfile=None, log=None, - cookiejar=None, ca_certs="", - disable_ssl_certificate_validation=True): + def __init__(self, path, keyfile=None, certfile=None, cookiejar=None, + ca_certs="", disable_ssl_certificate_validation=True): self.path = path if cookiejar is not None: self.cj = True @@ -210,7 +213,7 @@ class HTTPClient(object): self.cj = False self.server = Http(ca_certs=ca_certs, disable_ssl_certificate_validation=disable_ssl_certificate_validation) - self.log = log + self.response = None if keyfile: @@ -299,13 +302,12 @@ class HTTPClient(object): class SOAPClient(object): - def __init__(self, server_url, keyfile=None, certfile=None, log=None, + def __init__(self, server_url, keyfile=None, certfile=None, cookiejar=None, ca_certs="", disable_ssl_certificate_validation=True): - self.server = HTTPClient(server_url, keyfile, certfile, log, - cookiejar, ca_certs=ca_certs, + self.server = HTTPClient(server_url, keyfile, certfile, cookiejar, + ca_certs=ca_certs, disable_ssl_certificate_validation=disable_ssl_certificate_validation) - self.log = log self.response = None def send(self, request, path=None, headers=None, sign=None, sec=None): @@ -325,8 +327,7 @@ class SOAPClient(object): self.response = _response if _response: - if self.log: - self.log.info("SOAP response: %s" % _response) + logger.info("SOAP response: %s" % _response) return parse_soap_enveloped_saml_response(_response) else: return False diff --git a/src/saml2/virtual_org.py b/src/saml2/virtual_org.py index 13e713e1..a5d40f54 100644 --- a/src/saml2/virtual_org.py +++ b/src/saml2/virtual_org.py @@ -1,14 +1,13 @@ +import logging from saml2.attribute_resolver import AttributeResolver +logger = logging.getLogger(__name__) + class VirtualOrg(object): def __init__(self, sp, vorg, log=None): self.sp = sp # The parent SP client instance self.config = sp.config self.vorg_name = vorg - if log is None: - self.log = self.sp.logger - else: - self.log = log self.vorg_conf = self.config.vo_conf(self.vorg_name) def _cache_session(self, session_info): @@ -44,8 +43,7 @@ class VirtualOrg(object): # Remove the ones I have cached data from about this subject vo_members = [m for m in vo_members if not self.sp.users.cache.active( subject_id, m)] - if self.log: - self.log.info("VO members (not cached): %s" % vo_members) + logger.info("VO members (not cached): %s" % vo_members) return vo_members def get_common_identifier(self, subject_id): @@ -61,12 +59,9 @@ class VirtualOrg(object): return None def do_aggregation(self, subject_id, log=None): - if log is None: - log = self.log - - if log: - log.info("** Do VO aggregation **") - log.info("SubjectID: %s, VO:%s" % (subject_id, self.vorg_name)) + + logger.info("** Do VO aggregation **\nSubjectID: %s, VO:%s" % ( + subject_id, self.vorg_name)) to_ask = self.members_to_ask(subject_id) if to_ask: @@ -90,11 +85,9 @@ class VirtualOrg(object): log=log, real_id=subject_id): _ = self._cache_session(session_info) - if log: - log.info( - ">Issuers: %s" % self.sp.users.issuers_of_info(subject_id)) - log.info( - "AVA: %s" % (self.sp.users.get_identity(subject_id),)) + logger.info(">Issuers: %s" % self.sp.users.issuers_of_info( + subject_id)) + logger.info("AVA: %s" % (self.sp.users.get_identity(subject_id),)) return True else: |