sorcery 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sorcery might be problematic. Click here for more details.

Files changed (59) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +7 -7
  3. data/README.rdoc +14 -4
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/lib/generators/sorcery_migration/templates/core.rb +1 -1
  7. data/lib/generators/sorcery_migration/templates/reset_password.rb +4 -0
  8. data/lib/sorcery.rb +1 -0
  9. data/lib/sorcery/controller.rb +26 -6
  10. data/lib/sorcery/controller/adapters/sinatra.rb +12 -1
  11. data/lib/sorcery/controller/submodules/activity_logging.rb +18 -1
  12. data/lib/sorcery/controller/submodules/brute_force_protection.rb +2 -1
  13. data/lib/sorcery/controller/submodules/external.rb +10 -3
  14. data/lib/sorcery/controller/submodules/external/protocols/certs/ca-bundle.crt +5182 -0
  15. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +10 -6
  16. data/lib/sorcery/controller/submodules/external/providers/github.rb +80 -0
  17. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +5 -0
  18. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  19. data/lib/sorcery/controller/submodules/remember_me.rb +13 -4
  20. data/lib/sorcery/controller/submodules/session_timeout.rb +1 -1
  21. data/lib/sorcery/crypto_providers/aes256.rb +7 -3
  22. data/lib/sorcery/engine.rb +1 -0
  23. data/lib/sorcery/initializers/initializer.rb +81 -60
  24. data/lib/sorcery/model.rb +13 -11
  25. data/lib/sorcery/model/adapters/active_record.rb +2 -1
  26. data/lib/sorcery/model/adapters/mongoid.rb +7 -2
  27. data/lib/sorcery/model/submodules/brute_force_protection.rb +5 -3
  28. data/lib/sorcery/model/submodules/remember_me.rb +1 -1
  29. data/lib/sorcery/model/submodules/reset_password.rb +1 -2
  30. data/lib/sorcery/model/submodules/user_activation.rb +1 -2
  31. data/lib/sorcery/model/temporary_token.rb +5 -0
  32. data/lib/sorcery/test_helpers/internal/rails.rb +1 -1
  33. data/lib/sorcery/test_helpers/rails.rb +2 -2
  34. data/lib/sorcery/test_helpers/sinatra.rb +1 -1
  35. data/sorcery.gemspec +16 -9
  36. data/spec/Gemfile +1 -1
  37. data/spec/Gemfile.lock +9 -11
  38. data/spec/README.md +26 -0
  39. data/spec/rails3/Gemfile +2 -0
  40. data/spec/rails3/Gemfile.lock +33 -11
  41. data/spec/rails3/app/controllers/application_controller.rb +40 -22
  42. data/spec/rails3/app/views/application/index.html.erb +17 -0
  43. data/spec/rails3/spec/controller_activity_logging_spec.rb +23 -0
  44. data/spec/rails3/spec/controller_oauth2_spec.rb +61 -20
  45. data/spec/rails3/spec/controller_remember_me_spec.rb +37 -6
  46. data/spec/rails3/spec/controller_spec.rb +30 -0
  47. data/spec/rails3/spec/integration_spec.rb +23 -0
  48. data/spec/rails3/spec/spec_helper.rb +6 -3
  49. data/spec/rails3_mongoid/Gemfile.lock +9 -11
  50. data/spec/rails3_mongoid/spec/controller_spec.rb +130 -0
  51. data/spec/shared_examples/user_remember_me_shared_examples.rb +1 -0
  52. data/spec/shared_examples/user_shared_examples.rb +7 -7
  53. data/spec/sinatra/Gemfile.lock +9 -11
  54. data/spec/sinatra/spec/controller_oauth2_spec.rb +3 -6
  55. data/spec/sinatra/spec/controller_spec.rb +7 -0
  56. data/spec/sinatra_modular/Gemfile.lock +9 -11
  57. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +3 -6
  58. metadata +12 -5
  59. data/spec/rails3/public/index.html +0 -239
@@ -2,78 +2,88 @@ require 'oauth'
2
2
 
3
3
  class ApplicationController < ActionController::Base
4
4
  protect_from_forgery
5
-
5
+
6
6
  #before_filter :validate_session, :only => [:test_should_be_logged_in] if defined?(:validate_session)
7
7
  before_filter :require_login_from_http_basic, :only => [:test_http_basic_auth]
8
8
  before_filter :require_login, :only => [:test_logout, :test_should_be_logged_in, :some_action]
9
-
9
+
10
10
  def index
11
- render :text => ""
12
11
  end
13
12
 
14
13
  def some_action
15
14
  render :nothing => true
16
15
  end
17
-
16
+
18
17
  def test_login
19
18
  @user = login(params[:username], params[:password])
20
19
  render :text => ""
21
20
  end
22
21
 
22
+ def test_auto_login
23
+ @user = User.find(:first)
24
+ auto_login(@user)
25
+ @result = current_user
26
+ render :text => ""
27
+ end
28
+
23
29
  def test_return_to
24
30
  @user = login(params[:username], params[:password])
25
31
  redirect_back_or_to(:index, :notice => 'haha!')
26
32
  end
27
-
33
+
28
34
  def test_logout
29
35
  logout
30
36
  render :text => ""
31
37
  end
32
-
38
+
33
39
  def test_logout_with_remember
34
40
  remember_me!
35
41
  logout
36
42
  render :text => ""
37
43
  end
38
-
44
+
39
45
  def test_login_with_remember
40
46
  @user = login(params[:username], params[:password])
41
47
  remember_me!
42
-
48
+
43
49
  render :text => ""
44
50
  end
45
-
51
+
46
52
  def test_login_with_remember_in_login
47
53
  @user = login(params[:username], params[:password], params[:remember])
48
-
54
+
49
55
  render :text => ""
50
56
  end
51
-
57
+
52
58
  def test_login_from_cookie
53
59
  @user = current_user
54
60
  render :text => ""
55
61
  end
56
-
62
+
57
63
  def test_not_authenticated_action
58
64
  render :text => "test_not_authenticated_action"
59
65
  end
60
-
66
+
61
67
  def test_should_be_logged_in
62
68
  render :text => ""
63
69
  end
64
-
70
+
65
71
  def test_http_basic_auth
66
72
  render :text => "HTTP Basic Auth"
67
73
  end
68
-
74
+
69
75
  def login_at_test
70
76
  login_at(:twitter)
71
77
  end
72
-
78
+
73
79
  def login_at_test2
74
80
  login_at(:facebook)
75
81
  end
76
-
82
+
83
+ def login_at_test3
84
+ login_at(:github)
85
+ end
86
+
77
87
  def test_login_from
78
88
  if @user = login_from(:twitter)
79
89
  redirect_to "bla", :notice => "Success!"
@@ -81,7 +91,7 @@ class ApplicationController < ActionController::Base
81
91
  redirect_to "blu", :alert => "Failed!"
82
92
  end
83
93
  end
84
-
94
+
85
95
  def test_login_from2
86
96
  if @user = login_from(:facebook)
87
97
  redirect_to "bla", :notice => "Success!"
@@ -89,7 +99,15 @@ class ApplicationController < ActionController::Base
89
99
  redirect_to "blu", :alert => "Failed!"
90
100
  end
91
101
  end
92
-
102
+
103
+ def test_login_from3
104
+ if @user = login_from(:github)
105
+ redirect_to "bla", :notice => "Success!"
106
+ else
107
+ redirect_to "blu", :alert => "Failed!"
108
+ end
109
+ end
110
+
93
111
  def test_create_from_provider
94
112
  provider = params[:provider]
95
113
  login_from(provider)
@@ -99,9 +117,9 @@ class ApplicationController < ActionController::Base
99
117
  redirect_to "blu", :alert => "Failed!"
100
118
  end
101
119
  end
102
-
120
+
103
121
  protected
104
-
105
-
122
+
123
+
106
124
 
107
125
  end
@@ -0,0 +1,17 @@
1
+ <%= form_tag :action => :test_login, :method => :post do %>
2
+ <div class="field">
3
+ <%= label_tag :username %><br />
4
+ <%= text_field_tag :username %>
5
+ </div>
6
+ <div class="field">
7
+ <%= label_tag :password %><br />
8
+ <%= password_field_tag :password %>
9
+ </div>
10
+ <div class="actions">
11
+ <%= submit_tag "Login" %>
12
+ </div>
13
+ <div>
14
+ <%= label_tag "keep me logged in" %><br />
15
+ <%= check_box_tag :remember %>
16
+ </div>
17
+ <% end %>
@@ -78,5 +78,28 @@ describe ApplicationController do
78
78
  subject.current_users[1].should == user2
79
79
  subject.current_users[2].should == user3
80
80
  end
81
+
82
+ it "should not register login time if configured so" do
83
+ sorcery_controller_property_set(:register_login_time, false)
84
+ now = Time.now.utc
85
+ login_user
86
+ @user.last_login_at.should be_nil
87
+ end
88
+
89
+ it "should not register logout time if configured so" do
90
+ sorcery_controller_property_set(:register_logout_time, false)
91
+ now = Time.now.utc
92
+ login_user
93
+ logout_user
94
+ @user.last_logout_at.should be_nil
95
+ end
96
+
97
+ it "should not register last activity time if configured so" do
98
+ sorcery_controller_property_set(:register_last_activity_time, false)
99
+ now = Time.now.utc
100
+ login_user
101
+ get :some_action
102
+ @user.last_activity_at.should be_nil
103
+ end
81
104
  end
82
105
  end
@@ -5,9 +5,7 @@ def stub_all_oauth2_requests!
5
5
  @client = OAuth2::Client.new("key","secret", :site => "http://myapi.com")
6
6
  OAuth2::Client.stub!(:new).and_return(@client)
7
7
  @acc_token = OAuth2::AccessToken.new(@client, "asd", {})
8
- @webby = @client.web_server
9
- OAuth2::Strategy::WebServer.stub!(:new).and_return(@webby)
10
- @webby.stub!(:get_access_token).and_return(@acc_token)
8
+ @client.stub!(:get_token).and_return(@acc_token)
11
9
  @acc_token.stub!(:get).and_return({"id"=>"123", "name"=>"Noam Ben Ari", "first_name"=>"Noam", "last_name"=>"Ben Ari", "link"=>"http://www.facebook.com/nbenari1", "hometown"=>{"id"=>"110619208966868", "name"=>"Haifa, Israel"}, "location"=>{"id"=>"106906559341067", "name"=>"Pardes Hanah, Hefa, Israel"}, "bio"=>"I'm a new daddy, and enjoying it!", "gender"=>"male", "email"=>"nbenari@gmail.com", "timezone"=>2, "locale"=>"en_US", "languages"=>[{"id"=>"108405449189952", "name"=>"Hebrew"}, {"id"=>"106059522759137", "name"=>"English"}, {"id"=>"112624162082677", "name"=>"Russian"}], "verified"=>true, "updated_time"=>"2011-02-16T20:59:38+0000"}.to_json)
12
10
  end
13
11
 
@@ -15,78 +13,107 @@ describe ApplicationController do
15
13
  before(:all) do
16
14
  ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
17
15
  sorcery_reload!([:external])
18
- sorcery_controller_property_set(:external_providers, [:facebook])
16
+ sorcery_controller_property_set(:external_providers, [:facebook, :github])
19
17
  sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
20
18
  sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
21
19
  sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
20
+ sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w")
21
+ sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
22
+ sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com")
22
23
  end
23
-
24
+
24
25
  after(:all) do
25
26
  ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
26
27
  end
27
28
  # ----------------- OAuth -----------------------
28
29
  describe ApplicationController, "with OAuth features" do
29
-
30
+
30
31
  before(:each) do
31
32
  stub_all_oauth2_requests!
32
33
  end
33
-
34
+
34
35
  after(:each) do
35
36
  User.delete_all
36
37
  Authentication.delete_all
37
38
  end
38
-
39
+
39
40
  it "login_at redirects correctly" do
40
41
  create_new_user
41
42
  get :login_at_test2
42
43
  response.should be_a_redirect
43
- #response.should redirect_to("http://myapi.com/oauth/authorize?client_id=key&redirect_uri=http%3A%2F%2Fblabla.com&scope=email%2Coffline_access&type=web_server")
44
- response.should redirect_to("http://myapi.com/oauth/authorize?client_id=key&redirect_uri=http%3A%2F%2Fblabla.com&scope=email%2Coffline_access&response_type=code")
44
+ response.should redirect_to("http://myapi.com/oauth/authorize?redirect_uri=http%3A%2F%2Fblabla.com&scope=email%2Coffline_access")
45
45
  end
46
-
46
+
47
47
  it "'login_from' logins if user exists" do
48
48
  sorcery_model_property_set(:authentications_class, Authentication)
49
49
  create_new_external_user(:facebook)
50
50
  get :test_login_from2
51
51
  flash[:notice].should == "Success!"
52
52
  end
53
-
53
+
54
54
  it "'login_from' fails if user doesn't exist" do
55
55
  sorcery_model_property_set(:authentications_class, Authentication)
56
56
  create_new_user
57
57
  get :test_login_from2
58
58
  flash[:alert].should == "Failed!"
59
59
  end
60
+
61
+ # provider: github
62
+ it "login_at redirects correctly (github)" do
63
+ create_new_user
64
+ get :login_at_test3
65
+ response.should be_a_redirect
66
+ response.should redirect_to("http://myapi.com/oauth/authorize?redirect_uri=http%3A%2F%2Fblabla.com&scope=")
67
+ end
68
+
69
+ it "'login_from' logins if user exists (github)" do
70
+ sorcery_model_property_set(:authentications_class, Authentication)
71
+ create_new_external_user(:github)
72
+ get :test_login_from3
73
+ flash[:notice].should == "Success!"
74
+ end
75
+
76
+ it "'login_from' fails if user doesn't exist (github)" do
77
+ sorcery_model_property_set(:authentications_class, Authentication)
78
+ create_new_user
79
+ get :test_login_from3
80
+ flash[:alert].should == "Failed!"
81
+ end
82
+
60
83
  end
61
-
84
+
85
+
62
86
  describe ApplicationController do
63
87
  it_behaves_like "oauth2_controller"
64
88
  end
65
-
89
+
66
90
  describe ApplicationController, "OAuth with User Activation features" do
67
91
  before(:all) do
68
92
  ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
69
93
  sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
70
- sorcery_controller_property_set(:external_providers, [:facebook])
94
+ sorcery_controller_property_set(:external_providers, [:facebook, :github])
71
95
  sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
72
96
  sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
73
97
  sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
98
+ sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w")
99
+ sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
100
+ sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com")
74
101
  end
75
-
102
+
76
103
  after(:all) do
77
104
  ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
78
105
  end
79
-
106
+
80
107
  after(:each) do
81
108
  User.delete_all
82
109
  end
83
-
110
+
84
111
  it "should not send activation email to external users" do
85
112
  old_size = ActionMailer::Base.deliveries.size
86
113
  create_new_external_user(:facebook)
87
114
  ActionMailer::Base.deliveries.size.should == old_size
88
115
  end
89
-
116
+
90
117
  it "should not send external users an activation success email" do
91
118
  sorcery_model_property_set(:activation_success_email_method_name, nil)
92
119
  create_new_external_user(:facebook)
@@ -94,6 +121,20 @@ describe ApplicationController do
94
121
  @user.activate!
95
122
  ActionMailer::Base.deliveries.size.should == old_size
96
123
  end
124
+
125
+ # provider: github
126
+ it "should not send activation email to external users (github)" do
127
+ old_size = ActionMailer::Base.deliveries.size
128
+ create_new_external_user(:github)
129
+ ActionMailer::Base.deliveries.size.should == old_size
130
+ end
131
+
132
+ it "should not send external users an activation success email (github)" do
133
+ sorcery_model_property_set(:activation_success_email_method_name, nil)
134
+ create_new_external_user(:github)
135
+ old_size = ActionMailer::Base.deliveries.size
136
+ @user.activate!
137
+ ActionMailer::Base.deliveries.size.should == old_size
138
+ end
97
139
  end
98
-
99
140
  end
@@ -4,6 +4,7 @@ describe ApplicationController do
4
4
 
5
5
  # ----------------- REMEMBER ME -----------------------
6
6
  describe ApplicationController, "with remember me features" do
7
+
7
8
  before(:all) do
8
9
  ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/remember_me")
9
10
  sorcery_reload!([:remember_me])
@@ -25,25 +26,29 @@ describe ApplicationController do
25
26
 
26
27
  it "should set cookie on remember_me!" do
27
28
  post :test_login_with_remember, :username => 'gizmo', :password => 'secret'
28
- cookies["remember_me_token"].should == assigns[:current_user].remember_me_token
29
+ @request.cookies.merge!(cookies)
30
+ cookies = ActionDispatch::Cookies::CookieJar.build(@request)
31
+ cookies.signed["remember_me_token"].should == assigns[:current_user].remember_me_token
29
32
  end
30
33
 
31
34
  it "should clear cookie on forget_me!" do
32
35
  cookies["remember_me_token"] == {:value => 'asd54234dsfsd43534', :expires => 3600}
33
36
  get :test_logout
34
- cookies["remember_me_token"].should == nil
37
+ cookies["remember_me_token"].should be_nil
35
38
  end
36
39
 
37
40
  it "login(username,password,remember_me) should login and remember" do
38
41
  post :test_login_with_remember_in_login, :username => 'gizmo', :password => 'secret', :remember => "1"
39
- cookies["remember_me_token"].should_not be_nil
40
- cookies["remember_me_token"].should == assigns[:user].remember_me_token
42
+ @request.cookies.merge!(cookies)
43
+ cookies = ActionDispatch::Cookies::CookieJar.build(@request)
44
+ cookies.signed["remember_me_token"].should_not be_nil
45
+ cookies.signed["remember_me_token"].should == assigns[:user].remember_me_token
41
46
  end
42
47
 
43
48
  it "logout should also forget_me!" do
44
49
  session[:user_id] = @user.id
45
50
  get :test_logout_with_remember
46
- cookies["remember_me_token"].should == nil
51
+ cookies["remember_me_token"].should be_nil
47
52
  end
48
53
 
49
54
  it "should login_from_cookie" do
@@ -57,9 +62,35 @@ describe ApplicationController do
57
62
  assigns[:current_user].should == @user
58
63
  end
59
64
 
65
+ it "should not remember_me! when not asked to, even if third parameter is used" do
66
+ post :test_login_with_remember_in_login, :username => 'gizmo', :password => 'secret', :remember => "0"
67
+ cookies["remember_me_token"].should be_nil
68
+ end
69
+
60
70
  it "should not remember_me! when not asked to" do
61
71
  post :test_login, :username => 'gizmo', :password => 'secret'
62
- cookies["remember_me_token"].should == nil
72
+ cookies["remember_me_token"].should be_nil
73
+ end
74
+
75
+ # --- login_user(user) ---
76
+ specify { should respond_to(:auto_login) }
77
+
78
+ it "auto_login(user) should login a user instance without remembering" do
79
+ create_new_user
80
+ session[:user_id] = nil
81
+ subject.auto_login(@user)
82
+ get :test_login_from_cookie
83
+ assigns[:current_user].should == @user
84
+ cookies["remember_me_token"].should be_nil
63
85
  end
86
+
87
+ it "auto_login(user, true) should login a user instance with remembering" do
88
+ create_new_user
89
+ session[:user_id] = nil
90
+ subject.auto_login(@user, true)
91
+ get :test_login_from_cookie
92
+ assigns[:current_user].should == @user
93
+ cookies["remember_me_token"].should_not be_nil
94
+ end
64
95
  end
65
96
  end
@@ -28,13 +28,20 @@ describe ApplicationController do
28
28
  # ----------------- PLUGIN ACTIVATED -----------------------
29
29
  describe ApplicationController, "when activated with sorcery" do
30
30
  before(:all) do
31
+ sorcery_reload!
31
32
  User.delete_all
33
+ end
34
+
35
+ before(:each) do
32
36
  create_new_user
33
37
  end
34
38
 
35
39
  after(:each) do
36
40
  Sorcery::Controller::Config.reset!
41
+ sorcery_reload!
42
+ User.delete_all
37
43
  sorcery_controller_property_set(:user_class, User)
44
+ sorcery_model_property_set(:username_attribute_names, [:username, :email])
38
45
  end
39
46
 
40
47
  specify { should respond_to(:login) }
@@ -50,6 +57,12 @@ describe ApplicationController do
50
57
  assigns[:user].should == @user
51
58
  session[:user_id].should == @user.id
52
59
  end
60
+
61
+ it "login(email,password) should return the user when success and set the session with user.id" do
62
+ get :test_login, :username => 'bla@bla.com', :password => 'secret'
63
+ assigns[:user].should == @user
64
+ session[:user_id].should == @user.id
65
+ end
53
66
 
54
67
  it "login(username,password) should return nil and not set the session when failure" do
55
68
  get :test_login, :username => 'gizmo', :password => 'opensesame!'
@@ -107,6 +120,23 @@ describe ApplicationController do
107
120
  flash[:notice].should == "haha!"
108
121
  end
109
122
 
123
+
124
+ # --- auto_login(user) ---
125
+ specify { should respond_to(:auto_login) }
126
+
127
+ it "auto_login(user) should login a user instance" do
128
+ session[:user_id] = nil
129
+ subject.auto_login(@user)
130
+ subject.logged_in?.should be_true
131
+ end
132
+
133
+ it "auto_login(user) should work even if current_user was already set to false" do
134
+ get :test_logout
135
+ session[:user_id].should be_nil
136
+ subject.current_user.should be_false
137
+ get :test_auto_login
138
+ assigns[:result].should == User.find(:first)
139
+ end
110
140
  end
111
141
 
112
142
  end