Files
romm/backend/endpoints/responses/device.py
nendo 55638d15dc fix: address bugs, security issues, and convention violations in save-sync
- Fix broken path construction in FSSyncHandler: build_* methods now
  return relative paths; sync_watcher uses paths relative to sync base
  instead of CWD (was completely non-functional in production)
- Fix SSH connection leak in push-pull task: conn.close() now in finally
- Add log.warning for disabled SSH host key verification
- Fix race condition in session operation counter: use atomic SQL
  increment instead of read-then-write
- Extract _increment_session_counter helper, add exc_info to warnings
- Replace legacy session.query() with select() in sync_sessions_handler
- Fix orphaned session: trigger_push_pull now passes session_id to job
- Fix wasteful SSH download when no matched_save exists
- Fix BaseModel import collision in sync.py (pydantic -> project base)
- Fix ORM mutation in UserSchema.from_orm_with_request: set field on
  schema instance instead of mutating live ORM object
- Mask ssh_password and ssh_key_path in DeviceSchema API response
- Fix migration PostgreSQL compatibility: condition ON UPDATE clause
  on MySQL, drop enum in downgrade
- Rename copy-paste artifact rom_user_status_enum
2026-03-16 10:56:43 +09:00

56 lines
1.3 KiB
Python

from typing import Any
from pydantic import ConfigDict, field_serializer
from models.device import SyncMode
from .base import BaseModel, UTCDatetime
SENSITIVE_SYNC_CONFIG_KEYS = {"ssh_password", "ssh_key_path"}
class DeviceSyncSchema(BaseModel):
model_config = ConfigDict(from_attributes=True)
device_id: str
device_name: str | None
last_synced_at: UTCDatetime
is_untracked: bool
is_current: bool
class DeviceSchema(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
user_id: int
name: str | None
platform: str | None
client: str | None
client_version: str | None
ip_address: str | None
mac_address: str | None
hostname: str | None
sync_mode: SyncMode
sync_enabled: bool
sync_config: dict | None
last_seen: UTCDatetime | None
created_at: UTCDatetime
updated_at: UTCDatetime
@field_serializer("sync_config")
@classmethod
def mask_sensitive_fields(cls, v: dict | None) -> dict[str, Any] | None:
if not v:
return v
return {
k: "********" if k in SENSITIVE_SYNC_CONFIG_KEYS else val
for k, val in v.items()
}
class DeviceCreateResponse(BaseModel):
device_id: str
name: str | None
created_at: UTCDatetime