X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Fproviders%2Fsaml2%2Fprovider.py;h=7d47363c527439556e6f3a1e17dde750685e11b0;hp=d3ed5daad9e0ea43aad9643e332de387dd43c572;hb=277ed07e8810dbd0adbbf213f56246394753f452;hpb=8f6f3b2226d66a085fffa521dea1cf31c42e896f diff --git a/ipsilon/providers/saml2/provider.py b/ipsilon/providers/saml2/provider.py index d3ed5da..7d47363 100755 --- a/ipsilon/providers/saml2/provider.py +++ b/ipsilon/providers/saml2/provider.py @@ -18,23 +18,11 @@ # along with this program. If not, see . from ipsilon.providers.common import ProviderException +from ipsilon.tools.saml2metadata import SAML2_NAMEID_MAP import cherrypy import lasso -NAMEID_MAP = { - 'email': lasso.SAML2_NAME_IDENTIFIER_FORMAT_EMAIL, - 'encrypted': lasso.SAML2_NAME_IDENTIFIER_FORMAT_ENCRYPTED, - 'entity': lasso.SAML2_NAME_IDENTIFIER_FORMAT_ENTITY, - 'kerberos': lasso.SAML2_NAME_IDENTIFIER_FORMAT_KERBEROS, - 'persistent': lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT, - 'transient': lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT, - 'unspecified': lasso.SAML2_NAME_IDENTIFIER_FORMAT_UNSPECIFIED, - 'windows': lasso.SAML2_NAME_IDENTIFIER_FORMAT_WINDOWS, - 'x509': lasso.SAML2_NAME_IDENTIFIER_FORMAT_X509, -} - - class InvalidProviderId(ProviderException): def __init__(self, code): @@ -64,6 +52,7 @@ class ServiceProvider(object): idval = data.keys()[0] data = self.cfg.get_data(idval=idval) self._properties = data[idval] + self._staging = dict() @property def provider_id(self): @@ -73,13 +62,35 @@ class ServiceProvider(object): def name(self): return self._properties['name'] + @name.setter + def name(self, value): + self._staging['name'] = value + + @property + def owner(self): + if 'owner' in self._properties: + return self._properties['owner'] + else: + return '' + + @owner.setter + def owner(self, value): + self._staging['owner'] = value + @property - def allowed_namedids(self): - if 'allowed nameid' in self._properties: - return self._properties['allowed nameid'] + def allowed_nameids(self): + if 'allowed nameids' in self._properties: + allowed = self._properties['allowed nameids'] + return [x.strip() for x in allowed.split(',')] else: return self.cfg.default_allowed_nameids + @allowed_nameids.setter + def allowed_nameids(self, value): + if type(value) is not list: + raise ValueError("Must be a list") + self._staging['allowed nameids'] = ','.join(value) + @property def default_nameid(self): if 'default nameid' in self._properties: @@ -87,20 +98,43 @@ class ServiceProvider(object): else: return self.cfg.default_nameid + @default_nameid.setter + def default_nameid(self, value): + self._staging['default nameid'] = value + + def save_properties(self): + data = self.cfg.get_data(name='id', value=self.provider_id) + if len(data) != 1: + raise InvalidProviderId('Could not find SP data') + idval = data.keys()[0] + data = dict() + data[idval] = self._staging + self.cfg.save_data(data) + data = self.cfg.get_data(idval=idval) + self._properties = data[idval] + self._staging = dict() + def get_valid_nameid(self, nip): self._debug('Requested NameId [%s]' % (nip.format,)) if nip.format is None: - return NAMEID_MAP[self.default_nameid] + return SAML2_NAMEID_MAP[self.default_nameid] elif nip.format == lasso.SAML2_NAME_IDENTIFIER_FORMAT_UNSPECIFIED: - return NAMEID_MAP[self.default_nameid] + return SAML2_NAMEID_MAP[self.default_nameid] else: - allowed = self.allowed_namedids + allowed = self.allowed_nameids self._debug('Allowed NameIds %s' % (repr(allowed))) for nameid in allowed: - if nip.format == NAMEID_MAP[nameid]: + if nip.format == SAML2_NAMEID_MAP[nameid]: return nip.format raise NameIdNotAllowed(nip.format) + def permanently_delete(self): + data = self.cfg.get_data(name='id', value=self.provider_id) + if len(data) != 1: + raise InvalidProviderId('Could not find SP data') + idval = data.keys()[0] + self.cfg.del_datum(idval) + def _debug(self, fact): if cherrypy.config.get('debug', False): cherrypy.log(fact) @@ -109,3 +143,62 @@ class ServiceProvider(object): if 'strip domain' in self._properties: return username.split('@', 1)[0] return username + + +class ServiceProviderCreator(object): + + def __init__(self, config): + self.cfg = config + + def create_from_buffer(self, name, metabuf): + '''Test and add data''' + + test = lasso.Server() + test.addProviderFromBuffer(lasso.PROVIDER_ROLE_SP, metabuf) + newsps = test.get_providers() + if len(newsps) != 1: + raise InvalidProviderId("Metadata must contain one Provider") + + spid = newsps.keys()[0] + data = self.cfg.get_data(name='id', value=spid) + if len(data) != 0: + raise InvalidProviderId("Provider Already Exists") + datum = {'id': spid, 'name': name, 'type': 'SP', 'metadata': metabuf} + self.cfg.new_datum(datum) + + data = self.cfg.get_data(name='id', value=spid) + if len(data) != 1: + raise InvalidProviderId("Internal Error") + idval = data.keys()[0] + data = self.cfg.get_data(idval=idval) + sp = data[idval] + self.cfg.idp.add_provider(sp) + + return ServiceProvider(self.cfg, spid) + + +class IdentityProvider(object): + def __init__(self, config): + self.server = lasso.Server(config.idp_metadata_file, + config.idp_key_file, + None, + config.idp_certificate_file) + self.server.role = lasso.PROVIDER_ROLE_IDP + + def add_provider(self, sp): + self.server.addProviderFromBuffer(lasso.PROVIDER_ROLE_SP, + sp['metadata']) + self._debug('Added SP %s' % sp['name']) + + def get_login_handler(self, dump=None): + if dump: + return lasso.Login.newFromDump(self.server, dump) + else: + return lasso.Login(self.server) + + def get_providers(self): + return self.server.get_providers() + + def _debug(self, fact): + if cherrypy.config.get('debug', False): + cherrypy.log(fact)