1+ import logging
2+
13from rest_framework .decorators import api_view , authentication_classes
24from rest_framework .authentication import SessionAuthentication
35from rest_framework .exceptions import NotAuthenticated , ValidationError
46from rest_framework .request import Request
57from rest_framework .response import Response
68
9+ from thunderbird_accounts .authentication .middleware import AccountsOIDCBackend
710from thunderbird_accounts .authentication .serializers import UserProfileSerializer
811from thunderbird_accounts .authentication .clients import KeycloakClient
912
@@ -25,19 +28,10 @@ def get_active_sessions(request: Request):
2528 keycloak_client = KeycloakClient ()
2629 sessions = keycloak_client .get_active_sessions (request .user .oidc_id )
2730
28- # Print all keys from request.session
29- print (request .session .keys ())
30- print (request .session .items ())
31- print (request .session .values ())
32- print (request .session .get ('session_id' ))
33- print (request .session .get ('session_key' ))
34- print (request .session .get ('session_data' ))
35- print (request .session .get ('session_expiry' ))
36- print (request .session .get ('session_created' ))
37- print (request .session .get ('session_updated' ))
3831 return Response (sessions )
3932 except Exception as e :
40- raise ValidationError (f'Error fetching active sessions: { e } ' )
33+ logging .exception (f'Error fetching active sessions: { e } ' )
34+ raise ValidationError ('Error fetching active sessions' )
4135
4236
4337@api_view (['POST' ])
@@ -51,8 +45,30 @@ def sign_out_session(request: Request):
5145 if not session_id :
5246 raise ValidationError ('session_id is required' )
5347
48+ oidc_id_token = request .session .get ('oidc_id_token' )
49+
50+ if not oidc_id_token :
51+ raise ValidationError ('No oidc_id_token found in session' )
52+
5453 try :
54+ # Sign out from the Keycloak session
5555 keycloak_client = KeycloakClient ()
56- return Response (keycloak_client .sign_out_session (session_id ))
56+ keycloak_client .sign_out_session (session_id )
57+
58+ # Verify if the request's keycloak session_id matches the one in the ID token
59+ auth_backend = AccountsOIDCBackend ()
60+ payload = auth_backend .verify_token (oidc_id_token )
61+ keycloak_session_id = payload .get ('sid' )
62+
63+ if not keycloak_session_id :
64+ raise ValidationError ("'sid' claim not found in ID token. Did you enable back-channel logout in Keycloak?" )
65+
66+ if keycloak_session_id == session_id :
67+ # If so, delete current session data and cookie from Django as well
68+ request .session .flush ()
69+
70+ return Response ({'success' : True })
71+
5772 except Exception as e :
58- raise ValidationError (f'Error signing out session: { e } ' )
73+ logging .exception (f'Error signing out session: { e } ' )
74+ raise ValidationError ('Error signing out session' )
0 commit comments