From 83da2bf3963db3e4427bced3b4c0681e751e54da Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 23 Oct 2014 11:45:32 -0400 Subject: Refactor plugin configuration Fork a PluginConfig class out of PluginObject, the base object now supports a simple dictionary config, while using PluginConfig provide access to structured util.config based configuration. Change UI code that deal with plugins configuration to properly use the new structured config objects in order to represent data in appropriate format based on the data type. Use the new util.config objects to represent plugins configuration. Signed-off-by: Simo Sorce Reviewed-by: Patrick Uiterwijk --- ipsilon/providers/common.py | 17 +++--- ipsilon/providers/openid/auth.py | 4 +- ipsilon/providers/openid/extensions/common.py | 10 +++- ipsilon/providers/openid/meta.py | 4 +- ipsilon/providers/openidp.py | 69 +++++++++++----------- ipsilon/providers/saml2idp.py | 84 +++++++++++++-------------- 6 files changed, 96 insertions(+), 92 deletions(-) (limited to 'ipsilon/providers') diff --git a/ipsilon/providers/common.py b/ipsilon/providers/common.py index d882b40..ead50e2 100755 --- a/ipsilon/providers/common.py +++ b/ipsilon/providers/common.py @@ -18,8 +18,8 @@ # along with this program. If not, see . from ipsilon.util.log import Log -from ipsilon.util.plugin import PluginLoader, PluginObject -from ipsilon.util.plugin import PluginInstaller +from ipsilon.util.plugin import PluginInstaller, PluginLoader +from ipsilon.util.plugin import PluginObject, PluginConfig from ipsilon.util.page import Page import cherrypy @@ -49,10 +49,11 @@ class InvalidRequest(ProviderException): self._debug(message) -class ProviderBase(PluginObject): +class ProviderBase(PluginConfig, PluginObject): def __init__(self, name, path): - super(ProviderBase, self).__init__() + PluginConfig.__init__(self) + PluginObject.__init__(self) self.name = name self.path = path self.tree = None @@ -74,14 +75,14 @@ class ProviderBase(PluginObject): # configure self plugins = site[FACILITY] if self.name in plugins['config']: - self.set_config(plugins['config'][self.name]) + self.import_config(plugins['config'][self.name]) # init pages and admin interfaces self.tree = self.get_tree(site) self._debug('IdP Provider registered: %s' % self.name) - if self.get_config_value('enabled') == '1': + if self.get_config_value('enabled') is True: # and enable self self._enable(site) @@ -97,7 +98,7 @@ class ProviderBase(PluginObject): return self._enable(site) - self.set_config_value('enabled', '1') + self.set_config_value('enabled', True) self.save_plugin_config(FACILITY) def disable(self, site): @@ -109,7 +110,7 @@ class ProviderBase(PluginObject): root.del_subtree(self.name) self.is_enabled = False - self.set_config_value('enabled', '0') + self.set_config_value('enabled', False) self.save_plugin_config(FACILITY) self._debug('IdP Provider disabled: %s' % self.name) diff --git a/ipsilon/providers/openid/auth.py b/ipsilon/providers/openid/auth.py index da110f7..fba8d10 100755 --- a/ipsilon/providers/openid/auth.py +++ b/ipsilon/providers/openid/auth.py @@ -168,7 +168,7 @@ class AuthenticateRequest(ProviderPageBase): "Trust Root": request.trust_root, } userattrs = us.get_user_attrs() - for n, e in self.cfg.extensions.items(): + for n, e in self.cfg.extensions.available().items(): data = e.get_display_data(request, userattrs) self.debug('%s returned %s' % (n, repr(data))) for key, value in data.items(): @@ -194,7 +194,7 @@ class AuthenticateRequest(ProviderPageBase): claimed_id=identity_url ) userattrs = session.get_user_attrs() - for _, e in self.cfg.extensions.items(): + for _, e in self.cfg.extensions.available().items(): resp = e.get_response(request, userattrs) if resp is not None: response.addExtension(resp) diff --git a/ipsilon/providers/openid/extensions/common.py b/ipsilon/providers/openid/extensions/common.py index b75d394..804f695 100755 --- a/ipsilon/providers/openid/extensions/common.py +++ b/ipsilon/providers/openid/extensions/common.py @@ -49,13 +49,14 @@ FACILITY = 'openid_extensions' class LoadExtensions(Log): - def __init__(self, enabled): + def __init__(self): loader = PluginLoader(LoadExtensions, FACILITY, 'OpenidExtension') self.plugins = loader.get_plugin_data() available = self.plugins['available'].keys() self._debug('Available Extensions: %s' % str(available)) + def enable(self, enabled): for item in enabled: if item not in self.plugins['available']: self.debug('<%s> not available' % item) @@ -63,5 +64,8 @@ class LoadExtensions(Log): self.debug('Enable OpenId extension: %s' % item) self.plugins['available'][item].enable() - def get_extensions(self): - return self.plugins['available'] + def available(self): + available = self.plugins['available'] + if available is None: + available = dict() + return available diff --git a/ipsilon/providers/openid/meta.py b/ipsilon/providers/openid/meta.py index a04a78c..ea79439 100755 --- a/ipsilon/providers/openid/meta.py +++ b/ipsilon/providers/openid/meta.py @@ -42,7 +42,7 @@ class XRDSHandler(MetaHandler): 'http://specs.openid.net/auth/2.0/server', 'http://openid.net/server/1.0', ] - for _, e in self.cfg.extensions.items(): + for _, e in self.cfg.extensions.available().items(): types.extend(e.get_type_uris()) return self.reply(types=types, @@ -65,7 +65,7 @@ class UserXRDSHandler(XRDSHandler): 'http://specs.openid.net/auth/2.0/signon', 'http://openid.net/signon/1.0', ] - for _, e in self.cfg.extensions.items(): + for _, e in self.cfg.extensions.available().items(): types.extend(e.get_type_uris()) return self.reply(types=types, diff --git a/ipsilon/providers/openidp.py b/ipsilon/providers/openidp.py index 5abdcad..197b1cf 100755 --- a/ipsilon/providers/openidp.py +++ b/ipsilon/providers/openidp.py @@ -9,6 +9,7 @@ from ipsilon.providers.common import FACILITY from ipsilon.providers.openid.auth import OpenID from ipsilon.providers.openid.extensions.common import LoadExtensions from ipsilon.util.plugin import PluginObject +from ipsilon.util import config as pconfig from ipsilon.info.common import InfoMapping from openid.server.server import Server @@ -24,42 +25,41 @@ class IdpProvider(ProviderBase): self.page = None self.server = None self.basepath = None - self.extensions = None + self.extensions = LoadExtensions() + print self.extensions.available() + print self.extensions.available().keys() self.description = """ Provides OpenID 2.0 authentication infrastructure. """ - self._options = { - 'default email domain': [ - """Default email domain, for users missing email property.""", - 'string', - 'example.com' - ], - 'endpoint url': [ - """The Absolute URL of the OpenID provider""", - 'string', - 'http://localhost:8080/idp/openid/' - ], - 'identity url template': [ - """The templated URL where identities are exposed.""", - 'string', - 'http://localhost:8080/idp/openid/id/%(username)s' - ], - 'trusted roots': [ - """List of trusted relying parties.""", - 'list', - [] - ], - 'untrusted roots': [ - """List of untrusted relying parties.""", - 'list', - [] - ], - 'enabled extensions': [ - """List of enabled extensions""", - 'list', - [] - ], - } + self.new_config( + self.name, + pconfig.String( + 'default email domain', + 'Used for users missing the email property.', + 'example.com'), + pconfig.String( + 'endpoint url', + 'The Absolute URL of the OpenID provider', + 'http://localhost:8080/idp/openid/'), + pconfig.Template( + 'identity url template', + 'The templated URL where identities are exposed.', + 'http://localhost:8080/idp/openid/id/%(username)s'), + pconfig.List( + 'trusted roots', + 'List of trusted relying parties.'), + pconfig.List( + 'untrusted roots', + 'List of untrusted relying parties.'), + pconfig.Choice( + 'enabled extensions', + 'Choose the extensions to enable', + self.extensions.available().keys()), + pconfig.Condition( + 'enabled', + 'Whether the OpenID IDP is enabled', + False) + ) @property def endpoint_url(self): @@ -112,11 +112,10 @@ Provides OpenID 2.0 authentication infrastructure. """ def init_idp(self): self.server = Server(MemoryStore(), op_endpoint=self.endpoint_url) - loader = LoadExtensions(self.enabled_extensions) - self.extensions = loader.get_extensions() def on_enable(self): self.init_idp() + self.extensions.enable(self._config['enabled extensions'].get_value()) class Installer(object): diff --git a/ipsilon/providers/saml2idp.py b/ipsilon/providers/saml2idp.py index cb2c4a2..8896e16 100755 --- a/ipsilon/providers/saml2idp.py +++ b/ipsilon/providers/saml2idp.py @@ -27,6 +27,7 @@ from ipsilon.tools import saml2metadata as metadata from ipsilon.tools import files from ipsilon.util.user import UserSession from ipsilon.util.plugin import PluginObject +from ipsilon.util import config as pconfig import cherrypy import lasso import os @@ -126,48 +127,47 @@ class IdpProvider(ProviderBase): self.description = """ Provides SAML 2.0 authentication infrastructure. """ - self._options = { - 'idp storage path': [ - """ Path to data storage accessible by the IdP """, - 'string', - '/var/lib/ipsilon/saml2' - ], - 'idp metadata file': [ - """ The IdP Metadata file genearated at install time. """, - 'string', - 'metadata.xml' - ], - 'idp certificate file': [ - """ The IdP PEM Certificate genearated at install time. """, - 'string', - 'certificate.pem' - ], - 'idp key file': [ - """ The IdP Certificate Key genearated at install time. """, - 'string', - 'certificate.key' - ], - 'allow self registration': [ - """ Allow authenticated users to register applications. """, - 'boolean', - True - ], - 'default allowed nameids': [ - """Default Allowed NameIDs for Service Providers. """, - 'list', - ['persistent', 'transient', 'email', 'kerberos', 'x509'] - ], - 'default nameid': [ - """Default NameID used by Service Providers. """, - 'string', - 'persistent' - ], - 'default email domain': [ - """Default email domain, for users missing email property.""", - 'string', - 'example.com' - ] - } + self.new_config( + self.name, + pconfig.String( + 'idp storage path', + 'Path to data storage accessible by the IdP.', + '/var/lib/ipsilon/saml2'), + pconfig.String( + 'idp metadata file', + 'The IdP Metadata file genearated at install time.', + 'metadata.xml'), + pconfig.String( + 'idp certificate file', + 'The IdP PEM Certificate genearated at install time.', + 'certificate.pem'), + pconfig.String( + 'idp key file', + 'The IdP Certificate Key genearated at install time.', + 'certificate.key'), + pconfig.Condition( + 'allow self registration', + 'Allow authenticated users to register applications.', + True), + pconfig.Choice( + 'default allowed nameids', + 'Default Allowed NameIDs for Service Providers.', + metadata.SAML2_NAMEID_MAP.keys(), + ['persistent', 'transient', 'email', 'kerberos', 'x509']), + pconfig.Pick( + 'default nameid', + 'Default NameID used by Service Providers.', + metadata.SAML2_NAMEID_MAP.keys(), + 'persistent'), + pconfig.String( + 'default email domain', + 'Used for users missing the email property.', + 'example.com'), + pconfig.Condition( + 'enabled', + 'Whether the SAML IDP is enabled', + False) + ) if cherrypy.config.get('debug', False): import logging import sys -- cgit