roman-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,2 @@
1
+ * 0.0.1 (Sep 16, 2009) The beginning of easy OAuth for Warden
2
+ * 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,55 @@
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::RubyforgeTasks.new do |rubyforge|
26
+ rubyforge.doc_task = "yardoc"
27
+ end
28
+ rescue LoadError
29
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
+ end
31
+
32
+ require 'spec/rake/spectask'
33
+ Spec::Rake::SpecTask.new(:spec) do |spec|
34
+ spec.libs << 'lib' << 'spec'
35
+ spec.spec_files = FileList['spec/**/*_spec.rb']
36
+ end
37
+
38
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
39
+ spec.libs << 'lib' << 'spec'
40
+ spec.pattern = 'spec/**/*_spec.rb'
41
+ spec.rcov = true
42
+ end
43
+
44
+ task :spec => :check_dependencies
45
+
46
+ task :default => :spec
47
+
48
+ begin
49
+ require 'yard'
50
+ YARD::Rake::YardocTask.new
51
+ rescue LoadError
52
+ task :yardoc do
53
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
54
+ end
55
+ 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,72 @@
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
+ def self.included(base) #:nodoc:
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ #
15
+ # Helps to setup a new OAuth client authentication, to get started you need to define
16
+ # a service name, and then on the block assign the different values required in order
17
+ # to boot the OAuth process.
18
+ # @param [Symbol] service An identifier of the OAuth service
19
+ #
20
+ # @example
21
+ #
22
+ # Warden::Manager.oauth(:twitter) do
23
+ # consumer_key "<YOUR CONSUMER KEY>"
24
+ # consumer_secret "<YOUR CONSUMER SECRET>"
25
+ # options :site => 'http://twitter.com'
26
+ # end
27
+ #
28
+ def oauth(service, &block)
29
+ config = Warden::OAuth::Config.new
30
+ if block_given?
31
+ if block.arity == 1
32
+ yield config
33
+ else
34
+ config.instance_eval(&block)
35
+ end
36
+ end
37
+ config.check_requirements
38
+ config.provider_name = service
39
+ Warden::OAuth::Strategy.build(service, config)
40
+ end
41
+
42
+ module ClassMethods
43
+
44
+ #
45
+ # Assigns a block that handles how to find a User given an access_token.
46
+ # @param [Symbol] oauth_service The identifier specified on Warden::Manager.oauth
47
+ #
48
+ # @example
49
+ # Warden::Manager.access_token_user_finder(:twitter) do |access_token|
50
+ # # Find user with access_token
51
+ # end
52
+ #
53
+ def access_token_user_finder(oauth_service, &block)
54
+ raise Warden::OAuth::AccessTokenFinderMissing.new("You need to specify a block for Warden::Manager.acess_token_user_finder") unless block_given?
55
+ raise Warden::OAuth::AccessTokenFinderMissing.new("You need to specify a block for Warden::Manager.access_token_user_finder, this must receive one parameter") if block.arity != 1
56
+ @find_user_by_access_token ||= {}
57
+ @find_user_by_access_token[oauth_service] = block
58
+ end
59
+
60
+ def find_user_by_access_token(oauth_service, access_token) #:nodoc:
61
+ raise Warden::OAuth::AccessTokenFinderMissing.new("You need to specify a block for Warden::Manager.acess_token_user_finder") if @find_user_by_access_token.nil?
62
+ @find_user_by_access_token[oauth_service].call(access_token)
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+
72
+ Warden::Manager.send(:include, Warden::OAuth::Manager)
@@ -0,0 +1,127 @@
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 = Warden::Manager.find_user_by_access_token(config.provider_name , 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 throw_error_with_oauth_info
87
+ throw(:warden, :oauth => {
88
+ self.config.provider_name => {
89
+ :provider => config.provider_name,
90
+ :access_token => access_token,
91
+ :consumer_key => config.consumer_key,
92
+ :consumer_secret => config.consumer_secret
93
+ }
94
+ })
95
+ end
96
+
97
+ def store_request_token_on_session
98
+ session[:request_token] = request_token.token
99
+ session[:request_secret] = request_token.secret
100
+ end
101
+
102
+ def load_request_token_from_session
103
+ token = session.delete(:request_token)
104
+ secret = session.delete(:request_secret)
105
+ @request_token = ::OAuth::RequestToken.new(consumer, token, secret)
106
+ end
107
+
108
+ def missing_stored_token?
109
+ !request_token
110
+ end
111
+
112
+ def stored_token_match_recieved_token?
113
+ request_token.token == params['oauth_token']
114
+ end
115
+
116
+ def service_param_name
117
+ '%s_oauth' % config.provider_name
118
+ end
119
+
120
+ def config
121
+ self.class::CONFIG
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,80 @@
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
+ # Manages the creation and registration of the OAuth strategy specified
13
+ # on the keyword
14
+ #
15
+ # @param [Symbol] name of the oauth service
16
+ # @param [Walruz::Config] configuration specified on the declaration of the oauth service
17
+ #
18
+ def build(keyword, config)
19
+ strategy_class = self.create_oauth_strategy_class(keyword)
20
+ self.register_oauth_strategy_class(keyword, strategy_class)
21
+ self.set_oauth_service_info(strategy_class, config)
22
+ end
23
+
24
+ #
25
+ # Creates the OAuth Strategy class from the keyword specified on the declaration of the
26
+ # oauth service. This class will be namespaced inside Warden::OAuth::Strategy
27
+ #
28
+ # @param [Symbol] name of the OAuth service
29
+ # @return [Class] The class representing the Warden strategy
30
+ #
31
+ # @example
32
+ #
33
+ # self.create_oauth_strategy_class(:twitter) #=> Warden::OAuth::Strategy::Twitter
34
+ # # will create a class Warden::OAuth::Strategy::Twitter that extends from
35
+ # # Warden::OAuth::Strategy
36
+ #
37
+ def create_oauth_strategy_class(keyword)
38
+ class_name = Warden::OAuth::Utils.camelize(keyword.to_s)
39
+ if self.const_defined?(class_name)
40
+ self.const_get(class_name)
41
+ else
42
+ self.const_set(class_name, Class.new(self))
43
+ end
44
+ end
45
+
46
+ #
47
+ # Registers the generated OAuth Strategy in the Warden::Strategies collection, the label
48
+ # of the strategy will be the given oauth service name plus an '_oauth' postfix
49
+ #
50
+ # @param [Symbol] name of the OAuth service
51
+ #
52
+ # @example
53
+ # manager.oauth(:twitter) { |twitter| ... } # will register a strategy :twitter_oauth
54
+ #
55
+ def register_oauth_strategy_class(keyword, strategy_class)
56
+ keyword_name = "%s_oauth" % keyword.to_s
57
+ if Warden::Strategies[keyword_name.to_sym].nil?
58
+ Warden::Strategies.add(keyword_name.to_sym, strategy_class)
59
+ end
60
+ end
61
+
62
+ #
63
+ # Defines a CONFIG constant in the generated class that will hold the configuration information
64
+ # (consumer_key, consumer_secret and options) of the oauth service.
65
+ #
66
+ # @param [Class] strategy class that will hold the configuration info
67
+ # @param [Warden::OAuth::Config] configuration info of the oauth service
68
+ #
69
+ def set_oauth_service_info(strategy_class, config)
70
+ strategy_class.const_set("CONFIG", config) unless strategy_class.const_defined?("CONFIG")
71
+ end
72
+
73
+ protected :create_oauth_strategy_class,
74
+ :register_oauth_strategy_class,
75
+ :set_oauth_service_info
76
+
77
+ end
78
+
79
+ end
80
+ 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,35 @@
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?
@@ -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,121 @@
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
+ describe "without warden_oauth_service nor oauth_token parameter" do
46
+
47
+ before(:each) do
48
+ @response = @request.get("/")
49
+ end
50
+
51
+ it "should render the failure app response" do
52
+ @response.body.should == "You are not authenticated"
53
+ end
54
+
55
+ end
56
+
57
+ describe "with a warden_oauth_provider parameter" do
58
+
59
+ before(:each) do
60
+ FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/request_token',
61
+ :body => fixture_response("unauthorized_request_token"))
62
+ @response = @request.get("/", :input => 'warden_oauth_provider=example')
63
+ end
64
+
65
+ it "should redirect to the authorize url" do
66
+ @response.headers['Location'].should =~ %r"http://localhost:3000/oauth/authorize"
67
+ end
68
+
69
+ end
70
+
71
+ describe "when receiving a valid oauth response" do
72
+ include Rack::Test::Methods
73
+
74
+ def app
75
+ $app
76
+ end
77
+
78
+ before(:each) do
79
+ Warden::Manager.access_token_user_finder(:example) do |access_token|
80
+ Object.new if access_token.token == 'ABC' && access_token.secret == '123'
81
+ end
82
+ FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/request_token',
83
+ :body => fixture_response("unauthorized_request_token"))
84
+ get "/", 'warden_oauth_provider' => 'example'
85
+ end
86
+
87
+ describe "and the user is not found" do
88
+
89
+ before(:each) do
90
+ FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/access_token',
91
+ :body => 'oauth_token=ABD&oauth_token_secret=122')
92
+ get "/", 'oauth_token' => "SylltB94pocC6hex8kr9",
93
+ 'oauth_verifier' => "omPxEkKnnx9ygnu7dd6f"
94
+ end
95
+
96
+ it "should invoke the fail app" do
97
+ last_response.body.should == "No user with the given access token"
98
+ end
99
+
100
+ end
101
+
102
+ describe "and the user is found" do
103
+
104
+ before(:each) do
105
+ FakeWeb.register_uri(:post, 'http://localhost:3000/oauth/access_token',
106
+ :body => 'oauth_token=ABC&oauth_token_secret=123')
107
+ get "/", 'oauth_token' => "SylltB94pocC6hex8kr9",
108
+ 'oauth_verifier' => "omPxEkKnnx9ygnu7dd6f"
109
+ end
110
+
111
+ it "should go to the desired app" do
112
+ last_response.body.should == "Welcome"
113
+ end
114
+
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roman-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-09-16 00:00:00 -07: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: warden_oauth will help you create oauth authentication strategies using the oauth helper method on the Warden::Manager config setup
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
+ has_rdoc: false
107
+ homepage: http://github.com/roman/warden_oauth
108
+ licenses:
109
+ post_install_message:
110
+ rdoc_options:
111
+ - --charset=UTF-8
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: "0"
119
+ version:
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: "0"
125
+ version:
126
+ requirements: []
127
+
128
+ rubyforge_project: warden_oauth
129
+ rubygems_version: 1.3.5
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: OAuth Strategy generator for Warden Authentication Framework
133
+ test_files:
134
+ - spec/application_runner.rb
135
+ - spec/application_scenario.rb
136
+ - spec/spec_helper.rb
137
+ - spec/warden_oauth/manager_spec.rb
138
+ - spec/warden_oauth/strategy_spec.rb