seaislee1209 555c86ce76 feat: initialize AirGate - Volcengine IAM sub-account management platform
Backend (Django 4.2 + DRF):
- Admin auth with SimpleJWT
- Volcengine API client with HMAC-SHA256 signing
- IAM user management (create/sync/import/disable/enable)
- Billing query with pagination
- Feishu webhook notifications (async)
- APScheduler for periodic spending checks
- AES-256 encrypted credential storage
- API key auth for external system integration

Frontend (Vue 3 + Element Plus):
- Login page
- Dashboard with stats overview
- IAM user list with per-user threshold config
- Billing view with spending progress bars
- Alert history with type filtering
- Settings page for global config and Volcengine account management

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:03:30 +08:00

57 lines
1.3 KiB
Python

"""AES 加密/解密工具,用于安全存储火山引擎密钥"""
import logging
from cryptography.fernet import Fernet, InvalidToken
from django.conf import settings
logger = logging.getLogger(__name__)
_fernet = None
def _get_fernet():
global _fernet
if _fernet is not None:
return _fernet
key = settings.AIRGATE_ENCRYPTION_KEY
if not key:
logger.warning("AIRGATE_ENCRYPTION_KEY 未设置,密钥将以明文存储!")
return None
try:
_fernet = Fernet(key.encode() if isinstance(key, str) else key)
return _fernet
except Exception as e:
logger.error(f"加密密钥格式错误: {e}")
return None
def encrypt(plaintext: str) -> str:
if not plaintext:
return ''
f = _get_fernet()
if f is None:
return plaintext
return f.encrypt(plaintext.encode()).decode()
def decrypt(ciphertext: str) -> str:
if not ciphertext:
return ''
f = _get_fernet()
if f is None:
return ciphertext
try:
return f.decrypt(ciphertext.encode()).decode()
except InvalidToken:
logger.error("解密失败:密文无效或加密密钥已变更")
return ''
def make_hint(ak: str) -> str:
"""生成 AK 脱敏提示,如 AKLT****3A"""
if len(ak) <= 8:
return '****'
return f"{ak[:4]}****{ak[-4:]}"