We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Migrate EMail, TAN and VASCO token to Python 3
This slightly changes behavior: The VASCO token initialization now throws a ``ParameterError`` if the secret couldn't be decoded.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `privacyidea/lib/authcache.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 #
3 #  2017-08-11 Cornelius Kölbel <cornelius.koelbel@netknights.it>
4 #             initial writeup
5 #
6 #  License:  AGPLv3
7 #  contact:  http://www.privacyidea.org
8 #
9 # This code is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
11 # License as published by the Free Software Foundation; either
12 # version 3 of the License, or any later version.
13 #
14 # This code is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNE7SS FOR A PARTICULAR PURPOSE.  See the
17 # GNU AFFERO GENERAL PUBLIC LICENSE for more details.
18 #
19 # You should have received a copy of the GNU Affero General Public
20 # License along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22 import binascii
23 
24 from ..models import AuthCache, db
25 from sqlalchemy import and_
26 from privacyidea.lib.crypto import hash
27 import datetime
28 import logging
29 
30 log = logging.getLogger(__name__)
31 
32 
33 def _hash_password(password):
34     return binascii.hexlify(hash(password, seed=""))
35 
36 
37 def add_to_cache(username, realm, resolver, password):
38     # Can not store timezone aware timestamps!
39     first_auth = datetime.datetime.utcnow()
40     auth_hash = _hash_password(password)
41     record = AuthCache(username, realm, resolver, auth_hash, first_auth, first_auth)
42     log.debug('Adding record to auth cache: ({!r}, {!r}, {!r}, {!r})'.format(
43         username, realm, resolver, auth_hash))
44     r = record.save()
45     return r
46 
47 
48 def update_cache_last_auth(cache_id):
49     last_auth = datetime.datetime.utcnow()
50     AuthCache.query.filter(
51         AuthCache.id == cache_id).update({"last_auth": last_auth})
52     db.session.commit()
53 
54 
55 def delete_from_cache(username, realm, resolver, password):
56     r = db.session.query(AuthCache).filter(AuthCache.username == username,
57                                        AuthCache.realm == realm,
58                                        AuthCache.resolver == resolver,
59                                        AuthCache.authentication ==
60                                        _hash_password(password)).delete()
61     db.session.commit()
62     return r
63 
64 
65 def verify_in_cache(username, realm, resolver, password,
66                     first_auth = None,
67                     last_auth = None):
68     """
69     Verify if the given credentials are cached and if the time is correct.
70     
71     :param username: 
72     :param realm: 
73     :param resolver: 
74     :param password: 
75     :param first_auth: The timestamp when the entry was first written to the 
76         cache. Only find newer entries 
77     :param last_auth: The timestamp when the entry was last successfully 
78         verified. Only find newer entries 
79     :return: 
80     """
81     conditions = []
82     conditions.append(AuthCache.username == username)
83     conditions.append(AuthCache.realm == realm)
84     conditions.append(AuthCache.resolver == resolver)
85     auth_hash = _hash_password(password)
86     conditions.append(AuthCache.authentication == auth_hash)
87 
88     if first_auth:
89         conditions.append(AuthCache.first_auth > first_auth)
90     if last_auth:
91         conditions.append(AuthCache.last_auth > last_auth)
92 
93     filter_condition = and_(*conditions)
94     r = AuthCache.query.filter(filter_condition).first()
95     result = bool(r)
96 
97     if result:
98         # Update the last_auth
99         update_cache_last_auth(r.id)
100 
101     else:
102         # Delete older entries
103         delete_from_cache(username, realm, resolver, password)
104 
105     return result
106 
107
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/privacyidea/lib/authcache.py b/privacyidea/lib/authcache.py
--- a/privacyidea/lib/authcache.py
+++ b/privacyidea/lib/authcache.py
@@ -62,6 +62,21 @@
     return r
 
 
+def cleanup(minutes):
+    """
+    Will delete all authcache entries, where last_auth column is older than
+    the given minutes.
+
+    :param minutes: Age of the last_authentication in minutes
+    :type minutes: int
+    :return:
+    """
+    cleanuptime = datetime.datetime.utcnow() - datetime.timedelta(minutes=minutes)
+    r = db.session.query(AuthCache).filter(AuthCache.last_auth < cleanuptime).delete()
+    db.session.commit()
+    return r
+
+
 def verify_in_cache(username, realm, resolver, password,
                     first_auth = None,
                     last_auth = None):

{"golden_diff": "diff --git a/privacyidea/lib/authcache.py b/privacyidea/lib/authcache.py\n--- a/privacyidea/lib/authcache.py\n+++ b/privacyidea/lib/authcache.py\n@@ -62,6 +62,21 @@\n     return r\n \n \n+def cleanup(minutes):\n+    \"\"\"\n+    Will delete all authcache entries, where last_auth column is older than\n+    the given minutes.\n+\n+    :param minutes: Age of the last_authentication in minutes\n+    :type minutes: int\n+    :return:\n+    \"\"\"\n+    cleanuptime = datetime.datetime.utcnow() - datetime.timedelta(minutes=minutes)\n+    r = db.session.query(AuthCache).filter(AuthCache.last_auth < cleanuptime).delete()\n+    db.session.commit()\n+    return r\n+\n+\n def verify_in_cache(username, realm, resolver, password,\n                     first_auth = None,\n                     last_auth = None):\n", "issue": "Migrate EMail, TAN and VASCO token to Python 3\nThis slightly changes behavior: The VASCO token initialization now throws a ``ParameterError`` if the secret couldn't be decoded.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n#  2017-08-11 Cornelius K\u00f6lbel <cornelius.koelbel@netknights.it>\n#             initial writeup\n#\n#  License:  AGPLv3\n#  contact:  http://www.privacyidea.org\n#\n# This code is free software; you can redistribute it and/or\n# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE\n# License as published by the Free Software Foundation; either\n# version 3 of the License, or any later version.\n#\n# This code is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNE7SS FOR A PARTICULAR PURPOSE.  See the\n# GNU AFFERO GENERAL PUBLIC LICENSE for more details.\n#\n# You should have received a copy of the GNU Affero General Public\n# License along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nimport binascii\n\nfrom ..models import AuthCache, db\nfrom sqlalchemy import and_\nfrom privacyidea.lib.crypto import hash\nimport datetime\nimport logging\n\nlog = logging.getLogger(__name__)\n\n\ndef _hash_password(password):\n    return binascii.hexlify(hash(password, seed=\"\"))\n\n\ndef add_to_cache(username, realm, resolver, password):\n    # Can not store timezone aware timestamps!\n    first_auth = datetime.datetime.utcnow()\n    auth_hash = _hash_password(password)\n    record = AuthCache(username, realm, resolver, auth_hash, first_auth, first_auth)\n    log.debug('Adding record to auth cache: ({!r}, {!r}, {!r}, {!r})'.format(\n        username, realm, resolver, auth_hash))\n    r = record.save()\n    return r\n\n\ndef update_cache_last_auth(cache_id):\n    last_auth = datetime.datetime.utcnow()\n    AuthCache.query.filter(\n        AuthCache.id == cache_id).update({\"last_auth\": last_auth})\n    db.session.commit()\n\n\ndef delete_from_cache(username, realm, resolver, password):\n    r = db.session.query(AuthCache).filter(AuthCache.username == username,\n                                       AuthCache.realm == realm,\n                                       AuthCache.resolver == resolver,\n                                       AuthCache.authentication ==\n                                       _hash_password(password)).delete()\n    db.session.commit()\n    return r\n\n\ndef verify_in_cache(username, realm, resolver, password,\n                    first_auth = None,\n                    last_auth = None):\n    \"\"\"\n    Verify if the given credentials are cached and if the time is correct.\n    \n    :param username: \n    :param realm: \n    :param resolver: \n    :param password: \n    :param first_auth: The timestamp when the entry was first written to the \n        cache. Only find newer entries \n    :param last_auth: The timestamp when the entry was last successfully \n        verified. Only find newer entries \n    :return: \n    \"\"\"\n    conditions = []\n    conditions.append(AuthCache.username == username)\n    conditions.append(AuthCache.realm == realm)\n    conditions.append(AuthCache.resolver == resolver)\n    auth_hash = _hash_password(password)\n    conditions.append(AuthCache.authentication == auth_hash)\n\n    if first_auth:\n        conditions.append(AuthCache.first_auth > first_auth)\n    if last_auth:\n        conditions.append(AuthCache.last_auth > last_auth)\n\n    filter_condition = and_(*conditions)\n    r = AuthCache.query.filter(filter_condition).first()\n    result = bool(r)\n\n    if result:\n        # Update the last_auth\n        update_cache_last_auth(r.id)\n\n    else:\n        # Delete older entries\n        delete_from_cache(username, realm, resolver, password)\n\n    return result\n\n", "path": "privacyidea/lib/authcache.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n#  2017-08-11 Cornelius K\u00f6lbel <cornelius.koelbel@netknights.it>\n#             initial writeup\n#\n#  License:  AGPLv3\n#  contact:  http://www.privacyidea.org\n#\n# This code is free software; you can redistribute it and/or\n# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE\n# License as published by the Free Software Foundation; either\n# version 3 of the License, or any later version.\n#\n# This code is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNE7SS FOR A PARTICULAR PURPOSE.  See the\n# GNU AFFERO GENERAL PUBLIC LICENSE for more details.\n#\n# You should have received a copy of the GNU Affero General Public\n# License along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nimport binascii\n\nfrom ..models import AuthCache, db\nfrom sqlalchemy import and_\nfrom privacyidea.lib.crypto import hash\nimport datetime\nimport logging\n\nlog = logging.getLogger(__name__)\n\n\ndef _hash_password(password):\n    return binascii.hexlify(hash(password, seed=\"\"))\n\n\ndef add_to_cache(username, realm, resolver, password):\n    # Can not store timezone aware timestamps!\n    first_auth = datetime.datetime.utcnow()\n    auth_hash = _hash_password(password)\n    record = AuthCache(username, realm, resolver, auth_hash, first_auth, first_auth)\n    log.debug('Adding record to auth cache: ({!r}, {!r}, {!r}, {!r})'.format(\n        username, realm, resolver, auth_hash))\n    r = record.save()\n    return r\n\n\ndef update_cache_last_auth(cache_id):\n    last_auth = datetime.datetime.utcnow()\n    AuthCache.query.filter(\n        AuthCache.id == cache_id).update({\"last_auth\": last_auth})\n    db.session.commit()\n\n\ndef delete_from_cache(username, realm, resolver, password):\n    r = db.session.query(AuthCache).filter(AuthCache.username == username,\n                                       AuthCache.realm == realm,\n                                       AuthCache.resolver == resolver,\n                                       AuthCache.authentication ==\n                                       _hash_password(password)).delete()\n    db.session.commit()\n    return r\n\n\ndef cleanup(minutes):\n    \"\"\"\n    Will delete all authcache entries, where last_auth column is older than\n    the given minutes.\n\n    :param minutes: Age of the last_authentication in minutes\n    :type minutes: int\n    :return:\n    \"\"\"\n    cleanuptime = datetime.datetime.utcnow() - datetime.timedelta(minutes=minutes)\n    r = db.session.query(AuthCache).filter(AuthCache.last_auth < cleanuptime).delete()\n    db.session.commit()\n    return r\n\n\ndef verify_in_cache(username, realm, resolver, password,\n                    first_auth = None,\n                    last_auth = None):\n    \"\"\"\n    Verify if the given credentials are cached and if the time is correct.\n    \n    :param username: \n    :param realm: \n    :param resolver: \n    :param password: \n    :param first_auth: The timestamp when the entry was first written to the \n        cache. Only find newer entries \n    :param last_auth: The timestamp when the entry was last successfully \n        verified. Only find newer entries \n    :return: \n    \"\"\"\n    conditions = []\n    conditions.append(AuthCache.username == username)\n    conditions.append(AuthCache.realm == realm)\n    conditions.append(AuthCache.resolver == resolver)\n    auth_hash = _hash_password(password)\n    conditions.append(AuthCache.authentication == auth_hash)\n\n    if first_auth:\n        conditions.append(AuthCache.first_auth > first_auth)\n    if last_auth:\n        conditions.append(AuthCache.last_auth > last_auth)\n\n    filter_condition = and_(*conditions)\n    r = AuthCache.query.filter(filter_condition).first()\n    result = bool(r)\n\n    if result:\n        # Update the last_auth\n        update_cache_last_auth(r.id)\n\n    else:\n        # Delete older entries\n        delete_from_cache(username, realm, resolver, password)\n\n    return result\n\n", "path": "privacyidea/lib/authcache.py"}]}