Repository: privacyidea/privacyidea

Issue:
Fix empty line in audit log
If an error occurs during a request, both the error handler and the `after_request` handler call [`finalize_log()`](https://github.com/privacyidea/privacyidea/blob/9704cbc1c9df14d97d01a3fd902cdecb87408523/privacyidea/lib/auditmodules/sqlaudit.py#L217) which results in an empty line in the audit log.


Discussion:

Resolving patch:
diff --git a/privacyidea/api/before_after.py b/privacyidea/api/before_after.py
--- a/privacyidea/api/before_after.py
+++ b/privacyidea/api/before_after.py
@@ -38,9 +38,11 @@
 from privacyidea.lib.policy import PolicyClass
 from privacyidea.lib.event import EventConfiguration
 from privacyidea.lib.lifecycle import call_finalizers
-from privacyidea.api.auth import (user_required, admin_required)
+from privacyidea.api.auth import (user_required, admin_required, jwtauth)
 from privacyidea.lib.config import get_from_config, SYSCONF, update_config_object
 from privacyidea.lib.token import get_token_type
+from privacyidea.api.ttype import ttype_blueprint
+from privacyidea.api.validate import validate_blueprint
 from .resolver import resolver_blueprint
 from .policy import policy_blueprint
 from .realm import realm_blueprint
@@ -218,6 +220,11 @@ def before_request():
 @client_blueprint.after_request
 @subscriptions_blueprint.after_request
 @monitoring_blueprint.after_request
+@ttype_blueprint.after_request
+@validate_blueprint.after_request
+@register_blueprint.after_request
+@recover_blueprint.after_request
+@jwtauth.after_request
 @postrequest(sign_response, request=request)
 def after_request(response):
     """
@@ -226,7 +233,7 @@ def after_request(response):
     """
     # In certain error cases the before_request was not handled
     # completely so that we do not have an audit_object
-    if "audit_object" in g:
+    if "audit_object" in g and g.audit_object.audit_data:
         g.audit_object.finalize_log()
 
     # No caching!
diff --git a/privacyidea/api/ttype.py b/privacyidea/api/ttype.py
--- a/privacyidea/api/ttype.py
+++ b/privacyidea/api/ttype.py
@@ -33,10 +33,7 @@
 """
 from flask import (Blueprint,
                    request)
-from .lib.utils import (getParam,
-                        optional,
-                        required,
-                        send_result)
+from .lib.utils import getParam
 from ..lib.log import log_with
 from flask import g, jsonify, current_app, Response
 import logging
@@ -46,7 +43,6 @@
 from privacyidea.lib.config import (get_token_class, get_from_config,
                                     SYSCONF, update_config_object)
 from privacyidea.lib.user import get_user_from_param
-from privacyidea.api.lib.postpolicy import postrequest, sign_response
 from privacyidea.lib.utils import get_client_ip
 import json
 
@@ -82,23 +78,6 @@ def before_request():
                         "info": ""})
 
 
-@ttype_blueprint.after_request
-@postrequest(sign_response, request=request)
-def after_request(response):
-    """
-    This function is called after a request
-    :return: The response
-    """
-    # In certain error cases the before_request was not handled
-    # completely so that we do not have an audit_object
-    if "audit_object" in g:
-        g.audit_object.finalize_log()
-
-    # No caching!
-    response.headers['Cache-Control'] = 'no-cache'
-    return response
-
-
 @ttype_blueprint.route('/<ttype>', methods=['POST', 'GET'])
 @log_with(log)
 def token(ttype=None):
diff --git a/privacyidea/api/validate.py b/privacyidea/api/validate.py
--- a/privacyidea/api/validate.py
+++ b/privacyidea/api/validate.py
@@ -92,8 +92,6 @@
 from privacyidea.lib.policy import PolicyClass
 from privacyidea.lib.event import EventConfiguration
 import logging
-from privacyidea.api.lib.postpolicy import postrequest, sign_response
-from privacyidea.api.auth import jwtauth
 from privacyidea.api.register import register_blueprint
 from privacyidea.api.recover import recover_blueprint
 from privacyidea.lib.utils import get_client_ip
@@ -143,26 +141,6 @@ def before_request():
                         "info": ""})
 
 
-@validate_blueprint.after_request
-@register_blueprint.after_request
-@recover_blueprint.after_request
-@jwtauth.after_request
-@postrequest(sign_response, request=request)
-def after_request(response):
-    """
-    This function is called after a request
-    :return: The response
-    """
-    # In certain error cases the before_request was not handled
-    # completely so that we do not have an audit_object
-    if "audit_object" in g:
-        g.audit_object.finalize_log()
-
-    # No caching!
-    response.headers['Cache-Control'] = 'no-cache'
-    return response
-
-
 @validate_blueprint.route('/offlinerefill', methods=['POST'])
 @check_user_or_serial_in_request(request)
 @event("validate_offlinerefill", request, g)


Test patch: