sorcery 0.1.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/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +129 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +139 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/features/support/env.rb +13 -0
- data/lib/sorcery.rb +28 -0
- data/lib/sorcery/controller.rb +156 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +89 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +43 -0
- data/lib/sorcery/controller/submodules/session_timeout.rb +42 -0
- data/lib/sorcery/crypto_providers/aes256.rb +44 -0
- data/lib/sorcery/crypto_providers/bcrypt.rb +96 -0
- data/lib/sorcery/crypto_providers/md5.rb +39 -0
- data/lib/sorcery/crypto_providers/sha1.rb +40 -0
- data/lib/sorcery/crypto_providers/sha256.rb +55 -0
- data/lib/sorcery/crypto_providers/sha512.rb +55 -0
- data/lib/sorcery/engine.rb +20 -0
- data/lib/sorcery/model.rb +175 -0
- data/lib/sorcery/model/submodules/password_reset.rb +64 -0
- data/lib/sorcery/model/submodules/remember_me.rb +42 -0
- data/lib/sorcery/model/submodules/user_activation.rb +84 -0
- data/spec/Gemfile +11 -0
- data/spec/Gemfile.lock +108 -0
- data/spec/Rakefile +11 -0
- data/spec/rails3/.rspec +1 -0
- data/spec/rails3/Gemfile +12 -0
- data/spec/rails3/Gemfile.lock +114 -0
- data/spec/rails3/Rakefile +10 -0
- data/spec/rails3/app_root/.gitignore +4 -0
- data/spec/rails3/app_root/README +256 -0
- data/spec/rails3/app_root/Rakefile.unused +7 -0
- data/spec/rails3/app_root/app/controllers/application_controller.rb +61 -0
- data/spec/rails3/app_root/app/helpers/application_helper.rb +2 -0
- data/spec/rails3/app_root/app/mailers/sorcery_mailer.rb +25 -0
- data/spec/rails3/app_root/app/models/user.rb +3 -0
- data/spec/rails3/app_root/app/views/layouts/application.html.erb +14 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails3/app_root/config.ru +4 -0
- data/spec/rails3/app_root/config/application.rb +48 -0
- data/spec/rails3/app_root/config/boot.rb +13 -0
- data/spec/rails3/app_root/config/database.yml +27 -0
- data/spec/rails3/app_root/config/environment.rb +5 -0
- data/spec/rails3/app_root/config/environments/development.rb +26 -0
- data/spec/rails3/app_root/config/environments/in_memory.rb +0 -0
- data/spec/rails3/app_root/config/environments/production.rb +49 -0
- data/spec/rails3/app_root/config/environments/test.rb +35 -0
- data/spec/rails3/app_root/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails3/app_root/config/initializers/inflections.rb +10 -0
- data/spec/rails3/app_root/config/initializers/mime_types.rb +5 -0
- data/spec/rails3/app_root/config/initializers/secret_token.rb +7 -0
- data/spec/rails3/app_root/config/initializers/session_store.rb +8 -0
- data/spec/rails3/app_root/config/locales/en.yml +5 -0
- data/spec/rails3/app_root/config/routes.rb +67 -0
- data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +15 -0
- data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +9 -0
- data/spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/rails3/app_root/db/schema.rb +23 -0
- data/spec/rails3/app_root/db/seeds.rb +7 -0
- data/spec/rails3/app_root/lib/tasks/.gitkeep +0 -0
- data/spec/rails3/app_root/public/404.html +26 -0
- data/spec/rails3/app_root/public/422.html +26 -0
- data/spec/rails3/app_root/public/500.html +26 -0
- data/spec/rails3/app_root/public/favicon.ico +0 -0
- data/spec/rails3/app_root/public/images/rails.png +0 -0
- data/spec/rails3/app_root/public/index.html +239 -0
- data/spec/rails3/app_root/public/javascripts/application.js +2 -0
- data/spec/rails3/app_root/public/javascripts/controls.js +965 -0
- data/spec/rails3/app_root/public/javascripts/dragdrop.js +974 -0
- data/spec/rails3/app_root/public/javascripts/effects.js +1123 -0
- data/spec/rails3/app_root/public/javascripts/prototype.js +6001 -0
- data/spec/rails3/app_root/public/javascripts/rails.js +175 -0
- data/spec/rails3/app_root/public/robots.txt +5 -0
- data/spec/rails3/app_root/public/stylesheets/.gitkeep +0 -0
- data/spec/rails3/app_root/script/rails +6 -0
- data/spec/rails3/app_root/test/fixtures/users.yml +9 -0
- data/spec/rails3/app_root/test/performance/browsing_test.rb +9 -0
- data/spec/rails3/app_root/test/test_helper.rb +13 -0
- data/spec/rails3/app_root/test/unit/user_test.rb +8 -0
- data/spec/rails3/app_root/vendor/plugins/.gitkeep +0 -0
- data/spec/rails3/controller_brute_force_protection_spec.rb +72 -0
- data/spec/rails3/controller_remember_me_spec.rb +65 -0
- data/spec/rails3/controller_session_timeout_spec.rb +49 -0
- data/spec/rails3/controller_spec.rb +115 -0
- data/spec/rails3/spec_helper.rb +115 -0
- data/spec/rails3/user_activation_spec.rb +148 -0
- data/spec/rails3/user_password_reset_spec.rb +76 -0
- data/spec/rails3/user_remember_me_spec.rb +66 -0
- data/spec/rails3/user_spec.rb +283 -0
- data/spec/sorcery_crypto_providers_spec.rb +182 -0
- data/spec/spec_helper.rb +18 -0
- metadata +341 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), '..', '..', 'lib' )
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.root File.join(File.dirname(__FILE__), "app_root" )
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter "/config/"
|
7
|
+
|
8
|
+
add_group 'Controllers', 'app/controllers'
|
9
|
+
add_group 'Models', 'app/models'
|
10
|
+
add_group 'Helpers', 'app/helpers'
|
11
|
+
add_group 'Libraries', 'lib'
|
12
|
+
add_group 'Plugins', 'vendor/plugins'
|
13
|
+
add_group 'Migrations', 'db/migrate'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Set the default environment to sqlite3's in_memory database
|
17
|
+
ENV['RAILS_ENV'] ||= 'in_memory'
|
18
|
+
ENV['RAILS_ROOT'] = 'app_root'
|
19
|
+
|
20
|
+
# Load the Rails environment and testing framework
|
21
|
+
require "#{File.dirname(__FILE__)}/app_root/config/environment"
|
22
|
+
#require "#{File.dirname(__FILE__)}/../../init" # for plugins
|
23
|
+
require 'rspec/rails'
|
24
|
+
#require 'sorcery'
|
25
|
+
|
26
|
+
# Undo changes to RAILS_ENV
|
27
|
+
silence_warnings {RAILS_ENV = ENV['RAILS_ENV']}
|
28
|
+
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.use_transactional_fixtures = true
|
31
|
+
config.use_instantiated_fixtures = false
|
32
|
+
config.include RSpec::Rails::ControllerExampleGroup, :example_group => { :file_path => /controller(.)*_spec.rb$/ }#:file_path => /\bspec[\\\/]controllers[\\\/]/ }
|
33
|
+
|
34
|
+
config.before(:suite) do
|
35
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/core")
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after(:suite) do
|
39
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/core")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#----------------------------------------------------------------
|
44
|
+
#require File.join(File.dirname(__FILE__), 'app_root','app','models','user')
|
45
|
+
|
46
|
+
class TestUser < ActiveRecord::Base
|
47
|
+
activate_sorcery!
|
48
|
+
end
|
49
|
+
|
50
|
+
class TestMailer < ActionMailer::Base
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
module Sorcery
|
55
|
+
module Model
|
56
|
+
module Submodules
|
57
|
+
module TestSubmodule
|
58
|
+
def my_instance_method
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_new_user
|
66
|
+
user_attributes_hash = {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
|
67
|
+
@user = User.new(user_attributes_hash)
|
68
|
+
@user.save!
|
69
|
+
end
|
70
|
+
|
71
|
+
def login_user
|
72
|
+
subject.send(:login_user,@user)
|
73
|
+
subject.send(:after_login!,@user,['gizmo','secret'])
|
74
|
+
end
|
75
|
+
|
76
|
+
# TODO: rename to sorcery_reload!(subs = [], model_opts = {}, controller_opts = {})
|
77
|
+
def plugin_model_configure(submodules = [], options = {})
|
78
|
+
reload_user_class
|
79
|
+
|
80
|
+
# return to no-module configuration
|
81
|
+
::Sorcery::Controller::Config.init!
|
82
|
+
::Sorcery::Controller::Config.reset!
|
83
|
+
|
84
|
+
# configure
|
85
|
+
::Sorcery::Controller::Config.submodules = submodules
|
86
|
+
::Sorcery::Controller::Config.user_class = nil # the next line will reset it to User
|
87
|
+
ApplicationController.send(:include,::Sorcery::Controller)
|
88
|
+
|
89
|
+
User.activate_sorcery! do |config|
|
90
|
+
options.each do |property,value|
|
91
|
+
config.send(:"#{property}=", value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO: rename to sorcery_model_property_set(prop, val)
|
97
|
+
def plugin_set_model_config_property(property, *values)
|
98
|
+
User.class_eval do
|
99
|
+
sorcery_config.send(:"#{property}=", *values)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# TODO: rename to sorcery_controller_property_set(prop, val)
|
104
|
+
def plugin_set_controller_config_property(property, value)
|
105
|
+
ApplicationController.activate_sorcery! do |config|
|
106
|
+
config.send(:"#{property}=", value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def reload_user_class
|
113
|
+
Object.send(:remove_const,:User)
|
114
|
+
load 'user.rb'
|
115
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/app_root/app/mailers/sorcery_mailer')
|
3
|
+
|
4
|
+
describe "User with activation submodule" do
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:all) do
|
10
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
|
11
|
+
end
|
12
|
+
|
13
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
14
|
+
describe User, "loaded plugin configuration" do
|
15
|
+
before(:all) do
|
16
|
+
plugin_model_configure([:user_activation], :sorcery_mailer => ::SorceryMailer)
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
User.sorcery_config.reset!
|
21
|
+
plugin_model_configure([:user_activation], :sorcery_mailer => ::SorceryMailer)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should enable configuration option 'activation_state_attribute_name'" do
|
25
|
+
plugin_set_model_config_property(:activation_state_attribute_name, :status)
|
26
|
+
User.sorcery_config.activation_state_attribute_name.should equal(:status)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should enable configuration option 'activation_code_attribute_name'" do
|
30
|
+
plugin_set_model_config_property(:activation_code_attribute_name, :code)
|
31
|
+
User.sorcery_config.activation_code_attribute_name.should equal(:code)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should enable configuration option 'sorcery_mailer'" do
|
35
|
+
plugin_set_model_config_property(:sorcery_mailer, TestMailer)
|
36
|
+
User.sorcery_config.sorcery_mailer.should equal(TestMailer)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should enable configuration option 'activation_needed_email_method_name'" do
|
40
|
+
plugin_set_model_config_property(:activation_needed_email_method_name, :my_activation_email)
|
41
|
+
User.sorcery_config.activation_needed_email_method_name.should equal(:my_activation_email)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should enable configuration option 'activation_success_email_method_name'" do
|
45
|
+
plugin_set_model_config_property(:activation_success_email_method_name, :my_activation_email)
|
46
|
+
User.sorcery_config.activation_success_email_method_name.should equal(:my_activation_email)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "if mailer is nil on activation, throw exception!" do
|
50
|
+
expect{plugin_model_configure([:user_activation])}.to raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# ----------------- ACTIVATION PROCESS -----------------------
|
55
|
+
describe User, "activation process" do
|
56
|
+
before(:all) do
|
57
|
+
plugin_model_configure([:user_activation], :sorcery_mailer => ::SorceryMailer)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should generate an activation code on registration" do
|
61
|
+
create_new_user
|
62
|
+
@user.activation_code.should_not be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should initialize user state to 'pending'" do
|
66
|
+
create_new_user
|
67
|
+
@user.activation_state.should == "pending"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should respond to 'activate!'" do
|
71
|
+
create_new_user
|
72
|
+
@user.should respond_to(:activate!)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should clear activation code and change state to 'active' on activation" do
|
76
|
+
create_new_user
|
77
|
+
activation_code = @user.activation_code
|
78
|
+
@user.activate!
|
79
|
+
@user2 = User.find(@user.id) # go to db to make sure it was saved and not just in memory
|
80
|
+
@user2.activation_code.should be_nil
|
81
|
+
@user2.activation_state.should == "active"
|
82
|
+
User.find_by_activation_code(activation_code).should be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should send the user an activation email" do
|
86
|
+
old_size = ActionMailer::Base.deliveries.size
|
87
|
+
create_new_user
|
88
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
89
|
+
end
|
90
|
+
|
91
|
+
it "subsequent saves do not send activation email" do
|
92
|
+
create_new_user
|
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 "should send the user an activation success email on successful activation" do
|
100
|
+
create_new_user
|
101
|
+
old_size = ActionMailer::Base.deliveries.size
|
102
|
+
@user.activate!
|
103
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
104
|
+
end
|
105
|
+
|
106
|
+
it "subsequent saves do not send activation success email" do
|
107
|
+
create_new_user
|
108
|
+
@user.activate!
|
109
|
+
old_size = ActionMailer::Base.deliveries.size
|
110
|
+
@user.username = "Shauli"
|
111
|
+
@user.save!
|
112
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
113
|
+
end
|
114
|
+
|
115
|
+
it "activation needed email is optional" do
|
116
|
+
plugin_set_model_config_property(:activation_needed_email_method_name, nil)
|
117
|
+
old_size = ActionMailer::Base.deliveries.size
|
118
|
+
create_new_user
|
119
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
120
|
+
end
|
121
|
+
|
122
|
+
it "activation success email is optional" do
|
123
|
+
plugin_set_model_config_property(:activation_success_email_method_name, nil)
|
124
|
+
create_new_user
|
125
|
+
old_size = ActionMailer::Base.deliveries.size
|
126
|
+
@user.activate!
|
127
|
+
ActionMailer::Base.deliveries.size.should == old_size
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe User, "prevent non-active login feature" do
|
132
|
+
before(:all) do
|
133
|
+
plugin_model_configure([:user_activation], :sorcery_mailer => ::SorceryMailer)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should not allow a non-active user to authenticate" do
|
137
|
+
create_new_user
|
138
|
+
User.authenticate(@user.username,'secret').should be_false
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should allow a non-active user to authenticate if configured so" do
|
142
|
+
create_new_user
|
143
|
+
plugin_set_model_config_property(:prevent_non_active_users_to_login, false)
|
144
|
+
User.authenticate(@user.username,'secret').should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "User with password_reset submodule" do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/password_reset")
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/password_reset")
|
10
|
+
end
|
11
|
+
|
12
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
13
|
+
describe User, "loaded plugin configuration" do
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
plugin_model_configure([:password_reset], :sorcery_mailer => ::SorceryMailer)
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
User.sorcery_config.reset!
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should respond to 'reset_password!'" do
|
24
|
+
create_new_user
|
25
|
+
@user.should respond_to(:reset_password!)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# ----------------- PLUGIN ACTIVATED -----------------------
|
30
|
+
describe User, "when activated with sorcery" do
|
31
|
+
|
32
|
+
before(:all) do
|
33
|
+
plugin_model_configure([:password_reset], :sorcery_mailer => ::SorceryMailer)
|
34
|
+
end
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
User.delete_all
|
38
|
+
end
|
39
|
+
|
40
|
+
it "'reset_password!' should generate a reset_password_code" do
|
41
|
+
create_new_user
|
42
|
+
@user.reset_password_code.should be_nil
|
43
|
+
@user.reset_password!
|
44
|
+
@user.reset_password_code.should_not be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "the reset_password_code should be random" do
|
48
|
+
create_new_user
|
49
|
+
@user.reset_password!
|
50
|
+
old_password_code = @user.reset_password_code
|
51
|
+
@user.reset_password!
|
52
|
+
@user.reset_password_code.should_not == old_password_code
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should send an email on reset" do
|
56
|
+
create_new_user
|
57
|
+
old_size = ActionMailer::Base.deliveries.size
|
58
|
+
@user.reset_password!
|
59
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
60
|
+
end
|
61
|
+
|
62
|
+
it "when a new password is set, should delete reset_password_code" do
|
63
|
+
create_new_user
|
64
|
+
@user.reset_password!
|
65
|
+
@user.reset_password_code.should_not be_nil
|
66
|
+
@user.password = "blabulsdf"
|
67
|
+
@user.save!
|
68
|
+
@user.reset_password_code.should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "if mailer is nil on activation, throw exception!" do
|
72
|
+
expect{plugin_model_configure([:password_reset])}.to raise_error(ArgumentError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "User with remember_me submodule" do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/remember_me")
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/remember_me")
|
10
|
+
end
|
11
|
+
|
12
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
13
|
+
describe User, "loaded plugin configuration" do
|
14
|
+
before(:all) do
|
15
|
+
plugin_model_configure([:remember_me])
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
User.sorcery_config.reset!
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow configuration option 'remember_me_token_attribute_name'" do
|
23
|
+
plugin_set_model_config_property(:remember_me_token_attribute_name, :my_token)
|
24
|
+
User.sorcery_config.remember_me_token_attribute_name.should equal(:my_token)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow configuration option 'remember_me_token_expires_at_attribute_name'" do
|
28
|
+
plugin_set_model_config_property(:remember_me_token_expires_at_attribute_name, :my_expires)
|
29
|
+
User.sorcery_config.remember_me_token_expires_at_attribute_name.should equal(:my_expires)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should respond to 'remember_me!'" do
|
33
|
+
create_new_user
|
34
|
+
@user.should respond_to(:remember_me!)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should respond to 'forget_me!'" do
|
38
|
+
create_new_user
|
39
|
+
@user.should respond_to(:forget_me!)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should generate a new token on 'remember_me!'" do
|
43
|
+
create_new_user
|
44
|
+
@user.remember_me_token.should be_nil
|
45
|
+
@user.remember_me!
|
46
|
+
@user.remember_me_token.should_not be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should set an expiration based on 'remember_me_for' attribute" do
|
50
|
+
create_new_user
|
51
|
+
plugin_set_model_config_property(:remember_me_for, 2 * 60 * 60 * 24)
|
52
|
+
@user.remember_me!
|
53
|
+
@user.remember_me_token_expires_at.to_s.should == (Time.now + 2 * 60 * 60 * 24).utc.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should delete the token and expiration on 'forget_me!'" do
|
57
|
+
create_new_user
|
58
|
+
@user.remember_me!
|
59
|
+
@user.remember_me_token.should_not be_nil
|
60
|
+
@user.forget_me!
|
61
|
+
@user.remember_me_token.should be_nil
|
62
|
+
@user.remember_me_token_expires_at.should be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/app_root/app/mailers/sorcery_mailer')
|
3
|
+
|
4
|
+
describe "User with no submodules (core)" do
|
5
|
+
before(:all) do
|
6
|
+
plugin_model_configure
|
7
|
+
end
|
8
|
+
|
9
|
+
describe User, "when app has plugin loaded" do
|
10
|
+
it "should respond to the plugin activation class method" do
|
11
|
+
ActiveRecord::Base.should respond_to(:activate_sorcery!)
|
12
|
+
User.should respond_to(:activate_sorcery!)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "plugin activation should yield config to block" do
|
16
|
+
User.activate_sorcery! do |config|
|
17
|
+
config.class.should == ::Sorcery::Model::Config
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# ----------------- PLUGIN ACTIVATION -----------------------
|
23
|
+
describe TestUser, "Testing activated class self-registration" do
|
24
|
+
it "should register itself as user_class if activated" do
|
25
|
+
TestUser.class_eval do
|
26
|
+
activate_sorcery!
|
27
|
+
end
|
28
|
+
::Sorcery::Controller::Config.user_class.should == TestUser
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
33
|
+
describe User, "loaded plugin configuration" do
|
34
|
+
after(:each) do
|
35
|
+
User.sorcery_config.reset!
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should enable configuration option 'username_attribute_name'" do
|
39
|
+
plugin_set_model_config_property(:username_attribute_name, :email)
|
40
|
+
User.sorcery_config.username_attribute_name.should equal(:email)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should enable configuration option 'password_attribute_name'" do
|
44
|
+
plugin_set_model_config_property(:password_attribute_name, :mypassword)
|
45
|
+
User.sorcery_config.password_attribute_name.should equal(:mypassword)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should enable configuration option 'email_attribute_name'" do
|
49
|
+
plugin_set_model_config_property(:email_attribute_name, :my_email)
|
50
|
+
User.sorcery_config.email_attribute_name.should equal(:my_email)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should enable configuration option 'crypted_password_attribute_name'" do
|
54
|
+
plugin_set_model_config_property(:crypted_password_attribute_name, :password)
|
55
|
+
User.sorcery_config.crypted_password_attribute_name.should equal(:password)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should enable configuration option 'salt_attribute_name'" do
|
59
|
+
plugin_set_model_config_property(:salt_attribute_name, :my_salt)
|
60
|
+
User.sorcery_config.salt_attribute_name.should equal(:my_salt)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should enable configuration option 'encryption_algorithm'" do
|
64
|
+
plugin_set_model_config_property(:encryption_algorithm, :none)
|
65
|
+
User.sorcery_config.encryption_algorithm.should equal(:none)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should enable configuration option 'encryption_key'" do
|
69
|
+
plugin_set_model_config_property(:encryption_key, 'asdadas424234242')
|
70
|
+
User.sorcery_config.encryption_key.should == 'asdadas424234242'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should enable configuration option 'custom_encryption_provider'" do
|
74
|
+
plugin_set_model_config_property(:encryption_algorithm, :custom)
|
75
|
+
plugin_set_model_config_property(:custom_encryption_provider, Array)
|
76
|
+
User.sorcery_config.custom_encryption_provider.should equal(Array)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should enable configuration option 'salt_join_token'" do
|
80
|
+
salt_join_token = "--%%*&-"
|
81
|
+
plugin_set_model_config_property(:salt_join_token, salt_join_token)
|
82
|
+
User.sorcery_config.salt_join_token.should equal(salt_join_token)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should enable configuration option 'stretches'" do
|
86
|
+
stretches = 15
|
87
|
+
plugin_set_model_config_property(:stretches, stretches)
|
88
|
+
User.sorcery_config.stretches.should equal(stretches)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
# ----------------- PLUGIN ACTIVATED -----------------------
|
94
|
+
describe User, "when activated with sorcery" do
|
95
|
+
before(:all) do
|
96
|
+
plugin_model_configure
|
97
|
+
end
|
98
|
+
|
99
|
+
before(:each) do
|
100
|
+
User.delete_all
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should respond to class method authenticate" do
|
104
|
+
ActiveRecord::Base.should_not respond_to(:authenticate)
|
105
|
+
User.should respond_to(:authenticate)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "authenticate should return true if credentials are good" do
|
109
|
+
create_new_user
|
110
|
+
User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "authenticate should return false if credentials are bad" do
|
114
|
+
create_new_user
|
115
|
+
User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'wrong!').should be_false
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should respond to the class method encrypt" do
|
119
|
+
User.should respond_to(:encrypt)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# ----------------- REGISTRATION -----------------------
|
124
|
+
describe User, "registration" do
|
125
|
+
|
126
|
+
before(:all) do
|
127
|
+
plugin_model_configure()
|
128
|
+
end
|
129
|
+
|
130
|
+
before(:each) do
|
131
|
+
User.delete_all
|
132
|
+
end
|
133
|
+
|
134
|
+
it "by default, encryption_provider should not be nil" do
|
135
|
+
User.sorcery_config.encryption_provider.should_not be_nil
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should encrypt password when a new user is saved" do
|
139
|
+
create_new_user
|
140
|
+
@user.send(User.sorcery_config.crypted_password_attribute_name).should == User.encrypt('secret',@user.salt)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should clear the virtual password field if the encryption process worked" do
|
144
|
+
create_new_user
|
145
|
+
@user.password.should be_nil
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not clear the virtual password field if save failed due to validity" do
|
149
|
+
create_new_user
|
150
|
+
User.class_eval do
|
151
|
+
validates_format_of :email, :with => /^(.)+@(.)+$/, :if => Proc.new {|r| r.email}, :message => "is invalid"
|
152
|
+
end
|
153
|
+
@user.password = 'blupush'
|
154
|
+
@user.email = 'asd'
|
155
|
+
@user.save
|
156
|
+
@user.password.should_not be_nil
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should not clear the virtual password field if save failed due to exception" do
|
160
|
+
create_new_user
|
161
|
+
@user.password = 'blupush'
|
162
|
+
@user.email = nil
|
163
|
+
begin
|
164
|
+
@user.save # triggers SQL exception since email field is defined not null.
|
165
|
+
rescue
|
166
|
+
end
|
167
|
+
@user.password.should_not be_nil
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should not encrypt the password twice when a user is updated" do
|
171
|
+
create_new_user
|
172
|
+
@user.email = "blup@bla.com"
|
173
|
+
@user.save!
|
174
|
+
@user.send(User.sorcery_config.crypted_password_attribute_name).should == User.encrypt('secret',@user.salt)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should replace the crypted_password in case a new password is set" do
|
178
|
+
create_new_user
|
179
|
+
@user.password = 'new_secret'
|
180
|
+
@user.save!
|
181
|
+
@user.send(User.sorcery_config.crypted_password_attribute_name).should == User.encrypt('new_secret',@user.salt)
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
# ----------------- PASSWORD ENCRYPTION -----------------------
|
187
|
+
describe User, "special encryption cases" do
|
188
|
+
before(:all) do
|
189
|
+
plugin_model_configure()
|
190
|
+
@text = "Some Text!"
|
191
|
+
end
|
192
|
+
|
193
|
+
before(:each) do
|
194
|
+
User.delete_all
|
195
|
+
end
|
196
|
+
|
197
|
+
after(:each) do
|
198
|
+
User.sorcery_config.reset!
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should work with no password encryption" do
|
202
|
+
plugin_set_model_config_property(:encryption_algorithm, :none)
|
203
|
+
create_new_user
|
204
|
+
User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should work with custom password encryption" do
|
208
|
+
class MyCrypto
|
209
|
+
def self.encrypt(*tokens)
|
210
|
+
tokens.flatten.join('').gsub(/e/,'A')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
plugin_set_model_config_property(:encryption_algorithm, :custom)
|
214
|
+
plugin_set_model_config_property(:custom_encryption_provider, MyCrypto)
|
215
|
+
create_new_user
|
216
|
+
User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'secret').should be_true
|
217
|
+
end
|
218
|
+
|
219
|
+
it "if encryption algo is aes256, it should set key to crypto provider" do
|
220
|
+
plugin_set_model_config_property(:encryption_algorithm, :aes256)
|
221
|
+
plugin_set_model_config_property(:encryption_key, nil)
|
222
|
+
expect{User.encrypt(@text)}.to raise_error(ArgumentError)
|
223
|
+
plugin_set_model_config_property(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
224
|
+
expect{User.encrypt(@text)}.to_not raise_error(ArgumentError)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "if encryption algo is aes256, it should set key to crypto provider, even if attributes are set in reverse" do
|
228
|
+
plugin_set_model_config_property(:encryption_key, nil)
|
229
|
+
plugin_set_model_config_property(:encryption_algorithm, :none)
|
230
|
+
plugin_set_model_config_property(:encryption_key, "asd234dfs423fddsmndsflktsdf32343")
|
231
|
+
plugin_set_model_config_property(:encryption_algorithm, :aes256)
|
232
|
+
expect{User.encrypt(@text)}.to_not raise_error(ArgumentError)
|
233
|
+
end
|
234
|
+
|
235
|
+
it "if encryption algo is md5 it should work" do
|
236
|
+
plugin_set_model_config_property(:encryption_algorithm, :md5)
|
237
|
+
User.encrypt(@text).should == Sorcery::CryptoProviders::MD5.encrypt(@text)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "if encryption algo is sha1 it should work" do
|
241
|
+
plugin_set_model_config_property(:encryption_algorithm, :sha1)
|
242
|
+
User.encrypt(@text).should == Sorcery::CryptoProviders::SHA1.encrypt(@text)
|
243
|
+
end
|
244
|
+
|
245
|
+
it "if encryption algo is sha256 it should work" do
|
246
|
+
plugin_set_model_config_property(:encryption_algorithm, :sha256)
|
247
|
+
User.encrypt(@text).should == Sorcery::CryptoProviders::SHA256.encrypt(@text)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "if encryption algo is sha512 it should work" do
|
251
|
+
plugin_set_model_config_property(:encryption_algorithm, :sha512)
|
252
|
+
User.encrypt(@text).should == Sorcery::CryptoProviders::SHA512.encrypt(@text)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "salt should be random for each user and saved in db" do
|
256
|
+
plugin_set_model_config_property(:salt_attribute_name, :salt)
|
257
|
+
create_new_user
|
258
|
+
@user.salt.should_not be_nil
|
259
|
+
end
|
260
|
+
|
261
|
+
it "if salt is set should use it to encrypt" do
|
262
|
+
plugin_set_model_config_property(:salt_attribute_name, :salt)
|
263
|
+
plugin_set_model_config_property(:encryption_algorithm, :sha512)
|
264
|
+
create_new_user
|
265
|
+
@user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
266
|
+
@user.crypted_password.should == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
|
267
|
+
end
|
268
|
+
|
269
|
+
it "if salt_join_token is set should use it to encrypt" do
|
270
|
+
plugin_set_model_config_property(:salt_attribute_name, :salt)
|
271
|
+
plugin_set_model_config_property(:salt_join_token, "-@=>")
|
272
|
+
plugin_set_model_config_property(:encryption_algorithm, :sha512)
|
273
|
+
create_new_user
|
274
|
+
@user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret')
|
275
|
+
Sorcery::CryptoProviders::SHA512.join_token = ""
|
276
|
+
@user.crypted_password.should_not == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
|
277
|
+
Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token
|
278
|
+
@user.crypted_password.should == Sorcery::CryptoProviders::SHA512.encrypt('secret',@user.salt)
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|