你如何授权访问由控制器处理的页面,而没有相应的模型与 Cancancan?

How do you authorize access to a page dealed by a controller without corresponding model with Cancancan?

问题

没有对应型号的Spree管理控制器,其访问试用重定向到其他页面。

对应的尝试码:

module Spree
  module Admin
    class TutorialsController < Spree::Admin::BaseController
      authorize_resource :class => false

      def index
      end
    end
  end
end

并在 app/models/spree/ability_decorator.rb 中添加了以下内容:

  can :manage, :'tutorial'
  can :manage, :'admin/tutorial'
  can :manage, :'admin_tutorial'
  can :manage, :'spree/admin/tutorial'
  can :manage, :'spree_admin_tutorial'

但这些授权中的 none 可以解决问题。当然,在此位置添加 can :manage, :all 将使页面可按需要访问,因此这绝对是接近所需但不太宽松的解决方案,在此寻找。即使在控制器中使用 skip_authorization_check 也无济于事,请求将被重定向到 admin/products 以及这些相应的初始日志:

Started GET "/admin/tutorials" for 127.0.0.1 at 2020-04-30 17:11:28 +0200                                                                                                                     
Processing by Spree::Admin::TutorialsController#index as HTML                                                                                                                                 
  Spree::Preference Load (2.9ms)  SELECT  "spree_preferences".* FROM "spree_preferences" WHERE "spree_preferences"."key" =  LIMIT   [["key", "spree/backend_configuration/locale"], ["LIMI
T", 1]]                                                                                                                                                                                       
  ↳ /home/psychoslave/.rvm/gems/ruby-2.5.1@project/bundler/gems/spree_i18n-a03ecad00a1e/lib/spree_i18n/controller_locale_helper.rb:21                                                    
  Spree::User Load (3.2ms)  SELECT  "spree_users".* FROM "spree_users" WHERE "spree_users"."deleted_at" IS NULL AND "spree_users"."id" =  ORDER BY "spree_users"."id" ASC LIMIT   [["id", 
194], ["LIMIT", 1]]                                                                                                                                                                           
  ↳ /home/psychoslave/.rvm/gems/ruby-2.5.1@project/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98                                                                        
  Spree::Role Load (3.4ms)  SELECT "spree_roles".* FROM "spree_roles" INNER JOIN "spree_role_users" ON "spree_roles"."id" = "spree_role_users"."role_id" WHERE "spree_role_users"."user_id" = 
  [["user_id", 194]]                                                                                                                                                                        
  ↳ /home/psychoslave/.rvm/gems/ruby-2.5.1@project/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98                                                                        
  Spree::Producer Load (2.6ms)  SELECT  "spree_producers".* FROM "spree_producers" WHERE "spree_producers"."id" =  LIMIT   [["id", 16], ["LIMIT", 1]]
  ↳ app/models/spree/ability_decorator.rb:123                                                  
Redirected to http://localhost:5000/forbidden                                                                                                                                                 
Completed 302 Found in 80ms (ActiveRecord: 41.4ms)

经过几次其他重定向后,请求指向前面所述的路径。

相关资源

毕竟在这种情况下不需要特殊能力。与 Spree::Admin::BaseController 不同,Spree::BaseController 设置了授予目标访问权限的正确权限。为了保持 CSS 风格一致,需要明确的 layout 声明。

module Spree
  module Admin
    class TutorialsController < Spree::BaseController
      layout 'spree/layouts/admin'
      def index; end
    end
  end
end