Merge pull request #611 from odoo-dev/saas-3-really-fix-session-expired-fme
authorodony <odo@openerp.com>
Fri, 20 Jun 2014 09:02:22 +0000 (11:02 +0200)
committerodony <odo@openerp.com>
Fri, 20 Jun 2014 09:02:22 +0000 (11:02 +0200)
[MERGE]  http routing: fix handle_exception logic and _authenticate exceptions

* Better separate JsonRequest and HttpRequest handling
for exceptions, so each type of request handles exception
the right way. Previously HttpRequest would supersede
JsonRequest in some cases and generate pure HTML
responses where a JSON result was expected.
* Also ensure that ir.http._authenticate() only raises
two possible exception types, hiding any other kind
of internal errors:
 - openerp.exceptions.AccessDenied
 - openerp.http.SessionExpiredException

openerp/addons/base/ir/ir_http.py
openerp/http.py

index bd211d1..122b9d9 100644 (file)
@@ -71,17 +71,23 @@ class ir_http(osv.AbstractModel):
             request.uid = request.session.uid
 
     def _authenticate(self, auth_method='user'):
-        if request.session.uid:
-            try:
-                request.session.check_security()
-                # what if error in security.check()
-                #   -> res_users.check()
-                #   -> res_users.check_credentials()
-            except (openerp.exceptions.AccessDenied, openerp.http.SessionExpiredException):
-                # All other exceptions mean undetermined status (e.g. connection pool full),
-                # let them bubble up
-                request.session.logout()
-        getattr(self, "_auth_method_%s" % auth_method)()
+        try:
+            if request.session.uid:
+                try:
+                    request.session.check_security()
+                    # what if error in security.check()
+                    #   -> res_users.check()
+                    #   -> res_users.check_credentials()
+                except (openerp.exceptions.AccessDenied, openerp.http.SessionExpiredException):
+                    # All other exceptions mean undetermined status (e.g. connection pool full),
+                    # let them bubble up
+                    request.session.logout()
+            getattr(self, "_auth_method_%s" % auth_method)()
+        except (openerp.exceptions.AccessDenied, openerp.http.SessionExpiredException):
+            raise
+        except Exception:
+            _logger.exception("Exception during request Authentication.")
+            raise openerp.exceptions.AccessDenied()
         return auth_method
 
     def _handle_exception(self, exception):
index ec979fd..d32d003 100644 (file)
@@ -208,8 +208,6 @@ class WebRequest(object):
            to abitrary responses. Anything returned (except None) will
            be used as response.""" 
         self._failed = exception # prevent tx commit
-        if isinstance(exception, werkzeug.exceptions.HTTPException):
-            return exception
         raise
 
     def _call_function(self, *args, **kwargs):
@@ -456,6 +454,15 @@ class HttpRequest(WebRequest):
         params.pop('session_id', None)
         self.params = params
 
+    def _handle_exception(self, exception):
+        """Called within an except block to allow converting exceptions
+           to abitrary responses. Anything returned (except None) will
+           be used as response."""
+        try:
+            return super(HttpRequest, self)._handle_exception(exception)
+        except werkzeug.exceptions.HTTPException, e:
+            return e
+
     def dispatch(self):
         # TODO: refactor this correctly. This is a quick fix for pos demo.
         if request.httprequest.method == 'OPTIONS' and request.func and request.func.routing.get('cors'):