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.

Files changed (101) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +19 -0
  4. data/Gemfile.lock +129 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +139 -0
  7. data/Rakefile +61 -0
  8. data/VERSION +1 -0
  9. data/features/support/env.rb +13 -0
  10. data/lib/sorcery.rb +28 -0
  11. data/lib/sorcery/controller.rb +156 -0
  12. data/lib/sorcery/controller/submodules/brute_force_protection.rb +89 -0
  13. data/lib/sorcery/controller/submodules/remember_me.rb +43 -0
  14. data/lib/sorcery/controller/submodules/session_timeout.rb +42 -0
  15. data/lib/sorcery/crypto_providers/aes256.rb +44 -0
  16. data/lib/sorcery/crypto_providers/bcrypt.rb +96 -0
  17. data/lib/sorcery/crypto_providers/md5.rb +39 -0
  18. data/lib/sorcery/crypto_providers/sha1.rb +40 -0
  19. data/lib/sorcery/crypto_providers/sha256.rb +55 -0
  20. data/lib/sorcery/crypto_providers/sha512.rb +55 -0
  21. data/lib/sorcery/engine.rb +20 -0
  22. data/lib/sorcery/model.rb +175 -0
  23. data/lib/sorcery/model/submodules/password_reset.rb +64 -0
  24. data/lib/sorcery/model/submodules/remember_me.rb +42 -0
  25. data/lib/sorcery/model/submodules/user_activation.rb +84 -0
  26. data/spec/Gemfile +11 -0
  27. data/spec/Gemfile.lock +108 -0
  28. data/spec/Rakefile +11 -0
  29. data/spec/rails3/.rspec +1 -0
  30. data/spec/rails3/Gemfile +12 -0
  31. data/spec/rails3/Gemfile.lock +114 -0
  32. data/spec/rails3/Rakefile +10 -0
  33. data/spec/rails3/app_root/.gitignore +4 -0
  34. data/spec/rails3/app_root/README +256 -0
  35. data/spec/rails3/app_root/Rakefile.unused +7 -0
  36. data/spec/rails3/app_root/app/controllers/application_controller.rb +61 -0
  37. data/spec/rails3/app_root/app/helpers/application_helper.rb +2 -0
  38. data/spec/rails3/app_root/app/mailers/sorcery_mailer.rb +25 -0
  39. data/spec/rails3/app_root/app/models/user.rb +3 -0
  40. data/spec/rails3/app_root/app/views/layouts/application.html.erb +14 -0
  41. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  42. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  43. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  44. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  45. data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  46. data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  47. data/spec/rails3/app_root/config.ru +4 -0
  48. data/spec/rails3/app_root/config/application.rb +48 -0
  49. data/spec/rails3/app_root/config/boot.rb +13 -0
  50. data/spec/rails3/app_root/config/database.yml +27 -0
  51. data/spec/rails3/app_root/config/environment.rb +5 -0
  52. data/spec/rails3/app_root/config/environments/development.rb +26 -0
  53. data/spec/rails3/app_root/config/environments/in_memory.rb +0 -0
  54. data/spec/rails3/app_root/config/environments/production.rb +49 -0
  55. data/spec/rails3/app_root/config/environments/test.rb +35 -0
  56. data/spec/rails3/app_root/config/initializers/backtrace_silencers.rb +7 -0
  57. data/spec/rails3/app_root/config/initializers/inflections.rb +10 -0
  58. data/spec/rails3/app_root/config/initializers/mime_types.rb +5 -0
  59. data/spec/rails3/app_root/config/initializers/secret_token.rb +7 -0
  60. data/spec/rails3/app_root/config/initializers/session_store.rb +8 -0
  61. data/spec/rails3/app_root/config/locales/en.yml +5 -0
  62. data/spec/rails3/app_root/config/routes.rb +67 -0
  63. data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +15 -0
  64. data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +16 -0
  65. data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +9 -0
  66. data/spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  67. data/spec/rails3/app_root/db/schema.rb +23 -0
  68. data/spec/rails3/app_root/db/seeds.rb +7 -0
  69. data/spec/rails3/app_root/lib/tasks/.gitkeep +0 -0
  70. data/spec/rails3/app_root/public/404.html +26 -0
  71. data/spec/rails3/app_root/public/422.html +26 -0
  72. data/spec/rails3/app_root/public/500.html +26 -0
  73. data/spec/rails3/app_root/public/favicon.ico +0 -0
  74. data/spec/rails3/app_root/public/images/rails.png +0 -0
  75. data/spec/rails3/app_root/public/index.html +239 -0
  76. data/spec/rails3/app_root/public/javascripts/application.js +2 -0
  77. data/spec/rails3/app_root/public/javascripts/controls.js +965 -0
  78. data/spec/rails3/app_root/public/javascripts/dragdrop.js +974 -0
  79. data/spec/rails3/app_root/public/javascripts/effects.js +1123 -0
  80. data/spec/rails3/app_root/public/javascripts/prototype.js +6001 -0
  81. data/spec/rails3/app_root/public/javascripts/rails.js +175 -0
  82. data/spec/rails3/app_root/public/robots.txt +5 -0
  83. data/spec/rails3/app_root/public/stylesheets/.gitkeep +0 -0
  84. data/spec/rails3/app_root/script/rails +6 -0
  85. data/spec/rails3/app_root/test/fixtures/users.yml +9 -0
  86. data/spec/rails3/app_root/test/performance/browsing_test.rb +9 -0
  87. data/spec/rails3/app_root/test/test_helper.rb +13 -0
  88. data/spec/rails3/app_root/test/unit/user_test.rb +8 -0
  89. data/spec/rails3/app_root/vendor/plugins/.gitkeep +0 -0
  90. data/spec/rails3/controller_brute_force_protection_spec.rb +72 -0
  91. data/spec/rails3/controller_remember_me_spec.rb +65 -0
  92. data/spec/rails3/controller_session_timeout_spec.rb +49 -0
  93. data/spec/rails3/controller_spec.rb +115 -0
  94. data/spec/rails3/spec_helper.rb +115 -0
  95. data/spec/rails3/user_activation_spec.rb +148 -0
  96. data/spec/rails3/user_password_reset_spec.rb +76 -0
  97. data/spec/rails3/user_remember_me_spec.rb +66 -0
  98. data/spec/rails3/user_spec.rb +283 -0
  99. data/spec/sorcery_crypto_providers_spec.rb +182 -0
  100. data/spec/spec_helper.rb +18 -0
  101. 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