OpenProject 开发 FAQ 深度解读:数据库变更策略、插件开发入门与 2FA SMS 短信网关
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
OpenProject 开发 FAQ 汇集了社区开发者最常问的三个核心问题:数据库层面能否直接集成、如何开发自己的插件、以及两步验证(2FA)的短信网关机制。本文以 docs/development/faq/README.md 为主体骨架,结合 OpenProject 仓库中的生成器源码、two_factor_authentication 模块实现与安装配置文档,逐条给出解答、原理剖析与可落地的操作指引,帮助你快速绕开开发中的常见误区。
一、OpenProject 有数据库 ER 图(实体关系图)吗?
结论:没有,官方也不建议从数据库层面做集成。
FAQ 明确指出,OpenProject 的数据库布局处于持续变化之中,即便是从一个补丁版本升级到下一个补丁版本,也可能改变数据库结构。因此:
- 官方不提供 ER 图;
- 官方不建议在数据库层面进行集成(例如用于数据仓库 Data Warehousing 或仪表盘 Dashboard 开发)。
为什么数据库结构如此不稳定?
从仓库结构可以印证这一结论:db/migrate/目录下积累了 269 个迁移文件(db/migrate),OpenProject 通过 Rails 的 ActiveRecord Migration 机制持续演进表结构。迁移文件会随版本不断新增,任何表结构、索引、外键的调整都会直接反映到迁移历史中,因此以"某个版本的 ER 图"为基准做数据库集成,几乎必然在下一次升级时失效。
开发者应该怎么做?
官方推荐的集成路径是通过 OpenProject 的 API 层(位于 lib/api,以API::V3命名空间为主)进行数据交互,而不是直连数据库。API 提供了稳定的、版本化的契约,能够屏蔽底层表结构的持续变化。如果你的需求是数据仓库/BI 集成,可以优先评估官方 API 或导出能力,而不是解析数据库 schema。
二、如何开发自己的 OpenProject 插件?
FAQ 的答复是:插件开发文档目前确实有限,官方主要提供两处资源:
- 创建 OpenProject 插件(原文档中的
../create-openproject-plugin目录); - 一个原型插件仓库
openproject-proto_plugin,其中演示了添加菜单项、挂钩视图、定义项目菜单等基础能力。
2.1 插件本质上是什么?
OpenProject 插件是特殊的 Ruby Gem,通过Gemfile.plugins引入,与普通 Gem 一样获得版本管理和依赖解析能力。生成插件的命令为:
bundle exec rails generate open_project:plugin my_plugin ../plugins/该命令会在../plugins/openproject-my_plugin目录下生成一个 Rails Engine 形式的插件骨架。命令背后的实现是 lib/generators/open_project/plugin/plugin_generator.rb,从中可以看到生成器的工作方式:
- 默认插件名
openproject-new-plugin,默认输出目录vendor/gems(plugin_generator.rb); - 通过
full_name统一拼装为openproject-<plugin_name>命名(plugin_generator.rb); - 会依次生成插件根目录、
lib目录和bin目录(plugin_generator.rb)。
生成后,建议更新插件根目录下的openproject-my_plugin.gemspec。
提示:除了生成新插件,也可以直接克隆
openproject-proto_plugin示例插件并在此基础上改造。
2.2 如何把插件接入 OpenProject?
在根目录的Gemfile.plugins中声明依赖即可(参考 创建 OpenProject 插件):
group :opf_plugins do gem "openproject-my_plugin", :path => '../plugins/openproject-my_plugin' end如果文件中已有opf_plugins组,只需把gem行加入该组。随后安装:
bundle install2.3 生产环境如何部署插件?
FAQ 链接指向两种生产部署方式:
- Docker 容器:在 Docker 安装方式中挂载插件,详见 Docker 安装文档;
- DEB/RPM 打包安装:详见 添加插件(DEB/RPM 包)。
DEB/RPM 方式的核心步骤如下(来自 plugins 配置文档):
- 创建自定义 Gemfile(例如
/etc/openproject/Gemfile.custom):
group :opf_plugins do gem 'openproject-gitlab_integration', git: 'https://github.com/btey/openproject-gitlab-integration.git' end- 通过配置项告知安装包使用该 Gemfile:
openproject config:set CUSTOM_PLUGIN_GEMFILE="/etc/openproject/Gemfile.custom"- 若插件涉及 Angular 前端代码,还需重新编译前端资源(会安装 npm 依赖并显著增加磁盘与内存消耗,官方提示 Angular CLI 生产构建至少需要 4GB 内存):
openproject config:set RECOMPILE_ANGULAR_ASSETS="true"- 重新运行安装器完成重新打包、迁移与资源预编译:
sudo openproject configure2.4 插件类型与发布流程
创建插件文档中还给出了值得注意的类型划分:
- 纯后端插件:Rails Engine 形式的 Gem;
- 前端插件:以 npm 模块形式打包,需在插件根目录包含
package.json,自己负责加载图片、样式和 I18n 翻译(翻译经 Rails 从config/locales/js-<locale>.js拾取); - 混合插件(Hybrid):同时包含
Gem::Specification与package.json,既扩展 Rails 又扩展前端,在Gemfile.plugins的:opf_plugins组中声明后运行bundle install,前端构建管线(Angular CLI + esbuild)会自动打包其资源。注意:混合插件的 npm 依赖解析目前尚未完善。
发布插件的流程要点包括:代码审查、解决许可与版权问题(可借助rake copyright:authors:show['../Path/to/repository/']与rake copyright:update['path_to_plugin']任务)、完善 README 与 gemspec、创建 release 标签(如release/1.0.2)、gem build <name>.gemspec后gem push <name>-<version>.gem发布到 RubyGems。
三、OpenProject 的 2FA 短信网关用的是哪家?可以改吗?
结论:OpenProject 使用 MessageBird 作为 SMS 短信网关,FAQ 撰写时该配置不可更换。
不过,从当前仓库的源码来看,2FA 模块实际上已经抽象出了可插拔的 Token Strategy 机制,存在多个实现——FAQ 的结论需要结合这一现状来理解。
3.1 源码证据:MessageBird 策略实现
MessageBird 策略的实现位于 modules/two_factor_authentication/lib/open_project/two_factor_authentication/token_strategy/message_bird.rb,关键信息:
- 标识符为
:message_bird,支持sms和voice两种通道(message_bird.rb); - 通过
message_bird_client以配置中的apikey创建客户端(message_bird.rb); - 发送 SMS 时设置
validity: 720(720 秒 = 15 分钟登录令牌有效期减 3 分钟缓冲),并检查totalDeliveryFailedCount判断投递是否失败(message_bird.rb); - 语音通道通过
voice_message_create发送,支持多达 26 种语言(含zh-cn),并利用<break>标签为 TTS 播报加入停顿(message_bird.rb); - 发起方(originator)固定为
"OpenProject",代码中留有 TODO 提示其长度不能超过 11 个字符(message_bird.rb); - 收件人手机号会去除
+与空格后再传给 MessageBird(message_bird.rb)。
3.2 策略选择机制:并非只有一家
token_strategy目录下共有 6 个策略文件:base.rb、developer.rb、message_bird.rb、sns.rb、totp.rb、webauthn.rb(见 token_strategy 目录)。其中:
Sns策略通过 AWS SDK(aws-sdk-sns)发送短信,要求配置access_key_id、secret_access_key、region三项(sns.rb);Developer策略是开发环境专用,直接拒绝在生产环境使用(见 developer.rb)。
策略的管理与校验集中在 token_strategy_manager.rb:它遍历已注册的活动策略并逐一执行validate!,同时保证每种设备类型只被一个策略注册。因此,从源码结构看,短信/语音网关已经具备可替换的策略抽象——实际可用的网关取决于当前构建中注册并激活的策略。
3.3 SMS 设备模型
SMS 作为 2FA 设备,其模型位于 modules/two_factor_authentication/app/models/two_factor_authentication/device/sms.rb,约束包括:
phone_number必填、对同一用户唯一,且必须匹配\A(?:\+(?:[0-9][- ]?)+[0-9])?\z的国际格式(sms.rb);- 默认通道为
sms,可切换为voice(sms.rb); - 界面展示时会脱敏手机号,仅保留首尾(
redacted_identifier,sms.rb)。
3.4 对 FAQ 结论的正确理解
综合来看,FAQ 中"使用 MessageBird、目前无法更换"的表述,反映的是当时默认/内置网关即为 MessageBird 的现状;而从当前代码可以推断,网关实现已被抽象为 Token Strategy 并可扩展。若你需要在生产环境使用其他短信服务商,应优先查阅当前版本的 2FA 配置文档与策略注册机制,确认你所用版本支持哪些策略,而不是假设只有 MessageBird 一条路。
四、总结:三个 FAQ 问题的快速索引
| 问题 | 官方结论 | 仓库依据 |
|---|---|---|
| 有没有数据库 ER 图? | 没有,数据库结构随升级持续变化,不建议数据库层集成 | db/migrate 下 269 个迁移文件 |
| 插件开发文档在哪? | 文档有限,以 创建 OpenProject 插件 与openproject-proto_plugin示例为主 | lib/generators/open_project/plugin/plugin_generator.rb |
| 2FA 短信网关是哪家? | MessageBird,FAQ 撰写时不可更改 | modules/two_factor_authentication 中的 token_strategy 实现 |
开发者在做数据库集成、插件扩展或 2FA 改造前,建议先通读上述源码与文档,以当前版本的实际实现为准——OpenProject 的演进速度决定了"文档结论"与"代码现状"之间可能存在的时差,源码才是最终的事实来源。
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考