如何强制执行权限的最佳方式——控制器还是约束?

我有一个插件添加了一个名为 server 的模型,该模型包含一个 user_id 字段。我希望只有 server 的所有者才能执行 POST 请求(或者也许应该是 PUT?——该操作会在其服务器上对 Discourse 实例执行命令行重建;我不确定哪种才是最佳实践)。

config/routes.rb 中是这样写的:

post “/upgrade/:id” => “servers#queue_upgrade”, constraints: PfaffmanagerConstraint.new

建议在 pfaffmanager_constraint.rb 中的 matches? 方法检查 path_parameters[:action] 并在此处强制执行权限,还是在 servers_controller.rb 中执行?

另外,我认为我真正应该做的是将此路由移到 namespace :user 下,所以也许在我弄清楚这一点后,这个问题会随之解决。但目前这个方案几乎可行,我希望尽快让其他人尝试这段代码。

Rails 路由如下:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/config/routes.rb#L12

我的控制器尝试强制执行权限:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L53-L70

但是我的测试用例中,当另一个用户执行 post 请求时却返回了 200 状态码:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L149-L157

我想我需要以某种方式让 Ember 也关注这个问题?

难道你不能将一个方法传递给 before_action 来检查你的条件吗?

我认为权限应该在控制器或约束中强制执行。模型不知道是谁在调用它,我是这么想的。

非常感谢你对此事的思考。

我认为你需要一个守护方法来检查用户是否被允许执行特定操作,例如 can_upgrade_server?

此外,一旦你实现了该方法,就可以使用 guardian.ensure_can_upgrade_server!,它会检查条件并在条件不满足时抛出异常,这正好符合你的需求。

哇!守护者方法!太好了!我会去看看的!谢谢!

唯一使用 guardian 的模型是 user model。看起来 guardian 的大部分操作都在控制器中。

例如,categories 控制器使用了 ensure_can_create_category,我认为这个方法是神奇地在 lib/guardian.rb 中生成的。

但目前,我没有使用 guardian,因为我难以弄清楚如何正确实例化它。我的控制器中有以下内容:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L54-L75

以下是测试它的规范:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L154-L181