From 47f164498e6ade4d9de81e61be838aa2dfe89109 Mon Sep 17 00:00:00 2001 From: Anish Kr Singh <116036738+anishfyle@users.noreply.github.com> Date: Fri, 3 Jan 2025 11:39:19 +0530 Subject: [PATCH] feat: handle expired credentials/tokens (#226) * feat: handle expired credentials/tokens * pr comments --- apps/travelperk/urls.py | 4 +++- apps/travelperk/views.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/apps/travelperk/urls.py b/apps/travelperk/urls.py index f44afd3..73858bc 100644 --- a/apps/travelperk/urls.py +++ b/apps/travelperk/urls.py @@ -7,7 +7,8 @@ DisconnectTravelperkView, TravelperkPaymentProfileMappingView, SyncPaymentProfiles, - AdvancedSettingView + AdvancedSettingView, + ValidateHealthyToken ) app_name = 'travelperk' @@ -20,4 +21,5 @@ path('advanced_settings/', AdvancedSettingView.as_view(), name='advance-settings-view'), path('profile_mappings/', TravelperkPaymentProfileMappingView.as_view(), name='profile-mappings'), path('sync_payment_profile/', SyncPaymentProfiles.as_view(), name='sync-payment-profiles'), + path('token_health/', ValidateHealthyToken.as_view(), name='token-health'), ] diff --git a/apps/travelperk/views.py b/apps/travelperk/views.py index d8fe90f..2ecc624 100644 --- a/apps/travelperk/views.py +++ b/apps/travelperk/views.py @@ -269,3 +269,40 @@ class SyncPaymentProfiles(generics.ListAPIView): def get_queryset(self): return SyncPaymentProfileSerializer().sync_payment_profiles(self.kwargs['org_id']) + + +class ValidateHealthyToken(generics.ListAPIView): + """ + API to check if TravelPerk credentials are healthy + """ + def get(self, request, *args, **kwargs): + try: + travelperk = TravelPerk.objects.get(org_id__in=[kwargs['org_id']]) + travelperk_credentials = TravelperkCredential.objects.get(org_id=kwargs['org_id']) + + travelperk_connection = TravelperkConnector(travelperk_credentials, kwargs['org_id']) + + # Try to fetch profiles to verify credentials + profiles_generator = travelperk_connection.connection.invoice_profiles.get_all_generator() + next(profiles_generator, None) # Try to get first profile + + return Response( + data={'message': 'Ready'}, + status=status.HTTP_200_OK + ) + + except (TravelPerk.DoesNotExist, TravelperkCredential.DoesNotExist): + return Response( + data={'message': 'TravelPerk connection not found'}, + status=status.HTTP_404_NOT_FOUND + ) + except Exception: + # If we can't fetch profiles, credentials are likely expired + if travelperk: + travelperk.is_travelperk_connected = False + travelperk.save() + + return Response( + data={'message': 'Invalid credentials'}, + status=status.HTTP_400_BAD_REQUEST + ) \ No newline at end of file