warden-oauth2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGU5NWUxMzQzZjJjYTliNjYxY2NiZjJkZDY4NjJjMTUwNTk4NDExMg==
5
+ data.tar.gz: !binary |-
6
+ ZjM1ODEyMDM5ZjYyZTMzMzFjMWNkMThjM2FkNDM0NDVjMjBiOTQ2YQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ODdjNGZhZjFmOTNiM2IyODUzYjZlNzBmZTY1YmI1OWQ5ODJhZTA2YTgwZjUw
10
+ OTUxZTYyYmU2MTIzZjI1MTdiNGEwMjM0MTcyMDU2MTJmOTU2NWIyNzg0OTU1
11
+ Yjc4ODgzYWI1NTM0ZGQzMzVjZjUzNGJiYTkwMWFmNzNiNzc5MDQ=
12
+ data.tar.gz: !binary |-
13
+ NDFhMGJlZWE0N2M2MmE1YjE0YTIzMWUzMDY3ODFmODVhNDMzMThkZjE0YjI4
14
+ MzBjOTNiNjkzNzMwZTVhMDkxYWExMDg2ZTBhODUzMjY0MmY2NWQwMjI1Nzgy
15
+ ZGY0NTBhNzAyZjVhMWVhM2I5ZTcxOGVkZjI5YjEwZjE1ZTMwYWQ=
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.9.2
4
+ - 1.8.7
5
+ - jruby
6
+ - rbx
7
+ script: "bundle exec rake"
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in warden-oauth2.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'guard'
8
+ gem 'guard-rspec'
9
+ gem 'guard-bundler'
10
+ gem 'rb-fsevent'
11
+ gem 'growl'
12
+ gem 'pry'
13
+ end
@@ -0,0 +1,11 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+
8
+ guard 'bundler' do
9
+ watch('Gemfile')
10
+ watch(/^.+\.gemspec/)
11
+ end
@@ -0,0 +1,160 @@
1
+ # Warden::OAuth2 [![CI Status](https://secure.travis-ci.org/opperator/warden-oauth2.png)](http://travis-ci.org/opperator/warden-oauth2)
2
+
3
+ This library provides a robust set of authorization strategies for
4
+ Warden meant to be used to implement an OAuth 2.0 ([draft 22][oauth2])
5
+ provider.
6
+
7
+ ## Usage
8
+
9
+ ### Grape API Example
10
+
11
+ ```ruby
12
+ require 'grape'
13
+ require 'warden-oauth2'
14
+
15
+ class MyAPI < Grape::API
16
+ use Warden::Manager do |config|
17
+ strategies.add :bearer, Warden::OAuth2::Strategies::Bearer
18
+ strategies.add :client, Warden::OAuth2::Strategies::Client
19
+ strategies.add :public, Warden::OAuth2::Strategies::Public
20
+
21
+ config.default_strategies :bearer, :client, :public
22
+ config.failure_app Warden::OAuth2::FailureApp
23
+ end
24
+
25
+ helpers do
26
+ def warden; env['warden'] end
27
+ end
28
+
29
+ resources :hamburgers do
30
+ before do
31
+ warden.authenticate! scope: :hamburgers
32
+ end
33
+ end
34
+ end
35
+ ```
36
+
37
+ ## Configuration
38
+
39
+ You can configure Warden::OAuth2 like so:
40
+
41
+ ```ruby
42
+ Warden::OAuth2.configure do |config|
43
+ config.some_option = some_value
44
+ end
45
+ ```
46
+
47
+ ### Configurable Options
48
+
49
+ * **client_model:** A client application class. See **Models** below.
50
+ Defaults to `ClientApplication`.
51
+ * **token_model:** An access token class. See **Models** below. Defaults
52
+ to `AccessToken`.
53
+
54
+ ## Models
55
+
56
+ You will need to supply data models to back up the persistent facets of
57
+ your OAuth 2.0 implementation. Below are examples of the interfaces that
58
+ each require.
59
+
60
+ ### Client Application
61
+
62
+ ```ruby
63
+ class ClientApplication
64
+ # REQUIRED
65
+ def self.locate(client_id, client_secret = nil)
66
+ # Should return a client application matching the client_id
67
+ # provided, but should ONLY match client_secret if it is
68
+ # provided.
69
+ end
70
+
71
+ # OPTIONAL
72
+ def scope?(scope)
73
+ # True if the client should be able to access the scope passed
74
+ # (usually a symbol) without having an access token.
75
+ end
76
+ end
77
+ ```
78
+
79
+ ### Access Token
80
+
81
+ ```ruby
82
+ class AccessToken
83
+ # REQUIRED
84
+ def self.locate(token_string)
85
+ # Should return an access token matching the string provided.
86
+ # Note that you MAY include expired access tokens in the result
87
+ # of this method so long as you implement an instance #expired?
88
+ # method.
89
+ end
90
+
91
+ # OPTIONAL
92
+ def expired?
93
+ # True if the access token has reached its expiration.
94
+ end
95
+
96
+ # OPTIONAL
97
+ def scope?(scope)
98
+ # True if the scope passed in (usually a symbol) has been authorized
99
+ # for this access token.
100
+ end
101
+ end
102
+ ```
103
+
104
+ ## Strategies
105
+
106
+ ### Bearer
107
+
108
+ This strategy authenticates by trying to find an access token that is
109
+ supplied according to the OAuth 2.0 Bearer Token specification
110
+ ([draft 8][oauth2-bearer]). It does this by first extracting the access
111
+ token in string form and then calling the `.locate` method on your
112
+ access token model (see **Configuration** above).
113
+
114
+ Token-based strategies will also fail if they are expired or lack
115
+ sufficient scope. See **Models** above.
116
+
117
+ **User:** The Warden user is set to the client application returned by
118
+ `.locate`.
119
+
120
+ ### Client
121
+
122
+ This strategy authenticates an OAuth 2.0 client application directly for
123
+ endpoints that don't require a specific user. You might use this
124
+ strategy when you want to create an API for client statistics or if you
125
+ wish to rate limit based on a client application even for publicly
126
+ accessible endpoints.
127
+
128
+ **User:** The Warden user is set to the access token returned by `.locate`.
129
+
130
+ ### Public
131
+
132
+ This strategy succeeds by default and only fails if the authentication
133
+ scope is set and is something other than `:public`.
134
+
135
+ **User:** The Warden user is set to `nil`.
136
+
137
+ [oauth2]: http://tools.ietf.org/html/draft-ietf-oauth-v2-22
138
+ [oauth2-bearer]: http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-08
139
+
140
+ ## License
141
+
142
+ Copyright (C) 2011 by Michael Bleigh and Opperator, Inc.
143
+
144
+ Permission is hereby granted, free of charge, to any person obtaining a copy
145
+ of this software and associated documentation files (the "Software"), to deal
146
+ in the Software without restriction, including without limitation the rights
147
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
148
+ copies of the Software, and to permit persons to whom the Software is
149
+ furnished to do so, subject to the following conditions:
150
+
151
+ The above copyright notice and this permission notice shall be included in
152
+ all copies or substantial portions of the Software.
153
+
154
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
156
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
157
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
158
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
159
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
160
+ THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+ desc "Run specs."
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task :default => :spec
@@ -0,0 +1 @@
1
+ require 'warden/oauth2'
@@ -0,0 +1,32 @@
1
+ require 'warden'
2
+ require 'warden/oauth2/version'
3
+
4
+ module Warden
5
+ module OAuth2
6
+ class Configuration
7
+ attr_accessor :client_model, :token_model
8
+
9
+ def initialize
10
+ self.client_model = ClientApplication if defined?(ClientApplication)
11
+ self.token_model = AccessToken if defined?(AccessToken)
12
+ end
13
+ end
14
+
15
+ def self.config
16
+ @@config ||= Configuration.new
17
+ end
18
+
19
+ def self.configure
20
+ yield config
21
+ end
22
+
23
+ autoload :FailureApp, 'warden/oauth2/failure_app'
24
+ module Strategies
25
+ autoload :Base, 'warden/oauth2/strategies/base'
26
+ autoload :Public, 'warden/oauth2/strategies/public'
27
+ autoload :Token, 'warden/oauth2/strategies/token'
28
+ autoload :Client, 'warden/oauth2/strategies/client'
29
+ autoload :Bearer, 'warden/oauth2/strategies/bearer'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'warden-oauth2'
2
+
3
+ module Warden
4
+ module OAuth2
5
+ class ErrorApp
6
+ def self.call(env)
7
+ new.call(env)
8
+ end
9
+
10
+ def call(env)
11
+ warden = env['warden']
12
+ strategy = warden.winning_strategy
13
+ status = strategy.respond_to?(:error_status) ? strategy.error_status : 401
14
+ headers = {'Content-Type' => 'application/json'}
15
+ headers['X-Accepted-OAuth-Scopes'] = (strategy.scope || :public).to_s
16
+ body = "{\"error\":\"#{strategy.message}}"
17
+
18
+ Rack::Response.new(body, status, headers).finish
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Warden
2
+ module OAuth2
3
+ class FailureApp
4
+ def self.call(env)
5
+ new.call(env)
6
+ end
7
+
8
+ def call(env)
9
+ warden = env['warden']
10
+ strategy = warden.winning_strategy
11
+
12
+ body = '{"error":"' + strategy.message.to_s + '"}'
13
+ status = strategy.error_status rescue 401
14
+ headers = {'Content-Type' => 'application/json'}
15
+
16
+ headers['X-Accepted-OAuth-Scopes'] = (strategy.scope || :public).to_s
17
+
18
+ [status, headers, [body]]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'warden-oauth2'
2
+
3
+ module Warden
4
+ module OAuth2
5
+ module Strategies
6
+ class Base < Warden::Strategies::Base
7
+ def store?
8
+ false
9
+ end
10
+
11
+ def error_status
12
+ 400
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ require 'warden-oauth2'
2
+
3
+ module Warden
4
+ module OAuth2
5
+ module Strategies
6
+ class Bearer < Token
7
+ def valid?
8
+ !!token_string
9
+ end
10
+
11
+ def token_string
12
+ token_string_from_header || token_string_from_request_params
13
+ end
14
+
15
+ def token_string_from_header
16
+ Rack::Auth::AbstractRequest::AUTHORIZATION_KEYS.each do |key|
17
+ if env.key?(key) && token_string = env[key][/^Bearer (.*)/, 1]
18
+ return token_string
19
+ end
20
+ end
21
+ nil
22
+ end
23
+
24
+ def token_string_from_request_params
25
+ params[:access_token]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ require 'warden-oauth2'
2
+ require 'base64'
3
+
4
+ module Warden
5
+ module OAuth2
6
+ module Strategies
7
+ class Client < Base
8
+ attr_reader :client, :client_id, :client_secret
9
+
10
+ def authenticate!
11
+ @client = client_from_http_basic || client_from_request_params
12
+
13
+ if self.client
14
+ fail "insufficient_scope" and return if scope && client.respond_to?(:scope) && !client.scope?(scope)
15
+ success! self.client
16
+ else
17
+ fail "invalid_client"
18
+ end
19
+ end
20
+
21
+ def client_from_http_basic
22
+ return nil unless (env.keys & Rack::Auth::AbstractRequest::AUTHORIZATION_KEYS).any?
23
+ @client_id, @client_secret = *Rack::Auth::Basic::Request.new(env).credentials
24
+ Warden::OAuth2.config.client_model.locate(self.client_id, self.client_secret)
25
+ end
26
+
27
+ def client_from_request_params
28
+ @client_id, @client_secret = params[:client_id], params[:client_secret]
29
+ return nil unless self.client_id
30
+ Warden::OAuth2.config.client_model.locate(@client_id, @client_secret)
31
+ end
32
+
33
+ def public_client?
34
+ client && !client_secret
35
+ end
36
+
37
+ def error_status
38
+ case message
39
+ when "invalid_client" then 401
40
+ when "insufficient_scope" then 403
41
+ else 400
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ require 'warden-oauth2'
2
+
3
+ module Warden
4
+ module OAuth2
5
+ module Strategies
6
+ class Public < Base
7
+ def authenticate!
8
+ if scope && scope.to_sym != :public
9
+ fail! "insufficient_scope" and return
10
+ end
11
+
12
+ success! nil
13
+ end
14
+
15
+ def error_status
16
+ 401
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ require 'warden-oauth2'
2
+
3
+ module Warden
4
+ module OAuth2
5
+ module Strategies
6
+ class Token < Base
7
+ def valid?
8
+ !!token_string
9
+ end
10
+
11
+ def authenticate!
12
+ if token
13
+ fail! "invalid_token" and return if token.respond_to?(:expired?) && token.expired?
14
+ fail! "insufficient_scope" and return if scope && token.respond_to?(:scope?) && !token.scope?(scope)
15
+ success! token
16
+ else
17
+ fail! "invalid_request" and return unless token
18
+ end
19
+ end
20
+
21
+ def token
22
+ Warden::OAuth2.config.token_model.locate(token_string)
23
+ end
24
+
25
+ def token_string
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def error_status
30
+ case message
31
+ when "invalid_token" then 401
32
+ when "insufficient_scope" then 403
33
+ when "invalid_request" then 400
34
+ else 400
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ module Warden
2
+ module OAuth2
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :test
4
+
5
+ require 'rspec'
6
+ require 'rack/test'
7
+
8
+ require 'warden-oauth2'
9
+
10
+ RSpec.configure do |config|
11
+ config.include Rack::Test::Methods
12
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::OAuth2::FailureApp do
4
+ let(:app){ subject }
5
+ let(:warden){ mock(:winning_strategy => @strategy || strategy) }
6
+ let(:strategy){ mock(:message => 'invalid_request') }
7
+
8
+ context 'with all info' do
9
+ before do
10
+ @strategy = mock(:error_status => 502, :message => 'custom', :scope => 'random')
11
+ get '/unauthenticated', {}, 'warden' => warden
12
+ end
13
+
14
+ it 'should set the status from error_status if there is one' do
15
+ last_response.status.should == 502
16
+ end
17
+
18
+ it 'should set the message from the message' do
19
+ last_response.body.should == '{"error":"custom"}'
20
+ end
21
+
22
+ it 'should set the content type' do
23
+ last_response.headers['Content-Type'].should == 'application/json'
24
+ end
25
+
26
+ it 'should set the X-OAuth-Accepted-Scopes header' do
27
+ last_response.headers['X-Accepted-OAuth-Scopes'].should == 'random'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::OAuth2::Strategies::Bearer do
4
+ let(:strategy){ Warden::OAuth2::Strategies::Bearer }
5
+ let(:token_model){ mock(:AccessToken) }
6
+ subject{ strategy.new({'rack.input' => {}}) }
7
+
8
+ before do
9
+ Warden::OAuth2.config.token_model = token_model
10
+ end
11
+
12
+ describe '#token_string_from_header' do
13
+ Rack::Auth::AbstractRequest::AUTHORIZATION_KEYS.each do |key|
14
+ it "should recognize a bearer token in the #{key} environment key" do
15
+ subject.stub!(:env).and_return({key => "Bearer abc"})
16
+ subject.token_string_from_header.should == 'abc'
17
+ end
18
+ end
19
+
20
+ it 'should ignore a non-bearer authorization header' do
21
+ subject.stub!(:env).and_return('HTTP_AUTHORIZATION' => 'Other do do do')
22
+ subject.token_string_from_header.should be_nil
23
+ end
24
+ end
25
+
26
+ describe '#token_string_from_request_params' do
27
+ it 'should pull the :access_token param' do
28
+ subject.stub!(:params).and_return(:access_token => 'abc')
29
+ subject.token_string_from_request_params.should == 'abc'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::OAuth2::Strategies::Client do
4
+ let(:strategy){ Warden::OAuth2::Strategies::Client }
5
+ let(:client_model){ mock(:ClientApplication) }
6
+ subject{ strategy.new({'rack.input' => {}}) }
7
+
8
+ before do
9
+ Warden::OAuth2.config.client_model = client_model
10
+ end
11
+
12
+ describe '#client_from_http_basic' do
13
+ it 'should call through to the client application class locate method' do
14
+ subject.stub!(:env).and_return({
15
+ 'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('id:secret')}"
16
+ })
17
+
18
+ client_model.should_receive(:locate).with('id','secret').and_return("booya")
19
+ subject.client_from_http_basic.should == "booya"
20
+ end
21
+
22
+ it 'should return nil if no HTTP Basic credentials are provided' do
23
+ subject.client_from_http_basic.should be_nil
24
+ end
25
+ end
26
+
27
+ describe '#client_from_request_params' do
28
+ it 'should be nil if no client_id is provided' do
29
+ subject.stub!(:params).and_return({:client_secret => 'abc'})
30
+ subject.client_from_request_params.should be_nil
31
+ end
32
+
33
+ it 'should call through to locate if a client_id is present' do
34
+ subject.stub!(:params).and_return({:client_id => 'abc'})
35
+ client_model.should_receive(:locate).with('abc',nil)
36
+ subject.client_from_request_params
37
+ end
38
+
39
+ it 'should call through to locate if a client_id and secret are present' do
40
+ subject.stub!(:params).and_return({:client_id => 'abc', :client_secret => 'def'})
41
+ client_model.should_receive(:locate).with('abc','def')
42
+ subject.client_from_request_params
43
+ end
44
+ end
45
+
46
+ describe '#authorize!' do
47
+ it 'should succeed if a client is around' do
48
+ client_instance = mock
49
+ client_model.stub!(:locate).and_return(client_instance)
50
+ subject.stub!(:params).and_return(:client_id => 'awesome')
51
+ subject._run!
52
+ subject.user.should == client_instance
53
+ subject.result.should == :success
54
+ end
55
+
56
+ it 'should fail if no credentials are passed' do
57
+ subject._run!
58
+ subject.result.should == :failure
59
+ subject.message.should == "invalid_client"
60
+ subject.error_status.should == 401
61
+ end
62
+
63
+ it 'should fail if insufficient scope is provided' do
64
+ client_model.stub!(:locate).and_return(mock(:respond_to? => true, :scope? => false))
65
+ subject.stub!(:params).and_return(:client_id => 'abc')
66
+ subject.stub!(:scope).and_return(:confidential_client)
67
+ subject._run!
68
+ subject.result.should == :failure
69
+ subject.message.should == "insufficient_scope"
70
+ subject.error_status.should == 403
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::OAuth2::Strategies::Public do
4
+ let(:env){ {'PATH_INFO' => '/resource'} }
5
+ let(:strategy){ Warden::OAuth2::Strategies::Public }
6
+ subject{ strategy.new(env) }
7
+
8
+ it 'should succeed with no scope' do
9
+ subject._run!
10
+ subject.result.should == :success
11
+ end
12
+
13
+ it 'should succeed with a :public scope' do
14
+ subject.stub!(:scope).and_return(:public)
15
+ subject._run!
16
+ subject.result.should == :success
17
+ end
18
+
19
+ it 'should fail and halt with another scope' do
20
+ subject.stub!(:scope).and_return(:user)
21
+ subject._run!
22
+ subject.should be_halted
23
+ subject.message.should == "insufficient_scope"
24
+ subject.result.should == :failure
25
+ end
26
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::OAuth2::Strategies::Token do
4
+ let(:token_model){ mock }
5
+ let(:strategy){ Warden::OAuth2::Strategies::Token }
6
+ subject{ strategy.new({'rack.input' => {}}) }
7
+
8
+ before do
9
+ Warden::OAuth2.config.token_model = token_model
10
+ end
11
+
12
+ describe '#token' do
13
+ it 'should call through to .locate on the token_class with the token string' do
14
+ token_model.should_receive(:locate).with('abc')
15
+ subject.stub!(:token_string).and_return('abc')
16
+ subject.token
17
+ end
18
+ end
19
+
20
+ describe '#authenticate!' do
21
+ it 'should be successful if there is a token' do
22
+ token_instance = mock
23
+ subject.stub!(:token).and_return(token_instance)
24
+ subject._run!
25
+ subject.result.should == :success
26
+ subject.user.should == token_instance
27
+ end
28
+
29
+ it 'should fail if there is not a token' do
30
+ subject.stub!(:token).and_return(nil)
31
+ subject._run!
32
+ subject.result.should == :failure
33
+ subject.message.should == "invalid_request"
34
+ subject.error_status.should == 400
35
+ end
36
+
37
+ it 'should fail if the access token is expired' do
38
+ token_instance = mock(:respond_to? => true, :expired? => true, :scope? => true)
39
+ subject.stub!(:token).and_return(token_instance)
40
+ subject._run!
41
+ subject.result.should == :failure
42
+ subject.message.should == "invalid_token"
43
+ subject.error_status.should == 401
44
+ end
45
+
46
+ it 'should fail if there is insufficient scope' do
47
+ token_instance = mock(:respond_to? => true, :expired? => false, :scope? => false)
48
+ subject.stub!(:token).and_return(token_instance)
49
+ subject.stub!(:scope).and_return(:secret)
50
+ subject._run!
51
+ subject.result.should == :failure
52
+ subject.message.should == "insufficient_scope"
53
+ subject.error_status.should == 403
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/warden/oauth2/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Michael Bleigh"]
6
+ gem.email = ["michael@intridea.com"]
7
+ gem.description = %q{OAuth 2.0 strategies for Warden}
8
+ gem.summary = %q{OAuth 2.0 strategies for Warden}
9
+ gem.homepage = "https://github.com/opperator/warden-oauth2"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "warden-oauth2"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Warden::OAuth2::VERSION
17
+
18
+ gem.add_dependency 'warden'
19
+ gem.add_development_dependency 'rake'
20
+ gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'rack-test'
22
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warden-oauth2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bleigh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: warden
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: OAuth 2.0 strategies for Warden
70
+ email:
71
+ - michael@intridea.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - .travis.yml
79
+ - Gemfile
80
+ - Guardfile
81
+ - README.md
82
+ - Rakefile
83
+ - lib/warden-oauth2.rb
84
+ - lib/warden/oauth2.rb
85
+ - lib/warden/oauth2/error_app.rb
86
+ - lib/warden/oauth2/failure_app.rb
87
+ - lib/warden/oauth2/strategies/base.rb
88
+ - lib/warden/oauth2/strategies/bearer.rb
89
+ - lib/warden/oauth2/strategies/client.rb
90
+ - lib/warden/oauth2/strategies/public.rb
91
+ - lib/warden/oauth2/strategies/token.rb
92
+ - lib/warden/oauth2/version.rb
93
+ - spec/spec_helper.rb
94
+ - spec/warden/oauth2/failure_app_spec.rb
95
+ - spec/warden/oauth2/strategies/bearer_spec.rb
96
+ - spec/warden/oauth2/strategies/client_spec.rb
97
+ - spec/warden/oauth2/strategies/public_spec.rb
98
+ - spec/warden/oauth2/strategies/token_spec.rb
99
+ - warden-oauth2.gemspec
100
+ homepage: https://github.com/opperator/warden-oauth2
101
+ licenses: []
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.0.3
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: OAuth 2.0 strategies for Warden
123
+ test_files:
124
+ - spec/spec_helper.rb
125
+ - spec/warden/oauth2/failure_app_spec.rb
126
+ - spec/warden/oauth2/strategies/bearer_spec.rb
127
+ - spec/warden/oauth2/strategies/client_spec.rb
128
+ - spec/warden/oauth2/strategies/public_spec.rb
129
+ - spec/warden/oauth2/strategies/token_spec.rb