修复数据库连接URL中密码包含"@"的问题

This commit is contained in:
2026-02-24 17:01:39 +08:00
parent efc05f7278
commit 2826999ddc
2 changed files with 38 additions and 11 deletions

View File

@@ -5,10 +5,28 @@ from uuid import UUID
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.encryption import get_encryptor
from app.core.encryption import get_encryptor, is_encryption_configured
from app.infra.db.metadata import models
def _normalize_postgres_dsn(dsn: str) -> str:
if not dsn or "://" not in dsn:
return dsn
scheme, rest = dsn.split("://", 1)
if scheme not in ("postgresql", "postgres", "postgresql+psycopg"):
return dsn
if "@" not in rest:
return dsn
userinfo, hostinfo = rest.rsplit("@", 1)
if ":" not in userinfo:
return dsn
username, password = userinfo.split(":", 1)
if "@" not in password:
return dsn
password = password.replace("@", "%40")
return f"{scheme}://{username}:{password}@{hostinfo}"
@dataclass(frozen=True)
class ProjectDbRouting:
project_id: UUID
@@ -84,8 +102,12 @@ class MetadataRepository:
record = result.scalar_one_or_none()
if not record:
return None
encryptor = get_encryptor()
dsn = encryptor.decrypt(record.dsn_encrypted)
if is_encryption_configured():
encryptor = get_encryptor()
dsn = encryptor.decrypt(record.dsn_encrypted)
else:
dsn = record.dsn_encrypted
dsn = _normalize_postgres_dsn(dsn)
return ProjectDbRouting(
project_id=record.project_id,
db_role=record.db_role,
@@ -106,12 +128,14 @@ class MetadataRepository:
record = result.scalar_one_or_none()
if not record:
return None
encryptor = get_encryptor()
password = (
encryptor.decrypt(record.gs_admin_password_encrypted)
if record.gs_admin_password_encrypted
else None
)
if record.gs_admin_password_encrypted:
if is_encryption_configured():
encryptor = get_encryptor()
password = encryptor.decrypt(record.gs_admin_password_encrypted)
else:
password = record.gs_admin_password_encrypted
else:
password = None
return ProjectGeoServerInfo(
project_id=record.project_id,
gs_base_url=record.gs_base_url,