Return PAM errors from mod_intercept_form_submit
[cascardo/ipsilon.git] / ipsilon / login / common.py
index d616882..31053a0 100644 (file)
@@ -1,24 +1,10 @@
-# Copyright (C) 2013  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) 2013 Ipsilon project Contributors, for license see COPYING
 
 from ipsilon.util.page import Page
 from ipsilon.util.user import UserSession
 from ipsilon.util.plugin import PluginInstaller, PluginLoader
 
 from ipsilon.util.page import Page
 from ipsilon.util.user import UserSession
 from ipsilon.util.plugin import PluginInstaller, PluginLoader
-from ipsilon.util.plugin import PluginObject, PluginConfig
+from ipsilon.util.plugin import PluginObject
+from ipsilon.util.config import ConfigHelper
 from ipsilon.info.common import Info
 from ipsilon.util.cookies import SecureCookie
 import cherrypy
 from ipsilon.info.common import Info
 from ipsilon.util.cookies import SecureCookie
 import cherrypy
@@ -27,10 +13,10 @@ import cherrypy
 USERNAME_COOKIE = 'ipsilon_default_username'
 
 
 USERNAME_COOKIE = 'ipsilon_default_username'
 
 
-class LoginManagerBase(PluginConfig, PluginObject):
+class LoginManagerBase(ConfigHelper, PluginObject):
 
     def __init__(self, *args):
 
     def __init__(self, *args):
-        PluginConfig.__init__(self)
+        ConfigHelper.__init__(self)
         PluginObject.__init__(self, *args)
         self._root = None
         self._site = None
         PluginObject.__init__(self, *args)
         self._root = None
         self._site = None
@@ -99,7 +85,7 @@ class LoginManagerBase(PluginConfig, PluginObject):
             trans.wipe()
         raise cherrypy.HTTPRedirect(redirect)
 
             trans.wipe()
         raise cherrypy.HTTPRedirect(redirect)
 
-    def auth_failed(self, trans):
+    def auth_failed(self, trans, message=None):
         # try with next module
         next_login = self.next_login()
         if next_login:
         # try with next module
         next_login = self.next_login()
         if next_login:
@@ -118,7 +104,7 @@ class LoginManagerBase(PluginConfig, PluginObject):
         # destroy session and return error
         if 'login_return' not in transdata:
             session.logout(None)
         # destroy session and return error
         if 'login_return' not in transdata:
             session.logout(None)
-            raise cherrypy.HTTPError(401)
+            raise cherrypy.HTTPError(401, message)
 
         raise cherrypy.HTTPRedirect(transdata['login_return'])
 
 
         raise cherrypy.HTTPRedirect(transdata['login_return'])
 
@@ -141,6 +127,19 @@ class LoginManagerBase(PluginConfig, PluginObject):
         except (ValueError, IndexError):
             return None
 
         except (ValueError, IndexError):
             return None
 
+    def other_login_stacks(self):
+        plugins = self._site[FACILITY]
+        stack = list()
+        try:
+            idx = plugins.enabled.index(self.name)
+        except (ValueError, IndexError):
+            idx = None
+        for i in range(0, len(plugins.enabled)):
+            if i == idx:
+                continue
+            stack.append(plugins.available[plugins.enabled[i]])
+        return stack
+
     def on_enable(self):
 
         # and add self to the root
     def on_enable(self):
 
         # and add self to the root
@@ -171,7 +170,6 @@ class LoginFormBase(LoginPageBase):
 
     def GET(self, *args, **kwargs):
         context = self.create_tmpl_context()
 
     def GET(self, *args, **kwargs):
         context = self.create_tmpl_context()
-        # pylint: disable=star-args
         return self._template(self.formtemplate, **context)
 
     def root(self, *args, **kwargs):
         return self._template(self.formtemplate, **context)
 
     def root(self, *args, **kwargs):
@@ -181,11 +179,14 @@ class LoginFormBase(LoginPageBase):
             return op(*args, **kwargs)
 
     def create_tmpl_context(self, **kwargs):
             return op(*args, **kwargs)
 
     def create_tmpl_context(self, **kwargs):
-        next_url = None
-        next_login = self.lm.next_login()
-        if next_login:
-            next_url = '%s?%s' % (next_login.path,
-                                  self.trans.get_GET_arg())
+        other_stacks = None
+        other_login_stacks = self.lm.other_login_stacks()
+        if other_login_stacks:
+            other_stacks = list()
+            for ls in other_login_stacks:
+                url = '%s?%s' % (ls.path, self.trans.get_GET_arg())
+                name = ls.name
+                other_stacks.append({'url': url, 'name': name})
 
         cookie = SecureCookie(USERNAME_COOKIE)
         cookie.receive()
 
         cookie = SecureCookie(USERNAME_COOKIE)
         cookie.receive()
@@ -209,7 +210,7 @@ class LoginFormBase(LoginPageBase):
             "username_text": self.lm.username_text,
             "password_text": self.lm.password_text,
             "description": self.lm.help_text,
             "username_text": self.lm.username_text,
             "password_text": self.lm.password_text,
             "description": self.lm.help_text,
-            "next_url": next_url,
+            "other_stacks": other_stacks,
             "username": username,
             "login_target": target,
             "cancel_url": '%s/login/cancel?%s' % (self.basepath,
             "username": username,
             "login_target": target,
             "cancel_url": '%s/login/cancel?%s' % (self.basepath,
@@ -238,14 +239,14 @@ class Login(Page):
         self._site[FACILITY] = plugins
 
         available = plugins.available.keys()
         self._site[FACILITY] = plugins
 
         available = plugins.available.keys()
-        self._debug('Available login managers: %s' % str(available))
+        self.debug('Available login managers: %s' % str(available))
 
         for item in plugins.available:
             plugin = plugins.available[item]
             plugin.register(self, self._site)
 
         for item in plugins.enabled:
 
         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)
+            self.debug('Login plugin in enabled list: %s' % item)
             if item not in plugins.available:
                 continue
             plugins.available[item].enable()
             if item not in plugins.available:
                 continue
             plugins.available[item].enable()
@@ -321,7 +322,7 @@ class LoginManagerInstaller(object):
         self.ptype = 'login'
         self.name = None
 
         self.ptype = 'login'
         self.name = None
 
-    def unconfigure(self, opts):
+    def unconfigure(self, opts, changes):
         return
 
     def install_args(self, group):
         return
 
     def install_args(self, group):
@@ -330,7 +331,7 @@ class LoginManagerInstaller(object):
     def validate_args(self, args):
         return
 
     def validate_args(self, args):
         return
 
-    def configure(self, opts):
+    def configure(self, opts, changes):
         raise NotImplementedError
 
 
         raise NotImplementedError