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 ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
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
@@ -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,9 @@
1
+ module Warden
2
+ module OAuth
3
+
4
+ class ConfigError < ArgumentError; end
5
+ class ServiceAlreadyRegistered < StandardError; end
6
+ class AccessTokenFinderMissing < StandardError; end
7
+
8
+ end
9
+ 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
@@ -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