refactor(host): single-source ChannelPolicy, space-signed file grants, whole-file registration

- all authorization rules (owner/creator, per-channel read/write grants, who may
  remove whom, delete rules, structure management) live in ChannelPolicy; a test
  fails if they are reimplemented elsewhere
- ChannelInfo carries what the caller may do (can_*), member and invitation lists
  say who can be removed; clients display it and never derive it
- the host no longer stores or calls the file service: it only signs short-lived
  tickets from space permissions (create/put/get/delete/domain), and keeps an opaque
  fileDomain reference on the channel
- a whole file is registered in one request (last frame header + per-frame length and
  digest) instead of one request per 1 MiB frame; the signed manifest still has to
  match every digest
- drop file quota/threshold, receipts, reconcile and delete-queue code from the host
- contract generator emits constants for enums, error codes, token roles, permissions
  and share states
This commit is contained in:
justme committed 2026-10-19 13:38:40 +08:00
1 parent ccb2c074d6
commit 17638b6e20
36 files changed
+926 -589

No files matched your search

+15
View File
@@ -52,8 +52,23 @@ public sealed class ShareItemInfo
public sealed class ChannelInfo
{
// ───── 调用者在这个空间里的能力。前端只读不算:规则只在后端一处
/// <summary>调用者是空间所有者</summary>
[JsonPropertyName("is_owner")] public bool IsOwner { get; init; }
[JsonPropertyName("can_upload")] public bool CanUpload { get; init; }
/// <summary>能重命名频道、管理分组(所有者,或被授予「管理频道和分组」)</summary>
[JsonPropertyName("can_manage_structure")] public bool CanManageStructure { get; init; }
[JsonPropertyName("can_create_channel")] public bool CanCreateChannel { get; init; }
[JsonPropertyName("can_manage_folders")] public bool CanManageFolders { get; init; }
[JsonPropertyName("can_invite")] public bool CanInvite { get; init; }
[JsonPropertyName("can_edit_settings")] public bool CanEditSettings { get; init; }
[JsonPropertyName("can_manage_roles")] public bool CanManageRoles { get; init; }
/// <summary>能移除成员、撤销邀请;具体能移除谁见成员列表里每一项的 can_remove</summary>
[JsonPropertyName("can_remove_members")] public bool CanRemoveMembers { get; init; }
/// <summary>能删除任何人的消息和文件(所有者,或删除策略为 anyone)</summary>
[JsonPropertyName("can_delete_any")] public bool CanDeleteAny { get; init; }
/// <summary>能删除自己发的消息和文件</summary>
[JsonPropertyName("can_delete_own")] public bool CanDeleteOwn { get; init; }
[JsonPropertyName("password_required")] public bool PasswordRequired { get; init; }
[JsonPropertyName("creator_account")] public string? CreatorAccount { get; init; }
/// <summary>空间头像(data URL,PNG/JPEG/WebP/GIF),没有设置时为 null。</summary>