修复数据库连接URL中密码包含"@"的问题
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user