ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

rclone OneDrive 元数据实战:系统元数据、权限管理与 Graph API 对接细节

rclone OneDrive 元数据实战:系统元数据、权限管理与 Graph API 对接细节 rclone OneDrive 元数据实战系统元数据、权限管理与 Graph API 对接细节【免费下载链接】rclonersync for cloud storage - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone本文以 rclone OneDrive 后端的官方元数据说明文档 metadata.md 为主体系统讲解 OneDrive 在 rclone 中的元数据能力边界支持哪些系统元数据键、如何配置并读写共享权限permissions、Personal 与 Business 两种盘型的差异以及权限增删改在源码层面如何映射到 Microsoft Graph API 的具体调用。读完本文你可以直接用 rclone 对 OneDrive 文件/目录做元数据同步与权限治理并能看懂其底层实现与测试验证方式。1. OneDrive 元数据模型只有系统元数据没有用户元数据根据 metadata.md 的开篇说明OneDrive 目前支持 System Metadata系统元数据但不支持 User Metadata用户元数据且文件File和目录Folder均适用这一能力。写入元数据时rclone 只会写入可写的系统属性——任何只读或未识别的键都会被静默忽略。这一能力边界在源码中有明确的特性声明。onedrive.go 中的 features 定义ReadMetadata: true, WriteMetadata: true, UserMetadata: false, // 不支持用户自定义元数据 ReadDirMetadata: true, WriteDirMetadata: true, UserDirMetadata: false,也就是说你无法像操作 S3 或 B2 那样给文件挂任意foobar标签你能读写的键集合是后端预先定义好的那一批系统属性以及一个特殊的permissions键见后文。1.1 完整的系统元数据键表下表完整继承自 metadata.go 中的systemMetadataInfo定义第 27-126 行这也是rclone lsjson输出中可见的全部键键名类型只读说明content-typestring是文件的 MIME 类型mtimeRFC 3339否最后修改时间Business 精度为秒Personal 为毫秒btimeRFC 3339否文件创建birth时间utimeRFC 3339是上传时间created-by-display-namestring是创建者显示名created-by-idstring是创建者用户 IDdescriptionstring否已废弃文件短描述最多 1024 字符微软已不再支持idstring是该项在 OneDrive 内的唯一标识last-modified-by-display-namestring是最后修改者显示名last-modified-by-idstring是最后修改者 IDmalware-detectedboolean是OneDrive 是否检测到该项含恶意软件package-typestring是若存在表示该项是包如 OneNote某些场景按文件处理、某些场景按目录处理shared-owner-idstring是共享项所有者的 ID如已共享shared-by-idstring是执行共享的用户 ID如已共享shared-scopestring是共享范围anonymous、organization或usersshared-timeRFC 3339是共享发生的时间permissionsJSON视配置OneDrive 格式权限的 JSON 转储需开启--onedrive-metadata-permissions几个值得注意的实现细节时间格式metadata.go 第 22-23 行定义了双向格式——读取时输出为2006-01-02T15:04:05.999ZPersonal 返回毫秒Business 只有秒写入时按 RFC 3339 解析。description已名存实亡源码中Set方法遇到该键只会打一条 debug 日志metadata description is no longer supported -- skipping并跳过不再向 API 提交metadata.go 第 261-263 行。btime缺失时的回退toAPIMetadata()中若只提供了mtime而btime为零值会把mtime同时用作btime避免 API 创建时把createdDateTime覆盖掉metadata.go 第 298-301 行。2. 权限支持--onedrive-metadata-permissions开关与取值metadata.md 指出权限Permissions在设置--onedrive-metadata-permissions后才可用该选项在 onedrive.go 第 823 行注册为配置项metadata_permissionsMetadataPermissions rwChoice config:metadata_permissions文档声明的取值为read、write、read,write、off默认。从源码结构看rwChoices.Choices()metadata.go 第 131-138 行该选项底层是一个按位组合的fs.Bits类型实际还接受一个文档未列出的取值failok——设置后写权限失败时只记录 ERROR 日志而不使传输失败第 363-371 行的defer中吞掉错误。各取值的组合效果取值读权限写权限行为off默认否否不读不写省 API 调用read是否读权限需要额外 API 调用写元数据请求中携带的 permissions 会被忽略write否是只写不读read,write是是文档推荐组合更新/删除权限需要知道 Permission ID只有先读回来才能做 difffailok由组合决定由组合决定写入失败仅记日志不中断传输为什么推荐read,write权限的更新和删除操作都以 Permission ID 为准。rclone 的写入流程是先Get现有权限、再与传入的目标状态做 diff见第 4 节只开write时拿不到旧权限就无法判断哪些该更新、哪些该删除。性能上文档也给出了明确提醒读、写权限都需要额外 API 调用如果不需要权限操作建议省略该参数。2.1 权限的 JSON SchemaPersonal 与 Business 略有不同权限以 JSON 数组形式读/写schema 与 OneDrive Graph API 的 permission 资源一致但 Personal 与 Business 字段有差异Personal用grantedTo单数对象invitation字段Business用grantedToIdentities数组grantedTo已废弃。metadata.md 中给出的 OneDrive Personal 示例[ { id: 1234567890ABC!123, grantedTo: { user: { id: ryancontoso.com }, application: {}, device: {} }, invitation: { email: ryancontoso.com }, link: { webUrl: https://1drv.ms/t/s!1234567890ABC }, roles: [ read ], shareId: s!1234567890ABC } ]OneDrive Business 示例注意grantedToIdentities是数组且可混排链接型与用户型权限[ { id: 48d31887-5fad-4d73-a9f5-3c356e68a038, grantedToIdentities: [ { user: { displayName: ryancontoso.com }, application: {}, device: {} } ], link: { type: view, scope: users, webUrl: https://contoso.sharepoint.com/:w:/t/design/a577ghg9hgh737613bmbjf839026561fmzhsr85ng9f3hjck2t5s }, roles: [ read ], shareId: u!LKj1lkdlals90j1nlkascl }, { id: 5D33DD65C6932946, grantedTo: { user: { displayName: John Doe, id: efee1b77-fb3b-4f65-99d6-274c11914d12 }, application: {}, device: {} }, roles: [ owner ], shareId: FWxc1lasfdbEAGM5fI7B67aB5ZMPDMmQ11U } ]这些字段与 api/types.go 中的PermissionsType结构一一对应第 230-241 行其中还包含文档未强调的grantedToV2/grantedToIdentitiesV2变体Business 专用InheritedFrom继承权限的祖先引用也是只读字段。角色常量定义在同文件第 246-255 行read、write、owner、member。2.2 用--metadata-mapper写入权限的完整示例写入权限的方式是在元数据里传入一个permissions键值就是上述同格式的 JSON 字符串。rclone 的--metadata-mapper工具对这一步非常有帮助。文档给出的添加一个 read 权限请求示例{ Metadata: { permissions: [{\grantedToIdentities\:[{\user\:{\id\:\ryancontoso.com\}}],\roles\:[\read\]}] } }添加权限时的收件人解析规则来自 metadata.md 及fillRecipients实现可在grantedTo或grantedToIdentities的User.ID或DisplayName中提供邮箱地址也可以直接在User.ID中提供 ObjectID无的 ID 会被当作 ObjectID 处理添加用户权限时至少需要一个有效收件人否则addPermission直接跳过metadata.go 第 616-619 行设置Link.Scope为anonymous时支持创建公共链接——此时走的是 rclone 自己的PublicLink实现且若没有任何收件人则只创建链接后直接返回不能添加owner角色的邀请源码第 623-626 行会跳过注意若目标文件/目录上已存在冲突的权限添加操作可能失败。3. 权限更新与删除的语义metadata.md 对更新/删除的说明结合sortPermissionsmetadata.go 第 433-488 行的实现可以精确概括为更新传入的权限项同时包含 Permissionid和新的roles。roles是唯一可变更的属性且源码会做健全性检查——只有在旧权限中存在同 ID、且新旧角色确实不同旧角色非空、非owner时才会进入 update 队列否则记 debug 日志跳过。删除传入的 JSON 数组是希望保留的权限集合。旧权限中 ID 未出现在保留集合里、且角色非owner的项进入 remove 队列。传空数组即删除全部可删权限。owner角色不可删除会被忽略。添加id为空的新权限项进入 add 队列。3.1 权限变更如何落到 Graph APIprocessPermissions第 491-526 行按remove → add → update的固定顺序执行对应三个 API 端点操作方法/端点说明获取现有权限GET /{id}/permissionsgetPermissions每次读权限都会调用添加权限POST /{id}/invite请求体为AddPermissionsRequestrecipients、rolesretainInheritedPermissionsfalse更新权限PATCH /{id}/permissions/{permId}请求体仅含roles删除权限DELETE /{id}/permissions/{permId}无请求体所有调用都经过f.pacer.Call限速并用shouldRetry判断可重试错误失败时错误被fserrors.NoRetryError包装避免无意义重试。3.2 两个源码才能看到的坑(1) 用户权限必须排在组权限之前Graph API 怪癖orderPermissions第 404-430 行会把含用户身份的权限排到前面。源码注释解释了背景当同时为一个组和一个用户添加相同权限、且该用户正是组成员时若先加组权限Graph 会先返回已添加用户权限又立即把它丢掉。这个 workaround 有对应单测 metadata_test.go 的TestOrderPermissions/TestOrderPermissionsJSON覆盖对 Personal 与 Business 两种盘型分别验证包括grantedToV2的 Business 变体。(2) Business 下链接型权限不能更新只能删了再加sortPermissions中有一个特判第 452-460 行非 Personal 盘型下若待更新权限带有Link.WebURL即共享链接型权限会同时放入 remove 和 add 队列用删除重新添加绕过 Graph API 无法更新链接型权限的限制。4. 读写调用链与目录元数据4.1 对象侧Get → Set → Write以文件为例元数据更新的完整调用链updateMetadatametadata.go 第 760-790 行Get(ctx)把缓存的系统元数据转成fs.Metadata若MetadataPermissions含read此处会额外发起一次GET /permissions调用并序列化为permissions键Set(ctx, meta)只解析可写键mtime、btime、permissions返回设置了多少个可写属性——若为 0直接跳过后续 API 调用Write(ctx, updatePermissions)toAPIMetadata()组装出只含fileSystemInfo.lastModifiedDateTime/createdDateTime的api.Metadata通过PATCH提交随后若需要刷新 normalizedID 并调用WritePermissions。上传新文件的路径同理fetchMetadataForCreate第 703-733 行在创建上传请求时就把createdDateTime/lastModifiedDateTime一并带上mtime无条件写入。4.2 目录侧多一次 API 调用的原因文档提到在 OneDrive Business 上给 Folder 设置 mtime/btime 需要一次额外 API 调用。源码印证了这一点MkdirMetadata第 799-844 行在createDir成功后会再调用一次meta.Write(ctx, false)来设置 modtime源码注释直言 for some reason, OneDrive Business and Personal needs this extra step to set modtime. Seems like a bug...。目录的SetModTime还会尽量保留已有的非零btime第 945-955 行。权限对目录同样生效createDir中若元数据含permissions且开启了写权限会先RefreshPermissions再WritePermissions第 880-892 行因为权限必须作为独立步骤执行。5. 测试用例权限能力是如何被验证的内部测试 onedrive_internal_test.go 提供了与文档描述一一对应的行为验证需要真实远端环境运行TestWritePermissions第 75-148 行完整走一遍以 read 角色添加 → 更新为 write → 删除流程并断言远端读回的权限与预期 JSON 一致。它还先做skipIfSharingRefused预检——如果组织策略拒绝共享邀请sharingFailed错误测试整体跳过TestReadPermissions第 158-172 行验证只开read时携带 permissions 的写入不会改变远端权限TestReadMetadata第 175-198 行断言systemMetadataInfo中所有必选键package-type、shared-*等可选键除外都存在且非空TestDirectoryMetadata第 200 行起验证目录的 mtime/btime/权限读写包括operations.SetDirModTime与DirSetModTime两条改时间路径。这些测试从源码层面确认了文档中的关键承诺键集合完整、只读时不产生写副作用、目录与文件同等支持。6. 速查常用命令查看任意文件/目录的元数据与权限文档给出的 TIP直接可复制rclone lsjson remote:path --stat -M --onedrive-metadata-permissions read结合--metadata-mapper对单个对象写入权限以同步场景为例rclone copyto src:file.txt onedrive:file.txt \ --metadata \ --onedrive-metadata-permissions read,write \ --metadata-mapper { Metadata: { permissions: [{\grantedToIdentities\:[{\user\:{\id\:\ryancontoso.com\}}],\roles\:[\read\]}] } }要点回顾OneDrive 只有系统元数据键集合固定为第 1.1 节表格description已被微软废弃权限操作必须显式开启--onedrive-metadata-permissions读写都更推荐read,write权限 JSON 中 Personal 看grantedToBusiness 看grantedToIdentitiesroles唯一可更新owner不可删除permissions的值是目标保留集合而非要删除的集合语义差异是误删权限的高发点所有权限读写都伴随额外 API 调用Business 目录时间设置还会多一次 PATCH批量操作时需注意配额与耗时。【免费下载链接】rclonersync for cloud storage - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表