sorcery 0.5.1 → 0.5.2

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 (49) hide show
  1. data/README.rdoc +1 -1
  2. data/VERSION +1 -1
  3. data/lib/sorcery.rb +3 -5
  4. data/lib/sorcery/controller/adapters/sinatra.rb +35 -28
  5. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  6. data/lib/sorcery/engine.rb +0 -7
  7. data/lib/sorcery/initializers/initializer.rb +4 -2
  8. data/lib/sorcery/model.rb +2 -3
  9. data/lib/sorcery/test_helpers/internal/rails.rb +1 -0
  10. data/lib/sorcery/test_helpers/internal/sinatra.rb +3 -3
  11. data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +74 -0
  12. data/sorcery.gemspec +54 -2
  13. data/spec/Gemfile.lock +1 -1
  14. data/spec/rails3/Gemfile.lock +1 -1
  15. data/spec/rails3/spec/user_spec.rb +0 -10
  16. data/spec/rails3_mongoid/Gemfile.lock +1 -1
  17. data/spec/rails3_mongoid/spec/user_spec.rb +0 -10
  18. data/spec/sinatra/Gemfile.lock +1 -1
  19. data/spec/sinatra/Rakefile +1 -1
  20. data/spec/sinatra/filters.rb +20 -14
  21. data/spec/sinatra/modular.rb +157 -0
  22. data/spec/sinatra_modular/Gemfile +15 -0
  23. data/spec/sinatra_modular/Gemfile.lock +117 -0
  24. data/spec/sinatra_modular/Rakefile +11 -0
  25. data/spec/sinatra_modular/authentication.rb +3 -0
  26. data/spec/sinatra_modular/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  27. data/spec/sinatra_modular/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  28. data/spec/sinatra_modular/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  29. data/spec/sinatra_modular/db/migrate/core/20101224223620_create_users.rb +16 -0
  30. data/spec/sinatra_modular/db/migrate/external/20101224223628_create_authentications.rb +14 -0
  31. data/spec/sinatra_modular/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  32. data/spec/sinatra_modular/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  33. data/spec/sinatra_modular/filters.rb +27 -0
  34. data/spec/sinatra_modular/modular.rb +157 -0
  35. data/spec/sinatra_modular/myapp.rb +133 -0
  36. data/spec/sinatra_modular/sorcery_mailer.rb +25 -0
  37. data/spec/sinatra_modular/spec_modular/controller_activity_logging_spec.rb +85 -0
  38. data/spec/sinatra_modular/spec_modular/controller_brute_force_protection_spec.rb +70 -0
  39. data/spec/sinatra_modular/spec_modular/controller_http_basic_auth_spec.rb +53 -0
  40. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +120 -0
  41. data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +121 -0
  42. data/spec/sinatra_modular/spec_modular/controller_remember_me_spec.rb +64 -0
  43. data/spec/sinatra_modular/spec_modular/controller_session_timeout_spec.rb +57 -0
  44. data/spec/sinatra_modular/spec_modular/controller_spec.rb +116 -0
  45. data/spec/sinatra_modular/spec_modular/spec.opts +2 -0
  46. data/spec/sinatra_modular/spec_modular/spec_helper.rb +51 -0
  47. data/spec/sinatra_modular/user.rb +6 -0
  48. data/spec/sinatra_modular/views/test_login.erb +4 -0
  49. metadata +54 -2
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Modular do
4
+ before(:all) do
5
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/brute_force_protection")
6
+ end
7
+
8
+ after(:all) do
9
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/brute_force_protection")
10
+ end
11
+
12
+ # ----------------- SESSION TIMEOUT -----------------------
13
+ describe Modular, "with brute force protection features" do
14
+ before(:all) do
15
+ sorcery_reload!([:brute_force_protection])
16
+ end
17
+
18
+ before(:each) do
19
+ create_new_user
20
+ end
21
+
22
+ after(:each) do
23
+ Sorcery::Controller::Config.reset!
24
+ sorcery_controller_property_set(:user_class, User)
25
+ User.delete_all
26
+ Timecop.return
27
+ end
28
+
29
+ it "should count login retries" do
30
+ 3.times {get "/test_login", :username => 'gizmo', :password => 'blabla'}
31
+ User.find_by_username('gizmo').failed_logins_count.should == 3
32
+ end
33
+
34
+ it "should reset the counter on a good login" do
35
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 5)
36
+ 3.times {get "/test_login", :username => 'gizmo', :password => 'blabla'}
37
+ get "/test_login", :username => 'gizmo', :password => 'secret'
38
+ User.find_by_username('gizmo').failed_logins_count.should == 0
39
+ end
40
+
41
+ it "should lock user when number of retries reached the limit" do
42
+ User.find_by_username('gizmo').lock_expires_at.should be_nil
43
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
44
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
45
+ User.find_by_username('gizmo').lock_expires_at.should_not be_nil
46
+ end
47
+
48
+ it "should unlock after lock time period passes" do
49
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
50
+ sorcery_model_property_set(:login_lock_time_period, 0.2)
51
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
52
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
53
+ User.find_by_username('gizmo').lock_expires_at.should_not be_nil
54
+ Timecop.travel(Time.now+0.3)
55
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
56
+ User.find_by_username('gizmo').lock_expires_at.should be_nil
57
+ end
58
+
59
+ it "should not unlock if time period is 0 (permanent lock)" do
60
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
61
+ sorcery_model_property_set(:login_lock_time_period, 0)
62
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
63
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
64
+ unlock_date = User.find_by_username('gizmo').lock_expires_at
65
+ Timecop.travel(Time.now+1)
66
+ get "/test_login", :username => 'gizmo', :password => 'blabla'
67
+ User.find_by_username('gizmo').lock_expires_at.to_s.should == unlock_date.to_s
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'base64'
3
+
4
+ describe Modular do
5
+
6
+ # ----------------- HTTP BASIC AUTH -----------------------
7
+ describe Modular, "with http basic auth features" do
8
+ before(:all) do
9
+ sorcery_reload!([:http_basic_auth])
10
+ create_new_user
11
+ end
12
+
13
+ after(:each) do
14
+ get "/test_logout"
15
+ end
16
+
17
+ it "requests basic authentication when before_filter is used" do
18
+ session[:http_authentication_used] = nil
19
+ get "/test_http_basic_auth"
20
+ last_response.status.should == 401
21
+ session[:http_authentication_used].should == true
22
+ end
23
+
24
+ it "authenticates from http basic if credentials are sent" do
25
+ session[:http_authentication_used] = true
26
+ get "/test_http_basic_auth", {}, {"HTTP_AUTHORIZATION" => "Basic " + Base64::encode64("#{@user.username}:secret")}
27
+ last_response.should be_ok
28
+ end
29
+
30
+ it "fails authentication if credentials are wrong" do
31
+ session[:http_authentication_used] = true
32
+ get "/test_http_basic_auth", {}, {"HTTP_AUTHORIZATION" => "Basic " + Base64::encode64("#{@user.username}:wrong!")}
33
+ last_response.should redirect_to 'http://example.org/'
34
+ end
35
+
36
+ it "should allow configuration option 'controller_to_realm_map'" do
37
+ sorcery_controller_property_set(:controller_to_realm_map, {"1" => "2"})
38
+ Sorcery::Controller::Config.controller_to_realm_map.should == {"1" => "2"}
39
+ end
40
+
41
+ it "should display the correct realm name configured for the controller" do
42
+ sorcery_controller_property_set(:controller_to_realm_map, {"application" => "Salad"})
43
+ get "/test_http_basic_auth"
44
+ last_response.headers["WWW-Authenticate"].should == "Basic realm=\"Salad\""
45
+ end
46
+
47
+ it "should sign in the user's session on successful login" do
48
+ session[:http_authentication_used] = true
49
+ get "/test_http_basic_auth", {}, {"HTTP_AUTHORIZATION" => "Basic " + Base64::encode64("#{@user.username}:secret")}
50
+ session[:user_id].should == User.find_by_username(@user.username).id
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,120 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ def stub_all_oauth2_requests!
4
+ @client = OAuth2::Client.new("key","secret", :site => "http://myapi.com")
5
+ OAuth2::Client.stub!(:new).and_return(@client)
6
+ @acc_token = OAuth2::AccessToken.new(@client, "", "asd", nil, {})
7
+ @webby = @client.web_server
8
+ OAuth2::Strategy::WebServer.stub!(:new).and_return(@webby)
9
+ @webby.stub!(:get_access_token).and_return(@acc_token)
10
+ @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)
11
+ end
12
+
13
+ describe 'MyApp' do
14
+ before(:all) do
15
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/external")
16
+ sorcery_reload!([:external])
17
+ sorcery_controller_property_set(:external_providers, [:facebook])
18
+ sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
19
+ sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
20
+ sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
21
+ end
22
+
23
+ after(:all) do
24
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/external")
25
+ end
26
+ # ----------------- OAuth -----------------------
27
+ describe Modular, "with OAuth features" do
28
+
29
+ before(:each) do
30
+ stub_all_oauth2_requests!
31
+ end
32
+
33
+ after(:each) do
34
+ User.delete_all
35
+ Authentication.delete_all
36
+ end
37
+
38
+ it "login_at redirects correctly" do
39
+ create_new_user
40
+ get "/login_at_test2"
41
+ last_response.should be_a_redirect
42
+ #last_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")
43
+ last_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
+ end
45
+
46
+ it "'login_from' logins if user exists" do
47
+ sorcery_model_property_set(:authentications_class, Authentication)
48
+ create_new_external_user(:facebook)
49
+ get "/test_login_from2"
50
+ last_response.body.should == "Success!"
51
+ end
52
+
53
+ it "'login_from' fails if user doesn't exist" do
54
+ sorcery_model_property_set(:authentications_class, Authentication)
55
+ create_new_user
56
+ get "/test_login_from2"
57
+ last_response.body.should == "Failed!"
58
+ end
59
+ end
60
+
61
+ describe Modular, "'create_from'" do
62
+ before(:each) do
63
+ stub_all_oauth2_requests!
64
+ User.delete_all
65
+ Authentication.delete_all
66
+ end
67
+
68
+ it "should create a new user" do
69
+ sorcery_model_property_set(:authentications_class, Authentication)
70
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, {:username => "name"})
71
+ lambda do
72
+ get "/test_create_from_provider", :provider => "facebook"
73
+ end.should change(User, :count).by(1)
74
+ User.first.username.should == "Noam Ben Ari"
75
+ end
76
+
77
+ it "should support nested attributes" do
78
+ sorcery_model_property_set(:authentications_class, Authentication)
79
+ sorcery_controller_external_property_set(:facebook, :user_info_mapping, {:username => "hometown/name"})
80
+ lambda do
81
+ get "/test_create_from_provider", :provider => "facebook"
82
+ end.should change(User, :count).by(1)
83
+ User.first.username.should == "Haifa, Israel"
84
+ end
85
+ end
86
+
87
+ describe Modular, "OAuth with User Activation features" do
88
+ before(:all) do
89
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/activation")
90
+ sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
91
+ sorcery_controller_property_set(:external_providers, [:facebook])
92
+ sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
93
+ sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
94
+ sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
95
+ end
96
+
97
+ after(:all) do
98
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/activation")
99
+ end
100
+
101
+ after(:each) do
102
+ User.delete_all
103
+ end
104
+
105
+ it "should not send activation email to external users" do
106
+ old_size = ActionMailer::Base.deliveries.size
107
+ create_new_external_user(:facebook)
108
+ ActionMailer::Base.deliveries.size.should == old_size
109
+ end
110
+
111
+ it "should not send external users an activation success email" do
112
+ sorcery_model_property_set(:activation_success_email_method_name, nil)
113
+ create_new_external_user(:facebook)
114
+ old_size = ActionMailer::Base.deliveries.size
115
+ @user.activate!
116
+ ActionMailer::Base.deliveries.size.should == old_size
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'ostruct'
3
+
4
+ def stub_all_oauth_requests!
5
+ @consumer = OAuth::Consumer.new("key","secret", :site => "http://myapi.com")
6
+ OAuth::Consumer.stub!(:new).and_return(@consumer)
7
+ @req_token = OAuth::RequestToken.new(@consumer) # OpenStruct.new()
8
+ @consumer.stub!(:get_request_token).and_return(@req_token)
9
+ @acc_token = OAuth::AccessToken.new(@consumer)
10
+ @req_token.stub!(:get_access_token).and_return(@acc_token)
11
+ session[:request_token] = @req_token.token
12
+ session[:request_token_secret] = @req_token.secret
13
+ OAuth::RequestToken.stub!(:new).and_return(@req_token)
14
+ response = OpenStruct.new()
15
+ response.body = {"following"=>false, "listed_count"=>0, "profile_link_color"=>"0084B4", "profile_image_url"=>"http://a1.twimg.com/profile_images/536178575/noamb_normal.jpg", "description"=>"Programmer/Heavy Metal Fan/New Father", "status"=>{"text"=>"coming soon to sorcery gem: twitter and facebook authentication support.", "truncated"=>false, "favorited"=>false, "source"=>"web", "geo"=>nil, "in_reply_to_screen_name"=>nil, "in_reply_to_user_id"=>nil, "in_reply_to_status_id_str"=>nil, "created_at"=>"Sun Mar 06 23:01:12 +0000 2011", "contributors"=>nil, "place"=>nil, "retweeted"=>false, "in_reply_to_status_id"=>nil, "in_reply_to_user_id_str"=>nil, "coordinates"=>nil, "retweet_count"=>0, "id"=>44533012284706816, "id_str"=>"44533012284706816"}, "show_all_inline_media"=>false, "geo_enabled"=>true, "profile_sidebar_border_color"=>"a8c7f7", "url"=>nil, "followers_count"=>10, "screen_name"=>"nbenari", "profile_use_background_image"=>true, "location"=>"Israel", "statuses_count"=>25, "profile_background_color"=>"022330", "lang"=>"en", "verified"=>false, "notifications"=>false, "profile_background_image_url"=>"http://a3.twimg.com/profile_background_images/104087198/04042010339.jpg", "favourites_count"=>5, "created_at"=>"Fri Nov 20 21:58:19 +0000 2009", "is_translator"=>false, "contributors_enabled"=>false, "protected"=>false, "follow_request_sent"=>false, "time_zone"=>"Greenland", "profile_text_color"=>"333333", "name"=>"Noam Ben Ari", "friends_count"=>10, "profile_sidebar_fill_color"=>"C0DFEC", "id"=>123, "id_str"=>"91434812", "profile_background_tile"=>false, "utc_offset"=>-10800}.to_json
16
+ @acc_token.stub!(:get).and_return(response)
17
+ end
18
+
19
+ describe Modular do
20
+ before(:all) do
21
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/external")
22
+ sorcery_reload!([:external])
23
+ sorcery_controller_property_set(:external_providers, [:twitter])
24
+ sorcery_controller_external_property_set(:twitter, :key, "eYVNBjBDi33aa9GkA3w")
25
+ sorcery_controller_external_property_set(:twitter, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
26
+ sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com")
27
+ end
28
+
29
+ after(:all) do
30
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/external")
31
+ end
32
+ # ----------------- OAuth -----------------------
33
+ describe Modular, "'login_from'" do
34
+
35
+ before(:each) do
36
+ stub_all_oauth_requests!
37
+ end
38
+
39
+ after(:each) do
40
+ User.delete_all
41
+ Authentication.delete_all
42
+ end
43
+
44
+ it "login_at_test redirects correctly" do
45
+ create_new_user
46
+ get "/login_at_test"
47
+ last_response.should be_a_redirect
48
+ last_response.should redirect_to("http://myapi.com/oauth/authorize?oauth_callback=http%3A%2F%2Fblabla.com&oauth_token=")
49
+ end
50
+
51
+ it "logins if user exists" do
52
+ sorcery_model_property_set(:authentications_class, Authentication)
53
+ create_new_external_user(:twitter)
54
+ get '/test_login_from', :oauth_verifier => "blablaRERASDFcxvSDFA"
55
+ last_response.body.should == "Success!"
56
+ end
57
+
58
+ it "'login_from' fails if user doesn't exist" do
59
+ sorcery_model_property_set(:authentications_class, Authentication)
60
+ create_new_user
61
+ get '/test_login_from', :oauth_verifier => "blablaRERASDFcxvSDFA"
62
+ last_response.body.should == "Failed!"
63
+ end
64
+ end
65
+
66
+ describe Modular, "'create_from'" do
67
+ before(:each) do
68
+ stub_all_oauth_requests!
69
+ User.delete_all
70
+ Authentication.delete_all
71
+ end
72
+
73
+ it "should create a new user" do
74
+ sorcery_model_property_set(:authentications_class, Authentication)
75
+ sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "screen_name"})
76
+ lambda do
77
+ get :test_create_from_provider, :provider => "twitter"
78
+ end.should change(User, :count).by(1)
79
+ User.first.username.should == "nbenari"
80
+ end
81
+
82
+ it "should support nested attributes" do
83
+ sorcery_model_property_set(:authentications_class, Authentication)
84
+ sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "status/text"})
85
+ lambda do
86
+ get :test_create_from_provider, :provider => "twitter"
87
+ end.should change(User, :count).by(1)
88
+ User.first.username.should == "coming soon to sorcery gem: twitter and facebook authentication support."
89
+ end
90
+ end
91
+
92
+ describe Modular, "OAuth with User Activation features" do
93
+ before(:all) do
94
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/activation")
95
+ sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
96
+ end
97
+
98
+ after(:all) do
99
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/activation")
100
+ end
101
+
102
+ after(:each) do
103
+ User.delete_all
104
+ Authentication.delete_all
105
+ end
106
+
107
+ it "should not send activation email to external users" do
108
+ old_size = ActionMailer::Base.deliveries.size
109
+ create_new_external_user(:twitter)
110
+ ActionMailer::Base.deliveries.size.should == old_size
111
+ end
112
+
113
+ it "should not send external users an activation success email" do
114
+ sorcery_model_property_set(:activation_success_email_method_name, nil)
115
+ create_new_external_user(:twitter)
116
+ old_size = ActionMailer::Base.deliveries.size
117
+ @user.activate!
118
+ ActionMailer::Base.deliveries.size.should == old_size
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Modular do
4
+
5
+ # ----------------- REMEMBER ME -----------------------
6
+ describe Modular, "with remember me features" do
7
+ before(:all) do
8
+ ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/remember_me")
9
+ sorcery_reload!([:remember_me])
10
+ end
11
+
12
+ before(:each) do
13
+ create_new_user
14
+ end
15
+
16
+ after(:all) do
17
+ ActiveRecord::Migrator.rollback("#{APP_ROOT}/db/migrate/remember_me")
18
+ end
19
+
20
+ after(:each) do
21
+ session = nil
22
+ clear_cookies
23
+ User.delete_all
24
+ end
25
+
26
+ it "should set cookie on remember_me!" do
27
+ post "/test_login_with_remember", :username => 'gizmo', :password => 'secret'
28
+ cookies["remember_me_token"].should == assigns[:user].remember_me_token
29
+ end
30
+
31
+ it "should clear cookie on forget_me!" do
32
+ cookies["remember_me_token"] == {:value => 'asd54234dsfsd43534', :expires => 3600}
33
+ get '/test_logout'
34
+ cookies["remember_me_token"].should == nil
35
+ end
36
+
37
+ it "login(username,password,remember_me) should login and remember" do
38
+ 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
41
+ end
42
+
43
+ it "logout should also forget_me!" do
44
+ session[:user_id] = @user.id
45
+ get '/test_logout_with_remember'
46
+ cookies["remember_me_token"].should == nil
47
+ end
48
+
49
+ it "should login_from_cookie" do
50
+ post "/test_login_with_remember", :username => 'gizmo', :password => 'secret'
51
+ get_sinatra_app(subject).instance_eval do
52
+ @current_user = nil
53
+ end
54
+ session[:user_id] = nil
55
+ get '/test_login_from_cookie'
56
+ assigns[:current_user].should == @user
57
+ end
58
+
59
+ it "should not remember_me! when not asked to" do
60
+ post '/test_login', :username => 'gizmo', :password => 'secret'
61
+ cookies["remember_me_token"].should == nil
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Modular do
4
+
5
+ # ----------------- SESSION TIMEOUT -----------------------
6
+ describe Modular, "with session timeout features" do
7
+ before(:all) do
8
+ sorcery_reload!([:session_timeout])
9
+ sorcery_controller_property_set(:session_timeout,0.5)
10
+ create_new_user
11
+ end
12
+
13
+ after(:each) do
14
+ Timecop.return
15
+ end
16
+
17
+ it "should not reset session before session timeout" do
18
+ session[:user_id] = User.first.id
19
+ get "/test_should_be_logged_in"
20
+ last_response.should be_ok
21
+ end
22
+
23
+ it "should reset session after session timeout" do
24
+ get "/test_login", :username => 'gizmo', :password => 'secret'
25
+ session[:user_id].should_not be_nil
26
+ Timecop.travel(Time.now+0.6)
27
+ get "/test_should_be_logged_in"
28
+ last_response.should be_a_redirect
29
+ end
30
+
31
+ context "with 'session_timeout_from_last_action'" do
32
+ it "should not logout if there was activity" do
33
+ session[:user_id] = nil
34
+ sorcery_controller_property_set(:session_timeout,2)
35
+ sorcery_controller_property_set(:session_timeout_from_last_action, true)
36
+ get "/test_login", :username => 'gizmo', :password => 'secret'
37
+ Timecop.travel(Time.now+1)
38
+ get "/test_should_be_logged_in"
39
+ session[:user_id].should_not be_nil
40
+ Timecop.travel(Time.now+1)
41
+ get "/test_should_be_logged_in"
42
+ session[:user_id].should_not be_nil
43
+ last_response.should be_ok
44
+ end
45
+
46
+ it "should logout if there was no activity" do
47
+ sorcery_controller_property_set(:session_timeout,0.5)
48
+ sorcery_controller_property_set(:session_timeout_from_last_action, true)
49
+ get "/test_login", :username => 'gizmo', :password => 'secret'
50
+ Timecop.travel(Time.now+0.6)
51
+ get "/test_should_be_logged_in"
52
+ session[:user_id].should be_nil
53
+ last_response.should be_a_redirect
54
+ end
55
+ end
56
+ end
57
+ end