Skip to content

feat(drivers/onedrive_app): support mounting SharePoint site document library - #3252

Open
AkashiCoin wants to merge 3 commits into
OpenListTeam:mainfrom
AkashiCoin:feat/onedrive-app-sharepoint
Open

AkashiCoin wants to merge 3 commits into
OpenListTeam:mainfrom
AkashiCoin:feat/onedrive-app-sharepoint

Conversation

@AkashiCoin

@AkashiCoin AkashiCoin commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary / 摘要

OnedriveAPP (the client-credentials variant of the OneDrive driver) hardcodes the Graph path to /v1.0/users/{email}/drive/root, so it can only reach a user's OneDrive. This adds an opt-in SharePoint mode that targets a site's default document library.

User-visible behavior changes:

  • New is_sharepoint (bool, default false) and site_id (string) fields. With is_sharepoint enabled, requests go to /v1.0/sites/{siteId}/drive instead of /v1.0/users/{email}/drive.
  • site_id accepts <host>,<siteGuid>,<webGuid>, <host>:/sites/<name>, or a full site URL.
  • Existing storages are unaffected: is_sharepoint defaults to false, which keeps the original /users/{email}/drive path unchanged.

Important implementation changes:

  • Path-form and URL identifiers are resolved once in Init via GET /v1.0/sites/{id}?$select=id, and the resulting opaque ID is written back to the storage record.
  • Graph accepts the opaque host,<siteGuid>,<webGuid> form and the path form host:/sites/<name>, but only the opaque form can be followed by /drive — the path form's trailing colon terminates the segment and any suffix returns 400 Url specified is invalid. Since the driver builds URLs like /drive/root:/<path>:, normalization has to happen up front, and the resolved ID is persisted so subsequent Inits and cold starts use it directly.
  • Init validates site_id in SharePoint mode and email in user mode.
  • getDrive (quota reporting) follows the same mode switch.
  • Unit tests cover site ID normalization and URL construction.

Config/storage changes: two new fields are added to Addition, so existing storage records gain empty defaults on read-back. No migration is required and no existing field changes meaning.

  • This PR has breaking changes.
    / 此 PR 包含破坏性变更。
  • This PR changes public API, config, storage format, or migration behavior.
    / 此 PR 修改了公开 API、配置、存储格式或迁移行为。
  • This PR requires corresponding changes in related repositories.
    / 此 PR 需要关联仓库同步修改。

Related Issues / 关联 Issue

Relates to OpenListTeam/OpenList-Frontend#724
Relates to OpenListTeam/OpenList-Docs#394

Testing / 测试

  • go test ./...
  • Manual test / 手动测试:

Commands run:

gofmt -l drivers/onedrive_app/ # no output
go vet ./drivers/onedrive_app/
go test ./drivers/onedrive_app/
go test ./...

Platform: Windows 11, Go 1.27.3, local build of this branch.

Manual verification against a real tenant using client credentials and application permission Sites.ReadWrite.All:

  • List root, read quota, small-file upload, 6 MB upload via upload session, then download and verify the byte count — all OK
  • mkdir / rename / copy / move / remove — all OK
  • site_id supplied as a full URL, as <host>:/sites/<name>, and in the opaque comma form — all three mount correctly, and the resolved ID is persisted
  • Mounting a subfolder via root_folder_path, verified both before and after a restart
  • Site-collection root URL (https://contoso.sharepoint.com) resolves to the root site rather than the sub-site; its default library is separate from sub-site libraries and typically empty, so this is documented in the field help rather than rejected

Not covered:

  • Only the global region was exercised against a live tenant; cn / us / de share the same code path but were not validated.
  • Only Sites.ReadWrite.All was tested; scoped Sites.Selected was not.
  • Non-default document libraries within a site (e.g. App Packages) are out of scope — the driver uses the site's default library.

Checklist / 检查清单

  • I have read CONTRIBUTING.
    / 我已阅读 CONTRIBUTING。
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
    / 我确认此贡献符合仓库许可证、贡献规范和行为准则。
  • I have formatted the changed code with gofmt, go fmt, or prettier where applicable.
    / 我已按适用情况使用 gofmt、go fmt 或 prettier 格式化变更代码。
  • I have requested review from relevant maintainers or code owners where applicable.
    / 我已在适用情况下请求相关维护者或代码所有者审查。

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.
    / 此 PR 包含 AI 辅助内容。

Tools used / 使用工具:

  • ChatGPT
  • Codex
  • GitHub Copilot
  • Claude
  • Gemini
  • Other (please specify) / 其他(请注明):

Usage scope / 使用范围:

  • Code generation / 代码生成

  • Refactoring / 重构

  • Documentation / 文档

  • Tests / 测试

  • Translation / 翻译

  • Review assistance / 审查辅助

  • I have reviewed and validated all AI-assisted content included in this PR.
    / 我已审核并验证此 PR 中的所有 AI 辅助内容。

  • I have ensured that all AI-assisted commits include Co-Authored-By attribution.
    / 我已确保所有 AI 辅助提交都包含 Co-Authored-By 归属信息。

  • I can reproduce all AI-assisted content included in this PR without any AI tools.
    / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。

AkashiCoin and others added 2 commits October 24, 2026 18:18
- 新增 `is_sharepoint` 与 `site_id` 两个配置项,开启后走 `/sites/{siteId}/drive` 而不是 `/users/{email}/drive`
- 新增 `NormalizeSiteID`,接受 `siteId,siteGuid,webGuid`、`host:/sites/name`、站点 URL 和站点集合根 URL 四种写法
- 路径形式的 site 标识在 `Init` 阶段解析成 Graph 的逗号形式并回写存储,因为 `/sites/{path}:/` 后面不能继续拼 `/drive`
- `Init` 对 SharePoint 模式校验 `site_id`,非 SharePoint 模式校验 `email` 非空
- 配额查询 `getDrive` 同步区分两种模式
- 补充 `NormalizeSiteID` 与 URL 拼接的单元测试

Co-authored-by: Claude <81847+claude@users.noreply.github.com>
- 说明裸域名会解析成站点集合根站点,其默认文档库通常为空
- 补充完整站点 URL 也会被解析成 ID 形式
- 合并为两句话,缩短表单提示气泡长度

Co-authored-by: Claude <81847+claude@users.noreply.github.com>

jyxjjj commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

[P2] SharePoint 根站点 URL 会被规范化成错误的标识。NormalizeSiteID("https://contoso.sharepoint.com") 返回 "contoso.sharepoint.com:",随后请求 /sites/contoso.sharepoint.com:。Graph 的主机名寻址形式是 /sites/contoso.sharepoint.com,冒号形式用于带路径的站点。要单独处理空路径和根路径,只有存在站点子路径时才拼接冒号。

依据:https://learn.microsoft.com/en-us/graph/api/site-get?view=graph-rest-1.0


Generated by ChatGPT-6.1-Sol Medium

- `NormalizeSiteID` 对空站点路径走 `/sites/{hostname}` 主机名寻址,只有存在站点子路径时才生成 `/sites/{hostname}:/{path}:`
- 统一 `host:/path/:` 这类多重尾字符为单个冒号
- 补充裸主机名、带尾斜杠主机名、`host:/` 三种输入的用例

Co-authored-by: Claude <81847+claude@users.noreply.github.com>
@AkashiCoin

Copy link
Copy Markdown
Contributor Author

[P2] SharePoint 根站点 URL 会被规范化成错误的标识。NormalizeSiteID("https://contoso.sharepoint.com") 返回 "contoso.sharepoint.com:",随后请求 /sites/contoso.sharepoint.com:。Graph 的主机名寻址形式是 /sites/contoso.sharepoint.com,冒号形式用于带路径的站点。要单独处理空路径和根路径,只有存在站点子路径时才拼接冒号。

依据:https://learn.microsoft.com/en-us/graph/api/site-get?view=graph-rest-1.0

Generated by ChatGPT-6.1-Sol Medium

@jyxjjj 改了,分类做了处理,并增加了测试

@xrgzs

xrgzs commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

@AkashiCoin

Copy link
Copy Markdown
Contributor Author

@AkashiCoin 请完善文档 https://github.com/OpenListTeam/OpenList-Docs

已补充文档和前端显示。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants