From 309118c158d905d1b95ef73f518015b5dc113765 Mon Sep 17 00:00:00 2001
From: Antoine Lambert <antoine.lambert@inria.fr>
Date: Wed, 7 Apr 2021 18:47:56 +0200
Subject: [PATCH] django/backends: Improve expired token handling

The first time a user sends an expired token previously used to
perform authenticated Web API calls, Keycloak will return the
following error message: "Offline session not active".

So handle that error message too for indicating a token has expired.

Related to T3121
---
 swh/auth/django/backends.py                   |  5 ++-
 .../django/test_drf_bearer_token_auth.py      | 34 ++++++++++---------
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/swh/auth/django/backends.py b/swh/auth/django/backends.py
index 262475e..c5eeba4 100644
--- a/swh/auth/django/backends.py
+++ b/swh/auth/django/backends.py
@@ -201,7 +201,10 @@ class OIDCBearerTokenAuthentication(BaseAuthentication):
             raise ValidationError("Invalid bearer token")
         except KeycloakError as ke:
             error_msg = keycloak_error_message(ke)
-            if error_msg == "invalid_grant: Offline user session not found":
+            if error_msg in (
+                "invalid_grant: Offline session not active",
+                "invalid_grant: Offline user session not found",
+            ):
                 error_msg = (
                     "Bearer token expired after a long period of inactivity; "
                     "please generate a new one."
diff --git a/swh/auth/tests/django/test_drf_bearer_token_auth.py b/swh/auth/tests/django/test_drf_bearer_token_auth.py
index 7b490b4..c881236 100644
--- a/swh/auth/tests/django/test_drf_bearer_token_auth.py
+++ b/swh/auth/tests/django/test_drf_bearer_token_auth.py
@@ -129,23 +129,25 @@ def test_drf_oidc_bearer_token_expired_token(keycloak_oidc, api_client):
 
     api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {refresh_token}")
 
-    kc_error_dict = {
-        "error": "invalid_grant",
-        "error_description": "Offline user session not found",
-    }
+    for kc_err_msg in ("Offline session not active", "Offline user session not found"):
 
-    keycloak_oidc.refresh_token.side_effect = KeycloakError(
-        error_message=json.dumps(kc_error_dict).encode(), response_code=400
-    )
+        kc_error_dict = {
+            "error": "invalid_grant",
+            "error_description": kc_err_msg,
+        }
 
-    response = api_client.get(url)
-    expected_error_msg = (
-        "Bearer token expired after a long period of inactivity; "
-        "please generate a new one."
-    )
+        keycloak_oidc.refresh_token.side_effect = KeycloakError(
+            error_message=json.dumps(kc_error_dict).encode(), response_code=400
+        )
 
-    assert response.status_code == 403
-    assert expected_error_msg in json.dumps(response.data)
+        response = api_client.get(url)
+        expected_error_msg = (
+            "Bearer token expired after a long period of inactivity; "
+            "please generate a new one."
+        )
 
-    request = response.wsgi_request
-    assert isinstance(request.user, AnonymousUser)
+        assert response.status_code == 403
+        assert expected_error_msg in json.dumps(response.data)
+
+        request = response.wsgi_request
+        assert isinstance(request.user, AnonymousUser)
-- 
GitLab