Files
DocsGPT/application/security/encryption.py
Siddhant Rai 7c23f43c63 feat: Add MCP Server management functionality
- Implemented encryption utility for securely storing sensitive credentials.
- Added MCPServerModal component for managing MCP server configurations.
- Updated AddToolModal to include MCP server management.
- Enhanced localization with new strings for MCP server features.
- Introduced SVG icons for MCP tools in the frontend.
- Created a new settings section for MCP server configurations in the application.
2025-09-03 15:41:59 +05:30

98 lines
2.8 KiB
Python

"""
Simple encryption utility for securely storing sensitive credentials.
Uses XOR encryption with a key derived from app secret and user ID.
Note: This is basic obfuscation. For production, consider using cryptography library.
"""
import base64
import hashlib
import os
import json
def _get_encryption_key(user_id: str) -> bytes:
"""
Generate a consistent encryption key for a specific user.
Uses app secret + user ID to create a unique key per user.
"""
# Get app secret from environment or use a default (in production, always use env)
app_secret = os.environ.get(
"APP_SECRET_KEY", "default-docsgpt-secret-key-change-in-production"
)
# Combine app secret with user ID for user-specific encryption
combined = f"{app_secret}#{user_id}"
# Create a 32-byte key
key_material = hashlib.sha256(combined.encode()).digest()
return key_material
def _xor_encrypt_decrypt(data: bytes, key: bytes) -> bytes:
"""Simple XOR encryption/decryption."""
result = bytearray()
for i, byte in enumerate(data):
result.append(byte ^ key[i % len(key)])
return bytes(result)
def encrypt_credentials(credentials: dict, user_id: str) -> str:
"""
Encrypt credentials dictionary for secure storage.
Args:
credentials: Dictionary containing sensitive data
user_id: User ID for creating user-specific encryption key
Returns:
Base64 encoded encrypted string
"""
if not credentials:
return ""
try:
key = _get_encryption_key(user_id)
# Convert dict to JSON string and encrypt
json_str = json.dumps(credentials)
encrypted_data = _xor_encrypt_decrypt(json_str.encode(), key)
# Return base64 encoded for storage
return base64.b64encode(encrypted_data).decode()
except Exception as e:
# If encryption fails, store empty string (will require re-auth)
print(f"Warning: Failed to encrypt credentials: {e}")
return ""
def decrypt_credentials(encrypted_data: str, user_id: str) -> dict:
"""
Decrypt credentials from storage.
Args:
encrypted_data: Base64 encoded encrypted string
user_id: User ID for creating user-specific encryption key
Returns:
Dictionary containing decrypted credentials
"""
if not encrypted_data:
return {}
try:
key = _get_encryption_key(user_id)
# Decode and decrypt
encrypted_bytes = base64.b64decode(encrypted_data.encode())
decrypted_data = _xor_encrypt_decrypt(encrypted_bytes, key)
# Parse JSON back to dict
return json.loads(decrypted_data.decode())
except Exception as e:
# If decryption fails, return empty dict (will require re-auth)
print(f"Warning: Failed to decrypt credentials: {e}")
return {}