状态更新 2026-10

我已经完成了 pimsync 中 OAuth 支持的开发工作。该实现主要在 NextCloud 上进行了测试(包括其内置的 OAuth 提供程序以及 OIDC 插件),但应该也能与任何使用 OAuth 进行身份验证的 CalDAV/CardDAV 服务器配合使用。

它也应该能与 Google 的 CalDAV 实现兼容,尽管这一点尚未经过测试。

目前,主要还缺少文档——参考级别的文档已经就位,但一份更友好的、涵盖所有细节的“使用指南”仍在准备中。这既已明确列入计划,也十分必要。

实现细节[]

我用 Rust 编写了⼀个 sans-io 风格的 OAuth 库 liboauth,它本质上是整个认证流程的状态机。该库可与任何 Rust HTTP 客户端配合使用,包括 pimsync 所选用的 HTTP 实现 hyper。

liboauth v0.1.0 已发布至 crates.io,其集成测试以 NextCloud 作为服务器。随着在更多实际的 OAuth 实现中使用,它可能还需要进一步调整,但对于其他类型的软件来说已经完全可以使用。

我还基于 liboauth 编写了⼀个 tower/hyper 中间件。该中间件目前位于 pimsync 仓库中:由于上游正处于变化之中——旧版客户端 API 已被弃用且不再更新,而新版客户端 API 尚未存在——因此不适合直接合并到上游。

我希望在情况有所进展并伴随摘要式认证中间件一同完善后,再将其合入上游。

认证设置与常规存储配置分开,置于单独的 credential 块中。这样做是为了 (a) 避免让存储配置因过多指令而显得过于臃肿,以及 (b) 方便在两个存储之间复用相同的凭据(例如:CalDAV 和 CardDAV)。

一个 credentials 块大致如下所示:

    credentials nextcloud {
        auth_method oauth
        registration_url https://dav.example.com/oidc/registration
        token_url https://dav.example.com/oidc/token
        scope openid
        scope offline_access
        tokens_file ~/.local/state/pimsync/oauth/dav
        encryption_key {
            cmd hiq -dFpassword proto=pimsync-tokens
        }
    }

当服务器不支持动态客户端注册时,还需要配置一些额外的设置:

credentials nextcloud {
    auth_method oauth
    authorization_url https://nextcloud.example.com/authorize
    token_url https://nextcloud.example.com/token
    client_id my-client
    client_secret {
        cmd hiq -dFpassword proto=carddavs oauth-client
    }
    scope calendar
    scope contacts
    pkce off
    tokens_file ~/.local/state/pimsync/oauth/nextcloud
    encryption_key {
        cmd hiq -dFpassword proto=pimsync-tokens
    }
}

该实现还支持使用 OAuth + JMAP,尽管此路径尚未经过测试——欢迎提供相关反馈。

令牌存储[]

OAuth 令牌会过期,需要自动刷新。这一过程可能随时发生,因此 pimsync 必须能够存储这些令牌。最直观的做法似乎是将数据写入本地的密钥存储。

然而,向此类存储写入数据的时间点往往随机分布于一天中的各个时段,而此时计算机很可能正在执行与之无关的任务。在这些时刻弹出一个覆盖密钥存储中值的提示框,无疑会令人极为困扰。

某些“YOLO 风格”的密钥存储服务允许任何进程在无需用户确认的情况下覆盖(并读取!)任意密钥。采用这种方案可以避免上述问题,但仅支持这类服务显然是不负责任的。

为此,我们采用 ChaCha20-Poly1305 对令牌进行加密,并将其存储在磁盘上,所使用的密钥由 encryption_key 提供。该密钥仅在启动时读取一次,通常存放在密钥存储中(但在必要时也可置于纯文本文件中)。

待补充的细节[]

为 OAuth 使用自定义 TLS 配置的功能尚未实现。此外,pimsync 还可以在 OAuth 发现机制方面完善其集成测试,并按前述建议编写一份教程式的文档。

日志记录的改进[]

pimsync 现在会以 TRACE 级别记录针对所有存储类型(包括 JMAP)发出的所有 HTTP 请求。这一功能此前已完成约 80%,完成剩余部分将大大有助于排查故障。

参与讨论