Files
ChuBlog/docs/publishing.md
T
2026-10-16 18:09:11 +08:00

5.9 KiB
Raw Blame History

账户授权与文章发布

返回项目首页

用户与发布授权

完整接口见 API 文档。

  1. 注册:POST /api/auth/register,正文 { "username": "alice", "password": "至少12字节的口令" }。默认角色 reader,绝不接受客户端指定角色。ALLOW_REGISTRATION=false 可关闭注册。
  2. 登录:POST /api/auth/login,相同字段。浏览器保存 HttpOnly Cookie;返回 csrf。所有修改请求必须携带站点 Origin 和 X-CSRF-Token。
  3. 本地生成 ssh-keygen -t ed25519 或 ssh-keygen -t rsa -b 3072;登录后 PUT /api/account/ssh-key 提交 { "public_key": "ssh-ed25519 AAAA..." },只交公钥。RSA 使用标准 ssh-rsa AAAA... 公钥文本,支持 2048–8192 位;实际认证使用 RSA/SHA-256 或 RSA/SHA-512,不启用旧的 SHA-1 签名。见 OpenSSH 说明。
  4. 管理员登录后调用 PATCH /api/admin/users/alice,正文 { "enabled": true, "role": "publisher" }。服务器按公钥绑定的用户分配独立仓库。
  5. 此时 SSH 才接受该用户的密钥;reader、停用用户、未绑密钥的用户均不能访问 Git。管理员也需登记公钥才能发布。旧 prefixes 字段仅为兼容保留,不再用于文章隔离。
  • 授权与密钥独立:知道服务器地址、有网站账户、上传了公钥都不足以推送。
  • 设回 reader 或 enabled:false 会撤回发布授权,并使现有网站会话失效。
  • 禁止管理员停用自己或取消自己的管理角色。

本地 Git 工作流

  • 先通过可信渠道核对服务器 Ed25519 主机密钥指纹;不要禁用主机密钥检查。
  • 主机密钥保存在独立持久卷,重建容器不会更换。
  • 所有发布者使用同一个 OS 账户 git,身份由对应公钥的强制命令绑定,不由 Git author/email 决定。
# ~/.ssh/config
Host chublog
    HostName blog.example.com
    Port 2222
    User git
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# 无论作者是谁,别名都是 content.git;服务端按认证身份映射个人仓库。
# 首次 clone 自动创建服务器裸仓库,作者无须自己创建裸仓库。
git clone chublog:content.git my-articles
cd my-articles
# 仓库已有内容时,每轮编辑前先 git pull --ff-only。
# 创建 index.txt 和正文,格式见下文。
git add index.txt posts/first
git commit -m 'Publish first article'
git push -u origin main

文章目录与清单

仓库结构示例:

index.txt
posts/
└── first/
    ├── article.md
    └── cover.png

index.txt 为 UTF-8 三列文本,以空格或 Tab 分隔,无表头,允许空行:

first posts/first article.md
notes posts/my-notes notes.markdown
  • 三列依次为文章 ID、相对文件夹、正文文件名。
  • ID 在作者内唯一,支持 1–40 位小写字母、数字及中间短横线,另须避开保留名称。
  • 目录必须是 posts/<目录名>,目录名遵循 slug 规则,最多 80 字节;文件名只允许 ASCII 字母、数字、短横线、下划线与点,不能以点开头或含 ..。
  • 同一目录不能重复登记;正文可以任意命名,扩展名为 .md、.markdown 或 .txt。
  • 索引所指目录和正文必须存在,路径穿越和子目录正文被拒绝。
  • 索引上限 64 KiB、1000 项。

正文与图片

  • 正文沿用 YAML Frontmatter(参考正文样例),包含 title/date/updated/status/tags/description;slug 可省略,如填写则必须等于索引 ID。
  • .txt 正文也需要 Frontmatter,API 通过 format: text 表明正文应作为纯文本展示;其他正文为 format: markdown。
  • 图片置于同一目录,通过 ![说明](cover.png) 引用。

新增、修改与撤回

作者操作 系统处理
新建正文并在索引新增一行 校验后导入文章,在 ChuSQL 创建作者、ID、正文路径、状态等元信息
修改正文或索引中的目录/文件名,保留 ID 更新同一文章;站内 ID 不随目录移动而变化
删除索引中的一行 移除当前阅读内容、图片入口及对应数据库元信息,无需先删除本地正文
把索引清空 移除该作者所有当前文章,不影响其他作者
  • 未被索引选中的正文及目录视为无效内容,不导入阅读快照或数据库;图片只有被选中正文引用才作为公开资源导入;仍计算仓库容量并执行安全校验。
  • 删除正文但保留其索引项属于错误,整次推送会被拒绝。
  • status: draft 可保留登记但不公开;物理删除文件和撤回文章均不会擦除 Git 历史。

提交与并发限制

  • MVP 每次只接受一个直接继承个人远端 main 的提交,首次仅允许一个根提交。
  • 禁止 merge、force push、删除 main、标签及其他分支;多次本地提交应先整理为一次提交,再变基到最新远端。
  • 同一作者在多台电脑操作仍需处理并发冲突,不同作者互不争用同一个仓库锁。

作者隔离与文章地址

  • 站内文章 ID 为 作者名~文章ID,例如 Alice 的 first 对应 /api/posts/alice~first;不同作者可以使用相同的本地 ID。
  • 服务端分别保存每位作者的 Git 对象与历史,SSH 不能指定别人的仓库路径;作者无法通过 clone 或按提交哈希 fetch 读取其他作者草稿。
  • 作者自己已克隆的历史仍可在本地保留,不能靠撤回收回副本。

发布状态

  • API 自动同步,一般约 2 秒,数据库重建、失败重试或较多作者可能延迟。
  • GET /api/admin/status 的 commit 是作者提交映射的集合摘要,不是任一作者 Git 提交;indexed_commit 表示数据库已同步的集合版本。
  • Git 接受表示接收校验完成,不保证数据库已同步。
  • 当前不做站长内容审核,审核计划见 TODO。