-#!/usr/bin/python
-#
# Copyright (C) 2014 Simo Sorce <simo@redhat.com>
#
# see file 'COPYING' for use and warranty information
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import cherrypy
-from ipsilon.util.page import Page
+from ipsilon.admin.common import AdminPage
+from ipsilon.admin.common import ADMIN_STATUS_OK
+from ipsilon.admin.common import ADMIN_STATUS_ERROR
+from ipsilon.admin.common import ADMIN_STATUS_WARN
from ipsilon.providers.saml2.provider import ServiceProvider
from ipsilon.providers.saml2.provider import ServiceProviderCreator
from ipsilon.providers.saml2.provider import InvalidProviderId
import re
+import requests
VALID_IN_NAME = r'[^\ a-zA-Z0-9]'
-class NewSPAdminPage(Page):
+class NewSPAdminPage(AdminPage):
def __init__(self, site, parent):
- super(NewSPAdminPage, self).__init__(site)
+ super(NewSPAdminPage, self).__init__(site, form=True)
self.parent = parent
self.title = 'New Service Provider'
self.backurl = parent.url
def POST(self, *args, **kwargs):
if self.user.is_admin:
- #TODO: allow authenticated user to create SPs on their own
- # set the owner in that case
+ # TODO: allow authenticated user to create SPs on their own
+ # set the owner in that case
name = None
meta = None
if 'content-type' not in cherrypy.request.headers:
self._debug("Invalid request, missing content-type")
message = "Malformed request"
- message_type = "error"
+ 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':
if re.search(VALID_IN_NAME, value):
message = "Invalid name!" \
" Use only numbers and letters"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
return self.form_new(message, message_type)
name = value
- elif key == 'meta':
+ elif key == 'metatext':
+ if len(value) > 0:
+ meta = value
+ elif key == 'metafile':
if hasattr(value, 'content_type'):
meta = value.fullvalue()
else:
self._debug("Invalid format for 'meta'")
+ elif key == 'metaurl':
+ if len(value) > 0:
+ try:
+ r = requests.get(value)
+ r.raise_for_status()
+ meta = r.content
+ except Exception, e: # pylint: disable=broad-except
+ 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:
sp = spc.create_from_buffer(name, meta)
sp_page = self.parent.add_sp(name, sp)
message = "SP Successfully added"
- message_type = "success"
+ message_type = ADMIN_STATUS_OK
return sp_page.form_standard(message, message_type)
except InvalidProviderId, e:
message = str(e)
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
except Exception, e: # pylint: disable=broad-except
self._debug(repr(e))
message = "Failed to create Service Provider!"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
else:
message = "A name and a metadata file must be provided"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
else:
message = "Unauthorized"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
return self.form_new(message, message_type)
- def root(self, *args, **kwargs):
- op = getattr(self, cherrypy.request.method, self.GET)
- if callable(op):
- return op(*args, **kwargs)
-
class InvalidValueFormat(Exception):
pass
pass
-class SPAdminPage(Page):
+class SPAdminPage(AdminPage):
def __init__(self, sp, site, parent):
- super(SPAdminPage, self).__init__(site)
+ super(SPAdminPage, self).__init__(site, form=True)
self.parent = parent
self.sp = sp
self.title = sp.name
self.backurl = parent.url
self.url = '%s/sp/%s' % (parent.url, sp.name)
- def form_standard(self, message=None, message_type=None):
+ def form_standard(self, message=None, message_type=None, newurl=None):
return self._template('admin/providers/saml2_sp.html',
message=message,
message_type=message_type,
title=self.title,
name='saml2_sp_%s_form' % self.sp.name,
backurl=self.backurl, action=self.url,
- data=self.sp)
+ data=self.sp, newurl=newurl)
def GET(self, *args, **kwargs):
return self.form_standard()
self._debug("Replacing %s: %s -> %s" % (key,
self.sp.default_nameid,
value))
+ if not self.sp.is_valid_nameid(value):
+ raise InvalidValueFormat('Invalid default nameid value')
return {'default_nameid': value}
else:
raise UnauthorizedUser("Unauthorized to set default nameid value")
self._debug("Replacing %s: %s -> %s" % (key,
self.sp.allowed_nameids,
list(v)))
+ for x in v:
+ if not self.sp.is_valid_nameid(x):
+ l = ', '.join(self.sp.valid_nameids())
+ err = 'Invalid nameid [%s]. Available [%s].' % (x, l)
+ raise InvalidValueFormat(err)
return {'allowed_nameids': list(v)}
else:
raise UnauthorizedUser("Unauthorized to set alowed nameids values")
except InvalidValueFormat, e:
message = str(e)
- message_type = "warning"
+ message_type = ADMIN_STATUS_WARN
return self.form_standard(message, message_type)
except UnauthorizedUser, e:
message = str(e)
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
return self.form_standard(message, message_type)
except Exception, e: # pylint: disable=broad-except
self._debug("Error: %s" % repr(e))
message = "Internal Error"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
return self.form_standard(message, message_type)
if len(results) > 0:
self.sp.save_properties()
if 'rename' in results:
rename = results['rename']
+ self.url = '%s/sp/%s' % (self.parent.url, rename[1])
self.parent.rename_sp(rename[0], rename[1])
- message = "Properties succssfully changed"
- message_type = "success"
+ message = "Properties successfully changed"
+ message_type = ADMIN_STATUS_OK
except Exception: # pylint: disable=broad-except
message = "Failed to save data!"
- message_type = "error"
+ message_type = ADMIN_STATUS_ERROR
- return self.form_standard(message, message_type)
-
- def root(self, *args, **kwargs):
- op = getattr(self, cherrypy.request.method, self.GET)
- if callable(op):
- return op(*args, **kwargs)
+ return self.form_standard(message, message_type, self.url)
def delete(self):
self.parent.del_sp(self.sp.name)
self.sp.permanently_delete()
return self.parent.root()
- delete.exposed = True
+ delete.public_function = True
-class AdminPage(Page):
+class Saml2AdminPage(AdminPage):
def __init__(self, site, config):
- super(AdminPage, self).__init__(site)
+ super(Saml2AdminPage, self).__init__(site)
self.name = 'admin'
self.cfg = config
self.providers = []
self.menu = []
self.url = None
- self.sp = Page(self._site)
+ self.sp = AdminPage(self._site)
def add_sp(self, name, sp):
page = SPAdminPage(sp, self._site, self)
except Exception, e: # pylint: disable=broad-except
self._debug("Failed to remove provider %s: %s" % (name, str(e)))
+ def add_sps(self):
+ if self.cfg.idp:
+ for p in self.cfg.idp.get_providers():
+ try:
+ sp = ServiceProvider(self.cfg, p)
+ 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)))
+
def mount(self, page):
self.menu = page.menu
self.url = '%s/%s' % (page.url, self.name)
- for p in self.cfg.idp.get_providers():
- try:
- sp = ServiceProvider(self.cfg, p)
- 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.add_sps()
self.add_subtree('new', NewSPAdminPage(self._site, self))
page.add_subtree(self.name, self)