Repository: privacyidea/privacyidea

Issue:
token_type typo in validate.py audit
Hi @cornelinux,

It seems that there is a typo in the validate.py for `token_type` param, where it is spelled as `tokentype` instead.

For example:
```
    g.audit_object.log({"info": log_used_user(user, details.get("message")),
                        "success": result,
                        "serial": serial or details.get("serial"),
                        "tokentype": details.get("type")})
```

Correct one should be:
```
    g.audit_object.log({"info": log_used_user(user, details.get("message")),
                        "success": result,
                        "serial": serial or details.get("serial"),
                        "token_type": details.get("type")})
```

This cause the token type is not in our audit. There are multiple occurrence of this typos not just the above block of code.

Can we please confirm?

Best regards,

Quynh Nguyen


Discussion:
Hello @quynhnhatnguyen 
you are right. The correct key should be **token_type** with an underscore.
I can see that there is the wrong key in ``/validate/check`` and ``/validate/samlcheck``.
and in ``api/system.py::test``

If you see any further occurrences, please add them!

Thanks a lot for pointing this out. We will fix this in version 3.1.1.

Resolving patch:
diff --git a/privacyidea/api/system.py b/privacyidea/api/system.py
--- a/privacyidea/api/system.py
+++ b/privacyidea/api/system.py
@@ -353,7 +353,7 @@ def test(tokentype=None):
     tokenc = get_token_class(tokentype)
     res, description = tokenc.test_config(request.all_data)
     g.audit_object.log({"success": 1,
-                        "tokentype": tokentype})
+                        "token_type": tokentype})
     return send_result(res, details={"message": description})
 
 
diff --git a/privacyidea/api/validate.py b/privacyidea/api/validate.py
--- a/privacyidea/api/validate.py
+++ b/privacyidea/api/validate.py
@@ -338,7 +338,7 @@ def check():
     g.audit_object.log({"info": log_used_user(user, details.get("message")),
                         "success": result,
                         "serial": serial or details.get("serial"),
-                        "tokentype": details.get("type")})
+                        "token_type": details.get("type")})
     return send_result(result, details=details)
 
 
@@ -437,7 +437,7 @@ def samlcheck():
     g.audit_object.log({"info": log_used_user(user, details.get("message")),
                         "success": auth,
                         "serial": details.get("serial"),
-                        "tokentype": details.get("type"),
+                        "token_type": details.get("type"),
                         "user": user.login,
                         "resolver": user.resolver,
                         "realm": user.realm})
diff --git a/privacyidea/lib/auditmodules/sqlaudit.py b/privacyidea/lib/auditmodules/sqlaudit.py
--- a/privacyidea/lib/auditmodules/sqlaudit.py
+++ b/privacyidea/lib/auditmodules/sqlaudit.py
@@ -223,6 +223,11 @@ def finalize_log(self):
             self.audit_data["policies"] = ",".join(self.audit_data.get("policies",[]))
             if self.config.get("PI_AUDIT_SQL_TRUNCATE"):
                 self._truncate_data()
+            if "tokentype" in self.audit_data:
+                log.warning("We have a wrong 'tokentype' key. This should not happen. Fix it!. "
+                            "Error occurs in action: {0!r}.".format(self.audit_data.get("action")))
+                if not "token_type" in self.audit_data:
+                    self.audit_data["token_type"] = self.audit_data.get("tokentype")
             le = LogEntry(action=self.audit_data.get("action"),
                           success=int(self.audit_data.get("success", 0)),
                           serial=self.audit_data.get("serial"),


Test patch:
diff --git a/tests/test_lib_audit.py b/tests/test_lib_audit.py
--- a/tests/test_lib_audit.py
+++ b/tests/test_lib_audit.py
@@ -282,3 +282,12 @@ def test_09_check_external_audit_db(self):
         self.assertEquals(audit_log.total, 1)
         self.assertEquals(audit_log.auditdata[0].get("sig_check"), "FAIL")
         # TODO: add new audit entry and check for new style signature
+
+    def test_10_check_tokentype(self):
+        # Add a tokentype
+        self.Audit.log({"action": "test10", "tokentype": "spass"})
+        self.Audit.finalize_log()
+        audit_log = self.Audit.search({"action": "test10"})
+        self.assertEqual(audit_log.total, 1)
+        # The tokentype was actually written as token_type
+        self.assertEqual(audit_log.auditdata[0].get("token_type"), "spass")