sorcery 0.4.2 → 0.5.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 (93) hide show
  1. data/Gemfile +5 -2
  2. data/Gemfile.lock +12 -0
  3. data/README.rdoc +12 -7
  4. data/VERSION +1 -1
  5. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -1
  6. data/lib/sorcery/crypto_providers/common.rb +2 -2
  7. data/lib/sorcery/engine.rb +0 -4
  8. data/lib/sorcery/initializers/initializer.rb +1 -0
  9. data/lib/sorcery/model/adapters/active_record.rb +28 -0
  10. data/lib/sorcery/model/adapters/mongoid.rb +59 -0
  11. data/lib/sorcery/model/submodules/activity_logging.rb +12 -3
  12. data/lib/sorcery/model/submodules/brute_force_protection.rb +6 -1
  13. data/lib/sorcery/model/submodules/external.rb +1 -0
  14. data/lib/sorcery/model/submodules/remember_me.rb +15 -1
  15. data/lib/sorcery/model/submodules/reset_password.rb +10 -3
  16. data/lib/sorcery/model/submodules/user_activation.rb +11 -1
  17. data/lib/sorcery/model/temporary_token.rb +1 -1
  18. data/lib/sorcery/model.rb +15 -7
  19. data/lib/sorcery/sinatra.rb +0 -1
  20. data/lib/sorcery/test_helpers/internal/sinatra.rb +6 -54
  21. data/lib/sorcery/test_helpers/internal.rb +2 -1
  22. data/lib/sorcery/test_helpers/sinatra.rb +4 -1
  23. data/lib/sorcery.rb +22 -1
  24. data/sorcery.gemspec +107 -10
  25. data/spec/Gemfile.lock +1 -1
  26. data/spec/rails3/Gemfile.lock +5 -5
  27. data/spec/rails3/spec/user_reset_password_spec.rb +2 -2
  28. data/spec/rails3/spec/user_spec.rb +0 -1
  29. data/spec/rails3_mongoid/.gitignore +4 -0
  30. data/spec/rails3_mongoid/.rspec +1 -0
  31. data/spec/rails3_mongoid/Gemfile +14 -0
  32. data/spec/rails3_mongoid/Gemfile.lock +146 -0
  33. data/spec/rails3_mongoid/Rakefile +11 -0
  34. data/spec/rails3_mongoid/app/controllers/application_controller.rb +108 -0
  35. data/spec/rails3_mongoid/app/helpers/application_helper.rb +2 -0
  36. data/spec/rails3_mongoid/app/mailers/sorcery_mailer.rb +25 -0
  37. data/spec/rails3_mongoid/app/models/authentication.rb +7 -0
  38. data/spec/rails3_mongoid/app/models/user.rb +5 -0
  39. data/spec/rails3_mongoid/app/views/layouts/application.html.erb +14 -0
  40. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  41. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  42. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  43. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  44. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  45. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  46. data/spec/rails3_mongoid/config/application.rb +51 -0
  47. data/spec/rails3_mongoid/config/boot.rb +13 -0
  48. data/spec/rails3_mongoid/config/environment.rb +5 -0
  49. data/spec/rails3_mongoid/config/environments/development.rb +26 -0
  50. data/spec/rails3_mongoid/config/environments/in_memory.rb +0 -0
  51. data/spec/rails3_mongoid/config/environments/production.rb +49 -0
  52. data/spec/rails3_mongoid/config/environments/test.rb +35 -0
  53. data/spec/rails3_mongoid/config/initializers/backtrace_silencers.rb +7 -0
  54. data/spec/rails3_mongoid/config/initializers/inflections.rb +10 -0
  55. data/spec/rails3_mongoid/config/initializers/mime_types.rb +5 -0
  56. data/spec/rails3_mongoid/config/initializers/secret_token.rb +7 -0
  57. data/spec/rails3_mongoid/config/initializers/session_store.rb +8 -0
  58. data/spec/rails3_mongoid/config/locales/en.yml +5 -0
  59. data/spec/rails3_mongoid/config/mongoid.yml +7 -0
  60. data/spec/rails3_mongoid/config/routes.rb +59 -0
  61. data/spec/rails3_mongoid/config.ru +4 -0
  62. data/spec/rails3_mongoid/db/schema.rb +23 -0
  63. data/spec/rails3_mongoid/db/seeds.rb +7 -0
  64. data/spec/rails3_mongoid/lib/tasks/.gitkeep +0 -0
  65. data/spec/rails3_mongoid/public/404.html +26 -0
  66. data/spec/rails3_mongoid/public/422.html +26 -0
  67. data/spec/rails3_mongoid/public/500.html +26 -0
  68. data/spec/rails3_mongoid/public/favicon.ico +0 -0
  69. data/spec/rails3_mongoid/public/images/rails.png +0 -0
  70. data/spec/rails3_mongoid/public/javascripts/application.js +2 -0
  71. data/spec/rails3_mongoid/public/javascripts/controls.js +965 -0
  72. data/spec/rails3_mongoid/public/javascripts/dragdrop.js +974 -0
  73. data/spec/rails3_mongoid/public/javascripts/effects.js +1123 -0
  74. data/spec/rails3_mongoid/public/javascripts/prototype.js +6001 -0
  75. data/spec/rails3_mongoid/public/javascripts/rails.js +175 -0
  76. data/spec/rails3_mongoid/public/robots.txt +5 -0
  77. data/spec/rails3_mongoid/public/stylesheets/.gitkeep +0 -0
  78. data/spec/rails3_mongoid/script/rails +6 -0
  79. data/spec/rails3_mongoid/spec/spec.opts +2 -0
  80. data/spec/rails3_mongoid/spec/spec_helper.orig.rb +27 -0
  81. data/spec/rails3_mongoid/spec/spec_helper.rb +55 -0
  82. data/spec/rails3_mongoid/spec/user_activation_spec.rb +178 -0
  83. data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +31 -0
  84. data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +41 -0
  85. data/spec/rails3_mongoid/spec/user_oauth_spec.rb +34 -0
  86. data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +51 -0
  87. data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +174 -0
  88. data/spec/rails3_mongoid/spec/user_spec.rb +329 -0
  89. data/spec/rails3_mongoid/vendor/plugins/.gitkeep +0 -0
  90. data/spec/sinatra/Gemfile.lock +5 -5
  91. data/spec/sinatra/spec/spec_helper.rb +0 -1
  92. metadata +150 -37
  93. data/spec/untitled folder +0 -18
@@ -0,0 +1,175 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+ })();
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,27 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require File.expand_path("../../config/environment", __FILE__)
4
+ require 'rspec/rails'
5
+
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ # == Mock Framework
12
+ #
13
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
14
+ #
15
+ # config.mock_with :mocha
16
+ # config.mock_with :flexmock
17
+ # config.mock_with :rr
18
+ config.mock_with :rspec
19
+
20
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
21
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
22
+
23
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
24
+ # examples within a transaction, remove the following line or assign false
25
+ # instead of true.
26
+ config.use_transactional_fixtures = true
27
+ end
@@ -0,0 +1,55 @@
1
+ $: << File.join(File.dirname(__FILE__), '..', '..', 'lib' )
2
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
3
+ ENV['RAILS_ENV'] ||= 'test'
4
+ require File.expand_path("../../config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+ require 'timecop'
7
+
8
+ # require 'simplecov'
9
+ # SimpleCov.root File.join(File.dirname(__FILE__), "..", "..", "rails3" )
10
+ # SimpleCov.start do
11
+ # add_filter "/config/"
12
+ #
13
+ # add_group 'Controllers', 'app/controllers'
14
+ # add_group 'Models', 'app/models'
15
+ # add_group 'Helpers', 'app/helpers'
16
+ # add_group 'Libraries', 'lib'
17
+ # add_group 'Plugins', 'vendor/plugins'
18
+ # add_group 'Migrations', 'db/migrate'
19
+ # end
20
+
21
+ # Requires supporting ruby files with custom matchers and macros, etc,
22
+ # in spec/support/ and its subdirectories.
23
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
24
+
25
+
26
+
27
+ RSpec.configure do |config|
28
+ config.include RSpec::Rails::ControllerExampleGroup, :example_group => { :file_path => /controller(.)*_spec.rb$/ }
29
+ # == Mock Framework
30
+ #
31
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
32
+ #
33
+ # config.mock_with :mocha
34
+ # config.mock_with :flexmock
35
+ # config.mock_with :rr
36
+ config.mock_with :rspec
37
+ end
38
+
39
+ #----------------------------------------------------------------
40
+ # needed when running individual specs
41
+ require File.join(File.dirname(__FILE__), '..','app','models','user')
42
+ require File.join(File.dirname(__FILE__), '..','app','models','authentication')
43
+
44
+ class TestUser
45
+ include Mongoid::Document
46
+ authenticates_with_sorcery!
47
+ end
48
+
49
+ class TestMailer < ActionMailer::Base
50
+
51
+ end
52
+
53
+ include ::Sorcery::TestHelpers::Internal
54
+ include ::Sorcery::TestHelpers::Internal::Rails
55
+
@@ -0,0 +1,178 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../app/mailers/sorcery_mailer')
3
+
4
+ describe "User with activation submodule" do
5
+
6
+ # ----------------- PLUGIN CONFIGURATION -----------------------
7
+ describe User, "loaded plugin configuration" do
8
+ before(:all) do
9
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
10
+ end
11
+
12
+ after(:each) do
13
+ User.sorcery_config.reset!
14
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
15
+ end
16
+
17
+ it "should enable configuration option 'activation_state_attribute_name'" do
18
+ sorcery_model_property_set(:activation_state_attribute_name, :status)
19
+ User.sorcery_config.activation_state_attribute_name.should equal(:status)
20
+ end
21
+
22
+ it "should enable configuration option 'activation_token_attribute_name'" do
23
+ sorcery_model_property_set(:activation_token_attribute_name, :code)
24
+ User.sorcery_config.activation_token_attribute_name.should equal(:code)
25
+ end
26
+
27
+ it "should enable configuration option 'user_activation_mailer'" do
28
+ sorcery_model_property_set(:user_activation_mailer, TestMailer)
29
+ User.sorcery_config.user_activation_mailer.should equal(TestMailer)
30
+ end
31
+
32
+ it "should enable configuration option 'activation_needed_email_method_name'" do
33
+ sorcery_model_property_set(:activation_needed_email_method_name, :my_activation_email)
34
+ User.sorcery_config.activation_needed_email_method_name.should equal(:my_activation_email)
35
+ end
36
+
37
+ it "should enable configuration option 'activation_success_email_method_name'" do
38
+ sorcery_model_property_set(:activation_success_email_method_name, :my_activation_email)
39
+ User.sorcery_config.activation_success_email_method_name.should equal(:my_activation_email)
40
+ end
41
+
42
+ it "if mailer is nil on activation, throw exception!" do
43
+ expect{sorcery_reload!([:user_activation])}.to raise_error(ArgumentError)
44
+ end
45
+ end
46
+
47
+ # ----------------- ACTIVATION PROCESS -----------------------
48
+ describe User, "activation process" do
49
+ before(:all) do
50
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
51
+ end
52
+
53
+ before(:each) do
54
+ create_new_user
55
+ end
56
+
57
+ it "should initialize user state to 'pending'" do
58
+ @user.activation_state.should == "pending"
59
+ end
60
+
61
+ specify { @user.should respond_to(:activate!) }
62
+
63
+ it "should clear activation code and change state to 'active' on activation" do
64
+ activation_token = @user.activation_token
65
+ @user.activate!
66
+ @user2 = User.find(@user.id) # go to db to make sure it was saved and not just in memory
67
+ @user2.activation_token.should be_nil
68
+ @user2.activation_state.should == "active"
69
+ User.find_by_activation_token(activation_token).should be_nil
70
+ end
71
+
72
+ it "should send the user an activation email" do
73
+ old_size = ActionMailer::Base.deliveries.size
74
+ create_new_user
75
+ ActionMailer::Base.deliveries.size.should == old_size + 1
76
+ end
77
+
78
+ it "subsequent saves do not send activation email" do
79
+ old_size = ActionMailer::Base.deliveries.size
80
+ @user.username = "Shauli"
81
+ @user.save!
82
+ ActionMailer::Base.deliveries.size.should == old_size
83
+ end
84
+
85
+ it "should send the user an activation success email on successful activation" do
86
+ old_size = ActionMailer::Base.deliveries.size
87
+ @user.activate!
88
+ ActionMailer::Base.deliveries.size.should == old_size + 1
89
+ end
90
+
91
+ it "subsequent saves do not send activation success email" do
92
+ @user.activate!
93
+ old_size = ActionMailer::Base.deliveries.size
94
+ @user.username = "Shauli"
95
+ @user.save!
96
+ ActionMailer::Base.deliveries.size.should == old_size
97
+ end
98
+
99
+ it "activation needed email is optional" do
100
+ sorcery_model_property_set(:activation_needed_email_method_name, nil)
101
+ old_size = ActionMailer::Base.deliveries.size
102
+ create_new_user
103
+ ActionMailer::Base.deliveries.size.should == old_size
104
+ end
105
+
106
+ it "activation success email is optional" do
107
+ sorcery_model_property_set(:activation_success_email_method_name, nil)
108
+ old_size = ActionMailer::Base.deliveries.size
109
+ @user.activate!
110
+ ActionMailer::Base.deliveries.size.should == old_size
111
+ end
112
+ end
113
+
114
+ describe User, "prevent non-active login feature" do
115
+ before(:all) do
116
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
117
+ end
118
+
119
+ before(:each) do
120
+ User.delete_all
121
+ create_new_user
122
+ end
123
+
124
+ it "should not allow a non-active user to authenticate" do
125
+ User.authenticate(@user.username,'secret').should be_false
126
+ end
127
+
128
+ it "should allow a non-active user to authenticate if configured so" do
129
+ sorcery_model_property_set(:prevent_non_active_users_to_login, false)
130
+ User.authenticate(@user.username,'secret').should be_true
131
+ end
132
+ end
133
+
134
+ describe User, "load_from_activation_token" do
135
+ before(:all) do
136
+ sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
137
+ end
138
+
139
+ after(:each) do
140
+ Timecop.return
141
+ end
142
+
143
+ it "load_from_activation_token should return user when token is found" do
144
+ create_new_user
145
+ User.load_from_activation_token(@user.activation_token).should == @user
146
+ end
147
+
148
+ it "load_from_activation_token should NOT return user when token is NOT found" do
149
+ create_new_user
150
+ User.load_from_activation_token("a").should == nil
151
+ end
152
+
153
+ it "load_from_activation_token should return user when token is found and not expired" do
154
+ sorcery_model_property_set(:activation_token_expiration_period, 500)
155
+ create_new_user
156
+ User.load_from_activation_token(@user.activation_token).should == @user
157
+ end
158
+
159
+ it "load_from_activation_token should NOT return user when token is found and expired" do
160
+ sorcery_model_property_set(:activation_token_expiration_period, 0.1)
161
+ create_new_user
162
+ Timecop.travel(Time.now+0.5)
163
+ User.load_from_activation_token(@user.activation_token).should == nil
164
+ end
165
+
166
+ it "load_from_activation_token should return nil if token is blank" do
167
+ User.load_from_activation_token(nil).should == nil
168
+ User.load_from_activation_token("").should == nil
169
+ end
170
+
171
+ it "load_from_activation_token should always be valid if expiration period is nil" do
172
+ sorcery_model_property_set(:activation_token_expiration_period, nil)
173
+ create_new_user
174
+ User.load_from_activation_token(@user.activation_token).should == @user
175
+ end
176
+ end
177
+
178
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "User with activity logging submodule" do
4
+
5
+ # ----------------- PLUGIN CONFIGURATION -----------------------
6
+ describe User, "loaded plugin configuration" do
7
+ before(:all) do
8
+ sorcery_reload!([:activity_logging])
9
+ end
10
+
11
+ after(:each) do
12
+ User.sorcery_config.reset!
13
+ end
14
+
15
+ it "should allow configuration option 'last_login_at_attribute_name'" do
16
+ sorcery_model_property_set(:last_login_at_attribute_name, :login_time)
17
+ User.sorcery_config.last_login_at_attribute_name.should equal(:login_time)
18
+ end
19
+
20
+ it "should allow configuration option 'last_logout_at_attribute_name'" do
21
+ sorcery_model_property_set(:last_logout_at_attribute_name, :logout_time)
22
+ User.sorcery_config.last_logout_at_attribute_name.should equal(:logout_time)
23
+ end
24
+
25
+ it "should allow configuration option 'last_activity_at_attribute_name'" do
26
+ sorcery_model_property_set(:last_activity_at_attribute_name, :activity_time)
27
+ User.sorcery_config.last_activity_at_attribute_name.should equal(:activity_time)
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "User with brute_force_protection submodule" do
4
+
5
+ # ----------------- PLUGIN CONFIGURATION -----------------------
6
+ describe User, "loaded plugin configuration" do
7
+
8
+ before(:all) do
9
+ sorcery_reload!([:brute_force_protection])
10
+ create_new_user
11
+ end
12
+
13
+ after(:each) do
14
+ User.sorcery_config.reset!
15
+ end
16
+
17
+ specify { @user.should respond_to(:failed_logins_count) }
18
+ specify { @user.should respond_to(:lock_expires_at) }
19
+
20
+ it "should enable configuration option 'failed_logins_count_attribute_name'" do
21
+ sorcery_model_property_set(:failed_logins_count_attribute_name, :my_count)
22
+ User.sorcery_config.failed_logins_count_attribute_name.should equal(:my_count)
23
+ end
24
+
25
+ it "should enable configuration option 'lock_expires_at_attribute_name'" do
26
+ sorcery_model_property_set(:lock_expires_at_attribute_name, :expires)
27
+ User.sorcery_config.lock_expires_at_attribute_name.should equal(:expires)
28
+ end
29
+
30
+ it "should enable configuration option 'consecutive_login_retries_amount_allowed'" do
31
+ sorcery_model_property_set(:consecutive_login_retries_amount_limit, 34)
32
+ User.sorcery_config.consecutive_login_retries_amount_limit.should equal(34)
33
+ end
34
+
35
+ it "should enable configuration option 'login_lock_time_period'" do
36
+ sorcery_model_property_set(:login_lock_time_period, 2.hours)
37
+ User.sorcery_config.login_lock_time_period.should == 2.hours
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "User with oauth submodule" do
4
+
5
+ # ----------------- PLUGIN CONFIGURATION -----------------------
6
+ describe User, "loaded plugin configuration" do
7
+
8
+ before(:all) do
9
+ User.delete_all
10
+ Authentication.delete_all
11
+ sorcery_reload!([:external])
12
+ sorcery_controller_property_set(:external_providers, [:twitter])
13
+ sorcery_model_property_set(:authentications_class, Authentication)
14
+ sorcery_controller_external_property_set(:twitter, :key, "eYVNBjBDi33aa9GkA3w")
15
+ sorcery_controller_external_property_set(:twitter, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
16
+ sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com")
17
+ create_new_external_user(:twitter)
18
+ end
19
+
20
+ it "should respond to 'load_from_provider'" do
21
+ User.should respond_to(:load_from_provider)
22
+ end
23
+
24
+ it "'load_from_provider' should load user if exists" do
25
+ User.load_from_provider(:twitter,123).should == @user
26
+ end
27
+
28
+ it "'load_from_provider' should return nil if user doesn't exist" do
29
+ User.load_from_provider(:twitter,980342).should be_nil
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "User with remember_me submodule" do
4
+
5
+ # ----------------- PLUGIN CONFIGURATION -----------------------
6
+ describe User, "loaded plugin configuration" do
7
+ before(:all) do
8
+ sorcery_reload!([:remember_me])
9
+ create_new_user
10
+ end
11
+
12
+ after(:each) do
13
+ User.sorcery_config.reset!
14
+ end
15
+
16
+ it "should allow configuration option 'remember_me_token_attribute_name'" do
17
+ sorcery_model_property_set(:remember_me_token_attribute_name, :my_token)
18
+ User.sorcery_config.remember_me_token_attribute_name.should equal(:my_token)
19
+ end
20
+
21
+ it "should allow configuration option 'remember_me_token_expires_at_attribute_name'" do
22
+ sorcery_model_property_set(:remember_me_token_expires_at_attribute_name, :my_expires)
23
+ User.sorcery_config.remember_me_token_expires_at_attribute_name.should equal(:my_expires)
24
+ end
25
+
26
+ specify { @user.should respond_to(:remember_me!) }
27
+
28
+ specify { @user.should respond_to(:forget_me!) }
29
+
30
+ it "should generate a new token on 'remember_me!'" do
31
+ @user.remember_me_token.should be_nil
32
+ @user.remember_me!
33
+ @user.remember_me_token.should_not be_nil
34
+ end
35
+
36
+ it "should set an expiration based on 'remember_me_for' attribute" do
37
+ sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24)
38
+ @user.remember_me!
39
+ @user.remember_me_token_expires_at.utc.to_s.should == (Time.now + 2 * 60 * 60 * 24).utc.to_s
40
+ end
41
+
42
+ it "should delete the token and expiration on 'forget_me!'" do
43
+ @user.remember_me!
44
+ @user.remember_me_token.should_not be_nil
45
+ @user.forget_me!
46
+ @user.remember_me_token.should be_nil
47
+ @user.remember_me_token_expires_at.should be_nil
48
+ end
49
+ end
50
+
51
+ end