SP Portal administrative interface
[cascardo/ipsilon.git] / ipsilon / providers / saml2 / provider.py
index 5d36fbd..6cbf5ab 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
 
@@ -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(
@@ -74,6 +68,23 @@ class ServiceProvider(ServiceProviderConfig):
                 ' Only alphanumeric characters [A-Z,a-z,0-9] and spaces are'
                 '  accepted.',
                 self.name),
+            pconfig.String(
+                'Description',
+                'A description of the SP to show on the Portal.',
+                self.description),
+            pconfig.String(
+                'Service Provider link',
+                'A link to the Service Provider for the Portal.',
+                self.splink),
+            pconfig.Condition(
+                'Visible in Portal',
+                'This SP is visible in the Portal.',
+                self.visible),
+            pconfig.Image(
+                'Image File',
+                'Image to display for this SP in the Portal. Scale to '
+                '100x200 for best results.',
+                self.imagefile),
             pconfig.Pick(
                 'Default NameID',
                 'Default NameID used by Service Providers.',
@@ -112,6 +123,42 @@ class ServiceProvider(ServiceProviderConfig):
     def name(self, value):
         self._staging['name'] = value
 
+    @property
+    def description(self):
+        return self._properties.get('description', '')
+
+    @description.setter
+    def description(self, value):
+        self._staging['description'] = value
+
+    @property
+    def visible(self):
+        return self._properties.get('visible', True)
+
+    @visible.setter
+    def visible(self, value):
+        self._staging['visible'] = value
+
+    @property
+    def imagefile(self):
+        return self._properties.get('imagefile', '')
+
+    @imagefile.setter
+    def imagefile(self, value):
+        self._staging['imagefile'] = value
+
+    @property
+    def imageurl(self):
+        return pconfig.url_from_image(self._properties['imagefile'])
+
+    @property
+    def splink(self):
+        return self._properties.get('splink', '')
+
+    @splink.setter
+    def splink(self, value):
+        self._staging['splink'] = value
+
     @property
     def owner(self):
         if 'owner' in self._properties:
@@ -133,7 +180,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)
 
@@ -249,7 +296,8 @@ class ServiceProviderCreator(object):
     def __init__(self, config):
         self.cfg = config
 
-    def create_from_buffer(self, name, metabuf):
+    def create_from_buffer(self, name, metabuf, description='',
+                           visible=True, imagefile='', splink=''):
         '''Test and add data'''
 
         if re.search(VALID_IN_NAME, name):
@@ -266,7 +314,16 @@ class ServiceProviderCreator(object):
         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}
+        datum = {
+            'id': spid,
+            'name': name,
+            'type': 'SP',
+            'metadata': metabuf,
+            'description': description,
+            'visible': visible,
+            'imagefile': imagefile,
+            'splink': splink,
+        }
         self.cfg.new_datum(datum)
 
         data = self.cfg.get_data(name='id', value=spid)
@@ -281,12 +338,13 @@ 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,