-# 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
import cherrypy
from ipsilon.util import config as pconfig
from ipsilon.providers.saml2.provider import InvalidProviderId
from copy import deepcopy
import requests
+import logging
+import base64
+from urlparse import urlparse
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
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:
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)
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
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:
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:
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
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
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:
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
# 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):
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':
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
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)
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:
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