From ecd0985523b381a37a9cb8222afb08a0aa050810 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 5 Feb 2026 14:39:50 +0200 Subject: [PATCH] Add access token pre-validation to OAuth connectors --- .../app/connectors/airtable_history.py | 16 ++++++++++++++++ .../app/connectors/confluence_history.py | 16 ++++++++++++++++ surfsense_backend/app/connectors/jira_history.py | 16 ++++++++++++++++ .../app/connectors/linear_connector.py | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/surfsense_backend/app/connectors/airtable_history.py b/surfsense_backend/app/connectors/airtable_history.py index 64f6465fe..092485f77 100644 --- a/surfsense_backend/app/connectors/airtable_history.py +++ b/surfsense_backend/app/connectors/airtable_history.py @@ -71,6 +71,14 @@ class AirtableHistoryConnector: config_data = connector.config.copy() + # Check if access_token exists before processing + raw_access_token = config_data.get("access_token") + if not raw_access_token: + raise ValueError( + "Airtable access token not found. " + "Please reconnect your Airtable account." + ) + # Decrypt credentials if they are encrypted token_encrypted = config_data.get("_token_encrypted", False) if token_encrypted and config.SECRET_KEY: @@ -98,6 +106,14 @@ class AirtableHistoryConnector: f"Failed to decrypt Airtable credentials: {e!s}" ) from e + # Final validation after decryption + final_token = config_data.get("access_token") + if not final_token or (isinstance(final_token, str) and not final_token.strip()): + raise ValueError( + "Airtable access token is invalid or empty. " + "Please reconnect your Airtable account." + ) + try: self._credentials = AirtableAuthCredentialsBase.from_dict(config_data) except Exception as e: diff --git a/surfsense_backend/app/connectors/confluence_history.py b/surfsense_backend/app/connectors/confluence_history.py index 9e10ffcf1..908f532db 100644 --- a/surfsense_backend/app/connectors/confluence_history.py +++ b/surfsense_backend/app/connectors/confluence_history.py @@ -87,6 +87,14 @@ class ConfluenceHistoryConnector: if is_oauth: # OAuth 2.0 authentication + # Check if access_token exists before processing + raw_access_token = config_data.get("access_token") + if not raw_access_token: + raise ValueError( + "Confluence access token not found. " + "Please reconnect your Confluence account." + ) + # Decrypt credentials if they are encrypted token_encrypted = config_data.get("_token_encrypted", False) if token_encrypted and config.SECRET_KEY: @@ -118,6 +126,14 @@ class ConfluenceHistoryConnector: f"Failed to decrypt Confluence credentials: {e!s}" ) from e + # Final validation after decryption + final_token = config_data.get("access_token") + if not final_token or (isinstance(final_token, str) and not final_token.strip()): + raise ValueError( + "Confluence access token is invalid or empty. " + "Please reconnect your Confluence account." + ) + try: self._credentials = AtlassianAuthCredentialsBase.from_dict( config_data diff --git a/surfsense_backend/app/connectors/jira_history.py b/surfsense_backend/app/connectors/jira_history.py index 6e04ec2a4..46a28324d 100644 --- a/surfsense_backend/app/connectors/jira_history.py +++ b/surfsense_backend/app/connectors/jira_history.py @@ -86,6 +86,14 @@ class JiraHistoryConnector: if is_oauth: # OAuth 2.0 authentication + # Check if access_token exists before processing + raw_access_token = config_data.get("access_token") + if not raw_access_token: + raise ValueError( + "Jira access token not found. " + "Please reconnect your Jira account." + ) + if not config.SECRET_KEY: raise ValueError( "SECRET_KEY not configured but tokens are marked as encrypted" @@ -119,6 +127,14 @@ class JiraHistoryConnector: f"Failed to decrypt Jira credentials: {e!s}" ) from e + # Final validation after decryption + final_token = config_data.get("access_token") + if not final_token or (isinstance(final_token, str) and not final_token.strip()): + raise ValueError( + "Jira access token is invalid or empty. " + "Please reconnect your Jira account." + ) + try: self._credentials = AtlassianAuthCredentialsBase.from_dict( config_data diff --git a/surfsense_backend/app/connectors/linear_connector.py b/surfsense_backend/app/connectors/linear_connector.py index b8206a40d..6500b9027 100644 --- a/surfsense_backend/app/connectors/linear_connector.py +++ b/surfsense_backend/app/connectors/linear_connector.py @@ -116,6 +116,14 @@ class LinearConnector: config_data = connector.config.copy() + # Check if access_token exists before processing + raw_access_token = config_data.get("access_token") + if not raw_access_token: + raise ValueError( + "Linear access token not found. " + "Please reconnect your Linear account." + ) + # Decrypt credentials if they are encrypted token_encrypted = config_data.get("_token_encrypted", False) if token_encrypted and config.SECRET_KEY: @@ -143,6 +151,14 @@ class LinearConnector: f"Failed to decrypt Linear credentials: {e!s}" ) from e + # Final validation after decryption + final_token = config_data.get("access_token") + if not final_token or (isinstance(final_token, str) and not final_token.strip()): + raise ValueError( + "Linear access token is invalid or empty. " + "Please reconnect your Linear account." + ) + try: self._credentials = LinearAuthCredentialsBase.from_dict(config_data) except Exception as e: