warden_oauth_provider 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -49,6 +49,20 @@ During the oauth process, the end-user is redirected to your application to auth
49
49
  end
50
50
  end</pre>
51
51
 
52
+ h2. xauth
53
+
54
+ The oauth provider has support for xauth, which supports requests for access tokens without user interaction. More information can be found at "dev.twitter.com":https://dev.twitter.com/docs/oauth/xauth. In order to enable xauth, make sure you set the @xauth_enabled@ boolean for a trusted client application to @true@. Furthermore you should define how the strategy should authenticate a valid user of your system by defining a Proc for the @xauth_user@ Warden config option.
55
+
56
+ <pre>YourApp::Application.config.middleware.use Warden::Manager do |manager|
57
+ manager.default_strategies :oauth_provider, :http_basic, :password
58
+ manager.failure_app = SessionsController
59
+ manager.oauth_request_token_path = "/oauth/request_token"
60
+ manager.oauth_access_token_path = "/oauth/access_token"
61
+ manager.xauth_user = Proc.new do |env, username, password|
62
+ User.authenticate(username, password) # Return nil when authentication fails or a user when success
63
+ end
64
+ end</pre>
65
+
52
66
  h2. Reporting bugs
53
67
 
54
68
  Please report bugs in this gem via Github Issues: https://github.com/bluetools/warden_oauth_provider/issues
@@ -8,6 +8,7 @@ class CreateOauthTables < ActiveRecord::Migration
8
8
  t.string :key, :limit => 20
9
9
  t.string :secret, :limit => 40
10
10
  t.integer :user_id
11
+ t.boolean :xauth_enabled, :default => false
11
12
 
12
13
  t.timestamps
13
14
  end
@@ -23,12 +23,30 @@ module WardenOauthProvider
23
23
  request_token = WardenOauthProvider::Token::Request.create!(:client_application => client_application, :callback_url => oauth_request.oauth_callback)
24
24
  custom! [200, {}, ["oauth_token=#{escape(request_token.token)}&oauth_token_secret=#{escape(request_token.secret)}&oauth_callback_confirmed=true"]]
25
25
  when warden.config.oauth_access_token_path
26
+
27
+ if xauth_params? and xauth_mode == 'client_auth'
28
+
29
+ # Get the user authentication proc from the settings
30
+ user_authentication = warden.config.xauth_user || Proc.new { |env, username, password| nil }
31
+
32
+ # Create an access token when the client application has xauth enabled and the user can be authenticated
33
+ if client_application.xauth_enabled? and (user = user_authentication.call(env, xauth_username, xauth_password))
34
+ access_token = WardenOauthProvider::Token::Access.create!(:client_application => client_application, :user => user)
35
+ elsif user.nil?
36
+ fail!("Authentication failed")
37
+ else
38
+ fail!("xauth not allowed for client application")
39
+ end
40
+ else
26
41
 
27
- # Exchange the access token and return it
28
- if access_token = (current_token && current_token.exchange!(oauth_request.oauth_verifier))
29
- custom! [200, {}, ["oauth_token=#{escape(access_token.token)}&oauth_token_secret=#{escape(access_token.secret)}"]]
30
- else
31
- fail!("Request token exchange failed")
42
+ # Exchange the access token and return it
43
+ if !(access_token = (current_token && current_token.exchange!(oauth_request.oauth_verifier)))
44
+ fail!("Request token exchange failed")
45
+ end
46
+ end
47
+
48
+ if access_token
49
+ custom! [200, {}, ["oauth_token=#{escape(access_token.token)}&oauth_token_secret=#{escape(access_token.secret)}"]]
32
50
  end
33
51
  else
34
52
 
@@ -41,7 +59,7 @@ module WardenOauthProvider
41
59
  end
42
60
  end
43
61
 
44
- private
62
+ protected
45
63
 
46
64
  def request
47
65
  @request ||= Rack::Request.new(env)
@@ -77,6 +95,22 @@ module WardenOauthProvider
77
95
  env['warden']
78
96
  end
79
97
 
98
+ def xauth_params?
99
+ request.post? and !xauth_username.nil? and !xauth_password.nil?
100
+ end
101
+
102
+ def xauth_mode
103
+ request.params['x_auth_mode']
104
+ end
105
+
106
+ def xauth_username
107
+ request.params['x_auth_username']
108
+ end
109
+
110
+ def xauth_password
111
+ request.params['x_auth_password']
112
+ end
113
+
80
114
  end
81
115
 
82
116
  end
@@ -1,3 +1,3 @@
1
1
  module WardenOauthProvider
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -14,6 +14,6 @@ Warden::Strategies.add(:oauth_token, WardenOauthProvider::TokenStrategy)
14
14
 
15
15
  module Warden
16
16
  class Config
17
- hash_accessor :oauth_request_token_path, :oauth_access_token_path
17
+ hash_accessor :oauth_request_token_path, :oauth_access_token_path, :xauth_user
18
18
  end
19
19
  end
@@ -32,7 +32,7 @@ describe "OAuth all steps" do
32
32
 
33
33
  # Step 2 - Authorize
34
34
  req = WardenOauthProvider::Token::Request.find_by_token(oauth_request_token)
35
- env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John"}, {})
35
+ env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John", :password => "testtest"}, {})
36
36
  response = setup_rack.call(env_step2)
37
37
  response.first.should == 302
38
38
  location = URI.parse(response[1]["Location"])
@@ -6,7 +6,7 @@ describe "Authorize" do
6
6
 
7
7
  before(:all) do
8
8
  @request_token = Factory.create(:request_token, :client_application => Factory.create(:client_application))
9
- env = env_with_params("/oauth/authorize", {:oauth_token => @request_token.token, :username => "John"}, {})
9
+ env = env_with_params("/oauth/authorize", {:oauth_token => @request_token.token, :username => "John", :password => "testtest"}, {})
10
10
  @response = setup_rack.call(env)
11
11
  @location = URI.parse(@response[1]["Location"])
12
12
  @oauth_response = Hash[*@location.query.split("&").collect { |v| v.split("=") }.flatten]
@@ -34,7 +34,7 @@ describe "Authorize" do
34
34
  @request_token = Factory.create(:request_token, :client_application => Factory.create(:client_application))
35
35
  @request_token.invalidate!
36
36
 
37
- env = env_with_params("/oauth/authorize", {:oauth_token => @request_token.token}, {})
37
+ env = env_with_params("/oauth/authorize", {:oauth_token => @request_token.token, :username => "John", :password => "testtest"}, {})
38
38
  @response = setup_rack.call(env)
39
39
  @response.first.should == 401
40
40
  end
@@ -13,4 +13,5 @@ end
13
13
 
14
14
  Factory.define(:user) do |f|
15
15
  f.name "John"
16
+ f.password "testtest"
16
17
  end
@@ -25,11 +25,11 @@ module RequestHelper
25
25
  # Required for authorize call to the app
26
26
  Warden::Strategies.add(:success) do
27
27
  def valid?
28
- !params["username"].nil?
28
+ !params["username"].nil? and !params["password"].nil?
29
29
  end
30
30
 
31
31
  def authenticate!
32
- if u = User.where(:name => params["username"]).first
32
+ if u = User.where(:name => params["username"], :password => params["password"]).first
33
33
  success!(u)
34
34
  else
35
35
  fail!("User unknown")
@@ -41,6 +41,9 @@ module RequestHelper
41
41
  opts[:default_strategies] ||= [:oauth_provider, :success]
42
42
  opts[:oauth_request_token_path] ||= "/oauth/request_token"
43
43
  opts[:oauth_access_token_path] ||= "/oauth/access_token"
44
+ opts[:xauth_user] ||= Proc.new do |env, username, password|
45
+ User.where(:name => username, :password => password).first
46
+ end
44
47
 
45
48
  Rack::Builder.new do
46
49
  use opts[:session] || RequestHelper::Session
data/spec/spec_helper.rb CHANGED
@@ -30,6 +30,7 @@ ActiveRecord::Schema.define do
30
30
  t.string :key, :limit => 40
31
31
  t.string :secret, :limit => 40
32
32
  t.integer :user_id
33
+ t.boolean :xauth_enabled, :default => false
33
34
 
34
35
  t.timestamps
35
36
  end
@@ -59,6 +60,7 @@ ActiveRecord::Schema.define do
59
60
 
60
61
  create_table :users, :force => true do |t|
61
62
  t.string :name
63
+ t.string :password
62
64
  end
63
65
  end
64
66
 
@@ -46,7 +46,7 @@ describe WardenOauthProvider::TokenStrategy do
46
46
 
47
47
  # Step 2 - Authorize
48
48
  req = WardenOauthProvider::Token::Request.find_by_token(oauth_request_token)
49
- env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John"}, {})
49
+ env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John", :password => "testtest"}, {})
50
50
  response = setup_rack(nil, :session => session).call(env_step2)
51
51
  response.first.should == 302
52
52
  location = URI.parse(response[1]["Location"])
@@ -110,7 +110,7 @@ describe WardenOauthProvider::TokenStrategy do
110
110
 
111
111
  # Step 2 - Authorize
112
112
  req = WardenOauthProvider::Token::Request.find_by_token(oauth_request_token)
113
- env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John"}, {})
113
+ env_step2 = env_with_params("/oauth/authorize", {:oauth_token => oauth_request_token, :username => "John", :password => "testtest"}, {})
114
114
  response = setup_rack(nil, :session => session).call(env_step2)
115
115
  response.first.should == 302
116
116
  location = URI.parse(response[1]["Location"])
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'xauth' do
4
+
5
+ context "success" do
6
+ before(:all) do
7
+ @user = Factory(:user)
8
+ @client_application = Factory.create(:client_application, :xauth_enabled => true)
9
+
10
+ auth_str = oauth_header({
11
+ :realm => "MoneyBird",
12
+ :oauth_consumer_key => @client_application.key,
13
+ :oauth_signature_method => "PLAINTEXT",
14
+ :oauth_timestamp => Time.now.to_i,
15
+ :oauth_nonce => Time.now.to_f,
16
+ :oauth_signature => @client_application.secret + "%26"
17
+ })
18
+
19
+ xauth_params = {
20
+ :x_auth_mode => "client_auth",
21
+ :x_auth_username => "John",
22
+ :x_auth_password => "testtest"
23
+ }
24
+
25
+ env = env_with_params("/oauth/access_token", xauth_params.merge({ :method => "POST" }), {
26
+ "HTTP_AUTHORIZATION" => auth_str
27
+ })
28
+ @response = setup_rack.call(env)
29
+ @oauth_response = Hash[*@response.last.first.split("&").collect { |v| v.split("=") }.flatten]
30
+ end
31
+
32
+ it "should have an oauth access token" do
33
+ @oauth_response.keys.should include("oauth_token")
34
+ @oauth_response["oauth_token"].should_not be_nil
35
+ end
36
+
37
+ it "should have an oauth access token secret" do
38
+ @oauth_response.keys.should include("oauth_token_secret")
39
+ @oauth_response["oauth_token_secret"].should_not be_nil
40
+ end
41
+
42
+ it "should have stored an access token with the token and secret" do
43
+ WardenOauthProvider::Token::Access.where(:token => @oauth_response["oauth_token"], :secret => @oauth_response["oauth_token_secret"]).count.should == 1
44
+ end
45
+ end
46
+
47
+ context "Failure" do
48
+
49
+ before(:all) do
50
+ @user = Factory(:user)
51
+ @client_application = Factory.create(:client_application, :xauth_enabled => true)
52
+ end
53
+
54
+ it "should response with a 401 if the client application is unknown" do
55
+ auth_str = oauth_header({
56
+ :realm => "MoneyBird",
57
+ :oauth_consumer_key => "somerandomstring",
58
+ :oauth_signature_method => "PLAINTEXT",
59
+ :oauth_timestamp => Time.now.to_i,
60
+ :oauth_nonce => Time.now.to_f,
61
+ :oauth_signature => @client_application.secret + "%26"
62
+ })
63
+
64
+ xauth_params = {
65
+ :x_auth_mode => "client_auth",
66
+ :x_auth_username => "John",
67
+ :x_auth_password => "testtest"
68
+ }
69
+
70
+ env = env_with_params("/oauth/access_token", xauth_params.merge({ :method => "POST" }), {
71
+ "HTTP_AUTHORIZATION" => auth_str
72
+ })
73
+ @response = setup_rack.call(env)
74
+ @response.first.should == 401
75
+ end
76
+
77
+ it "should response with a 401 if the credentials are invalid" do
78
+ auth_str = oauth_header({
79
+ :realm => "MoneyBird",
80
+ :oauth_consumer_key => @client_application.key,
81
+ :oauth_signature_method => "PLAINTEXT",
82
+ :oauth_timestamp => Time.now.to_i,
83
+ :oauth_nonce => Time.now.to_f,
84
+ :oauth_signature => @client_application.secret + "%26"
85
+ })
86
+
87
+ xauth_params = {
88
+ :x_auth_mode => "client_auth",
89
+ :x_auth_username => "John",
90
+ :x_auth_password => "invalidpassword"
91
+ }
92
+
93
+ env = env_with_params("/oauth/access_token", xauth_params.merge({ :method => "POST" }), {
94
+ "HTTP_AUTHORIZATION" => auth_str
95
+ })
96
+ @response = setup_rack.call(env)
97
+ @response.first.should == 401
98
+ end
99
+
100
+ it "should response with a 401 if the client application is not authorized for xauth" do
101
+ @client_application.update_attribute(:xauth_enabled, false)
102
+
103
+ auth_str = oauth_header({
104
+ :realm => "MoneyBird",
105
+ :oauth_consumer_key => @client_application.key,
106
+ :oauth_signature_method => "PLAINTEXT",
107
+ :oauth_timestamp => Time.now.to_i,
108
+ :oauth_nonce => Time.now.to_f,
109
+ :oauth_signature => @client_application.secret + "%26"
110
+ })
111
+
112
+ xauth_params = {
113
+ :x_auth_mode => "client_auth",
114
+ :x_auth_username => "John",
115
+ :x_auth_password => "testtest"
116
+ }
117
+
118
+ env = env_with_params("/oauth/access_token", xauth_params.merge({ :method => "POST" }), {
119
+ "HTTP_AUTHORIZATION" => auth_str
120
+ })
121
+ @response = setup_rack.call(env)
122
+ @response.first.should == 401
123
+ end
124
+
125
+ it "should response with a 401 if no xauth user proc is given" do
126
+ auth_str = oauth_header({
127
+ :realm => "MoneyBird",
128
+ :oauth_consumer_key => @client_application.key,
129
+ :oauth_signature_method => "PLAINTEXT",
130
+ :oauth_timestamp => Time.now.to_i,
131
+ :oauth_nonce => Time.now.to_f,
132
+ :oauth_signature => @client_application.secret + "%26"
133
+ })
134
+
135
+ xauth_params = {
136
+ :x_auth_mode => "client_auth",
137
+ :x_auth_username => "John",
138
+ :x_auth_password => "testtest"
139
+ }
140
+
141
+ env = env_with_params("/oauth/access_token", xauth_params.merge({ :method => "POST" }), {
142
+ "HTTP_AUTHORIZATION" => auth_str
143
+ })
144
+ @response = setup_rack(nil, :xauth_user => nil).call(env)
145
+ @response.first.should == 401
146
+ end
147
+ end
148
+
149
+ end
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
7
7
  s.version = WardenOauthProvider::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Edwin Vlieg", "Berend van Bruijnsvoort"]
10
- s.email = ["info@moneybird.nl"]
11
- s.homepage = "http://www.moneybird.nl"
10
+ s.email = ["info@moneybird.com"]
11
+ s.homepage = "https://github.com/bluetools/warden_oauth_provider"
12
12
  s.summary = %q{Warden strategy for OAuth provider}
13
13
  s.description = %q{Warden strategy for OAuth provider}
14
14
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warden_oauth_provider
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ - 1
10
+ version: 1.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Edwin Vlieg
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-07-29 00:00:00 +02:00
19
+ date: 2011-08-30 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -128,7 +128,7 @@ dependencies:
128
128
  version_requirements: *id007
129
129
  description: Warden strategy for OAuth provider
130
130
  email:
131
- - info@moneybird.nl
131
+ - info@moneybird.com
132
132
  executables: []
133
133
 
134
134
  extensions: []
@@ -164,9 +164,10 @@ files:
164
164
  - spec/spec_helper.rb
165
165
  - spec/token_spec.rb
166
166
  - spec/token_strategy_spec.rb
167
+ - spec/xauth_spec.rb
167
168
  - warden_oauth_provider.gemspec
168
169
  has_rdoc: true
169
- homepage: http://www.moneybird.nl
170
+ homepage: https://github.com/bluetools/warden_oauth_provider
170
171
  licenses: []
171
172
 
172
173
  post_install_message:
@@ -212,3 +213,4 @@ test_files:
212
213
  - spec/spec_helper.rb
213
214
  - spec/token_spec.rb
214
215
  - spec/token_strategy_spec.rb
216
+ - spec/xauth_spec.rb