使用 PostgreSQL 插件时的权限问题和 auth 插件的安全性以及论坛界面问题

我这里也是一样。我不知道 discourse 是否支持输入框缩进功能。

5 个赞

可以,但需要先选中文本再点 tab

shift + tab 也是工作的

4 个赞

已发放等级

3 个赞

仍然报错 app PostgresError: permission denied for schema public

我也没有在实际生产中使用过postgres,不过根据我刚刚查询的结果,此处应当需要

GRANT ALL ON SCHEMA public TO koishi;

这会赋予当前所连接数据库的全部(create+usage)权限,而不会得到跨数据库的权限。而对ORM而言,拥有database内的完整权限是合理的。

这样后续第三点中数据库相关的问题应当不存在,如果有问题请再提出。

6 个赞

虽然这可能是一个 bug,但任何时候都不推荐 插件 使用数据库的 drop 功能。插件的行为会影响到每一个用户使用的实例,插件作者误用了此功能后可能会造成巨大的代价。

需要删除表的时候,推荐按照以下方法操作:

  1. 整个数据库 进行一次备份
  2. 使用专门的数据库管理软件进行删除操作

大多的附加主题是主题作者根据自己的需求和喜好进行布局的,这个主题的作者可能没有经常更换主题的需求,所以隐藏了这个选框。


这里确实可以改进一下。

4 个赞

是使用模板项目启动的,使用 ctx.http 时改过全局代理,使用全局代理时无法打开插件市场,然后就把全局代理配置项清空了,再之后插件市场就出现了这个问题 ,但是可以正常加载使用

今天早上又出现了新的问题


所有依赖无法获取版本,日志中也有好几屏(几十条 “[W] market connect ECONNREFUSED 127.0.0.1:80” 报错)

插件市场可以搜索到插件但是无法修改和添加

也许可以在 auth 插件中增加一个配置项, 不论原有插件是否开放, 均对外部用户不可见, 这个选项可以覆盖所有插件的可见性设置

我也不清楚这是怎么出现的了,到处折腾一下,有时手动增加了一些插件或者修改配置网页就会自动刷新。我现在重启浏览器之后再尝试登出登录,那个只有一个叉叉的提示神奇地消失了。

这样操作并移除 SUPERUSER 权限之后确实可以正常使用了,感谢。(但没有测试过从零开始是否有效)

建议在 database-postgres 插件的 usage 描述中增加对权限要求的描述, 并提醒用户不要直接使用数据库的 SUPERUSER 用户以增加数据库安全性。
确保积极响应 《Koishi 实例安全性公告 》文件的相关政策。

当时我在开发插件,已经 extend 了一个数据表,但是某个字段设计有问题想更改,直接更改字段名之后发现原有字段还残留在数据表中,我想着还没有数据就直接把整个表删除重新创建,然后就使用了这个 drop 方法。

当时的上下文是

export function apply(ctx: Context) {
  ctx.database.drop(‘一个不存在的表’);
  ctx.model.extend("...", { ... });
 }

ctx.database.drop 实际上是一个异步方法,但我当时没有注意到这一点,忘了加 await 关键字,不清楚这个问题是否和异步操作有关。

为什么会 drop 到一个不存在的表?因为有 hmr,我的字没打完就自动重载触发了这个语句。

然后就是不知怎么回事重启 koishi 之后 “koishi” 数据库就被重置了,对于开发者来说这是毁灭性的影响。如果使用了其他插件并存储了一些数据,那么这些数据都会消失。

首先建议 koishi 提高数据库插件自身的 Robustness 和安全性,不管插件开发者怎么折腾都不会把整个数据库重置;插件也许可以做更精细的权限控制,比如默认没有删除表的权限、只能删除由该插件声明的表等等。

其次是完善文档,如果 任何时候都不推荐 插件 使用数据库的 drop 功能,那么应该在 数据库操作 (Database) | Koishi 这个 api 旁边注明他的危险性以及可能的严重后果,增加一个类似插件市场中不安全插件的图标标识。

然后如果可能的话,再出一个数据库备份插件,因为数据无价。

2 个赞

从早上到现在,再去看发现又可以使用了。

但是重启 koishi 之后又不行了,难道又要等一段时间才能刷新出来?

:roll_eyes:

2 个赞

Koishi 的文档接受 PR,该项建议可以直接在文档底部点击”在 GitHub 编辑此页面“反馈修改~

不过我认为在 API 处标注不推荐使用有些欠妥。不推荐 drop 的原因出在设计层,而非 API 本身的行为上。该 API 行为稳定符合预期,清楚其功能后使用并不会产生不可控结果。或许在开发指南的数据库部分新增相关条目更合适。

2 个赞

我确认了源码,ctx.database.drop(‘一个不存在的表’); 不应该造成任何预期外的问题,我也无法复现你的问题。我现在倾向于认为在你hmr时实际上输入了空参数或空字符串作为参数,从而如预期地删除了全表。

至于在此处开发时使用drop,本质和使用外部数据库管理软件进行操作并无区别,这无可厚非。我们不推荐实际生产上的插件使用drop,因为这可能引发全局而不可控的副作用,破坏其他可能使用此表此列的插件的行为,而几乎不存在真正使用drop有意义的场景。而只要不使用drop,就无论如何不应该出现所述将整个数据库重置等对数据造成极大危害的情形。假如需要在版本更迭中进行数据表迁移,我们也有legacy和migrate。

5 个赞

这个反倒是不行的,一个框架最优先需要保证的是开发者的需求,虽然我们不推荐开发者 drop 掉整个数据库,但我们并不应该在代码里阻碍开发者这么做。而我们应当做的就是,在代码中提供这样的功能,但不建议开发者这样使用。


那确实应该是 hmr 导致了数据库 drop,这也是预期的行为。只要文件发生变动,hmr 就会重载新文件的逻辑。


个人认为 drop 操作及其后果应该由开发者学习数据库的过程中了解。作为对比,DataGrip 等世界一流数据库管理软件在 Drop 操作中也没有任何有关危险性的文字或颜色提示。如果需要这类功能的话,不如在进行危险操作的时候使用一个带有此类警告的软件。


插件市场十个月前应该已有开发者发布了这样的插件,并也在本论坛发帖。可以搜索一下。

3 个赞

谢谢大佬们的解答。

空参数时竟然会删除全部表吗?这个我没看到文档中有提到。

GPT 对此给出的回答是:

在 SQL ORM(Object-Relational Mapping,对象关系映射)框架中,drop 函数的行为可以依据具体的 ORM 框架和其版本有所不同。通常,ORM 框架提供了操作数据库的抽象,包括创建、查询、更新和删除数据库表的功能。

对于 drop 函数,它一般用于删除数据库中的表。如果你没有指定具体的表名作为参数,其行为取决于该函数在你使用的 ORM 框架中的具体实现:

  • 在一些 ORM 框架中,如果 drop 函数的参数为空,它可能不会执行任何操作,因为安全机制防止无意中删除所有表。
  • 在其他框架中,调用 drop 函数而不指定具体表名可能会导致一个错误或警告,提示需要明确指定要删除的表。
  • 极少数情况下,如果框架设计允许这种操作,调用 drop 函数而不指定参数可能会删除所有表,但这种设计非常危险,因为它可能导致数据丢失,所以大多数 ORM 框架都不会允许这样做。

我的本意不是想 drop 掉整个数据库,提供这个功能没问题,但不应那么容易地被触发到。特别是开启了 hmr 的情况,可能也有其他开发者刚打了个括号就重载触发 drop 掉了整个数据库。

hmr 是预期的行为,drop 空参数删除全表也是预期行为,但这两结合起来应该不是开发者想看到的。

DataGrip 是专业的数据库管理软件,开发者理应在了解数据库之后才使用它,它假设了开发者具备一定的专业知识。

而 Koishi 是一个聊天机器人框架,封装了很多应用层的东西,Koishi 用户的技术门槛较低,其他开发者可能跟我一样是数据库新手,这时给出必要的警告我觉得是合理的。

3 个赞

你描述的这种行为仅会在 hmr 启用+编辑器实时保存+drop代码在加载时触发 时出现。作为一个开发者,如果其开发环境设置了实时保存,本人应当对其影响有一定了解和预期。Koishi 无法对每个开发者的环境做出假设并一一对应,所以按照更主流的开发习惯默认启用了 hmr,并在开发指南内描述了其行为。我觉得这是比较合理的处理。如果为了取消某种编辑器设置和开发设置叠加导致的不希望产生的行为而修改框架代码或文档,似乎有点本末倒置。自行修改开发环境应该是更合理的处理。

update:

对此说得更有道理。


因为我前述的这种特殊情况出现的稀有性,在 Koishi 现有开发指南已经非常新人友好,而数据库相关接口的描述也非常清晰的前提下,没有这个警告的负面影响应该是非常有限的。不过我支持你向开发指南的数据库相关教程贡献这项警告~

2 个赞

你说得对。原来我们有dropAll,那无参数的drop确实应该是个错误(从类型检查上现在也确实是个错误)。我们会考虑从代码上阻止这一行为。

3 个赞

看了这些讨论,我觉得可以直接把 drop 从文档中删掉(

2 个赞

还有个场景,我的亲身经历。

在使用 hmr 和 ctx.model.extend 时,因为我的键入速度很慢,等我全部键入完成看一眼数据库时,发现了众多由子串组成的表 :sob:

1 个赞

好想吐槽啊……你能不能把 IDE 改成「失焦保存」啊……

这样只有当你离开 IDE 窗口转向其他窗口的时候,hmr 才会重载你的代码

3 个赞

有道理啊,自动保存习惯了 :wink:

2 个赞

所以这位的 IDE 是只要敲了东西就会保存吗?

我的是按 ctrl+S 才会保存的。

5 个赞

是的

3 个赞

那你可能需要关闭 hmr 插件比较好

4 个赞