2016-10-22 47 views
0

我試圖在OAuth2服務中創建一個功能,開發人員可以在其中創建,讀取和銷燬供其應用程序使用我的服務的範圍。在Heroku的config/initializers/doorkeeper.rb中設置的重置範圍

爲了做到這一點,我創建了一個基本的Scope模型,我希望門衛更新其用戶來創建/銷燬任何範圍的@optional_scopes/@scopes。 (注意:只有在沒有使用的情況下才能銷燬示波器。)

注意(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填充複選框。

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

到:

關注與此代碼跨Heroku的情況下適當地更新,我也重寫了看門的self.configuration方法

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在創建操作後沒有得到適當的重置。

非常感謝您的時間和任何幫助!

回答

0

好了,好了,在寫這篇的過程中,我慢了下來,並想出解決方案,這是對我的鼻子前面...

在看門人的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 

這引起了我所有的測試失敗由於NoMethodError爲超類的Doorkeeper::OAuth::Scopes然後我意識到我需要重新編寫方法,包括陣列的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.

我希望這一切可以幫助別人一天!