warden_oauth 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/CHANGELOG +6 -0
- data/LICENSE +20 -0
- data/README.rdoc +60 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/warden_oauth.rb +19 -0
- data/lib/warden_oauth/config.rb +43 -0
- data/lib/warden_oauth/errors.rb +9 -0
- data/lib/warden_oauth/manager.rb +43 -0
- data/lib/warden_oauth/strategy.rb +140 -0
- data/lib/warden_oauth/strategy_builder.rb +92 -0
- data/lib/warden_oauth/utils.rb +40 -0
- data/spec/application_runner.rb +11 -0
- data/spec/application_scenario.rb +36 -0
- data/spec/fixtures/authorize_request_token.txt +1 -0
- data/spec/fixtures/unauthorized_request_token.txt +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/warden_oauth/manager_spec.rb +48 -0
- data/spec/warden_oauth/strategy_spec.rb +144 -0
- data/warden_oauth.gemspec +87 -0
- metadata +140 -0
data/.document
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
* 0.0.2 (Oct 1, 2009) Keep the manager out of the business of strategies
|
2
|
+
* Removing the access_token_user_finder from Warden::Manager and adding it to
|
3
|
+
the Warden::StrategyBuilder module
|
4
|
+
|
5
|
+
* 0.0.1 (Sep 16, 2009) The beginning of easy OAuth for Warden
|
6
|
+
* Adding the initial implementation of the warden_oauth gem
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Roman Gonzalez
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
= warden_oauth
|
2
|
+
|
3
|
+
warden_oauth enhances the Warden authentication framework, offering a simple interface for creating
|
4
|
+
oauth strategies.
|
5
|
+
|
6
|
+
== Getting Started
|
7
|
+
|
8
|
+
To get started you just have to require the warden_oauth libraries, and setup the
|
9
|
+
oauth services you would like to have on the <tt>Warden::Manager</tt> middleware declaration:
|
10
|
+
|
11
|
+
Warden::Manager do |manager|
|
12
|
+
manager.failure_app = FailureApp
|
13
|
+
manager.oauth(:twitter) do |twitter|
|
14
|
+
twitter.consumer_secret = <YOUR CONSUMER SECRET>
|
15
|
+
twitter.consumer_key = <YOUR CONSUMER KEY>
|
16
|
+
twitter.options :site => 'http://twitter.com'
|
17
|
+
end
|
18
|
+
manager.default_strategies(:twitter_oauth, :password, :other)
|
19
|
+
end
|
20
|
+
|
21
|
+
== Giving an Access Token fetcher
|
22
|
+
|
23
|
+
Users get identified on a system via an access_token and an access_secret, when a valid access_token is
|
24
|
+
recevied, warden_oauth calls a fetcher declared on <tt>Warden::Manager.access_token_user_finder</tt>.
|
25
|
+
|
26
|
+
Warden::Manager.access_token_user_finder(:twitter) do |access_token|
|
27
|
+
User.find_by_access_token_and_access_secret(access_token.token, access_token.secret)
|
28
|
+
end
|
29
|
+
|
30
|
+
If a user is returned, then this is the user that is going to be authenticated in the session, otherwise the
|
31
|
+
<tt>FailureApp</tt> will be called, you may check the <tt>env['warden.options'][:oauth][:access_token]</tt> to check
|
32
|
+
the original access_token and <em>create a new user</em> from there if desired.
|
33
|
+
|
34
|
+
== Strategy Class info
|
35
|
+
|
36
|
+
When you declare an oauth strategy on the <tt>Warden::Manager</tt> initialization, (e.g. manager.oauth(:service_name))
|
37
|
+
a <tt>Warden::OAuth::Strategy::ServiceName</tt> will be declared, at the same time this class will be registered as
|
38
|
+
<tt>:service_name_oauth</tt> on the <tt>Warden::Strategies</tt>.
|
39
|
+
|
40
|
+
So if we have a declaration like the one of the Getting Started section, we will have an Strategy class
|
41
|
+
called <tt>Warden::OAuth::Strategy::Twitter</tt>, and this will be registered as <tt>:twitter_oauth</tt>.
|
42
|
+
|
43
|
+
== Running the Strategy
|
44
|
+
|
45
|
+
In order to get the strategy running in the app, you have to specify a parameter called warden_oauth_provider
|
46
|
+
with the name of the oauth service you want to start. So for example, if you would like to boot the twitter
|
47
|
+
oauth example given on the "Getting Started" section you just have to specify the parameter on a protected
|
48
|
+
url.
|
49
|
+
|
50
|
+
In Rails:
|
51
|
+
|
52
|
+
link_to 'Twitter Authentication', url_for(login_path(:warden_oauth_provider => 'twitter'))
|
53
|
+
|
54
|
+
== Note on Patches/Pull Requests
|
55
|
+
|
56
|
+
For any error send an email to: romanandreg [at] gmail [dot] com
|
57
|
+
|
58
|
+
== Copyright
|
59
|
+
|
60
|
+
Copyright (c) 2009 Roman Gonzalez. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "warden_oauth"
|
8
|
+
gem.summary = %Q{OAuth Strategy generator for Warden Authentication Framework}
|
9
|
+
gem.description = %Q{
|
10
|
+
warden_oauth will help you create oauth authentication strategies using the oauth
|
11
|
+
helper method on the Warden::Manager config setup
|
12
|
+
}
|
13
|
+
gem.email = "romanandreg@gmail.com"
|
14
|
+
gem.homepage = "http://github.com/roman/warden_oauth"
|
15
|
+
gem.authors = ["Roman Gonzalez"]
|
16
|
+
gem.rubyforge_project = "warden_oauth"
|
17
|
+
gem.add_dependency('warden')
|
18
|
+
gem.add_dependency('oauth')
|
19
|
+
gem.add_development_dependency("rack-test")
|
20
|
+
gem.add_development_dependency("fakeweb")
|
21
|
+
gem.add_development_dependency("rspec")
|
22
|
+
gem.add_development_dependency("yard")
|
23
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
24
|
+
end
|
25
|
+
Jeweler::GemcutterTasks.new
|
26
|
+
rescue LoadError
|
27
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'spec/rake/spectask'
|
31
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
37
|
+
spec.libs << 'lib' << 'spec'
|
38
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
39
|
+
spec.rcov = true
|
40
|
+
end
|
41
|
+
|
42
|
+
task :spec => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :spec
|
45
|
+
|
46
|
+
begin
|
47
|
+
require 'yard'
|
48
|
+
YARD::Rake::YardocTask.new
|
49
|
+
rescue LoadError
|
50
|
+
task :yardoc do
|
51
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
52
|
+
end
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/lib/warden_oauth.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rack"
|
2
|
+
require "warden"
|
3
|
+
require "oauth"
|
4
|
+
|
5
|
+
module Warden
|
6
|
+
module OAuth
|
7
|
+
|
8
|
+
base_path = File.dirname(__FILE__) + "/warden_oauth"
|
9
|
+
|
10
|
+
require base_path + "/errors"
|
11
|
+
autoload :Utils, base_path + '/utils'
|
12
|
+
autoload :StrategyBuilder, base_path + '/strategy_builder'
|
13
|
+
autoload :Strategy, base_path + '/strategy'
|
14
|
+
autoload :Config, base_path + "/config"
|
15
|
+
require base_path + "/manager"
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Warden
|
2
|
+
module OAuth
|
3
|
+
|
4
|
+
#
|
5
|
+
# Holds all the information of the OAuth service.
|
6
|
+
#
|
7
|
+
class Config
|
8
|
+
attr_accessor :provider_name
|
9
|
+
|
10
|
+
def consumer_key(key = nil)
|
11
|
+
unless key.nil?
|
12
|
+
@consumer_key = key
|
13
|
+
end
|
14
|
+
@consumer_key
|
15
|
+
end
|
16
|
+
alias_method :consumer_key=, :consumer_key
|
17
|
+
|
18
|
+
def consumer_secret(secret = nil)
|
19
|
+
unless secret.nil?
|
20
|
+
@consumer_secret = secret
|
21
|
+
end
|
22
|
+
@consumer_secret
|
23
|
+
end
|
24
|
+
alias_method :consumer_secret=, :consumer_secret
|
25
|
+
|
26
|
+
def options(options = nil)
|
27
|
+
unless options.nil?
|
28
|
+
@options = options
|
29
|
+
end
|
30
|
+
@options
|
31
|
+
end
|
32
|
+
alias_method :options=, :options
|
33
|
+
|
34
|
+
def check_requirements
|
35
|
+
if @consumer_key.nil? || @consumer_secret.nil?
|
36
|
+
raise Warden::OAuth::ConfigError.new("You need to specify the consumer key and the consumer secret")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Warden
|
2
|
+
module OAuth
|
3
|
+
|
4
|
+
#
|
5
|
+
# Holds all the extensions made to Warden::Manager in order to create OAuth
|
6
|
+
# consumers.
|
7
|
+
#
|
8
|
+
module Manager
|
9
|
+
|
10
|
+
#
|
11
|
+
# Helps to setup a new OAuth client authentication, to get started you need to define
|
12
|
+
# a service name, and then on the block assign the different values required in order
|
13
|
+
# to boot the OAuth process.
|
14
|
+
# @param [Symbol] service An identifier of the OAuth service
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
#
|
18
|
+
# Warden::Manager.oauth(:twitter) do
|
19
|
+
# consumer_key "<YOUR CONSUMER KEY>"
|
20
|
+
# consumer_secret "<YOUR CONSUMER SECRET>"
|
21
|
+
# options :site => 'http://twitter.com'
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
def oauth(service, &block)
|
25
|
+
config = Warden::OAuth::Config.new
|
26
|
+
if block_given?
|
27
|
+
if block.arity == 1
|
28
|
+
yield config
|
29
|
+
else
|
30
|
+
config.instance_eval(&block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
config.check_requirements
|
34
|
+
config.provider_name = service
|
35
|
+
Warden::OAuth::Strategy.build(service, config)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Warden::Manager.send(:include, Warden::OAuth::Manager)
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Warden
|
2
|
+
module OAuth
|
3
|
+
|
4
|
+
#
|
5
|
+
# Holds all the main logic of the OAuth authentication, all the generated
|
6
|
+
# OAuth classes will extend from this class
|
7
|
+
#
|
8
|
+
class Strategy < Warden::Strategies::Base
|
9
|
+
extend StrategyBuilder
|
10
|
+
|
11
|
+
######################
|
12
|
+
### Strategy Logic ###
|
13
|
+
######################
|
14
|
+
|
15
|
+
#
|
16
|
+
# An OAuth strategy will be valid to execute if:
|
17
|
+
# * A 'warden_oauth_provider' parameter is given, with the name of the OAuth service
|
18
|
+
# * A 'oauth_token' is being receive on the request (response from an OAuth provider)
|
19
|
+
#
|
20
|
+
def valid?
|
21
|
+
(params.include?('warden_oauth_provider') && params['warden_oauth_provider'] == config.provider_name.to_s) ||
|
22
|
+
params.include?('oauth_token')
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# Manages the OAuth authentication process, there can be 3 outcomes from this Strategy:
|
28
|
+
# 1. The OAuth credentials are invalid and the FailureApp is called
|
29
|
+
# 2. The OAuth credentials are valid, but there is no user associated to them. In this case
|
30
|
+
# the FailureApp is called, but the env['warden.options'][:oauth][:access_token] will be
|
31
|
+
# available.
|
32
|
+
# 3. The OAuth credentials are valid, and the user is authenticated successfuly
|
33
|
+
#
|
34
|
+
# @note
|
35
|
+
# If you want to signup users with the twitter credentials, you can manage the creation of a new
|
36
|
+
# user in the FailureApp with the given access_token
|
37
|
+
#
|
38
|
+
def authenticate!
|
39
|
+
if params.include?('warden_oauth_provider')
|
40
|
+
store_request_token_on_session
|
41
|
+
redirect!(request_token.authorize_url)
|
42
|
+
|
43
|
+
elsif params.include?('oauth_token')
|
44
|
+
load_request_token_from_session
|
45
|
+
if missing_stored_token?
|
46
|
+
fail!("There is no OAuth authentication in progress")
|
47
|
+
elsif !stored_token_match_recieved_token?
|
48
|
+
fail!("Received OAuth token didn't match stored OAuth token")
|
49
|
+
else
|
50
|
+
user = find_user_by_access_token(access_token)
|
51
|
+
if user.nil?
|
52
|
+
fail!("User with access token not found")
|
53
|
+
throw_error_with_oauth_info
|
54
|
+
else
|
55
|
+
success!(user)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def fail!(msg) #:nodoc:
|
63
|
+
self.errors.add(service_param_name.to_sym, msg)
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
###################
|
68
|
+
### OAuth Logic ###
|
69
|
+
###################
|
70
|
+
|
71
|
+
def consumer
|
72
|
+
@consumer ||= ::OAuth::Consumer.new(config.consumer_key, config.consumer_secret, config.options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def request_token
|
76
|
+
host_with_port = Warden::OAuth::Utils.host_with_port(request)
|
77
|
+
@request_token ||= consumer.get_request_token(:oauth_callback => host_with_port)
|
78
|
+
end
|
79
|
+
|
80
|
+
def access_token
|
81
|
+
@access_token ||= request_token.get_access_token(:oauth_verifier => params['oauth_verifier'])
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
def find_user_by_access_token(access_token)
|
87
|
+
raise RuntimeError.new(<<-ERROR_MESSAGE) unless self.respond_to?(:_find_user_by_access_token)
|
88
|
+
|
89
|
+
You need to define a finder by access_token for this strategy.
|
90
|
+
Write on the warden initializer the following code:
|
91
|
+
Warden::Strategies[:#{config.provider_name}_oauth].access_token_user_finder do |access_token|
|
92
|
+
# Logic to get your user from an access_token
|
93
|
+
end
|
94
|
+
|
95
|
+
ERROR_MESSAGE
|
96
|
+
self._find_user_by_access_token(access_token)
|
97
|
+
end
|
98
|
+
|
99
|
+
def throw_error_with_oauth_info
|
100
|
+
throw(:warden, :oauth => {
|
101
|
+
self.config.provider_name => {
|
102
|
+
:provider => config.provider_name,
|
103
|
+
:access_token => access_token,
|
104
|
+
:consumer_key => config.consumer_key,
|
105
|
+
:consumer_secret => config.consumer_secret
|
106
|
+
}
|
107
|
+
})
|
108
|
+
end
|
109
|
+
|
110
|
+
def store_request_token_on_session
|
111
|
+
session[:request_token] = request_token.token
|
112
|
+
session[:request_secret] = request_token.secret
|
113
|
+
end
|
114
|
+
|
115
|
+
def load_request_token_from_session
|
116
|
+
token = session.delete(:request_token)
|
117
|
+
secret = session.delete(:request_secret)
|
118
|
+
@request_token = ::OAuth::RequestToken.new(consumer, token, secret)
|
119
|
+
end
|
120
|
+
|
121
|
+
def missing_stored_token?
|
122
|
+
!request_token
|
123
|
+
end
|
124
|
+
|
125
|
+
def stored_token_match_recieved_token?
|
126
|
+
request_token.token == params['oauth_token']
|
127
|
+
end
|
128
|
+
|
129
|
+
def service_param_name
|
130
|
+
'%s_oauth' % config.provider_name
|
131
|
+
end
|
132
|
+
|
133
|
+
def config
|
134
|
+
self.class::CONFIG
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Warden
|
2
|
+
module OAuth
|
3
|
+
|
4
|
+
#
|
5
|
+
# Handles the creation an registration of OAuth strategies based on configuration parameters
|
6
|
+
# via the Warden::Manager.oauth method
|
7
|
+
#
|
8
|
+
module StrategyBuilder
|
9
|
+
extend self
|
10
|
+
|
11
|
+
|
12
|
+
#
|
13
|
+
# Defines the user finder from the access_token for the strategy, receives a block
|
14
|
+
# that will be invoked each time you want to find an user via an access_token in your
|
15
|
+
# system.
|
16
|
+
#
|
17
|
+
# @param blk Block that recieves the access_token as a parameter and will return a user or nil
|
18
|
+
#
|
19
|
+
def access_token_user_finder(&blk)
|
20
|
+
define_method(:_find_user_by_access_token, &blk)
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Manages the creation and registration of the OAuth strategy specified
|
25
|
+
# on the keyword
|
26
|
+
#
|
27
|
+
# @param [Symbol] name of the oauth service
|
28
|
+
# @param [Walruz::Config] configuration specified on the declaration of the oauth service
|
29
|
+
#
|
30
|
+
def build(keyword, config)
|
31
|
+
strategy_class = self.create_oauth_strategy_class(keyword)
|
32
|
+
self.register_oauth_strategy_class(keyword, strategy_class)
|
33
|
+
self.set_oauth_service_info(strategy_class, config)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Creates the OAuth Strategy class from the keyword specified on the declaration of the
|
38
|
+
# oauth service. This class will be namespaced inside Warden::OAuth::Strategy
|
39
|
+
#
|
40
|
+
# @param [Symbol] name of the OAuth service
|
41
|
+
# @return [Class] The class representing the Warden strategy
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
#
|
45
|
+
# self.create_oauth_strategy_class(:twitter) #=> Warden::OAuth::Strategy::Twitter
|
46
|
+
# # will create a class Warden::OAuth::Strategy::Twitter that extends from
|
47
|
+
# # Warden::OAuth::Strategy
|
48
|
+
#
|
49
|
+
def create_oauth_strategy_class(keyword)
|
50
|
+
class_name = Warden::OAuth::Utils.camelize(keyword.to_s)
|
51
|
+
if self.const_defined?(class_name)
|
52
|
+
self.const_get(class_name)
|
53
|
+
else
|
54
|
+
self.const_set(class_name, Class.new(self))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Registers the generated OAuth Strategy in the Warden::Strategies collection, the label
|
60
|
+
# of the strategy will be the given oauth service name plus an '_oauth' postfix
|
61
|
+
#
|
62
|
+
# @param [Symbol] name of the OAuth service
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# manager.oauth(:twitter) { |twitter| ... } # will register a strategy :twitter_oauth
|
66
|
+
#
|
67
|
+
def register_oauth_strategy_class(keyword, strategy_class)
|
68
|
+
keyword_name = "%s_oauth" % keyword.to_s
|
69
|
+
if Warden::Strategies[keyword_name.to_sym].nil?
|
70
|
+
Warden::Strategies.add(keyword_name.to_sym, strategy_class)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Defines a CONFIG constant in the generated class that will hold the configuration information
|
76
|
+
# (consumer_key, consumer_secret and options) of the oauth service.
|
77
|
+
#
|
78
|
+
# @param [Class] strategy class that will hold the configuration info
|
79
|
+
# @param [Warden::OAuth::Config] configuration info of the oauth service
|
80
|
+
#
|
81
|
+
def set_oauth_service_info(strategy_class, config)
|
82
|
+
strategy_class.const_set("CONFIG", config) unless strategy_class.const_defined?("CONFIG")
|
83
|
+
end
|
84
|
+
|
85
|
+
protected :create_oauth_strategy_class,
|
86
|
+
:register_oauth_strategy_class,
|
87
|
+
:set_oauth_service_info
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Warden
|
2
|
+
module OAuth
|
3
|
+
|
4
|
+
#
|
5
|
+
# Contains methods from Rails to avoid unnecessary dependencies
|
6
|
+
#
|
7
|
+
module Utils
|
8
|
+
|
9
|
+
#
|
10
|
+
# Fetched from ActiveSupport::Inflector.camelize to avoid dependencies
|
11
|
+
#
|
12
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
13
|
+
if first_letter_in_uppercase
|
14
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
15
|
+
else
|
16
|
+
lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Fetched from ActionController::Request to avoid dependencies
|
22
|
+
#
|
23
|
+
def host_with_port(request)
|
24
|
+
url = request.scheme + "://"
|
25
|
+
url << request.host
|
26
|
+
|
27
|
+
if request.scheme == "https" && request.port != 443 ||
|
28
|
+
request.scheme == "http" && request.port != 80
|
29
|
+
url << ":#{request.port}"
|
30
|
+
end
|
31
|
+
|
32
|
+
url
|
33
|
+
end
|
34
|
+
|
35
|
+
module_function :camelize, :host_with_port
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'rubygems'
|
4
|
+
require 'warden_oauth'
|
5
|
+
require File.dirname(__FILE__) + "/application_scenario"
|
6
|
+
|
7
|
+
Warden::Manager.access_token_user_finder do |access_token|
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
Rack::Handler::Mongrel.run $app, :Port => '4567'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ClientApp
|
2
|
+
|
3
|
+
def self.call(env)
|
4
|
+
env['warden'].authenticate!
|
5
|
+
[200, {"Content-Type" => 'text/plain'}, "Welcome"]
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
class ErrorApp
|
11
|
+
|
12
|
+
def self.call(env)
|
13
|
+
if env['warden.options'][:oauth].nil?
|
14
|
+
[401, {'Content-Type' => 'text/plain'}, "You are not authenticated"]
|
15
|
+
else
|
16
|
+
access_token = env['warden.options'][:oauth][:access_token]
|
17
|
+
[401, {'Content-Type' => 'text/plain'}, "No user with the given access token"]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
$app = Rack::Builder.new do
|
24
|
+
use Rack::Session::Cookie
|
25
|
+
use Warden::Manager do |manager|
|
26
|
+
manager.oauth(:example) do |example|
|
27
|
+
example.consumer_key "aCOTnTeKniyifcwwF3Mo"
|
28
|
+
example.consumer_secret "dEu91qxWfO0Z4Be1tHGuZ63FzHoUm9mk4Z8rzKa8"
|
29
|
+
example.options :site => 'http://localhost:3000'
|
30
|
+
end
|
31
|
+
manager.default_strategies :example_oauth
|
32
|
+
manager.failure_app = ErrorApp
|
33
|
+
end
|
34
|
+
run ClientApp
|
35
|
+
end if $app.nil?
|
36
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
oauth_token=SylltB94pocC6hex8kr9&oauth_verifier=omPxEkKnnx9ygnu7dd6f
|
@@ -0,0 +1 @@
|
|
1
|
+
oauth_token=SylltB94pocC6hex8kr9&oauth_token_secret=WkU0NDgdOlKeB7arFWJyAQjlaVZEEcH0lhdy1kFs&oauth_callback_confirmed=true
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'rubygems'
|
4
|
+
require 'warden_oauth'
|
5
|
+
require 'spec'
|
6
|
+
require 'fakeweb'
|
7
|
+
require 'spec/autorun'
|
8
|
+
|
9
|
+
require File.dirname(__FILE__) + "/application_scenario"
|
10
|
+
|
11
|
+
Spec::Runner.configure do |config|
|
12
|
+
config.before(:all) do
|
13
|
+
FakeWeb.allow_net_connect = false
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Warden::Manager do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
failure_app = lambda { |env| "Failure" }
|
7
|
+
@manager = Warden::Manager.new(nil, :failure_app => failure_app)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should respond to an `oauth` message" do
|
11
|
+
@manager.should respond_to(:oauth)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#oauth" do
|
15
|
+
|
16
|
+
describe "when initialize" do
|
17
|
+
|
18
|
+
it "should require setting the consumer_key" do
|
19
|
+
lambda do
|
20
|
+
@manager.oauth(:service) do |service|
|
21
|
+
service.consumer_secret "ABC"
|
22
|
+
end
|
23
|
+
end.should raise_error(Warden::OAuth::ConfigError, "You need to specify the consumer key and the consumer secret")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should require setting the consumer_secret" do
|
27
|
+
lambda do
|
28
|
+
@manager.oauth(:service) do |service|
|
29
|
+
service.consumer_key "ABC"
|
30
|
+
end
|
31
|
+
end.should raise_error(Warden::OAuth::ConfigError, "You need to specify the consumer key and the consumer secret")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should create a new instance of strategy" do
|
35
|
+
@manager.oauth(:service) do |service|
|
36
|
+
service.consumer_key "ABC"
|
37
|
+
service.consumer_secret "123"
|
38
|
+
end
|
39
|
+
lambda do
|
40
|
+
Warden::OAuth::Strategy::Service
|
41
|
+
end.should_not raise_error(NameError)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
require "rack/test"
|
3
|
+
|
4
|
+
describe Warden::OAuth::Strategy do
|
5
|
+
|
6
|
+
def fixture_response(name)
|
7
|
+
filename = File.dirname(__FILE__) + "/../fixtures/%s.txt" % name
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.build' do
|
11
|
+
before(:each) do
|
12
|
+
@config = Warden::OAuth::Config.new
|
13
|
+
@config.consumer_key "ABC"
|
14
|
+
@config.consumer_secret "123"
|
15
|
+
@config.options :site => 'http://service.com'
|
16
|
+
Warden::OAuth::Strategy.send(:remove_const, "Service") if Warden::OAuth::Strategy.const_defined?("Service")
|
17
|
+
Warden::Strategies.clear!
|
18
|
+
Warden::OAuth::Strategy.build(:service, @config)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should create a new instance that extends from Warden::OAuth::Strategy" do
|
22
|
+
Warden::OAuth::Strategy.const_defined?("Service").should be_true
|
23
|
+
(Warden::OAuth::Strategy::Service < Warden::OAuth::Strategy).should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should register the oauth service key on the Warden strategies with `_oauth` appended" do
|
27
|
+
Warden::Strategies[:service_oauth].should_not be_nil
|
28
|
+
Warden::OAuth::Strategy::Service.should_not be_nil
|
29
|
+
Warden::Strategies[:service_oauth].should == Warden::OAuth::Strategy::Service
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should assign the oauth_service config as a constant" do
|
33
|
+
Warden::OAuth::Strategy::Service::CONFIG.should_not be_nil
|
34
|
+
Warden::OAuth::Strategy::Service::CONFIG.should == @config
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "when invoking the strategy" do
|
40
|
+
|
41
|
+
before(:each) do
|
42
|
+
@request = Rack::MockRequest.new($app)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe "without warden_oauth_service nor oauth_token parameter" do
|
47
|
+
|
48
|
+
before(:each) do
|
49
|
+
@response = @request.get("/")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should render the failure app response" do
|
53
|
+
@response.body.should == "You are not authenticated"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "with a warden_oauth_provider parameter" do
|
59
|
+
|
60
|
+
before(:each) do
|
61
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/request_token',
|
62
|
+
:body => fixture_response("unauthorized_request_token"))
|
63
|
+
@response = @request.get("/", :input => 'warden_oauth_provider=example')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should redirect to the authorize url" do
|
67
|
+
@response.headers['Location'].should =~ %r"http://localhost:3000/oauth/authorize"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "when receiving a valid oauth response" do
|
73
|
+
include Rack::Test::Methods
|
74
|
+
|
75
|
+
def app
|
76
|
+
$app
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "and the access_token_finder hasn't been declared" do
|
80
|
+
|
81
|
+
before(:each) do
|
82
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/request_token',
|
83
|
+
:body => fixture_response("unauthorized_request_token"))
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should raise an exception saying that the access_token_finder is not declared" do
|
87
|
+
get "/", 'warden_oauth_provider' => 'example'
|
88
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/access_token',
|
89
|
+
:body => 'oauth_token=ABC&oauth_token_secret=123')
|
90
|
+
lambda do
|
91
|
+
get "/", 'oauth_token' => "SylltB94pocC6hex8kr9",
|
92
|
+
'oauth_verifier' => "omPxEkKnnx9ygnu7dd6f"
|
93
|
+
end.should raise_error(RuntimeError, /strategy/)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "and the access_token_finder has been declared" do
|
99
|
+
|
100
|
+
before(:each) do
|
101
|
+
Warden::Strategies[:example_oauth].access_token_user_finder do |access_token|
|
102
|
+
Object.new if access_token.token == 'ABC' && access_token.secret == '123'
|
103
|
+
end
|
104
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/request_token',
|
105
|
+
:body => fixture_response("unauthorized_request_token"))
|
106
|
+
get "/", 'warden_oauth_provider' => 'example'
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "and the user is not found" do
|
110
|
+
|
111
|
+
before(:each) do
|
112
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/access_token',
|
113
|
+
:body => 'oauth_token=ABD&oauth_token_secret=122')
|
114
|
+
get "/", 'oauth_token' => "SylltB94pocC6hex8kr9",
|
115
|
+
'oauth_verifier' => "omPxEkKnnx9ygnu7dd6f"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should invoke the fail app" do
|
119
|
+
last_response.body.should == "No user with the given access token"
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "and the user is found" do
|
125
|
+
|
126
|
+
before(:each) do
|
127
|
+
FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/access_token',
|
128
|
+
:body => 'oauth_token=ABC&oauth_token_secret=123')
|
129
|
+
get "/", 'oauth_token' => "SylltB94pocC6hex8kr9",
|
130
|
+
'oauth_verifier' => "omPxEkKnnx9ygnu7dd6f"
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should go to the desired app" do
|
134
|
+
last_response.body.should == "Welcome"
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{warden_oauth}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Roman Gonzalez"]
|
12
|
+
s.date = %q{2009-11-02}
|
13
|
+
s.description = %q{
|
14
|
+
warden_oauth will help you create oauth authentication strategies using the oauth
|
15
|
+
helper method on the Warden::Manager config setup
|
16
|
+
}
|
17
|
+
s.email = %q{romanandreg@gmail.com}
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"LICENSE",
|
20
|
+
"README.rdoc"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
".gitignore",
|
25
|
+
"CHANGELOG",
|
26
|
+
"LICENSE",
|
27
|
+
"README.rdoc",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"lib/warden_oauth.rb",
|
31
|
+
"lib/warden_oauth/config.rb",
|
32
|
+
"lib/warden_oauth/errors.rb",
|
33
|
+
"lib/warden_oauth/manager.rb",
|
34
|
+
"lib/warden_oauth/strategy.rb",
|
35
|
+
"lib/warden_oauth/strategy_builder.rb",
|
36
|
+
"lib/warden_oauth/utils.rb",
|
37
|
+
"spec/application_runner.rb",
|
38
|
+
"spec/application_scenario.rb",
|
39
|
+
"spec/fixtures/authorize_request_token.txt",
|
40
|
+
"spec/fixtures/unauthorized_request_token.txt",
|
41
|
+
"spec/spec_helper.rb",
|
42
|
+
"spec/warden_oauth/manager_spec.rb",
|
43
|
+
"spec/warden_oauth/strategy_spec.rb",
|
44
|
+
"warden_oauth.gemspec"
|
45
|
+
]
|
46
|
+
s.homepage = %q{http://github.com/roman/warden_oauth}
|
47
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
48
|
+
s.require_paths = ["lib"]
|
49
|
+
s.rubyforge_project = %q{warden_oauth}
|
50
|
+
s.rubygems_version = %q{1.3.5}
|
51
|
+
s.summary = %q{OAuth Strategy generator for Warden Authentication Framework}
|
52
|
+
s.test_files = [
|
53
|
+
"spec/application_runner.rb",
|
54
|
+
"spec/application_scenario.rb",
|
55
|
+
"spec/spec_helper.rb",
|
56
|
+
"spec/warden_oauth/manager_spec.rb",
|
57
|
+
"spec/warden_oauth/strategy_spec.rb"
|
58
|
+
]
|
59
|
+
|
60
|
+
if s.respond_to? :specification_version then
|
61
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
62
|
+
s.specification_version = 3
|
63
|
+
|
64
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
65
|
+
s.add_runtime_dependency(%q<warden>, [">= 0"])
|
66
|
+
s.add_runtime_dependency(%q<oauth>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<warden>, [">= 0"])
|
73
|
+
s.add_dependency(%q<oauth>, [">= 0"])
|
74
|
+
s.add_dependency(%q<rack-test>, [">= 0"])
|
75
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
76
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
77
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
78
|
+
end
|
79
|
+
else
|
80
|
+
s.add_dependency(%q<warden>, [">= 0"])
|
81
|
+
s.add_dependency(%q<oauth>, [">= 0"])
|
82
|
+
s.add_dependency(%q<rack-test>, [">= 0"])
|
83
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
84
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
85
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
86
|
+
end
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: warden_oauth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roman Gonzalez
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-02 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: warden
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: oauth
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rack-test
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: fakeweb
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
type: :development
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: yard
|
67
|
+
type: :development
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
description: " \n warden_oauth will help you create oauth authentication strategies using the oauth\n helper method on the Warden::Manager config setup\n "
|
76
|
+
email: romanandreg@gmail.com
|
77
|
+
executables: []
|
78
|
+
|
79
|
+
extensions: []
|
80
|
+
|
81
|
+
extra_rdoc_files:
|
82
|
+
- LICENSE
|
83
|
+
- README.rdoc
|
84
|
+
files:
|
85
|
+
- .document
|
86
|
+
- .gitignore
|
87
|
+
- CHANGELOG
|
88
|
+
- LICENSE
|
89
|
+
- README.rdoc
|
90
|
+
- Rakefile
|
91
|
+
- VERSION
|
92
|
+
- lib/warden_oauth.rb
|
93
|
+
- lib/warden_oauth/config.rb
|
94
|
+
- lib/warden_oauth/errors.rb
|
95
|
+
- lib/warden_oauth/manager.rb
|
96
|
+
- lib/warden_oauth/strategy.rb
|
97
|
+
- lib/warden_oauth/strategy_builder.rb
|
98
|
+
- lib/warden_oauth/utils.rb
|
99
|
+
- spec/application_runner.rb
|
100
|
+
- spec/application_scenario.rb
|
101
|
+
- spec/fixtures/authorize_request_token.txt
|
102
|
+
- spec/fixtures/unauthorized_request_token.txt
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
- spec/warden_oauth/manager_spec.rb
|
105
|
+
- spec/warden_oauth/strategy_spec.rb
|
106
|
+
- warden_oauth.gemspec
|
107
|
+
has_rdoc: true
|
108
|
+
homepage: http://github.com/roman/warden_oauth
|
109
|
+
licenses: []
|
110
|
+
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options:
|
113
|
+
- --charset=UTF-8
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: "0"
|
121
|
+
version:
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: "0"
|
127
|
+
version:
|
128
|
+
requirements: []
|
129
|
+
|
130
|
+
rubyforge_project: warden_oauth
|
131
|
+
rubygems_version: 1.3.5
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: OAuth Strategy generator for Warden Authentication Framework
|
135
|
+
test_files:
|
136
|
+
- spec/application_runner.rb
|
137
|
+
- spec/application_scenario.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/warden_oauth/manager_spec.rb
|
140
|
+
- spec/warden_oauth/strategy_spec.rb
|