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.
- data/Gemfile +5 -2
- data/Gemfile.lock +12 -0
- data/README.rdoc +12 -7
- data/VERSION +1 -1
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -1
- data/lib/sorcery/crypto_providers/common.rb +2 -2
- data/lib/sorcery/engine.rb +0 -4
- data/lib/sorcery/initializers/initializer.rb +1 -0
- data/lib/sorcery/model/adapters/active_record.rb +28 -0
- data/lib/sorcery/model/adapters/mongoid.rb +59 -0
- data/lib/sorcery/model/submodules/activity_logging.rb +12 -3
- data/lib/sorcery/model/submodules/brute_force_protection.rb +6 -1
- data/lib/sorcery/model/submodules/external.rb +1 -0
- data/lib/sorcery/model/submodules/remember_me.rb +15 -1
- data/lib/sorcery/model/submodules/reset_password.rb +10 -3
- data/lib/sorcery/model/submodules/user_activation.rb +11 -1
- data/lib/sorcery/model/temporary_token.rb +1 -1
- data/lib/sorcery/model.rb +15 -7
- data/lib/sorcery/sinatra.rb +0 -1
- data/lib/sorcery/test_helpers/internal/sinatra.rb +6 -54
- data/lib/sorcery/test_helpers/internal.rb +2 -1
- data/lib/sorcery/test_helpers/sinatra.rb +4 -1
- data/lib/sorcery.rb +22 -1
- data/sorcery.gemspec +107 -10
- data/spec/Gemfile.lock +1 -1
- data/spec/rails3/Gemfile.lock +5 -5
- data/spec/rails3/spec/user_reset_password_spec.rb +2 -2
- data/spec/rails3/spec/user_spec.rb +0 -1
- data/spec/rails3_mongoid/.gitignore +4 -0
- data/spec/rails3_mongoid/.rspec +1 -0
- data/spec/rails3_mongoid/Gemfile +14 -0
- data/spec/rails3_mongoid/Gemfile.lock +146 -0
- data/spec/rails3_mongoid/Rakefile +11 -0
- data/spec/rails3_mongoid/app/controllers/application_controller.rb +108 -0
- data/spec/rails3_mongoid/app/helpers/application_helper.rb +2 -0
- data/spec/rails3_mongoid/app/mailers/sorcery_mailer.rb +25 -0
- data/spec/rails3_mongoid/app/models/authentication.rb +7 -0
- data/spec/rails3_mongoid/app/models/user.rb +5 -0
- data/spec/rails3_mongoid/app/views/layouts/application.html.erb +14 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails3_mongoid/config/application.rb +51 -0
- data/spec/rails3_mongoid/config/boot.rb +13 -0
- data/spec/rails3_mongoid/config/environment.rb +5 -0
- data/spec/rails3_mongoid/config/environments/development.rb +26 -0
- data/spec/rails3_mongoid/config/environments/in_memory.rb +0 -0
- data/spec/rails3_mongoid/config/environments/production.rb +49 -0
- data/spec/rails3_mongoid/config/environments/test.rb +35 -0
- data/spec/rails3_mongoid/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails3_mongoid/config/initializers/inflections.rb +10 -0
- data/spec/rails3_mongoid/config/initializers/mime_types.rb +5 -0
- data/spec/rails3_mongoid/config/initializers/secret_token.rb +7 -0
- data/spec/rails3_mongoid/config/initializers/session_store.rb +8 -0
- data/spec/rails3_mongoid/config/locales/en.yml +5 -0
- data/spec/rails3_mongoid/config/mongoid.yml +7 -0
- data/spec/rails3_mongoid/config/routes.rb +59 -0
- data/spec/rails3_mongoid/config.ru +4 -0
- data/spec/rails3_mongoid/db/schema.rb +23 -0
- data/spec/rails3_mongoid/db/seeds.rb +7 -0
- data/spec/rails3_mongoid/lib/tasks/.gitkeep +0 -0
- data/spec/rails3_mongoid/public/404.html +26 -0
- data/spec/rails3_mongoid/public/422.html +26 -0
- data/spec/rails3_mongoid/public/500.html +26 -0
- data/spec/rails3_mongoid/public/favicon.ico +0 -0
- data/spec/rails3_mongoid/public/images/rails.png +0 -0
- data/spec/rails3_mongoid/public/javascripts/application.js +2 -0
- data/spec/rails3_mongoid/public/javascripts/controls.js +965 -0
- data/spec/rails3_mongoid/public/javascripts/dragdrop.js +974 -0
- data/spec/rails3_mongoid/public/javascripts/effects.js +1123 -0
- data/spec/rails3_mongoid/public/javascripts/prototype.js +6001 -0
- data/spec/rails3_mongoid/public/javascripts/rails.js +175 -0
- data/spec/rails3_mongoid/public/robots.txt +5 -0
- data/spec/rails3_mongoid/public/stylesheets/.gitkeep +0 -0
- data/spec/rails3_mongoid/script/rails +6 -0
- data/spec/rails3_mongoid/spec/spec.opts +2 -0
- data/spec/rails3_mongoid/spec/spec_helper.orig.rb +27 -0
- data/spec/rails3_mongoid/spec/spec_helper.rb +55 -0
- data/spec/rails3_mongoid/spec/user_activation_spec.rb +178 -0
- data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +31 -0
- data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +41 -0
- data/spec/rails3_mongoid/spec/user_oauth_spec.rb +34 -0
- data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +51 -0
- data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +174 -0
- data/spec/rails3_mongoid/spec/user_spec.rb +329 -0
- data/spec/rails3_mongoid/vendor/plugins/.gitkeep +0 -0
- data/spec/sinatra/Gemfile.lock +5 -5
- data/spec/sinatra/spec/spec_helper.rb +0 -1
- metadata +150 -37
- 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
|
+
})();
|
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,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
|