重置在Heroku上的config / initializers / doorkeeper.rb中设置的范围

时间:2016-10-22 00:06:58

标签: ruby-on-rails heroku doorkeeper

我尝试在OAuth2服务中创建一项功能,开发人员可以在其中创建,读取和销毁范围,供其使用我的服务的应用程序使用。

为了做到这一点,我创建了一个基本的Scope模型,我希望Doorkeeper能够用用户来自的任何范围更新其@optional_scopes / @scopes并创建/破坏。 (注意:范围只有在不使用时才能销毁。)

Note(TL; DR):这一切都在开发中完美运行,但它并没有在Heroku上进行生产 - 所以问题的关键在于如何更新Doorkeeper内部的实例变量通常是在应用程序的初始化时设置....如果可能的话就可以了!

我已将初始化程序设置为抓取数据库中的所有范围并将其设置为optional_scopes

config/initializers/doorkeeper.rb:

Doorkeeper.configure do
  ...
  default_scopes :public
  optional_scopes( *Scope.where.not(name: 'public').map{ |s| s.name } )
  ...
end

我有一个基本的控制器用于我的" CRD"范围内有一个过滤器,用于在创建或销毁一个范围列表后重置范围列表:

class ScopesController < ApplicationController
  after_action :set_optional_scopes, only: [ :create, :destroy ]
  ...

  def set_optional_scopes
    Doorkeeper.configuration.instance_variable_set(
      '@optional_scopes',
      Scope.where.not(name: 'public').map{ |s| s.name }
    )
  end
end

在我的链接应用程序的视图中,我有一个范围循环,它为用户提供了用户复选框。 views/doorkeeper/applications/_form.html.erb:

<% Doorkeeper.configuration.optional_scopes.each do |scope| %>
  <%= check_box_tag(
    scope,
    'true',
    application_has_scope?( application, scope.to_s )
  ) %>
  <%= label_tag(
    scope,
    scope.to_s,
    class: 'no-style display-inline-block'
  ) %>
  <br>
<% end %>

请注意我如何调用Doorkeeper.configuration.optional_scopes来填充复选框。

关于在Heroku实例中适当更新此代码的问题,我还覆盖了来自:{/ p>的门卫的self.configuration方法。

module Doorkeeper
  ...
  def self.configuration
    @config || (fail MissingConfiguration)
  end
  ...
end

为:

module Doorkeeper
  def self.configuration
    if @config
      # Reset the scopes every time the config is called
      @config.instance_variable_set(
        '@scopes',
        Scope.all.map{ |s| s.name }
      )
      @config
    else
      (fail MissingConfiguration)
    end
  end
end

因此,正如我上面所说,这在开发中运作良好。但是,在生产中,它无法更新复选框列表,这意味着Doorkeeper.configuration.optional_scopes在创建操作后没有得到适当的重置。

非常感谢你的时间和任何帮助!

1 个答案:

答案 0 :(得分:0)

好吧,好吧,在写这篇文章的过程中,我放慢速度,想出解决方案,这就在我的面前......

在覆盖门卫的self.configuration方法时,我需要做的就是重置optional_scopes而不是scopes,因为scopes被定义为{{1}无论如何。

所以它看起来像这样:

default_scopes + optional_scopes

这导致我的所有测试因def self.configuration if @config # Reset the scopes every time the config is called @config.instance_variable_set( '@optional_scopes', Scope.where.not(name: 'public').map{ |s| s.name } ) @config else (fail MissingConfiguration) end end 的超级类NoMethodError而失败,然后我意识到我需要重写该方法以包含elsif for Array。所以,这是方法:

Doorkeeper::OAuth::Scopes

您可以看到原始的here.

我希望有一天这一切都能帮到某人!