summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-10-27 11:25:46 -0400
committerPatrick Uiterwijk <puiterwijk@redhat.com>2014-11-12 23:47:25 +0100
commitb7b80c5c0fc1895e85aae3acbfcbbc593a42697f (patch)
tree530512524a374059a9648ace99c56146af95bf4d
parentc6b167fcf290c415b8d1903237fb5405b7213405 (diff)
downloadipsilon-b7b80c5c0fc1895e85aae3acbfcbbc593a42697f.tar.gz
ipsilon-b7b80c5c0fc1895e85aae3acbfcbbc593a42697f.tar.xz
ipsilon-b7b80c5c0fc1895e85aae3acbfcbbc593a42697f.zip
Refactor plugin initialization and enablement
Move most plugin enablement and initialization code in plugin.py to reduce code duplication and simplify and unifify plugin enablement for all base plugin types (login, info, providers). This patch breaks backwards compatibility as it changes how the list of enabled plugins is stored in the database tables. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
-rwxr-xr-xipsilon/admin/common.py89
-rwxr-xr-xipsilon/admin/login.py12
-rwxr-xr-xipsilon/helpers/common.py5
-rwxr-xr-xipsilon/helpers/ipa.py2
-rwxr-xr-xipsilon/info/common.py52
-rwxr-xr-xipsilon/info/infoldap.py26
-rwxr-xr-xipsilon/info/nss.py24
-rwxr-xr-xipsilon/login/authfas.py21
-rwxr-xr-xipsilon/login/authform.py21
-rwxr-xr-xipsilon/login/authkrb.py27
-rwxr-xr-xipsilon/login/authldap.py22
-rwxr-xr-xipsilon/login/authpam.py23
-rwxr-xr-xipsilon/login/authtest.py19
-rwxr-xr-xipsilon/login/common.py116
-rwxr-xr-xipsilon/providers/common.py80
-rwxr-xr-xipsilon/providers/openid/extensions/ax.py2
-rwxr-xr-xipsilon/providers/openid/extensions/cla.py2
-rwxr-xr-xipsilon/providers/openid/extensions/common.py16
-rwxr-xr-xipsilon/providers/openid/extensions/fas_teams.py2
-rwxr-xr-xipsilon/providers/openid/extensions/sreg.py2
-rwxr-xr-xipsilon/providers/openid/extensions/teams.py2
-rwxr-xr-xipsilon/providers/openidp.py31
-rwxr-xr-xipsilon/providers/saml2idp.py29
-rwxr-xr-xipsilon/util/plugin.py137
-rwxr-xr-xquickrun.py2
25 files changed, 318 insertions, 446 deletions
diff --git a/ipsilon/admin/common.py b/ipsilon/admin/common.py
index 530cb22..9c82142 100755
--- a/ipsilon/admin/common.py
+++ b/ipsilon/admin/common.py
@@ -20,7 +20,6 @@
import cherrypy
from ipsilon.util.page import Page
from ipsilon.util.page import admin_protect
-from ipsilon.util.plugin import PluginObject
from ipsilon.util import config as pconfig
@@ -96,7 +95,7 @@ class AdminPluginConfig(AdminPage):
if len(new_db_values) != 0:
# First we try to save in the database
try:
- self._po.save_plugin_config(self.facility, new_db_values)
+ self._po.save_plugin_config(new_db_values)
message = "New configuration saved."
message_type = "success"
except Exception: # pylint: disable=broad-except
@@ -104,7 +103,7 @@ class AdminPluginConfig(AdminPage):
message_type = "error"
# Then refresh the actual objects
- self._po.refresh_plugin_config(self.facility)
+ self._po.refresh_plugin_config()
return self.root_with_msg(message=message,
message_type=message_type)
@@ -123,45 +122,40 @@ class AdminPluginsOrder(AdminPage):
def GET(self, *args, **kwargs):
return self.parent.root_with_msg()
- def _get_enabled_by_name(self):
- by_name = dict()
- for p in self._site[self.facility]['available'].values():
+ def _get_enabled_list(self):
+ cur = list()
+ for p in self._site[self.facility].available.values():
if p.is_enabled:
- by_name[p.name] = p
- return by_name
+ cur.append(p.name)
+ return cur
@admin_protect
def POST(self, *args, **kwargs):
message = "Nothing was modified."
message_type = "info"
- by_name = self._get_enabled_by_name()
+ cur_enabled = self._get_enabled_list()
if 'order' in kwargs:
order = kwargs['order'].split(',')
if len(order) != 0:
- new_names = []
- new_plugins = []
+ new_order = []
try:
for v in order:
val = v.strip()
- if val not in by_name:
+ if val not in cur_enabled:
error = "Invalid plugin name: %s" % val
raise ValueError(error)
- new_names.append(val)
- new_plugins.append(by_name[val])
- if len(new_names) < len(by_name):
- for val in by_name:
- if val not in new_names:
- new_names.append(val)
- new_plugins.append(by_name[val])
+ new_order.append(val)
+ if len(new_order) < len(cur_enabled):
+ for val in cur_enabled:
+ if val not in new_order:
+ new_order.append(val)
- self.parent.save_enabled_plugins(new_names)
- self.parent.reorder_plugins(new_names)
+ self.parent.save_enabled_plugins(new_order)
# When all is saved update also live config. The
- # live config is a list of the actual plugin
- # objects.
- self._site[self.facility]['enabled'] = new_plugins
+ # live config is the ordered list of plugin names.
+ self._site[self.facility].refresh_enabled()
message = "New configuration saved."
message_type = "success"
@@ -190,9 +184,9 @@ class AdminPlugins(AdminPage):
self.order = None
parent.add_subtree(name, self)
- for plugin in self._site[facility]['available']:
+ for plugin in self._site[facility].available:
cherrypy.log.error('Admin info plugin: %s' % plugin)
- obj = self._site[facility]['available'][plugin]
+ obj = self._site[facility].available[plugin]
page = AdminPluginConfig(obj, self._site, self)
if hasattr(obj, 'admin'):
obj.admin.mount(page)
@@ -202,34 +196,17 @@ class AdminPlugins(AdminPage):
self.order = AdminPluginsOrder(self._site, self, facility)
def save_enabled_plugins(self, names):
- po = PluginObject()
- po.name = "global"
- globalconf = dict()
- globalconf['order'] = ','.join(names)
- po.import_config(globalconf)
- po.save_plugin_config(self.facility)
-
- def reorder_plugins(self, names):
- return
+ self._site[self.facility].save_enabled(names)
def root_with_msg(self, message=None, message_type=None):
plugins = self._site[self.facility]
- enabled = []
- if self.order:
- for plugin in plugins['enabled']:
- if plugin.is_enabled:
- enabled.append(plugin.name)
- else:
- for _, plugin in plugins['available'].iteritems():
- if plugin.is_enabled:
- enabled.append(plugin.name)
targs = {'title': self.title,
'menu': self._master.menu,
'message': message,
'message_type': message_type,
- 'available': plugins['available'],
- 'enabled': enabled,
+ 'available': plugins.available,
+ 'enabled': plugins.enabled,
'baseurl': self.url,
'newurl': self.url}
if self.order:
@@ -246,15 +223,13 @@ class AdminPlugins(AdminPage):
def enable(self, plugin):
msg = None
plugins = self._site[self.facility]
- if plugin not in plugins['available']:
+ if plugin not in plugins.available:
msg = "Unknown plugin %s" % plugin
return self.root_with_msg(msg, "error")
- obj = plugins['available'][plugin]
+ obj = plugins.available[plugin]
if not obj.is_enabled:
- obj.enable(self._site)
- if self.order:
- enabled = list(x.name for x in plugins['enabled'])
- self.save_enabled_plugins(enabled)
+ obj.enable()
+ obj.save_enabled_state()
msg = "Plugin %s enabled" % obj.name
return self.root_with_msg(msg, "success")
enable.public_function = True
@@ -263,15 +238,13 @@ class AdminPlugins(AdminPage):
def disable(self, plugin):
msg = None
plugins = self._site[self.facility]
- if plugin not in plugins['available']:
+ if plugin not in plugins.available:
msg = "Unknown plugin %s" % plugin
return self.root_with_msg(msg, "error")
- obj = plugins['available'][plugin]
+ obj = plugins.available[plugin]
if obj.is_enabled:
- obj.disable(self._site)
- if self.order:
- enabled = list(x.name for x in plugins['enabled'])
- self.save_enabled_plugins(enabled)
+ obj.disable()
+ obj.save_enabled_state()
msg = "Plugin %s disabled" % obj.name
return self.root_with_msg(msg, "success")
disable.public_function = True
diff --git a/ipsilon/admin/login.py b/ipsilon/admin/login.py
index c1a1c73..ae5b15a 100755
--- a/ipsilon/admin/login.py
+++ b/ipsilon/admin/login.py
@@ -10,15 +10,3 @@ class LoginPlugins(AdminPlugins):
def __init__(self, site, parent):
super(LoginPlugins, self).__init__('login', site, parent, FACILITY)
self.title = 'Login Plugins'
-
- def reorder_plugins(self, order):
- plugins = self._site[FACILITY]['available']
- root = self._site[FACILITY]['root']
- prev_obj = None
- for name in order:
- if prev_obj is None:
- root.first_login = plugins[name]
- else:
- prev_obj.next_login = plugins[name]
- prev_obj = plugins[name]
- prev_obj.next_login = None
diff --git a/ipsilon/helpers/common.py b/ipsilon/helpers/common.py
index 6ec2819..f670bc6 100755
--- a/ipsilon/helpers/common.py
+++ b/ipsilon/helpers/common.py
@@ -20,8 +20,11 @@
from ipsilon.util.plugin import PluginInstaller
+FACILITY = 'environment_helpers'
+
+
class EnvHelpersInstall(object):
def __init__(self):
- pi = PluginInstaller(EnvHelpersInstall)
+ pi = PluginInstaller(EnvHelpersInstall, FACILITY)
self.plugins = pi.get_plugins()
diff --git a/ipsilon/helpers/ipa.py b/ipsilon/helpers/ipa.py
index 4a4849a..d01d663 100755
--- a/ipsilon/helpers/ipa.py
+++ b/ipsilon/helpers/ipa.py
@@ -46,7 +46,7 @@ failure (see logs) and retry.
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'ipa'
self.ptype = 'helper'
self.logger = None
diff --git a/ipsilon/info/common.py b/ipsilon/info/common.py
index 586b9e5..a3a297f 100755
--- a/ipsilon/info/common.py
+++ b/ipsilon/info/common.py
@@ -11,40 +11,13 @@ from ipsilon.util.plugin import PluginObject, PluginConfig
class InfoProviderBase(PluginConfig, PluginObject):
- def __init__(self):
+ def __init__(self, *pargs):
PluginConfig.__init__(self)
- PluginObject.__init__(self)
- self._site = None
- self.is_enabled = False
+ PluginObject.__init__(self, *pargs)
def get_user_attrs(self, user):
raise NotImplementedError
- def enable(self, site):
- if self.is_enabled:
- return
-
- if not self._site:
- self._site = site
- plugins = self._site[FACILITY]
-
- # configure self
- if self.name in plugins['config']:
- self.import_config(plugins['config'][self.name])
-
- plugins['enabled'].append(self)
- self.is_enabled = True
- self.debug('Info plugin enabled: %s' % self.name)
-
- def disable(self, site):
- if not self.is_enabled:
- return
-
- plugins = self._site[FACILITY]
- plugins['enabled'].remove(self)
- self.is_enabled = False
- self.debug('Info plugin disabled: %s' % self.name)
-
class InfoMapping(Log):
@@ -96,23 +69,22 @@ class Info(Log):
def __init__(self, site):
self._site = site
- loader = PluginLoader(Info, FACILITY, 'InfoProvider')
- self._site[FACILITY] = loader.get_plugin_data()
- plugins = self._site[FACILITY]
+ plugins = PluginLoader(Info, FACILITY, 'InfoProvider')
+ plugins.get_plugin_data()
+ self._site[FACILITY] = plugins
- available = plugins['available'].keys()
+ available = plugins.available.keys()
self.debug('Available info providers: %s' % str(available))
- plugins['root'] = self
- for item in plugins['whitelist']:
- self.debug('Login plugin in whitelist: %s' % item)
- if item not in plugins['available']:
+ for item in plugins.enabled:
+ self.debug('Login plugin in enabled list: %s' % item)
+ if item not in plugins.available:
self.debug('Info Plugin %s not found' % item)
continue
- plugins['available'][item].enable(self._site)
+ plugins.available[item].enable()
def get_user_attrs(self, user, requested=None):
- plugins = self._site[FACILITY]['available']
+ plugins = self._site[FACILITY].available
result = dict()
for _, p in plugins.items():
@@ -146,5 +118,5 @@ class InfoProviderInstaller(object):
class InfoProviderInstall(object):
def __init__(self):
- pi = PluginInstaller(InfoProviderInstall)
+ pi = PluginInstaller(InfoProviderInstall, FACILITY)
self.plugins = pi.get_plugins()
diff --git a/ipsilon/info/infoldap.py b/ipsilon/info/infoldap.py
index 369d3f1..da9819a 100755
--- a/ipsilon/info/infoldap.py
+++ b/ipsilon/info/infoldap.py
@@ -29,8 +29,8 @@ ldap_mapping = {
class InfoProvider(InfoProviderBase):
- def __init__(self):
- super(InfoProvider, self).__init__()
+ def __init__(self, *pargs):
+ super(InfoProvider, self).__init__(*pargs)
self.mapper = InfoMapping()
self.mapper.set_mapping(ldap_mapping)
self.name = 'ldap'
@@ -151,9 +151,10 @@ Info plugin that uses LDAP to retrieve user data. """
class Installer(InfoProviderInstaller):
- def __init__(self):
+ def __init__(self, *pargs):
super(Installer, self).__init__()
self.name = 'ldap'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--info-ldap', choices=['yes', 'no'], default='no',
@@ -172,10 +173,10 @@ class Installer(InfoProviderInstaller):
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'ldap'
po.wipe_data()
- po.wipe_config_values(self.facility)
+ po.wipe_config_values()
config = dict()
if 'info_ldap_server_url' in opts:
config['server url'] = opts['info_ldap_server_url']
@@ -193,15 +194,8 @@ class Installer(InfoProviderInstaller):
elif 'ldap_bind_dn_template' in opts:
config['user dn template'] = opts['ldap_bind_dn_template']
config['tls'] = 'Demand'
- po.save_plugin_config(self.facility, config)
+ po.save_plugin_config(config)
- # Replace global config, only one plugin info can be used
- po.name = 'global'
- globalconf = po.get_plugin_config(self.facility)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('ldap')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(self.facility, globalconf)
+ # Update global config to add login plugin
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/info/nss.py b/ipsilon/info/nss.py
index 3dfd885..50c84a8 100755
--- a/ipsilon/info/nss.py
+++ b/ipsilon/info/nss.py
@@ -20,8 +20,8 @@ posix_map = {
class InfoProvider(InfoProviderBase):
- def __init__(self):
- super(InfoProvider, self).__init__()
+ def __init__(self, *pargs):
+ super(InfoProvider, self).__init__(*pargs)
self.mapper = InfoMapping()
self.mapper.set_mapping(posix_map)
self.name = 'nss'
@@ -75,9 +75,10 @@ class InfoProvider(InfoProviderBase):
class Installer(InfoProviderInstaller):
- def __init__(self):
+ def __init__(self, *pargs):
super(Installer, self).__init__()
self.name = 'nss'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--info-nss', choices=['yes', 'no'], default='no',
@@ -88,18 +89,11 @@ class Installer(InfoProviderInstaller):
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'nss'
po.wipe_data()
- po.wipe_config_values(self.facility)
+ po.wipe_config_values()
- # Replace global config, only one plugin info can be used
- po.name = 'global'
- globalconf = po.get_plugin_config(self.facility)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('nss')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(self.facility, globalconf)
+ # Update global config to add login plugin
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/login/authfas.py b/ipsilon/login/authfas.py
index 71db372..cb1c324 100755
--- a/ipsilon/login/authfas.py
+++ b/ipsilon/login/authfas.py
@@ -5,7 +5,6 @@
from ipsilon.info.common import InfoMapping
from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util import config as pconfig
import cherrypy
@@ -175,9 +174,10 @@ Form based login Manager that uses the Fedora Authentication Server
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'fas'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--fas', choices=['yes', 'no'], default='no',
@@ -188,20 +188,11 @@ class Installer(object):
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'fas'
po.wipe_data()
-
- po.wipe_config_values(FACILITY)
+ po.wipe_config_values()
# Update global config to add login plugin
- po = PluginObject()
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('fas')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/login/authform.py b/ipsilon/login/authform.py
index 4e9f5c1..45c92a5 100755
--- a/ipsilon/login/authform.py
+++ b/ipsilon/login/authform.py
@@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util.user import UserSession
from ipsilon.util import config as pconfig
@@ -105,9 +104,10 @@ LoadModule authnz_pam_module modules/mod_authnz_pam.so
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'form'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--form', choices=['yes', 'no'], default='no',
@@ -128,21 +128,14 @@ class Installer(object):
httpd_conf.write(hunk)
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'form'
po.wipe_data()
- po.wipe_config_values(FACILITY)
+ po.wipe_config_values()
- # Update global config, put 'krb' always first
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('form')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ # Update global config to add login plugin
+ po.is_enabled = True
+ po.save_enabled_state()
# for selinux enabled platforms, ignore if it fails just report
try:
diff --git a/ipsilon/login/authkrb.py b/ipsilon/login/authkrb.py
index f2af0a0..e426d2c 100755
--- a/ipsilon/login/authkrb.py
+++ b/ipsilon/login/authkrb.py
@@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipsilon.login.common import LoginPageBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util.user import UserSession
from string import Template
@@ -61,8 +60,9 @@ class KrbError(LoginPageBase):
if 'WWW-Authenticate' not in cherrypy.request.headers:
cherrypy.response.status = 401
- if self.lm.next_login:
- return self.lm.next_login.page.root(*args, **kwargs)
+ next_login = self.lm.next_login()
+ if next_login:
+ return next_login.page.root(*args, **kwargs)
conturl = '%s/login' % self.basepath
return self._template('login/krb.html',
@@ -117,9 +117,10 @@ CONF_TEMPLATE = """
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'krb'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--krb', choices=['yes', 'no'], default='no',
@@ -152,17 +153,15 @@ class Installer(object):
httpd_conf.write(hunk)
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'krb'
po.wipe_data()
# Update global config, put 'krb' always first
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.insert(0, 'krb')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ ph = self.pargs[0]
+ ph.refresh_enabled()
+ if 'krb' not in ph.enabled:
+ enabled = []
+ enabled.extend(ph.enabled)
+ enabled.insert(0, 'krb')
+ ph.save_enabled(enabled)
diff --git a/ipsilon/login/authldap.py b/ipsilon/login/authldap.py
index f51f375..06dac09 100755
--- a/ipsilon/login/authldap.py
+++ b/ipsilon/login/authldap.py
@@ -3,7 +3,6 @@
# Copyright (C) 2014 Ipsilon Contributors, see COPYING for license
from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util.log import Log
from ipsilon.util import config as pconfig
@@ -176,9 +175,10 @@ authentication. """
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'ldap'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--ldap', choices=['yes', 'no'], default='no',
@@ -193,27 +193,19 @@ class Installer(object):
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'ldap'
po.wipe_data()
+ po.wipe_config_values()
- po.wipe_config_values(FACILITY)
config = dict()
if 'ldap_server_url' in opts:
config['server url'] = opts['ldap_server_url']
if 'ldap_bind_dn_template' in opts:
config['bind dn template'] = opts['ldap_bind_dn_template']
config['tls'] = 'Demand'
- po.save_plugin_config(FACILITY, config)
+ po.save_plugin_config(config)
# Update global config to add login plugin
- po = PluginObject()
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('ldap')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/login/authpam.py b/ipsilon/login/authpam.py
index c7cb9a0..e07bedf 100755
--- a/ipsilon/login/authpam.py
+++ b/ipsilon/login/authpam.py
@@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util import config as pconfig
import pam
@@ -120,9 +119,10 @@ for authentication. """
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'pam'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--pam', choices=['yes', 'no'], default='no',
@@ -135,25 +135,16 @@ class Installer(object):
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'pam'
po.wipe_data()
-
- po.wipe_config_values(FACILITY)
+ po.wipe_config_values()
config = {'service name': opts['pam_service']}
- po.save_plugin_config(FACILITY, config)
+ po.save_plugin_config(config)
# Update global config to add login plugin
- po = PluginObject()
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('pam')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ po.is_enabled = True
+ po.save_enabled_state()
# for selinux enabled platforms, ignore if it fails just report
try:
diff --git a/ipsilon/login/authtest.py b/ipsilon/login/authtest.py
index e3f8eff..8a24500 100755
--- a/ipsilon/login/authtest.py
+++ b/ipsilon/login/authtest.py
@@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
from ipsilon.util.plugin import PluginObject
from ipsilon.util import config as pconfig
import cherrypy
@@ -102,9 +101,10 @@ Form based TEST login Manager, DO NOT EVER ACTIVATE IN PRODUCTION """
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'testauth'
self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--testauth', choices=['yes', 'no'], default='no',
@@ -114,19 +114,12 @@ class Installer(object):
if opts['testauth'] != 'yes':
return
+ print self.pargs
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'testauth'
po.wipe_data()
# Update global config to add login plugin
- po = PluginObject()
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('testauth')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/login/common.py b/ipsilon/login/common.py
index ad09ce1..b394fa0 100755
--- a/ipsilon/login/common.py
+++ b/ipsilon/login/common.py
@@ -31,14 +31,13 @@ USERNAME_COOKIE = 'ipsilon_default_username'
class LoginManagerBase(PluginConfig, PluginObject):
- def __init__(self):
+ def __init__(self, *args):
PluginConfig.__init__(self)
- PluginObject.__init__(self)
+ PluginObject.__init__(self, *args)
+ self._root = None
self._site = None
self.path = '/'
- self.next_login = None
self.info = None
- self.is_enabled = False
def redirect_to_path(self, path):
base = cherrypy.config.get('base.mount', "")
@@ -94,8 +93,9 @@ class LoginManagerBase(PluginConfig, PluginObject):
def auth_failed(self, trans):
# try with next module
- if self.next_login:
- return self.redirect_to_path(self.next_login.path)
+ next_login = self.next_login()
+ if next_login:
+ return self.redirect_to_path(next_login.path)
# return to the caller if any
session = UserSession()
@@ -117,62 +117,26 @@ class LoginManagerBase(PluginConfig, PluginObject):
def get_tree(self, site):
raise NotImplementedError
- def enable(self, site):
- if self.is_enabled:
- return
+ def register(self, root, site):
+ self._root = root
+ self._site = site
- if not self._site:
- self._site = site
+ def next_login(self):
plugins = self._site[FACILITY]
+ try:
+ idx = plugins.enabled.index(self.name)
+ item = plugins.enabled[idx + 1]
+ return plugins.available[item]
+ except (ValueError, IndexError):
+ return None
- # configure self
- if self.name in plugins['config']:
- self.import_config(plugins['config'][self.name])
+ def on_enable(self):
# and add self to the root
- root = plugins['root']
- root.add_subtree(self.name, self.get_tree(site))
-
- # finally add self in login chain
- prev_obj = None
- for prev_obj in plugins['enabled']:
- if prev_obj.next_login:
- break
- if prev_obj:
- while prev_obj.next_login:
- prev_obj = prev_obj.next_login
- prev_obj.next_login = self
- if not root.first_login:
- root.first_login = self
-
- plugins['enabled'].append(self)
- self.is_enabled = True
- self._debug('Login plugin enabled: %s' % self.name)
+ self._root.add_subtree(self.name, self.get_tree(self._site))
# Get handle of the info plugin
- self.info = root.info
-
- def disable(self, site):
- if not self.is_enabled:
- return
-
- plugins = self._site[FACILITY]
-
- # remove self from chain
- root = plugins['root']
- if root.first_login == self:
- root.first_login = self.next_login
- elif root.first_login:
- prev_obj = root.first_login
- while prev_obj.next_login != self:
- prev_obj = prev_obj.next_login
- if prev_obj:
- prev_obj.next_login = self.next_login
- self.next_login = None
-
- plugins['enabled'].remove(self)
- self.is_enabled = False
- self._debug('Login plugin disabled: %s' % self.name)
+ self.info = self._root.info
class LoginPageBase(Page):
@@ -207,8 +171,9 @@ class LoginFormBase(LoginPageBase):
def create_tmpl_context(self, **kwargs):
next_url = None
- if self.lm.next_login is not None:
- next_url = '%s?%s' % (self.lm.next_login.path,
+ next_login = self.lm.next_login()
+ if next_login:
+ next_url = '%s?%s' % (next_login.path,
self.trans.get_GET_arg())
cookie = SecureCookie(USERNAME_COOKIE)
@@ -253,31 +218,42 @@ class Login(Page):
def __init__(self, *args, **kwargs):
super(Login, self).__init__(*args, **kwargs)
self.cancel = Cancel(*args, **kwargs)
- self.first_login = None
self.info = Info(self._site)
- loader = PluginLoader(Login, FACILITY, 'LoginManager')
- self._site[FACILITY] = loader.get_plugin_data()
- plugins = self._site[FACILITY]
+ plugins = PluginLoader(Login, FACILITY, 'LoginManager')
+ plugins.get_plugin_data()
+ self._site[FACILITY] = plugins
- available = plugins['available'].keys()
+ available = plugins.available.keys()
self._debug('Available login managers: %s' % str(available))
- plugins['root'] = self
- for item in plugins['whitelist']:
- self._debug('Login plugin in whitelist: %s' % item)
- if item not in plugins['available']:
+ for item in plugins.available:
+ plugin = plugins.available[item]
+ plugin.register(self, self._site)
+
+ for item in plugins.enabled:
+ self._debug('Login plugin in enabled list: %s' % item)
+ if item not in plugins.available:
continue
- plugins['available'][item].enable(self._site)
+ plugins.available[item].enable()
def add_subtree(self, name, page):
self.__dict__[name] = page
+ def get_first_login(self):
+ plugin = None
+ plugins = self._site[FACILITY]
+ if plugins.enabled:
+ first = plugins.enabled[0]
+ plugin = plugins.available[first]
+ return plugin
+
def root(self, *args, **kwargs):
- if self.first_login:
+ plugin = self.get_first_login()
+ if plugin:
trans = self.get_valid_transaction('login', **kwargs)
redirect = '%s/login/%s?%s' % (self.basepath,
- self.first_login.path,
+ plugin.path,
trans.get_GET_arg())
raise cherrypy.HTTPRedirect(redirect)
return self._template('login/index.html', title='Login')
@@ -312,5 +288,5 @@ class Cancel(Page):
class LoginMgrsInstall(object):
def __init__(self):
- pi = PluginInstaller(LoginMgrsInstall)
+ pi = PluginInstaller(LoginMgrsInstall, FACILITY)
self.plugins = pi.get_plugins()
diff --git a/ipsilon/providers/common.py b/ipsilon/providers/common.py
index ead50e2..03118ae 100755
--- a/ipsilon/providers/common.py
+++ b/ipsilon/providers/common.py
@@ -51,68 +51,29 @@ class InvalidRequest(ProviderException):
class ProviderBase(PluginConfig, PluginObject):
- def __init__(self, name, path):
+ def __init__(self, name, path, *pargs):
PluginConfig.__init__(self)
- PluginObject.__init__(self)
+ PluginObject.__init__(self, *pargs)
self.name = name
+ self._root = None
self.path = path
self.tree = None
- self.is_enabled = False
-
- def on_enable(self):
- # this one does nothing
- # derived classes can override with custom behavior
- return
def get_tree(self, site):
raise NotImplementedError
- def register(self, site):
- if self.tree:
- # already registered
- return
-
- # configure self
- plugins = site[FACILITY]
- if self.name in plugins['config']:
- self.import_config(plugins['config'][self.name])
+ def register(self, root, site):
+ self._root = root
# 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') is True:
- # and enable self
- self._enable(site)
-
- def _enable(self, site):
- root = site[FACILITY]['root']
- root.add_subtree(self.name, self.tree)
- self._debug('IdP Provider enabled: %s' % self.name)
- self.is_enabled = True
- self.on_enable()
-
- def enable(self, site):
- if self.is_enabled:
- return
-
- self._enable(site)
- self.set_config_value('enabled', True)
- self.save_plugin_config(FACILITY)
-
- def disable(self, site):
- if not self.is_enabled:
- return
-
- # remove self to the root
- root = site[FACILITY]['root']
- root.del_subtree(self.name)
+ def on_enable(self):
+ self._root.add_subtree(self.name, self.tree)
- self.is_enabled = False
- self.set_config_value('enabled', False)
- self.save_plugin_config(FACILITY)
- self._debug('IdP Provider disabled: %s' % self.name)
+ def on_disable(self):
+ self._root.del_subtree(self.name)
class ProviderPageBase(Page):
@@ -155,21 +116,26 @@ FACILITY = 'provider_config'
class LoadProviders(Log):
def __init__(self, root, site):
- loader = PluginLoader(LoadProviders, FACILITY, 'IdpProvider')
- site[FACILITY] = loader.get_plugin_data()
- providers = site[FACILITY]
+ plugins = PluginLoader(LoadProviders, FACILITY, 'IdpProvider')
+ plugins.get_plugin_data()
+ site[FACILITY] = plugins
- available = providers['available'].keys()
+ available = plugins.available.keys()
self._debug('Available providers: %s' % str(available))
- providers['root'] = root
- for item in providers['available']:
- plugin = providers['available'][item]
- plugin.register(site)
+ for item in plugins.available:
+ plugin = plugins.available[item]
+ plugin.register(root, site)
+
+ for item in plugins.enabled:
+ self._debug('Provider plugin in enabled list: %s' % item)
+ if item not in plugins.available:
+ continue
+ plugins.available[item].enable()
class ProvidersInstall(object):
def __init__(self):
- pi = PluginInstaller(ProvidersInstall)
+ pi = PluginInstaller(ProvidersInstall, FACILITY)
self.plugins = pi.get_plugins()
diff --git a/ipsilon/providers/openid/extensions/ax.py b/ipsilon/providers/openid/extensions/ax.py
index 7daa52a..d00a4fc 100755
--- a/ipsilon/providers/openid/extensions/ax.py
+++ b/ipsilon/providers/openid/extensions/ax.py
@@ -28,7 +28,7 @@ AP_MAP = {
class OpenidExtension(OpenidExtensionBase):
- def __init__(self):
+ def __init__(self, *pargs):
super(OpenidExtension, self).__init__('Attribute Exchange')
self.type_uris = [
ax.AXMessage.ns_uri,
diff --git a/ipsilon/providers/openid/extensions/cla.py b/ipsilon/providers/openid/extensions/cla.py
index cc4d11d..481f341 100755
--- a/ipsilon/providers/openid/extensions/cla.py
+++ b/ipsilon/providers/openid/extensions/cla.py
@@ -10,7 +10,7 @@ from openid_cla import cla
class OpenidExtension(OpenidExtensionBase):
- def __init__(self):
+ def __init__(self, *pargs):
super(OpenidExtension, self).__init__('CLAs')
self.type_uris = [
cla.cla_uri,
diff --git a/ipsilon/providers/openid/extensions/common.py b/ipsilon/providers/openid/extensions/common.py
index 804f695..02cd1a0 100755
--- a/ipsilon/providers/openid/extensions/common.py
+++ b/ipsilon/providers/openid/extensions/common.py
@@ -50,22 +50,20 @@ FACILITY = 'openid_extensions'
class LoadExtensions(Log):
def __init__(self):
- loader = PluginLoader(LoadExtensions, FACILITY, 'OpenidExtension')
- self.plugins = loader.get_plugin_data()
+ self.plugins = PluginLoader(LoadExtensions,
+ FACILITY, 'OpenidExtension')
+ self.plugins.get_plugin_data()
- available = self.plugins['available'].keys()
+ 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']:
+ if item not in self.plugins.available:
self.debug('<%s> not available' % item)
continue
self.debug('Enable OpenId extension: %s' % item)
- self.plugins['available'][item].enable()
+ self.plugins.available[item].enable()
def available(self):
- available = self.plugins['available']
- if available is None:
- available = dict()
- return available
+ return self.plugins.available
diff --git a/ipsilon/providers/openid/extensions/fas_teams.py b/ipsilon/providers/openid/extensions/fas_teams.py
index fd9dd27..4de2e83 100755
--- a/ipsilon/providers/openid/extensions/fas_teams.py
+++ b/ipsilon/providers/openid/extensions/fas_teams.py
@@ -10,7 +10,7 @@ from openid_teams import teams
class OpenidExtension(Teams):
- def __init__(self):
+ def __init__(self, *pargs):
super(OpenidExtension, self).__init__('Fedora Teams')
def _resp(self, request, userdata):
diff --git a/ipsilon/providers/openid/extensions/sreg.py b/ipsilon/providers/openid/extensions/sreg.py
index a2b4db7..e1144fc 100755
--- a/ipsilon/providers/openid/extensions/sreg.py
+++ b/ipsilon/providers/openid/extensions/sreg.py
@@ -10,7 +10,7 @@ from openid.extensions import sreg
class OpenidExtension(OpenidExtensionBase):
- def __init__(self):
+ def __init__(self, *pargs):
super(OpenidExtension, self).__init__('Simple Registration')
self.type_uris = [
sreg.ns_uri_1_1,
diff --git a/ipsilon/providers/openid/extensions/teams.py b/ipsilon/providers/openid/extensions/teams.py
index 50c09af..258a437 100755
--- a/ipsilon/providers/openid/extensions/teams.py
+++ b/ipsilon/providers/openid/extensions/teams.py
@@ -34,5 +34,5 @@ class Teams(OpenidExtensionBase):
class OpenidExtension(Teams):
- def __init__(self):
+ def __init__(self, *pargs):
super(OpenidExtension, self).__init__('Teams')
diff --git a/ipsilon/providers/openidp.py b/ipsilon/providers/openidp.py
index 197b1cf..335b41b 100755
--- a/ipsilon/providers/openidp.py
+++ b/ipsilon/providers/openidp.py
@@ -5,7 +5,6 @@
from __future__ import absolute_import
from ipsilon.providers.common import ProviderBase
-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
@@ -19,8 +18,8 @@ from openid.store.memstore import MemoryStore
class IdpProvider(ProviderBase):
- def __init__(self):
- super(IdpProvider, self).__init__('openid', 'openid')
+ def __init__(self, *pargs):
+ super(IdpProvider, self).__init__('openid', 'openid', *pargs)
self.mapping = InfoMapping()
self.page = None
self.server = None
@@ -55,10 +54,6 @@ Provides OpenID 2.0 authentication infrastructure. """
'enabled extensions',
'Choose the extensions to enable',
self.extensions.available().keys()),
- pconfig.Condition(
- 'enabled',
- 'Whether the OpenID IDP is enabled',
- False)
)
@property
@@ -99,10 +94,10 @@ Provides OpenID 2.0 authentication infrastructure. """
# self.admin = AdminPage(site, self)
# Expose OpenID presence in the root
- headers = site[FACILITY]['root'].default_headers
+ headers = self._root.default_headers
headers['X-XRDS-Location'] = self.endpoint_url+'XRDS'
- html_heads = site[FACILITY]['root'].html_heads
+ html_heads = self._root.html_heads
HEAD_LINK = '<link rel="%s" href="%s">'
openid_heads = [HEAD_LINK % ('openid2.provider', self.endpoint_url),
HEAD_LINK % ('openid.server', self.endpoint_url)]
@@ -114,15 +109,17 @@ Provides OpenID 2.0 authentication infrastructure. """
self.server = Server(MemoryStore(), op_endpoint=self.endpoint_url)
def on_enable(self):
+ super(IdpProvider, self).on_enable()
self.init_idp()
self.extensions.enable(self._config['enabled extensions'].get_value())
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'openid'
self.ptype = 'provider'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--openid', choices=['yes', 'no'], default='yes',
@@ -139,12 +136,14 @@ class Installer(object):
proto, opts['hostname'], opts['instance'])
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'openid'
po.wipe_data()
-
- po.wipe_config_values(FACILITY)
+ po.wipe_config_values()
config = {'endpoint url': url,
- 'identity_url_template': '%sid/%%(username)s' % url,
- 'enabled': '1'}
- po.save_plugin_config(FACILITY, config)
+ 'identity_url_template': '%sid/%%(username)s' % url}
+ po.save_plugin_config(config)
+
+ # Update global config to add login plugin
+ po.is_enabled = True
+ po.save_enabled_state()
diff --git a/ipsilon/providers/saml2idp.py b/ipsilon/providers/saml2idp.py
index 8896e16..b0f4304 100755
--- a/ipsilon/providers/saml2idp.py
+++ b/ipsilon/providers/saml2idp.py
@@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipsilon.providers.common import ProviderBase, ProviderPageBase
-from ipsilon.providers.common import FACILITY
from ipsilon.providers.saml2.auth import AuthenticateRequest
from ipsilon.providers.saml2.admin import Saml2AdminPage
from ipsilon.providers.saml2.provider import IdentityProvider
@@ -119,8 +118,8 @@ class SAML2(ProviderPageBase):
class IdpProvider(ProviderBase):
- def __init__(self):
- super(IdpProvider, self).__init__('saml2', 'saml2')
+ def __init__(self, *pargs):
+ super(IdpProvider, self).__init__('saml2', 'saml2', *pargs)
self.admin = None
self.page = None
self.idp = None
@@ -163,10 +162,6 @@ Provides SAML 2.0 authentication infrastructure. """
'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
@@ -242,7 +237,8 @@ Provides SAML 2.0 authentication infrastructure. """
return idp
def on_enable(self):
- self.init_idp()
+ super(IdpProvider, self).on_enable()
+ self.idp = self.init_idp()
if hasattr(self, 'admin'):
if self.admin:
self.admin.add_sps()
@@ -250,9 +246,10 @@ Provides SAML 2.0 authentication infrastructure. """
class Installer(object):
- def __init__(self):
+ def __init__(self, *pargs):
self.name = 'saml2'
self.ptype = 'provider'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--saml2', choices=['yes', 'no'], default='yes',
@@ -297,17 +294,19 @@ class Installer(object):
meta.output(os.path.join(path, 'metadata.xml'))
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'saml2'
po.wipe_data()
-
- po.wipe_config_values(FACILITY)
+ po.wipe_config_values()
config = {'idp storage path': path,
'idp metadata file': 'metadata.xml',
'idp certificate file': cert.cert,
- 'idp key file': cert.key,
- 'enabled': '1'}
- po.save_plugin_config(FACILITY, config)
+ 'idp key file': cert.key}
+ po.save_plugin_config(config)
+
+ # Update global config to add login plugin
+ po.is_enabled = True
+ po.save_enabled_state()
# Fixup permissions so only the ipsilon user can read these files
files.fix_user_dirs(path, opts['system_user'])
diff --git a/ipsilon/util/plugin.py b/ipsilon/util/plugin.py
index f303078..063767c 100755
--- a/ipsilon/util/plugin.py
+++ b/ipsilon/util/plugin.py
@@ -31,7 +31,7 @@ class Plugins(object):
def __init__(self):
self._providers_tree = None
- def _load_class(self, tree, class_type, file_name):
+ def _load_class(self, tree, class_type, file_name, *pargs):
cherrypy.log.error('Check module %s for class %s' % (file_name,
class_type))
name, ext = os.path.splitext(os.path.split(file_name)[-1])
@@ -47,12 +47,12 @@ class Plugins(object):
return
if hasattr(mod, class_type):
- instance = getattr(mod, class_type)()
+ instance = getattr(mod, class_type)(*pargs)
public_name = getattr(instance, 'name', name)
tree[public_name] = instance
cherrypy.log.error('Added module %s as %s' % (name, public_name))
- def _load_classes(self, tree, path, class_type):
+ def _load_classes(self, tree, path, class_type, *pargs):
files = None
try:
files = os.listdir(path)
@@ -62,58 +62,108 @@ class Plugins(object):
for name in files:
filename = os.path.join(path, name)
- self._load_class(tree, class_type, filename)
+ self._load_class(tree, class_type, filename, *pargs)
- def get_plugins(self, path, class_type):
+ def get_plugins(self, path, class_type, *pargs):
plugins = dict()
- self._load_classes(plugins, path, class_type)
+ self._load_classes(plugins, path, class_type, *pargs)
return plugins
-class PluginLoader(object):
+class PluginLoader(Log):
def __init__(self, baseobj, facility, plugin_type):
- config = AdminStore().load_options(facility)
- cherrypy.log('LOAD: %s\n' % repr(config))
- whitelist = []
- if 'global' in config:
- sec = config['global']
- if 'order' in sec:
- whitelist = sec['order'].split(',')
- if cherrypy.config.get('debug', False):
- cherrypy.log('[%s] %s: %s' % (facility, whitelist, config))
- if config is None:
- config = dict()
+ self._pathname, _ = os.path.split(inspect.getfile(baseobj))
+ self.facility = facility
+ self._plugin_type = plugin_type
+ self.available = dict()
+ self.enabled = list()
+ self.__data = None
+
+ # Defer initialization or instantiating the store will fail at load
+ # time when used with Installer plugins as the cherrypy config context
+ # is created after all Installer plugins are loaded.
+ @property
+ def _data(self):
+ if not self.__data:
+ self.__data = AdminStore()
+ return self.__data
+ def get_plugins(self):
p = Plugins()
- (pathname, dummy) = os.path.split(inspect.getfile(baseobj))
- self._plugins = {
- 'config': config,
- 'available': p.get_plugins(pathname, plugin_type),
- 'whitelist': whitelist,
- 'enabled': []
- }
+ return p.get_plugins(self._pathname, self._plugin_type, self)
+
+ def refresh_enabled(self):
+ config = self._data.load_options(self.facility, name='global')
+ self.enabled = []
+ if config:
+ if 'enabled' in config:
+ self.enabled = config['enabled'].split(',')
def get_plugin_data(self):
- return self._plugins
+ self.available = self.get_plugins()
+ self.refresh_enabled()
+ def save_enabled(self, enabled):
+ if enabled:
+ self._data.save_options(self.facility, 'global',
+ {'enabled': ','.join(enabled)})
+ else:
+ self._data.delete_options(self.facility, 'global',
+ {'enabled': '*'})
+ self.debug('Plugin enabled state saved: %s' % enabled)
+ self.refresh_enabled()
-class PluginInstaller(object):
- def __init__(self, baseobj):
- (pathname, dummy) = os.path.split(inspect.getfile(baseobj))
- self._pathname = pathname
- def get_plugins(self):
- p = Plugins()
- return p.get_plugins(self._pathname, 'Installer')
+class PluginInstaller(PluginLoader):
+ def __init__(self, baseobj, facility):
+ super(PluginInstaller, self).__init__(baseobj, facility, 'Installer')
class PluginObject(Log):
- def __init__(self):
+ def __init__(self, plugins):
self.name = None
self._config = None
self._data = AdminStore()
+ self._plugins = plugins
+ self.is_enabled = False
+
+ def on_enable(self):
+ return
+
+ def on_disable(self):
+ return
+
+ def save_enabled_state(self):
+ enabled = []
+ self._plugins.refresh_enabled()
+ enabled.extend(self._plugins.enabled)
+ if self.is_enabled:
+ if self.name not in enabled:
+ enabled.append(self.name)
+ else:
+ if self.name in enabled:
+ enabled.remove(self.name)
+ self._plugins.save_enabled(enabled)
+
+ def enable(self):
+ if self.is_enabled:
+ return
+
+ self.refresh_plugin_config()
+ self.on_enable()
+ self.is_enabled = True
+ self.debug('Plugin enabled: %s' % self.name)
+
+ def disable(self):
+ if not self.is_enabled:
+ return
+
+ self.on_disable()
+
+ self.is_enabled = False
+ self.debug('Plugin disabled: %s' % self.name)
def import_config(self, config):
self._config = config
@@ -121,18 +171,19 @@ class PluginObject(Log):
def export_config(self):
return self._config
- def get_plugin_config(self, facility):
- return self._data.load_options(facility, self.name)
+ def get_plugin_config(self):
+ return self._data.load_options(self._plugins.facility, self.name)
- def refresh_plugin_config(self, facility):
- config = self.get_plugin_config(facility)
- self.import_config(config)
+ def refresh_plugin_config(self):
+ config = self.get_plugin_config()
+ if config:
+ self.import_config(config)
- def save_plugin_config(self, facility, config=None):
+ def save_plugin_config(self, config=None):
if config is None:
config = self.export_config()
- self._data.save_options(facility, self.name, config)
+ self._data.save_options(self._plugins.facility, self.name, config)
def get_data(self, idval=None, name=None, value=None):
return self._data.get_data(self.name, idval=idval, name=name,
@@ -147,8 +198,8 @@ class PluginObject(Log):
def del_datum(self, idval):
self._data.del_datum(self.name, idval)
- def wipe_config_values(self, facility):
- self._data.delete_options(facility, self.name, None)
+ def wipe_config_values(self):
+ self._data.delete_options(self._plugins.facility, self.name, None)
def wipe_data(self):
self._data.wipe_data(self.name)
diff --git a/quickrun.py b/quickrun.py
index 0546fcc..ac22f6b 100755
--- a/quickrun.py
+++ b/quickrun.py
@@ -41,7 +41,7 @@ CONF_TEMPLATE="templates/install/ipsilon.conf"
ADMIN_TEMPLATE='''
CREATE TABLE login_config (name TEXT,option TEXT,value TEXT);
-INSERT INTO login_config VALUES('global', 'order', 'testauth');
+INSERT INTO login_config VALUES('global', 'enabled', 'testauth');
'''
USERS_TEMPLATE='''