mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 00:23:17 +00:00
- 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.
98 lines
2.8 KiB
Python
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 {}
|