X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ipsilon%2Fproviders%2Fsaml2%2Fadmin.py;h=9d06be1f057b1ae26020214f0a94c8b5fd0dc70e;hb=a7c8333f98f4030e02d434fa78e8fc79c0340939;hp=f8163f702064283b1023503b3d3b6c1469aaf508;hpb=348fcbcbaf5c686cdb077c9bed53ded95ad04b49;p=cascardo%2Fipsilon.git diff --git a/ipsilon/providers/saml2/admin.py b/ipsilon/providers/saml2/admin.py index f8163f7..9d06be1 100644 --- a/ipsilon/providers/saml2/admin.py +++ b/ipsilon/providers/saml2/admin.py @@ -1,19 +1,4 @@ -# Copyright (C) 2014 Simo Sorce -# -# 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 . +# Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING import cherrypy from ipsilon.util import config as pconfig @@ -28,6 +13,9 @@ from ipsilon.providers.saml2.provider import ServiceProviderCreator from ipsilon.providers.saml2.provider import InvalidProviderId from copy import deepcopy import requests +import logging +import base64 +from urlparse import urlparse class NewSPAdminPage(AdminPage): @@ -57,18 +45,46 @@ class NewSPAdminPage(AdminPage): # set the owner in that case name = None meta = None + description = None + splink = None + visible = False + imagefile = None if 'content-type' not in cherrypy.request.headers: - self._debug("Invalid request, missing content-type") + self.debug("Invalid request, missing content-type") message = "Malformed request" message_type = ADMIN_STATUS_ERROR return self.form_new(message, message_type) ctype = cherrypy.request.headers['content-type'].split(';')[0] if ctype != 'multipart/form-data': - self._debug("Invalid form type (%s), trying to cope" % ( - cherrypy.request.content_type,)) + self.debug("Invalid form type (%s), trying to cope" % ( + cherrypy.request.content_type,)) for key, value in kwargs.iteritems(): if key == 'name': name = value + elif key == 'description': + description = value + elif key == 'splink': + # pylint: disable=unused-variable + (scheme, netloc, path, params, query, frag) = urlparse( + value + ) + # minimum URL validation + if (scheme not in ['http', 'https'] or not netloc): + message = "Invalid URL for Service Provider link" + message_type = ADMIN_STATUS_ERROR + return self.form_new(message, message_type) + splink = value + elif key == 'portalvisible' and value.lower() == 'on': + visible = True + elif key == 'imagefile': + if hasattr(value, 'content_type'): + imagefile = value.fullvalue() + if len(imagefile) == 0: + imagefile = None + else: + imagefile = base64.b64encode(imagefile) + else: + self.debug("Invalid format for 'imagefile'") elif key == 'metatext': if len(value) > 0: meta = value @@ -76,7 +92,7 @@ class NewSPAdminPage(AdminPage): if hasattr(value, 'content_type'): meta = value.fullvalue() else: - self._debug("Invalid format for 'meta'") + self.debug("Invalid format for 'meta'") elif key == 'metaurl': if len(value) > 0: try: @@ -84,7 +100,7 @@ class NewSPAdminPage(AdminPage): r.raise_for_status() meta = r.content except Exception, e: # pylint: disable=broad-except - self._debug("Failed to fetch metadata: " + repr(e)) + self.debug("Failed to fetch metadata: " + repr(e)) message = "Failed to fetch metadata: " + repr(e) message_type = ADMIN_STATUS_ERROR return self.form_new(message, message_type) @@ -92,7 +108,8 @@ class NewSPAdminPage(AdminPage): if name and meta: try: spc = ServiceProviderCreator(self.parent.cfg) - sp = spc.create_from_buffer(name, meta) + sp = spc.create_from_buffer(name, meta, description, + visible, imagefile, splink) sp_page = self.parent.add_sp(name, sp) message = "SP Successfully added" message_type = ADMIN_STATUS_OK @@ -101,7 +118,7 @@ class NewSPAdminPage(AdminPage): message = str(e) message_type = ADMIN_STATUS_ERROR except Exception, e: # pylint: disable=broad-except - self._debug(repr(e)) + self.debug(repr(e)) message = "Failed to create Service Provider!" message_type = ADMIN_STATUS_ERROR else: @@ -156,6 +173,9 @@ class SPAdminPage(AdminPage): value = kwargs[name] if isinstance(option, pconfig.List): value = [x.strip() for x in value.split('\n')] + # for normal lists we want unordered comparison + if set(value) == set(option.get_value()): + continue elif isinstance(option, pconfig.Condition): value = True else: @@ -167,9 +187,9 @@ class SPAdminPage(AdminPage): aname = '%s_%s' % (name, a) if aname in kwargs: value.append(a) - elif type(option) is pconfig.ComplexList: + elif isinstance(option, pconfig.MappingList): current = deepcopy(option.get_value()) - value = get_complex_list_value(name, + value = get_mapping_list_value(name, current, **kwargs) # if current value is None do nothing @@ -177,9 +197,9 @@ class SPAdminPage(AdminPage): if option.get_value() is None: continue # else pass and let it continue as None - elif type(option) is pconfig.MappingList: + elif isinstance(option, pconfig.ComplexList): current = deepcopy(option.get_value()) - value = get_mapping_list_value(name, + value = get_complex_list_value(name, current, **kwargs) # if current value is None do nothing @@ -191,11 +211,8 @@ class SPAdminPage(AdminPage): continue if value != option.get_value(): - if (type(option) is pconfig.List and - set(value) == set(option.get_value())): - continue cherrypy.log.error("Storing %s = %s" % - (name, value)) + (name, value), severity=logging.DEBUG) new_db_values[name] = value if len(new_db_values) != 0: @@ -206,8 +223,11 @@ class SPAdminPage(AdminPage): if (not self.user.is_admin and self.user.name != self.sp.owner): raise UnauthorizedUser("Unauthorized to set owner") - elif key in ['Owner', 'Default NameID', 'Allowed NameIDs', - 'Attribute Mapping', 'Allowed Attributes']: + elif key in ['User Owner', 'Default NameID', + 'Allowed NameIDs', 'Attribute Mapping', + 'Allowed Attributes', 'Description', + 'Service Provider link', + 'Visible in Portal', 'Image File']: if not self.user.is_admin: raise UnauthorizedUser( "Unauthorized to set %s" % key @@ -215,9 +235,12 @@ class SPAdminPage(AdminPage): # Make changes in current config for name, option in conf.iteritems(): + if name not in new_db_values: + continue value = new_db_values.get(name, False) # A value of None means remove from the data store - if value is False or value == []: + if ((value is False or value == []) and + name != 'Visible in Portal'): continue if name == 'Name': if not self.sp.is_valid_name(value): @@ -230,6 +253,12 @@ class SPAdminPage(AdminPage): self.parent.rename_sp(option.get_value(), value) elif name == 'User Owner': self.sp.owner = value + elif name == 'Description': + self.sp.description = value + elif name == 'Visible in Portal': + self.sp.visible = value + elif name == 'Service Provider link': + self.sp.splink = value elif name == 'Default NameID': self.sp.default_nameid = value elif name == 'Allowed NameIDs': @@ -238,6 +267,17 @@ class SPAdminPage(AdminPage): self.sp.attribute_mappings = value elif name == 'Allowed Attributes': self.sp.allowed_attributes = value + elif name == 'Image File': + if hasattr(value, 'content_type'): + # pylint: disable=maybe-no-member + blob = value.fullvalue() + if len(blob) > 0: + self.sp.imagefile = base64.b64encode(blob) + else: + raise InvalidValueFormat( + 'Invalid Image file format' + ) + except InvalidValueFormat, e: message = str(e) message_type = ADMIN_STATUS_WARN @@ -247,7 +287,7 @@ class SPAdminPage(AdminPage): message_type = ADMIN_STATUS_ERROR return self.root_with_msg(message, message_type) except Exception as e: # pylint: disable=broad-except - self._debug("Error: %s" % repr(e)) + self.debug("Error: %s" % repr(e)) message = "Internal Error" message_type = ADMIN_STATUS_ERROR return self.root_with_msg(message, message_type) @@ -300,7 +340,7 @@ class Saml2AdminPage(AdminPage): self.providers.remove(page.sp) self.sp.del_subtree(name) except Exception, e: # pylint: disable=broad-except - self._debug("Failed to remove provider %s: %s" % (name, str(e))) + self.debug("Failed to remove provider %s: %s" % (name, str(e))) def add_sps(self): if self.cfg.idp: @@ -310,7 +350,7 @@ class Saml2AdminPage(AdminPage): self.del_sp(sp.name) self.add_sp(sp.name, sp) except Exception, e: # pylint: disable=broad-except - self._debug("Failed to find provider %s: %s" % (p, str(e))) + self.debug("Failed to find provider %s: %s" % (p, str(e))) def mount(self, page): self.menu = page.menu