Handle invalid/expired transactions gracefully
authorSimo Sorce <simo@redhat.com>
Fri, 10 Oct 2014 17:34:00 +0000 (13:34 -0400)
committerPatrick Uiterwijk <puiterwijk@redhat.com>
Fri, 24 Oct 2014 16:03:28 +0000 (18:03 +0200)
Return a useful error page every time and invalid or expired
transaction is requested, instead of ending up with an internal
backtrace and an ugly 500 error.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
ipsilon/login/authkrb.py
ipsilon/login/common.py
ipsilon/util/page.py

index 965d018..724c2ce 100755 (executable)
@@ -20,7 +20,6 @@
 from ipsilon.login.common import LoginPageBase, LoginManagerBase
 from ipsilon.login.common import FACILITY
 from ipsilon.util.plugin import PluginObject
-from ipsilon.util.trans import Transaction
 from ipsilon.util.user import UserSession
 from string import Template
 import cherrypy
@@ -38,7 +37,7 @@ class Krb(LoginPageBase):
 class KrbAuth(LoginPageBase):
 
     def root(self, *args, **kwargs):
-        trans = Transaction('login', **kwargs)
+        trans = self.get_valid_transaction('login', **kwargs)
         # If we can get here, we must be authenticated and remote_user
         # was set. Check the session has a user set already or error.
         us = UserSession()
@@ -71,7 +70,8 @@ class KrbError(LoginPageBase):
                                   cont=conturl)
 
         # If we get here, negotiate failed
-        return self.lm.auth_failed(Transaction('login', **kwargs))
+        trans = self.get_valid_transaction('login', **kwargs)
+        return self.lm.auth_failed(trans)
 
 
 class LoginManager(LoginManagerBase):
index 94284b0..cb45fd6 100755 (executable)
@@ -24,7 +24,6 @@ from ipsilon.util.plugin import PluginLoader, PluginObject
 from ipsilon.util.plugin import PluginInstaller
 from ipsilon.info.common import Info
 from ipsilon.util.cookies import SecureCookie
-from ipsilon.util.trans import Transaction
 import cherrypy
 
 
@@ -193,7 +192,7 @@ class LoginFormBase(LoginPageBase):
         return self._template(self.formtemplate, **context)
 
     def root(self, *args, **kwargs):
-        self.trans = Transaction('login', **kwargs)
+        self.trans = self.get_valid_transaction('login', **kwargs)
         op = getattr(self, cherrypy.request.method, self.GET)
         if callable(op):
             return op(*args, **kwargs)
@@ -265,7 +264,7 @@ class Login(Page):
 
     def root(self, *args, **kwargs):
         if self.first_login:
-            trans = Transaction('login', **kwargs)
+            trans = self.get_valid_transaction('login', **kwargs)
             redirect = '%s/login/%s?%s' % (self.basepath,
                                            self.first_login.path,
                                            trans.get_GET_arg())
index f98b2d9..213f945 100755 (executable)
@@ -19,6 +19,7 @@
 
 from ipsilon.util.log import Log
 from ipsilon.util.user import UserSession
+from ipsilon.util.trans import Transaction
 from urllib import unquote
 import cherrypy
 
@@ -113,4 +114,11 @@ class Page(Log):
     def del_subtree(self, name):
         del self.__dict__[name]
 
+    def get_valid_transaction(self, provider, **kwargs):
+        try:
+            return Transaction(provider, **kwargs)
+        except ValueError:
+            msg = 'Transaction expired, or cookies not available'
+            raise cherrypy.HTTPError(401, msg)
+
     exposed = True