Files
MoviePilot/app/db/models/widget.py
jxxghp 721c03734a feat(widget): 提供受限凭据和只读快照接口 (#7175)
* feat(widget): add restricted read-only snapshot foundation

* test(widget): 补齐运行时与文档迁移契约
2026-10-25 06:02:47 +08:00

35 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
小组件专用凭据记录;主登录资料与原始 secret 均不落入该表。
"""
from sqlalchemy import Float, ForeignKey, Index, Integer, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base import Base, get_id_column
class WidgetRegistration(Base):
"""
每用户每安装最多一项授权,删除用户时级联移除,身份重建另有 owner 校验。
"""
id = get_id_column()
# 随机登记 UUID,不使用递增主键作为外部身份。
registration_id: Mapped[str] = mapped_column(String(36), nullable=False)
# 本机安装 UUID;同账号同安装的轮换只占一个名额。
installation_id: Mapped[str] = mapped_column(String(36), nullable=False)
# 当前账号主键,外键不代替不可变身份校验。
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("user.id", ondelete="CASCADE"), nullable=False)
# 数据库分配的不可变身份,阻止删除重建与主键复用。
owner: Mapped[str] = mapped_column(String(32), nullable=False)
# 完整专用 Bearer 的 SHA-256 十六进制摘要。
secret_digest: Mapped[str] = mapped_column(String(64), nullable=False)
# UTC Unix 秒,有效期只由服务端决定。
expires_at: Mapped[float] = mapped_column(Float, nullable=False)
__table_args__ = (
UniqueConstraint("registration_id", name="uq_widgetregistration_registration"),
UniqueConstraint("user_id", "installation_id", name="uq_widgetregistration_installation"),
Index("ix_widgetregistration_owner", "owner"),
)