在 Heroku 上重置 config/initializers/doorkeeper.rb 中设置的范围
Reset scopes set in config/initializers/doorkeeper.rb on Heroku
我正在尝试在我的 OAuth2 服务中创建一个功能,开发人员可以在其中创建、读取和销毁作用域,以供使用我的服务的应用程序使用。
为了做到这一点,我创建了一个基本的 Scope
模型,我希望 Doorkeeper 更新它的 @optional_scopes
/ @scopes
与用户来的任何范围 creates/destroys。 (注意:范围只有在不使用时才能销毁。)
注意(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 实例中适当更新,我还覆盖了 Doorkeeper 的 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
在创建操作后没有得到适当的重置。
非常感谢您的宝贵时间和帮助!
好吧,好吧,在写这个的过程中,我放慢了脚步,想出了解决办法,就在我眼前……
在覆盖 Doorkeeper 的 self.configuration
方法时,我需要做的就是重置 optional_scopes
而不是 scopes
,因为 scopes
被定义为 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
由于Doorkeeper::OAuth::Scopes
的超级class 的NoMethodError
,这导致我所有的测试都失败,然后我意识到我需要重写该方法以包含数组的elsif。所以,这是该方法:
module OAuth
class Scopes
def +(other)
if other.is_a? Scopes
self.class.from_array(all + other.all)
elsif other.is_a? Array
self.class.from_array(all + other)
else
super(other)
end
end
end
end
可以看到原文here.
我希望所有这些总有一天能对某人有所帮助!
我正在尝试在我的 OAuth2 服务中创建一个功能,开发人员可以在其中创建、读取和销毁作用域,以供使用我的服务的应用程序使用。
为了做到这一点,我创建了一个基本的 Scope
模型,我希望 Doorkeeper 更新它的 @optional_scopes
/ @scopes
与用户来的任何范围 creates/destroys。 (注意:范围只有在不使用时才能销毁。)
注意(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 实例中适当更新,我还覆盖了 Doorkeeper 的 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
在创建操作后没有得到适当的重置。
非常感谢您的宝贵时间和帮助!
好吧,好吧,在写这个的过程中,我放慢了脚步,想出了解决办法,就在我眼前……
在覆盖 Doorkeeper 的 self.configuration
方法时,我需要做的就是重置 optional_scopes
而不是 scopes
,因为 scopes
被定义为 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
由于Doorkeeper::OAuth::Scopes
的超级class 的NoMethodError
,这导致我所有的测试都失败,然后我意识到我需要重写该方法以包含数组的elsif。所以,这是该方法:
module OAuth
class Scopes
def +(other)
if other.is_a? Scopes
self.class.from_array(all + other.all)
elsif other.is_a? Array
self.class.from_array(all + other)
else
super(other)
end
end
end
end
可以看到原文here.
我希望所有这些总有一天能对某人有所帮助!