[Kimchi-devel] [PATCH] [Wok 5/6] Log failed user requests
Lucio Correia
luciojhc at linux.vnet.ibm.com
Thu Jun 9 20:59:08 UTC 2016
Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
---
src/wok/control/base.py | 124 ++++++++++++++++++++++--------------------------
src/wok/exception.py | 28 ++++++++---
2 files changed, 78 insertions(+), 74 deletions(-)
diff --git a/src/wok/control/base.py b/src/wok/control/base.py
index 9b34c55..69541b1 100644
--- a/src/wok/control/base.py
+++ b/src/wok/control/base.py
@@ -30,9 +30,7 @@ from wok.auth import USER_GROUPS, USER_NAME, USER_ROLES
from wok.control.utils import get_class_name, internal_redirect, model_fn
from wok.control.utils import parse_request, validate_method
from wok.control.utils import validate_params
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import MissingParameter, NotFoundError
-from wok.exception import OperationFailed, UnauthorizedError, WokException
+from wok.exception import InvalidOperation, UnauthorizedError, WokException
from wok.message import WokMessage
from wok.reqlogger import RequestRecord
from wok.utils import get_plugin_from_request, utf8_dict, wok_log, encode_value
@@ -119,6 +117,10 @@ class Resource(object):
def _generate_action_handler_base(self, action_name, render_fn,
destructive=False, action_args=None):
def wrapper(*args, **kwargs):
+ # status must be always set in order to request be logged.
+ # use 500 as fallback for "exception not handled" cases.
+ status = 500
+
method = 'POST'
validate_method((method), self.role_key, self.admin_methods)
try:
@@ -138,7 +140,18 @@ class Resource(object):
action_fn = getattr(self.model, model_fn(self, action_name))
action_result = action_fn(*model_args)
+ status = 200
+ if destructive is False or \
+ ('persistent' in self.info.keys() and
+ self.info['persistent'] is True):
+ result = render_fn(self, action_result)
+ status = cherrypy.response.status
+ return result
+ except WokException, e:
+ status = e.getHttpStatusCode()
+ raise cherrypy.HTTPError(status, e.message)
+ finally:
# log request
code = self.getRequestMessage(method, action_name)
reqParams = utf8_dict(self.log_args, request)
@@ -147,29 +160,11 @@ class Resource(object):
msg,
app=get_plugin_from_request(),
req=method,
+ status=status,
user=cherrypy.session.get(USER_NAME, 'N/A'),
ip=cherrypy.request.remote.ip
).log()
- if destructive is False or \
- ('persistent' in self.info.keys() and
- self.info['persistent'] is True):
- return render_fn(self, action_result)
- except MissingParameter, e:
- raise cherrypy.HTTPError(400, e.message)
- except InvalidParameter, e:
- raise cherrypy.HTTPError(400, e.message)
- except InvalidOperation, e:
- raise cherrypy.HTTPError(400, e.message)
- except UnauthorizedError, e:
- raise cherrypy.HTTPError(403, e.message)
- except NotFoundError, e:
- raise cherrypy.HTTPError(404, e.message)
- except OperationFailed, e:
- raise cherrypy.HTTPError(500, e.message)
- except WokException, e:
- raise cherrypy.HTTPError(500, e.message)
-
wrapper.__name__ = action_name
wrapper.exposed = True
return wrapper
@@ -190,13 +185,13 @@ class Resource(object):
e = InvalidOperation('WOKAPI0002E', {'resource':
get_class_name(self)})
raise cherrypy.HTTPError(405, e.message)
- except OperationFailed, e:
- raise cherrypy.HTTPError(500, e.message)
- except InvalidOperation, e:
- raise cherrypy.HTTPError(400, e.message)
@cherrypy.expose
def index(self, *args, **kargs):
+ # status must be always set in order to request be logged.
+ # use 500 as fallback for "exception not handled" cases.
+ status = 500
+
method = validate_method(('GET', 'DELETE', 'PUT'),
self.role_key, self.admin_methods)
@@ -208,30 +203,27 @@ class Resource(object):
result = {'GET': self.get,
'DELETE': self.delete,
'PUT': self.update}[method](*args, **kargs)
- except InvalidOperation, e:
- raise cherrypy.HTTPError(400, e.message)
- except InvalidParameter, e:
- raise cherrypy.HTTPError(400, e.message)
- except UnauthorizedError, e:
- raise cherrypy.HTTPError(403, e.message)
- except NotFoundError, e:
- raise cherrypy.HTTPError(404, e.message)
- except OperationFailed, e:
- raise cherrypy.HTTPError(500, e.message)
+
+ status = cherrypy.response.status
except WokException, e:
- raise cherrypy.HTTPError(500, e.message)
-
- # log request
- if method not in LOG_DISABLED_METHODS:
- code = self.getRequestMessage(method)
- msg = WokMessage(code, self.log_args).get_text(prepend_code=False)
- RequestRecord(
- msg,
- app=get_plugin_from_request(),
- req=method,
- user=cherrypy.session.get(USER_NAME, 'N/A'),
- ip=cherrypy.request.remote.ip
- ).log()
+ status = e.getHttpStatusCode()
+ raise cherrypy.HTTPError(status, e.message)
+ except cherrypy.HTTPError, e:
+ status = e.status
+ raise
+ finally:
+ # log request
+ if method not in LOG_DISABLED_METHODS:
+ code = self.getRequestMessage(method)
+ msg = WokMessage(code, self.log_args)
+ RequestRecord(
+ msg.get_text(prepend_code=False),
+ app=get_plugin_from_request(),
+ req=method,
+ status=status,
+ user=cherrypy.session.get(USER_NAME, 'N/A'),
+ ip=cherrypy.request.remote.ip
+ ).log()
return result
@@ -311,10 +303,6 @@ class AsyncResource(Resource):
e = InvalidOperation('WOKAPI0002E', {'resource':
get_class_name(self)})
raise cherrypy.HTTPError(405, e.message)
- except OperationFailed, e:
- raise cherrypy.HTTPError(500, e.message)
- except InvalidOperation, e:
- raise cherrypy.HTTPError(400, e.message)
cherrypy.response.status = 202
return wok.template.render("Task", task)
@@ -437,6 +425,10 @@ class Collection(object):
@cherrypy.expose
def index(self, *args, **kwargs):
+ # status must be always set in order to request be logged.
+ # use 500 as fallback for "exception not handled" cases.
+ status = 500
+
params = {}
method = validate_method(('GET', 'POST'),
self.role_key, self.admin_methods)
@@ -449,7 +441,16 @@ class Collection(object):
elif method == 'POST':
params = parse_request()
result = self.create(params, *args)
-
+ status = cherrypy.response.status
+ return result
+ except WokException, e:
+ status = e.getHttpStatusCode()
+ raise cherrypy.HTTPError(status, e.message)
+ except cherrypy.HTTPError, e:
+ status = e.status
+ raise
+ finally:
+ if method not in LOG_DISABLED_METHODS:
# log request
code = self.getRequestMessage(method)
reqParams = utf8_dict(self.log_args, params)
@@ -458,24 +459,11 @@ class Collection(object):
msg,
app=get_plugin_from_request(),
req=method,
+ status=status,
user=cherrypy.session.get(USER_NAME, 'N/A'),
ip=cherrypy.request.remote.ip
).log()
- return result
- except InvalidOperation, e:
- raise cherrypy.HTTPError(400, e.message)
- except InvalidParameter, e:
- raise cherrypy.HTTPError(400, e.message)
- except MissingParameter, e:
- raise cherrypy.HTTPError(400, e.message)
- except NotFoundError, e:
- raise cherrypy.HTTPError(404, e.message)
- except OperationFailed, e:
- raise cherrypy.HTTPError(500, e.message)
- except WokException, e:
- raise cherrypy.HTTPError(500, e.message)
-
class AsyncCollection(Collection):
"""
diff --git a/src/wok/exception.py b/src/wok/exception.py
index 90b6410..f8f4bd4 100644
--- a/src/wok/exception.py
+++ b/src/wok/exception.py
@@ -28,30 +28,44 @@ class WokException(Exception):
def __init__(self, code='', args=None):
if args is None:
args = {}
+ self.httpStatusCode = 500
self.code = code
msg = WokMessage(code, args).get_text()
cherrypy.log.error_log.error(msg)
Exception.__init__(self, msg)
+ def getHttpStatusCode(self):
+ return self.httpStatusCode
+
class NotFoundError(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(NotFoundError, self).__init__(code, args)
+ self.httpStatusCode = 404
class OperationFailed(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(OperationFailed, self).__init__(code, args)
+ self.httpStatusCode = 500
class MissingParameter(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(MissingParameter, self).__init__(code, args)
+ self.httpStatusCode = 400
class InvalidParameter(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(InvalidParameter, self).__init__(code, args)
+ self.httpStatusCode = 400
class InvalidOperation(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(InvalidOperation, self).__init__(code, args)
+ self.httpStatusCode = 400
class IsoFormatError(WokException):
@@ -67,4 +81,6 @@ class TimeoutExpired(WokException):
class UnauthorizedError(WokException):
- pass
+ def __init__(self, code='', args=None):
+ super(UnauthorizedError, self).__init__(code, args)
+ self.httpStatusCode = 403
--
1.9.1
More information about the Kimchi-devel
mailing list