Add support for logout over SOAP
[cascardo/ipsilon.git] / ipsilon / providers / saml2 / provider.py
index d3cc144..b70582e 100644 (file)
@@ -1,25 +1,11 @@
-# Copyright (C) 2014  Simo Sorce <simo@redhat.com>
-#
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
 
 from ipsilon.providers.common import ProviderException
 from ipsilon.util import config as pconfig
 from ipsilon.util.config import ConfigHelper
-from ipsilon.tools.saml2metadata import SAML2_NAMEID_MAP
+from ipsilon.tools.saml2metadata import SAML2_NAMEID_MAP, NSMAP
 from ipsilon.util.log import Log
+from lxml import etree
 import lasso
 import re
 
@@ -32,7 +18,7 @@ class InvalidProviderId(ProviderException):
     def __init__(self, code):
         message = 'Invalid Provider ID: %s' % code
         super(InvalidProviderId, self).__init__(message)
-        self._debug(message)
+        self.debug(message)
 
 
 class NameIdNotAllowed(Exception):
@@ -64,6 +50,14 @@ class ServiceProvider(ServiceProviderConfig):
         self._properties = data[idval]
         self._staging = dict()
         self.load_config()
+        self.logout_mechs = []
+        xmldoc = etree.XML(str(data[idval]['metadata']))
+        logout = xmldoc.xpath('//md:EntityDescriptor'
+                              '/md:SPSSODescriptor'
+                              '/md:SingleLogoutService',
+                              namespaces=NSMAP)
+        for service in logout:
+            self.logout_mechs.append(service.values()[0])
 
     def load_config(self):
         self.new_config(
@@ -133,7 +127,7 @@ class ServiceProvider(ServiceProviderConfig):
 
     @allowed_nameids.setter
     def allowed_nameids(self, value):
-        if type(value) is not list:
+        if not isinstance(value, list):
             raise ValueError("Must be a list")
         self._staging['allowed nameids'] = ','.join(value)
 
@@ -207,12 +201,12 @@ class ServiceProvider(ServiceProviderConfig):
         self.load_config()
 
     def get_valid_nameid(self, nip):
-        self._debug('Requested NameId [%s]' % (nip.format,))
+        self.debug('Requested NameId [%s]' % (nip.format,))
         if nip.format is None:
             return SAML2_NAMEID_MAP[self.default_nameid]
         else:
             allowed = self.allowed_nameids
-            self._debug('Allowed NameIds %s' % (repr(allowed)))
+            self.debug('Allowed NameIds %s' % (repr(allowed)))
             for nameid in allowed:
                 if nip.format == SAML2_NAMEID_MAP[nameid]:
                     return nip.format
@@ -281,17 +275,18 @@ class ServiceProviderCreator(object):
 
 
 class IdentityProvider(Log):
-    def __init__(self, config):
+    def __init__(self, config, sessionfactory):
         self.server = lasso.Server(config.idp_metadata_file,
                                    config.idp_key_file,
                                    None,
                                    config.idp_certificate_file)
         self.server.role = lasso.PROVIDER_ROLE_IDP
+        self.sessionfactory = sessionfactory
 
     def add_provider(self, sp):
         self.server.addProviderFromBuffer(lasso.PROVIDER_ROLE_SP,
                                           sp['metadata'])
-        self._debug('Added SP %s' % sp['name'])
+        self.debug('Added SP %s' % sp['name'])
 
     def get_login_handler(self, dump=None):
         if dump: