Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5a0b9bb
encrypt oauth auth settings at rest
jordanrfrazier Aug 22, 2025
8e89ef4
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
f66f222
Fix rebase changes and add env to env server config
jordanrfrazier Aug 22, 2025
c385207
Correctly unmask secretstr before encryption
jordanrfrazier Aug 22, 2025
9da2f0f
update mcp-composer args
jordanrfrazier Aug 22, 2025
ca1426d
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 22, 2025
75af111
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
2cb3637
ruff
jordanrfrazier Aug 22, 2025
cb6d331
ruff
jordanrfrazier Aug 22, 2025
175278f
ruff
jordanrfrazier Aug 22, 2025
17adeba
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
2eed48e
ruff
jordanrfrazier Aug 22, 2025
074ef60
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 22, 2025
7cbed82
catch invalidtoken error
jordanrfrazier Aug 22, 2025
54b15ba
ruff
jordanrfrazier Aug 22, 2025
942dfb6
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
c5d71d9
ruff
jordanrfrazier Aug 22, 2025
ecee186
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
16eec45
ruff
jordanrfrazier Aug 22, 2025
4d0b3a3
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 22, 2025
05f7e6e
ruff
jordanrfrazier Aug 22, 2025
bc6b9b7
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
73c9646
ruff
jordanrfrazier Aug 22, 2025
6b22074
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
449d2e9
fix test
jordanrfrazier Aug 22, 2025
767fda6
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 22, 2025
a7445b7
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 25, 2025
58e2af7
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 25, 2025
9c64d76
remove oauth mention in server config
jordanrfrazier Aug 25, 2025
27f3ca2
Merge branch 'main' into mcp-composer-oauth
jordanrfrazier Aug 25, 2025
f6c8243
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 25, 2025
8950670
ruff
jordanrfrazier Aug 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
catch invalidtoken error
  • Loading branch information
jordanrfrazier committed Aug 22, 2025
commit 7cbed8296d99faa7ba404d41b296cae49bc4d0b3
7 changes: 4 additions & 3 deletions src/backend/base/langflow/services/auth/mcp_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from typing import Any

from cryptography.fernet import InvalidToken
from loguru import logger

from langflow.services.auth import utils as auth_utils
Expand Down Expand Up @@ -38,7 +39,7 @@ def encrypt_auth_settings(auth_settings: dict[str, Any] | None) -> dict[str, Any
auth_utils.decrypt_api_key(encrypted_settings[field], settings_service)
# If decrypt succeeds, it's already encrypted
logger.debug(f"Field {field} is already encrypted")
except (ValueError, TypeError, KeyError):
except (ValueError, TypeError, KeyError, InvalidToken):
# If decrypt fails, the value is plaintext and needs encryption
encrypted_value = auth_utils.encrypt_api_key(encrypted_settings[field], settings_service)
encrypted_settings[field] = encrypted_value
Expand Down Expand Up @@ -71,7 +72,7 @@ def decrypt_auth_settings(auth_settings: dict[str, Any] | None) -> dict[str, Any
decrypted_value = auth_utils.decrypt_api_key(decrypted_settings[field], settings_service)
decrypted_settings[field] = decrypted_value
logger.debug(f"Decrypted field {field}")
except (ValueError, TypeError, KeyError) as e:
except (ValueError, TypeError, KeyError, InvalidToken) as e:
# If decryption fails, assume the value is already plaintext
# This handles backward compatibility with existing unencrypted data
logger.debug(f"Field {field} appears to be plaintext or decryption failed: {e}")
Expand All @@ -96,7 +97,7 @@ def is_encrypted(value: str) -> bool:
try:
# Try to decrypt - if it succeeds, it's encrypted
auth_utils.decrypt_api_key(value, settings_service)
except (ValueError, TypeError, KeyError):
except (ValueError, TypeError, KeyError, InvalidToken):
# If decryption fails, it's not encrypted
return False
else:
Expand Down
25 changes: 14 additions & 11 deletions src/backend/tests/unit/services/auth/test_mcp_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@
@pytest.fixture
def mock_settings_service():
"""Mock settings service for testing."""
from cryptography.fernet import Fernet
import base64

Check failure on line 18 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (F401)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:18:12: F401 `base64` imported but unused

Check failure on line 18 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (I001)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:17:5: I001 Import block is un-sorted or un-formatted

Check failure on line 18 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (F401)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:18:12: F401 `base64` imported but unused

Check failure on line 18 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (I001)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:17:5: I001 Import block is un-sorted or un-formatted

mock_service = Mock()
# Generate a valid Fernet key
valid_key = Fernet.generate_key().decode()

# Create a SecretStr mock
secret_key_mock = Mock(spec=SecretStr)
secret_key_mock.get_secret_value.return_value = valid_key
mock_service.auth_settings.SECRET_KEY = secret_key_mock
# Generate a valid Fernet key that's already properly formatted
# Fernet.generate_key() returns a URL-safe base64-encoded 32-byte key
valid_key = Fernet.generate_key()
# Decode it to string for storage
valid_key_str = valid_key.decode('utf-8')

Check failure on line 25 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (Q000)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:25:38: Q000 Single quotes found but double quotes preferred

Check failure on line 25 in src/backend/tests/unit/services/auth/test_mcp_encryption.py

View workflow job for this annotation

GitHub Actions / Ruff Style Check (3.13)

Ruff (Q000)

src/backend/tests/unit/services/auth/test_mcp_encryption.py:25:38: Q000 Single quotes found but double quotes preferred

# Create a proper SecretStr object
secret_key_obj = SecretStr(valid_key_str)
mock_service.auth_settings.SECRET_KEY = secret_key_obj
return mock_service


Expand Down Expand Up @@ -117,15 +120,15 @@
mock_get_settings.return_value = mock_settings_service

partial_settings = {
"auth_type": "basic",
"password": "my-password",
"auth_type": "api",
"api_key": "sk-test-api-key-123",
"username": "admin",
}

encrypted = encrypt_auth_settings(partial_settings)

# Password should be encrypted
assert encrypted["password"] != partial_settings["password"]
# API key should be encrypted
assert encrypted["api_key"] != partial_settings["api_key"]

# Other fields unchanged
assert encrypted["auth_type"] == partial_settings["auth_type"]
Expand Down
Loading