summaryrefslogtreecommitdiffstats
path: root/ipsilon/login
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 /ipsilon/login
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>
Diffstat (limited to 'ipsilon/login')
-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
7 files changed, 92 insertions, 157 deletions
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()