Permalink
Browse files

Authenticate requests with warden

If the warden instance is availble in the current session, use it to
authenticate the request. Warden is setup outside the hovercraft server
at the rack layer. This just adds a global filter instead of resource or
route specific ones. Closes issue #4
  • Loading branch information...
1 parent 5c4436a commit 12f887f28f00dc4f1b8ab54080c62f6f7975b364 @vanstee committed Jul 30, 2012
View
@@ -92,6 +92,48 @@ extensible at this point. Consider it a proof of concept.
curl -X DELETE http://localhost:9292/employees/1.json
```
+## Authentication
+
+1. Include `warden` in your Gemfile:
+
+ ```ruby
+ gem 'warden'
+ ```
+
+2. Use rack builder to add warden strategies to your rackup file:
+
+ ```ruby
+ # config.ru
+
+ require 'bundler'
+ Bundler.require
+
+ application = Rack::Builder.new do
+ use Rack::Session::Cookie, secret: '...'
+
+ Warden::Strategies.add :password do
+ def valid?
+ ...
+ end
+
+ def authenticate
+ ...
+ end
+ end
+
+ use Warden::Manager do |manager|
+ manager.default_strategies :password
+ manager.failure_app = ...
+ end
+
+ run Hovercraft::Server
+ end
+
+ run application
+ ```
+
+See the [warden project](https://github.com/hassox/warden/) for more in-depth examples or help troubleshooting.
+
## Give Back
1. Fork it:
@@ -1,6 +1,7 @@
require 'hovercraft/loader'
-require 'hovercraft/routes'
require 'hovercraft/helpers'
+require 'hovercraft/filters'
+require 'hovercraft/routes'
require 'sinatra/base'
require 'rack/contrib/post_body_content_type_parser'
require 'forwardable'
@@ -18,23 +19,34 @@ def initialize
def application
application = Sinatra.new
application = configure(application)
+ application = generate_filters(application)
application = generate_routes(application)
application
end
def configure(application)
application.register(Hovercraft::Helpers)
+ application.register(Hovercraft::Filters)
application.register(Hovercraft::Routes)
application.use(Rack::PostBodyContentTypeParser)
application
end
+ def generate_filters(application)
+ Hovercraft::Filters.public_instance_methods.each do |filter|
+ application.send(filter)
+ end
+
+ application
+ end
+
def generate_routes(application)
with_each_model do |model_class, model_name, plural_model_name|
- application.methods.grep(/generate/).each do |action|
- application.send(action, model_class, model_name, plural_model_name)
+ Hovercraft::Routes.public_instance_methods.each do |route|
+ application.send(route, model_class, model_name, plural_model_name)
end
end
+
application
end
end
@@ -0,0 +1,9 @@
+module Hovercraft
+ module Filters
+ def generate_authentication_filter
+ before do
+ authenticate_with_warden
+ end
+ end
+ end
+end
@@ -4,6 +4,14 @@ def self.registered(application)
application.helpers(Hovercraft::Helpers)
end
+ def authenticate_with_warden
+ warden.authenticate! if warden
+ end
+
+ def warden
+ env.fetch('warden')
+ end
+
def respond_with(content)
if content.respond_to?(format_method_name)
content.send(format_method_name)
@@ -13,6 +13,11 @@
end
describe '#application' do
+ before do
+ Hovercraft::Filters.stub(public_instance_methods: [])
+ Hovercraft::Routes.stub(public_instance_methods: [])
+ end
+
it 'creates a sinatra application' do
subject.application.ancestors.should include(Sinatra::Base)
end
@@ -23,6 +28,12 @@
subject.application
end
+ it 'generates filters for the application' do
+ subject.should_receive(:generate_filters)
+
+ subject.application
+ end
+
it 'generates routes for the application' do
subject.should_receive(:generate_routes)
@@ -39,7 +50,13 @@
subject.configure(application)
end
- it 'registers the methods to generate actions' do
+ it 'registers the methods to generate filters' do
+ application.should_receive(:register).with(Hovercraft::Filters)
+
+ subject.configure(application)
+ end
+
+ it 'registers the methods to generate routes' do
application.should_receive(:register).with(Hovercraft::Routes)
subject.configure(application)
@@ -0,0 +1,34 @@
+require 'hovercraft/filters'
+require 'hovercraft/helpers'
+require 'sinatra'
+require 'rack/test'
+
+describe Hovercraft::Filters do
+ include Rack::Test::Methods
+
+ let(:application) { Sinatra.new }
+
+ alias :app :application
+
+ before do
+ application.register(Hovercraft::Helpers)
+ application.register(Hovercraft::Filters)
+ end
+
+ describe '#generate_authentication_filter' do
+ before do
+ application.generate_authentication_filter
+ end
+
+ it 'generates a global filter' do
+ application.filters[:before][0][0] == //
+ end
+
+ it 'authenticates a request' do
+ block = application.filters[:before][0][3]
+ block.should_receive(:[])
+
+ get '/'
+ end
+ end
+end
@@ -15,6 +15,31 @@
end
end
+ describe '#authenticate_with_warden' do
+ let(:warden) { stub(authenticate!: nil) }
+
+ before { subject.stub(warden: warden) }
+
+ it 'uses warden to authenticate' do
+ warden.should_receive(:authenticate!)
+
+ subject.authenticate_with_warden
+ end
+ end
+
+ describe '#warden' do
+ let(:warden) { stub }
+ let(:env) { stub }
+
+ before { subject.stub(env: env) }
+
+ it 'finds the warden instance in the current session' do
+ env.stub(:fetch).with('warden') { warden }
+
+ subject.warden
+ end
+ end
+
describe '#respond_with' do
it 'serializes the content to the preferred format' do
subject.stub(format: :json)

0 comments on commit 12f887f

Please sign in to comment.