Repository: privacyidea/privacyidea

Issue:
Audit log reports failure for /validate/triggerchallenge request even if it succeeded
Under privacyIDEA 2.17, the audit log in the web UI reports `success=false` for the `/validate/triggerchallenge` API request even if it succeeded, i.e. a response like the following was received:

<pre>{
   "id" : 1,
   "jsonrpc" : "2.0",
   "version" : "privacyIDEA 2.17",
   "versionnumber" : "2.17",
   "detail" : {
      "transaction_ids" : [
         "17450725081512532280",
         "12888459006279906330"
      ],
      "messages" : [
         "Enter the OTP from the Email:",
         "please enter otp: "
      ],
      "threadid" : 140717024941952
   },
   "result" : {
      "value" : 2,
      "status" : true
   },
   "time" : 1484660674.08898,
   "signature" : "..."
}
</pre>


Discussion:
At the beginning of each request an audit object is created in the global request object ``g``.
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/api/validate.py#L127

The ``g.audit_object`` ususally is an instance of the ``SQLAudit`` class. During the request code can add information to the audit entry by calling ``g.audit_object.log()`` like here:
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/api/validate.py#L241
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/api/validate.py#L254

At the end of the request the audit log entry is "finalized".
https://github.com/privacyidea/privacyidea/blob/master/privacyidea/api/validate.py#L153
This means the audit entry is signed and written to the database.

So somewhere in the if-branch the audit log should be updated with a successful entry and also maybe with a serial number of the token, for which the challenge was triggered. 
...and maybe with the username, who triggered the challenge... and any other information.

You are welcome to identify the missing data and issue a PR.


Thank you for the pointers! I guess an interesting question is: Should a `/validate/triggerchallenge` request which triggers zero challenges be considered successful? I mean, the request itself is successful and returns a response like this:
<pre>{
   "result" : {
      "status" : true,
      "value" : 0
   },
   "version" : "privacyIDEA unknown",
   "signature" : "...",
   "jsonrpc" : "2.0",
   "id" : 1,
   "time" : 1484759478.81169,
   "detail" : {
      "transaction_ids" : [],
      "threadid" : 140094614299520,
      "messages" : []
   },
   "versionnumber" : "unknown"
}</pre>
The ``/validate/check`` request is logged as ``False`` in the audit log, if the authentication failed and the response is

    {"status": true,
     "value": false},

So in case the result of ``/validate/triggerchallenge``is

    {"status": true,
     "value": 0}

It sounds sensible to me to log this in the audit log as ``False``. Since the try to trigger a challenge resulted in not triggering a challenge...


Resolving patch:
diff --git a/privacyidea/api/validate.py b/privacyidea/api/validate.py
--- a/privacyidea/api/validate.py
+++ b/privacyidea/api/validate.py
@@ -445,7 +445,19 @@ def trigger_challenge():
             if success:
                 result_obj += 1
                 details.get("transaction_ids").append(transactionid)
+                # This will write only the serial of the token that was processed last to the audit log
+                g.audit_object.log({
+                    "serial": token_obj.token.serial,
+                })
             details.get("messages").append(return_message)
 
+    g.audit_object.log({
+        "user": user.login,
+        "resolver": user.resolver,
+        "realm": user.realm,
+        "success": result_obj > 0,
+        "info": "triggered {0!s} challenges".format(result_obj),
+    })
+
     return send_result(result_obj, details=details)
 


Test patch: