sorcery 0.8.6 → 0.9.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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +75 -14
  4. data/CHANGELOG.md +23 -1
  5. data/Gemfile +1 -0
  6. data/README.md +137 -86
  7. data/gemfiles/active_record-rails40.gemfile +7 -0
  8. data/gemfiles/active_record-rails41.gemfile +3 -2
  9. data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
  10. data/gemfiles/mongo_mapper-rails41.gemfile +2 -1
  11. data/gemfiles/mongoid-rails40.gemfile +9 -0
  12. data/gemfiles/mongoid-rails41.gemfile +3 -5
  13. data/gemfiles/mongoid3-rails32.gemfile +9 -0
  14. data/lib/generators/sorcery/USAGE +1 -1
  15. data/lib/generators/sorcery/install_generator.rb +19 -5
  16. data/lib/generators/sorcery/templates/initializer.rb +34 -9
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +3 -1
  18. data/lib/generators/sorcery/templates/migration/core.rb +2 -2
  19. data/lib/generators/sorcery/templates/migration/external.rb +3 -1
  20. data/lib/sorcery.rb +75 -43
  21. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  22. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  23. data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
  24. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
  25. data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
  26. data/lib/sorcery/controller.rb +5 -64
  27. data/lib/sorcery/controller/config.rb +65 -0
  28. data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
  29. data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
  30. data/lib/sorcery/controller/submodules/external.rb +8 -28
  31. data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
  32. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
  33. data/lib/sorcery/model.rb +43 -175
  34. data/lib/sorcery/model/config.rb +96 -0
  35. data/lib/sorcery/model/submodules/activity_logging.rb +29 -36
  36. data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -37
  37. data/lib/sorcery/model/submodules/external.rb +53 -9
  38. data/lib/sorcery/model/submodules/remember_me.rb +12 -31
  39. data/lib/sorcery/model/submodules/reset_password.rb +21 -39
  40. data/lib/sorcery/model/submodules/user_activation.rb +21 -63
  41. data/lib/sorcery/model/temporary_token.rb +4 -4
  42. data/lib/sorcery/providers/base.rb +11 -0
  43. data/lib/sorcery/providers/facebook.rb +1 -1
  44. data/lib/sorcery/providers/github.rb +1 -1
  45. data/lib/sorcery/providers/google.rb +1 -1
  46. data/lib/sorcery/providers/heroku.rb +57 -0
  47. data/lib/sorcery/providers/jira.rb +77 -0
  48. data/lib/sorcery/providers/linkedin.rb +1 -1
  49. data/lib/sorcery/providers/liveid.rb +1 -1
  50. data/lib/sorcery/providers/salesforce.rb +50 -0
  51. data/lib/sorcery/providers/twitter.rb +1 -1
  52. data/lib/sorcery/providers/vk.rb +6 -4
  53. data/lib/sorcery/providers/xing.rb +1 -1
  54. data/lib/sorcery/test_helpers/internal.rb +7 -3
  55. data/lib/sorcery/test_helpers/rails/controller.rb +5 -1
  56. data/lib/sorcery/version.rb +3 -0
  57. data/sorcery.gemspec +6 -2
  58. data/spec/active_record/user_activity_logging_spec.rb +9 -0
  59. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  60. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  61. data/spec/{active_record → controllers}/controller_http_basic_auth_spec.rb +14 -11
  62. data/spec/{active_record → controllers}/controller_oauth2_spec.rb +128 -56
  63. data/spec/{active_record → controllers}/controller_oauth_spec.rb +94 -70
  64. data/spec/{active_record → controllers}/controller_remember_me_spec.rb +32 -12
  65. data/spec/{active_record → controllers}/controller_session_timeout_spec.rb +15 -5
  66. data/spec/{shared_examples/controller_shared_examples.rb → controllers/controller_spec.rb} +34 -19
  67. data/spec/{datamapper → data_mapper}/user_activation_spec.rb +1 -1
  68. data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
  69. data/spec/{datamapper → data_mapper}/user_brute_force_protection_spec.rb +1 -1
  70. data/spec/{datamapper → data_mapper}/user_oauth_spec.rb +1 -1
  71. data/spec/{datamapper → data_mapper}/user_remember_me_spec.rb +1 -1
  72. data/spec/{datamapper → data_mapper}/user_reset_password_spec.rb +1 -1
  73. data/spec/{datamapper → data_mapper}/user_spec.rb +1 -1
  74. data/spec/mongoid/user_spec.rb +13 -0
  75. data/spec/orm/active_record.rb +12 -0
  76. data/spec/orm/{datamapper.rb → data_mapper.rb} +16 -2
  77. data/spec/orm/mongo_mapper.rb +0 -1
  78. data/spec/orm/mongoid.rb +4 -0
  79. data/spec/rails_app/app/controllers/sorcery_controller.rb +62 -1
  80. data/spec/rails_app/app/{datamapper → data_mapper}/authentication.rb +0 -0
  81. data/spec/rails_app/app/{datamapper → data_mapper}/user.rb +0 -0
  82. data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
  83. data/spec/rails_app/config/routes.rb +9 -0
  84. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
  85. data/spec/shared_examples/user_activation_shared_examples.rb +7 -7
  86. data/spec/shared_examples/user_activity_logging_shared_examples.rb +73 -5
  87. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +127 -9
  88. data/spec/shared_examples/user_oauth_shared_examples.rb +3 -6
  89. data/spec/shared_examples/user_remember_me_shared_examples.rb +6 -3
  90. data/spec/shared_examples/user_reset_password_shared_examples.rb +10 -10
  91. data/spec/shared_examples/user_shared_examples.rb +117 -30
  92. data/spec/spec_helper.rb +7 -22
  93. metadata +36 -58
  94. data/Gemfile.rails4 +0 -22
  95. data/VERSION +0 -1
  96. data/lib/sorcery/model/adapters/active_record.rb +0 -54
  97. data/lib/sorcery/model/adapters/datamapper.rb +0 -123
  98. data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -60
  99. data/lib/sorcery/model/adapters/mongoid.rb +0 -88
  100. data/lib/sorcery/test_helpers/rails.rb +0 -7
  101. data/spec/active_record/controller_activity_logging_spec.rb +0 -29
  102. data/spec/active_record/controller_brute_force_protection_spec.rb +0 -158
  103. data/spec/active_record/controller_spec.rb +0 -8
  104. data/spec/active_record/integration_spec.rb +0 -23
  105. data/spec/datamapper/controller_activity_logging_spec.rb +0 -17
  106. data/spec/datamapper/controller_spec.rb +0 -8
  107. data/spec/datamapper/user_activity_logging_spec.rb +0 -9
  108. data/spec/mongo_mapper/controller_spec.rb +0 -8
  109. data/spec/mongoid/controller_activity_logging_spec.rb +0 -16
  110. data/spec/mongoid/controller_spec.rb +0 -8
  111. data/spec/rails_app/public/404.html +0 -26
  112. data/spec/rails_app/public/422.html +0 -26
  113. data/spec/rails_app/public/500.html +0 -26
  114. data/spec/rails_app/public/favicon.ico +0 -0
  115. data/spec/rails_app/public/images/rails.png +0 -0
  116. data/spec/rails_app/public/javascripts/application.js +0 -2
  117. data/spec/rails_app/public/javascripts/controls.js +0 -965
  118. data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
  119. data/spec/rails_app/public/javascripts/effects.js +0 -1123
  120. data/spec/rails_app/public/javascripts/prototype.js +0 -6001
  121. data/spec/rails_app/public/javascripts/rails.js +0 -175
  122. data/spec/rails_app/public/robots.txt +0 -5
  123. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  124. data/spec/shared_examples/controller_activity_logging_shared_examples.rb +0 -125
  125. data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -52
  126. data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -62
@@ -1,60 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Adapters
4
- module MongoMapper
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- extend Sorcery::Model
9
- end
10
-
11
- def increment(attr)
12
- self.class.increment(id, attr => 1)
13
- end
14
-
15
- def sorcery_save(options = {})
16
- if options.delete(:raise_on_failure) && options[:validate] != false
17
- save! options
18
- else
19
- save options
20
- end
21
- end
22
-
23
- def update_many_attributes(attrs)
24
- update_attributes(attrs)
25
- end
26
-
27
- module ClassMethods
28
- def credential_regex(credential)
29
- return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
30
- return credential
31
- end
32
-
33
- def find_by_credentials(credentials)
34
- @sorcery_config.username_attribute_names.each do |attribute|
35
- @user = where(attribute => credential_regex(credentials[0])).first
36
- break if @user
37
- end
38
- @user
39
- end
40
-
41
- def find_by_id(id)
42
- find(id)
43
- end
44
-
45
- def find_by_activation_token(token)
46
- where(sorcery_config.activation_token_attribute_name => token).first
47
- end
48
-
49
- def transaction(&blk)
50
- tap(&blk)
51
- end
52
-
53
- def find_by_sorcery_token(token_attr_name, token)
54
- where(token_attr_name => token).first
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,88 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Adapters
4
- module Mongoid
5
- module InstanceMethods
6
- def increment(attr)
7
- self.inc(attr, 1)
8
- end
9
-
10
- def update_many_attributes(attrs)
11
- attrs.each do |name, value|
12
- attrs[name] = value.utc if value.is_a?(ActiveSupport::TimeWithZone)
13
- self.send(:"#{name}=", value)
14
- end
15
- self.class.where(:_id => self.id).update_all(attrs)
16
- end
17
-
18
- def update_single_attribute(name, value)
19
- update_many_attributes(name => value)
20
- end
21
-
22
- def sorcery_save(options = {})
23
- mthd = options.delete(:raise_on_failure) ? :save! : :save
24
- self.send(mthd, options)
25
- end
26
- end
27
-
28
- module ClassMethods
29
- def credential_regex(credential)
30
- return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@sorcery_config.downcase_username_before_authenticating)
31
- credential
32
- end
33
-
34
- def find_by_credentials(credentials)
35
- @sorcery_config.username_attribute_names.each do |attribute|
36
- @user = where(attribute => credential_regex(credentials[0])).first
37
- break if @user
38
- end
39
- @user
40
- end
41
-
42
- def find_by_provider_and_uid(provider, uid)
43
- @user_klass ||= ::Sorcery::Controller::Config.user_class.to_s.constantize
44
- where(@user_klass.sorcery_config.provider_attribute_name => provider, @user_klass.sorcery_config.provider_uid_attribute_name => uid).first
45
- end
46
-
47
- def find_by_id(id)
48
- find(id)
49
- rescue ::Mongoid::Errors::DocumentNotFound
50
- nil
51
- end
52
-
53
- def find_by_activation_token(token)
54
- where(sorcery_config.activation_token_attribute_name => token).first
55
- end
56
-
57
- def find_by_remember_me_token(token)
58
- where(sorcery_config.remember_me_token_attribute_name => token).first
59
- end
60
-
61
- def find_by_username(username)
62
- query = sorcery_config.username_attribute_names.map {|name| {name => username}}
63
- any_of(*query).first
64
- end
65
-
66
- def transaction(&blk)
67
- tap(&blk)
68
- end
69
-
70
- def find_by_sorcery_token(token_attr_name, token)
71
- where(token_attr_name => token).first
72
- end
73
-
74
- def find_by_email(email)
75
- where(sorcery_config.email_attribute_name => email).first
76
- end
77
-
78
- def get_current_users
79
- config = sorcery_config
80
- where(config.last_activity_at_attribute_name.ne => nil) \
81
- .where("this.#{config.last_logout_at_attribute_name} == null || this.#{config.last_activity_at_attribute_name} > this.#{config.last_logout_at_attribute_name}") \
82
- .where(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc).order_by([:_id,:asc])
83
- end
84
- end
85
- end
86
- end
87
- end
88
- end
@@ -1,7 +0,0 @@
1
- module Sorcery
2
- module TestHelpers
3
- module Rails
4
-
5
- end
6
- end
7
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'shared_examples/controller_activity_logging_shared_examples'
4
-
5
- describe SorceryController, :active_record => true do
6
- before(:all) do
7
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging")
8
- User.reset_column_information
9
- end
10
-
11
- after(:all) do
12
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activity_logging")
13
-
14
- sorcery_controller_property_set(:register_login_time, true)
15
- sorcery_controller_property_set(:register_logout_time, true)
16
- sorcery_controller_property_set(:register_last_activity_time, true)
17
- # sorcery_controller_property_set(:last_login_from_ip_address_name, true)
18
- end
19
-
20
- # ----------------- ACTIVITY LOGGING -----------------------
21
- context "with activity logging features" do
22
- after(:each) do
23
- User.delete_all
24
- end
25
-
26
- it_behaves_like "controller_activity_logging"
27
-
28
- end
29
- end
@@ -1,158 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SorceryController, :active_record => true do
4
-
5
- let(:db_user) { User.find_by_email 'bla@bla.com' }
6
- let!(:user) { create_new_user }
7
-
8
- def request_test_login
9
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
10
- end
11
-
12
- before(:all) do
13
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
14
- User.reset_column_information
15
- end
16
-
17
- after(:all) do
18
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
19
- end
20
-
21
- # ----------------- SESSION TIMEOUT -----------------------
22
- describe "brute force protection features" do
23
-
24
- before(:all) do
25
- sorcery_reload!([:brute_force_protection])
26
- end
27
-
28
-
29
- after(:each) do
30
- Sorcery::Controller::Config.reset!
31
- sorcery_controller_property_set(:user_class, User)
32
- Timecop.return
33
- end
34
-
35
- it "counts login retries" do
36
- 3.times { request_test_login }
37
- expect(db_user.failed_logins_count).to eq 3
38
- end
39
-
40
- it "generates unlock token before mail is sent" do
41
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
42
- sorcery_model_property_set(:login_lock_time_period, 0)
43
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
44
- 3.times { request_test_login }
45
- expect(ActionMailer::Base.deliveries.last.body.to_s.match(db_user.unlock_token)).not_to be_nil
46
- end
47
-
48
- it "unlocks after entering unlock token" do
49
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
50
- sorcery_model_property_set(:login_lock_time_period, 0)
51
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
52
- 3.times { request_test_login }
53
-
54
- expect(db_user.unlock_token).not_to be_nil
55
-
56
- token = db_user.unlock_token
57
- user = User.load_from_unlock_token(token)
58
-
59
- expect(user).not_to be_nil
60
-
61
- user.unlock!
62
- expect(User.load_from_unlock_token(db_user.unlock_token)).to be_nil
63
- end
64
-
65
- it "resets the counter on a good login" do
66
- # dirty hack for rails 4
67
- allow(@controller).to receive(:register_last_activity_time_to_db)
68
-
69
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 5)
70
- 3.times { request_test_login }
71
- get :test_login, :email => 'bla@bla.com', :password => 'secret'
72
-
73
- expect(db_user.failed_logins_count).to eq 0
74
- end
75
-
76
- it "locks user when number of retries reached the limit" do
77
- expect(db_user.lock_expires_at).to be_nil
78
-
79
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
80
- request_test_login
81
-
82
- expect(db_user.reload.lock_expires_at).not_to be_nil
83
- end
84
-
85
- it "unlocks after lock time period passes" do
86
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
87
- sorcery_model_property_set(:login_lock_time_period, 0.2)
88
- 2.times { request_test_login }
89
-
90
- expect(db_user.reload.lock_expires_at).not_to be_nil
91
-
92
- Timecop.travel(Time.now.in_time_zone + 0.3)
93
- request_test_login
94
-
95
- expect(db_user.reload.lock_expires_at).to be_nil
96
- end
97
-
98
- it "doest not unlock if time period is 0 (permanent lock)" do
99
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
100
- sorcery_model_property_set(:login_lock_time_period, 0)
101
- 2.times { request_test_login }
102
- unlock_date = db_user.lock_expires_at
103
- Timecop.travel(Time.now.in_time_zone + 1)
104
- request_test_login
105
-
106
- expect(db_user.lock_expires_at.to_s).to eq unlock_date.to_s
107
- end
108
-
109
- context "unlock_token_mailer_disabled is true" do
110
-
111
- before(:each) do
112
- sorcery_model_property_set(:unlock_token_mailer_disabled, true)
113
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
114
- sorcery_model_property_set(:login_lock_time_period, 0)
115
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
116
- end
117
-
118
- it "generates unlock token after user locked" do
119
- 3.times { request_test_login }
120
-
121
- expect(db_user.unlock_token).not_to be_nil
122
- end
123
-
124
- it "doest *not* automatically send unlock mail" do
125
- old_size = ActionMailer::Base.deliveries.size
126
- 3.times { request_test_login }
127
-
128
- expect(ActionMailer::Base.deliveries.size).to eq old_size
129
- end
130
-
131
- end
132
-
133
- context "unlock_token_mailer_disabled is false" do
134
-
135
- before(:each) do
136
- sorcery_model_property_set(:unlock_token_mailer_disabled, false)
137
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
138
- sorcery_model_property_set(:login_lock_time_period, 0)
139
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
140
- end
141
-
142
- it "sets the unlock token after user locked" do
143
- 3.times { request_test_login }
144
-
145
- expect(db_user.unlock_token).not_to be_nil
146
- end
147
-
148
- it "automatically sends unlock mail" do
149
- old_size = ActionMailer::Base.deliveries.size
150
- 3.times { request_test_login }
151
-
152
- expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
153
- end
154
-
155
- end
156
-
157
- end
158
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
- require 'shared_examples/controller_shared_examples'
3
-
4
- describe SorceryController, :active_record => true do
5
-
6
- it_should_behave_like "sorcery_controller"
7
-
8
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "the login process", :type => :request, :active_record => true do
4
- before(:all) do
5
- sorcery_reload!
6
- create_new_user
7
- end
8
-
9
- after(:all) do
10
- end
11
- end
12
- # it "handles unverified request", :js => true do
13
- # visit root_path
14
- # #save_and_open_page
15
- # fill_in 'Username', :with => 'gizmo1'
16
- # fill_in 'Password', :with => 'secret'
17
- # # <input name="authenticity_token" type="hidden" value="+8M9lXnjnhAW/mAuzwI9Mmy6hM+00qZJa8VMQUg+NmM=">
18
- # page.execute_script("$$('hidden').value='mezuza'")
19
- # #save_and_open_page
20
- # click_button 'Login'
21
- # save_and_open_page
22
- # end
23
- # end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
- require 'shared_examples/controller_activity_logging_shared_examples'
3
-
4
- describe SorceryController, :datamapper => true do
5
-
6
- # ----------------- ACTIVITY LOGGING -----------------------
7
- context "with activity logging features" do
8
- after(:each) do
9
- # NOTE dm-constraints supports only pg and mysql
10
- Authentication.all.destroy
11
- User.delete_all
12
- end
13
-
14
- it_behaves_like "controller_activity_logging"
15
-
16
- end
17
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
- require 'shared_examples/controller_shared_examples'
3
-
4
- describe SorceryController, :datamapper => true do
5
-
6
- it_should_behave_like "sorcery_controller"
7
-
8
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'shared_examples/user_activity_logging_shared_examples'
4
-
5
- describe User, "with activity logging submodule", :datamapper => true do
6
-
7
- it_behaves_like "rails_3_activity_logging_model"
8
-
9
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
- require 'shared_examples/controller_shared_examples'
3
-
4
- describe SorceryController, :mongo_mapper => true do
5
-
6
- it_should_behave_like "sorcery_controller"
7
-
8
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
- require 'shared_examples/controller_activity_logging_shared_examples'
3
-
4
- describe SorceryController, :mongoid => true do
5
-
6
- # ----------------- ACTIVITY LOGGING -----------------------
7
- context "with activity logging features" do
8
- after(:each) do
9
- User.delete_all
10
- end
11
-
12
-
13
- it_behaves_like "controller_activity_logging"
14
-
15
- end
16
- end