summary refs log tree commit
diff options
context:
space:
mode:
authorJames Tucker <jftucker@gmail.com>2013-01-13 13:10:20 -0800
committerJames Tucker <jftucker@gmail.com>2013-01-13 13:27:44 -0800
commit87df8796a6e4555ec8fd3817c419c6b44b7ca459 (patch)
tree85c6566b3989ea69de9fbd8f617021d6c33ff5e0
parent9974169974dd947f45d203969bf9d2a4d6ab2aef (diff)
downloadrack-87df8796a6e4555ec8fd3817c419c6b44b7ca459.tar.gz
Reimplement auth scheme fix
 * Add Rack::Auth.add_scheme to enable folks to fix anything that breaks
 * Add common auth schemes, MS ones, AWS ones, etc are missing, as unlikely
 * Checked Rails - they don't use our authorization code
 * Checked Warden - uses rails
 * Checked Omniauth - uses rails
 * Checked doorkeeper - users rails
 * Checked rack-authentication - does it's own thing
 * Checked warden-oauth - doesn't do headers
 * Checked devise - uses rails
 * Checked oauth2-rack - header creation only
 * Checked rack-oauth2-server - does it's own thing
 * Probably missed a bunch, but that'll have to do
-rw-r--r--lib/rack.rb12
-rw-r--r--lib/rack/auth/abstract/request.rb6
-rw-r--r--test/spec_auth.rb57
3 files changed, 74 insertions, 1 deletions
diff --git a/lib/rack.rb b/lib/rack.rb
index acfcb5ac..18d50971 100644
--- a/lib/rack.rb
+++ b/lib/rack.rb
@@ -73,6 +73,18 @@ module Rack
       autoload :Params, "rack/auth/digest/params"
       autoload :Request, "rack/auth/digest/request"
     end
+
+    # Not all of the following schemes are "standards", but they are used often.
+    @schemes = %w[basic digest bearer mac token oauth oauth2]
+
+    def self.add_scheme scheme
+      @schemes << scheme
+      @schemes.uniq!
+    end
+
+    def self.schemes
+      @schemes.dup
+    end
   end
 
   module Session
diff --git a/lib/rack/auth/abstract/request.rb b/lib/rack/auth/abstract/request.rb
index 9e15c720..c1553bf7 100644
--- a/lib/rack/auth/abstract/request.rb
+++ b/lib/rack/auth/abstract/request.rb
@@ -21,7 +21,11 @@ module Rack
       end
 
       def scheme
-        @scheme ||= parts.first.downcase.to_sym
+        @scheme ||=
+          begin
+            s = parts.first.downcase
+            Rack::Auth.schemes.include?(s) ? s.to_sym : s
+          end
       end
 
       def params
diff --git a/test/spec_auth.rb b/test/spec_auth.rb
new file mode 100644
index 00000000..6588bd12
--- /dev/null
+++ b/test/spec_auth.rb
@@ -0,0 +1,57 @@
+require 'rack'
+
+describe Rack::Auth do
+  it "should have all common authentication schemes" do
+    Rack::Auth.schemes.should.include? 'basic'
+    Rack::Auth.schemes.should.include? 'digest'
+    Rack::Auth.schemes.should.include? 'bearer'
+    Rack::Auth.schemes.should.include? 'token'
+  end
+
+  it "should allow registration of new auth schemes" do
+    Rack::Auth.schemes.should.not.include "test"
+    Rack::Auth.add_scheme "test"
+    Rack::Auth.schemes.should.include "test"
+  end
+end
+
+describe Rack::Auth::AbstractRequest do
+  it "should symbolize known auth schemes" do
+    env = Rack::MockRequest.env_for('/')
+    env['HTTP_AUTHORIZATION'] = 'Basic aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :basic
+
+
+    env['HTTP_AUTHORIZATION'] = 'Digest aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :digest
+
+    env['HTTP_AUTHORIZATION'] = 'Bearer aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :bearer
+
+    env['HTTP_AUTHORIZATION'] = 'MAC aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :mac
+
+    env['HTTP_AUTHORIZATION'] = 'Token aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :token
+
+    env['HTTP_AUTHORIZATION'] = 'OAuth aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :oauth
+
+    env['HTTP_AUTHORIZATION'] = 'OAuth2 aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == :oauth2
+  end
+
+  it "should not symbolize unknown auth schemes" do
+    env = Rack::MockRequest.env_for('/')
+    env['HTTP_AUTHORIZATION'] = 'magic aXJyZXNwb25zaWJsZQ=='
+    req = Rack::Auth::AbstractRequest.new(env)
+    req.scheme.should == "magic"
+  end
+end