2014-03-13 97 views
1

我有一個Sinatra應用程序,所有路線默認情況下都需要用戶登錄。事情是這樣的:過濾條件前

before do 
    env['warden'].authenticate! 
end 

get :index do 
    render :index 
end 

現在我想用一個自定義的西納特拉條件作出例外,但如果條件爲真,我無法找到一個方法來讀取/假/零

def self.public(enable) 
    condition { 
    if enable 
     puts 'yes' 
    else 
     puts 'no' 
    end 
    } 
end 

before do 
    # unless public? 
    env['warden'].authenticate! 
end 

get :index do 
    render :index 
end 

get :foo, :public => true do 
    render :index 
end 

由於即使條件未定義,也必須進行身份驗證檢查,但我仍然必須使用before篩選器,但我不確定如何訪問我的自定義條件。

+0

公共方法在上下文之前不可用,因爲它被定義爲類方法。你有沒有檢查方法被定義爲實例方法(沒有自己)? – MikeZ

+0

如果我將方法定義爲實例(沒有自己),那麼我將無法將其用作規則條件,並且我想保留在DSL中編寫公共URL的方式。在閱讀請求對象的條件之前,我正在考慮**,或者將** public => false **作爲任何規則的默認條件。無論如何,我只是想簡單地指定一些默認規則的例外。 – SystematicFrank

+0

我注意到的是,條件似乎在**過濾器之後被解析**,那是當我用完想法時的一點。 – SystematicFrank

回答

1

我用Sinatra的helpers和Sinatra的internals來解決這個問題。我認爲這應該適用於您:

helpers do 
    def skip_authentication? 
    possible_routes = self.class.routes[request.request_method] 

    possible_routes.any? do |pattern, _, conditions, _| 
     pattern.match(request.path_info) && 
     conditions.any? {|c| c.name == :authentication } 
    end 
    end 
end 

before do 
    skip_authentication? || env['warden'].authenticate! 
end 

set(:authentication) do |enabled| 
    condition(:authentication) { true } unless enabled 
end 

get :index do 
    render :index 
end 

get :foo, authentication: false do 
    render :index 
end