2014-03-13 41 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