sorcery 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +122 -5
  4. data/CHANGELOG.md +37 -1
  5. data/Gemfile +10 -18
  6. data/README.md +159 -88
  7. data/gemfiles/active_record-rails40.gemfile +7 -0
  8. data/gemfiles/active_record-rails41.gemfile +7 -0
  9. data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
  10. data/gemfiles/mongo_mapper-rails41.gemfile +9 -0
  11. data/gemfiles/mongoid-rails40.gemfile +9 -0
  12. data/gemfiles/mongoid-rails41.gemfile +9 -0
  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/adapters/active_record_adapter.rb +120 -0
  21. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  22. data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
  23. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
  24. data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
  25. data/lib/sorcery/controller/config.rb +65 -0
  26. data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
  27. data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
  28. data/lib/sorcery/controller/submodules/external.rb +35 -40
  29. data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
  30. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
  31. data/lib/sorcery/controller.rb +10 -74
  32. data/lib/sorcery/model/config.rb +96 -0
  33. data/lib/sorcery/model/submodules/activity_logging.rb +30 -13
  34. data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -21
  35. data/lib/sorcery/model/submodules/external.rb +53 -9
  36. data/lib/sorcery/model/submodules/remember_me.rb +15 -19
  37. data/lib/sorcery/model/submodules/reset_password.rb +33 -34
  38. data/lib/sorcery/model/submodules/user_activation.rb +36 -47
  39. data/lib/sorcery/model/temporary_token.rb +4 -4
  40. data/lib/sorcery/model.rb +73 -173
  41. data/lib/sorcery/protocols/oauth.rb +42 -0
  42. data/lib/sorcery/protocols/oauth2.rb +47 -0
  43. data/lib/sorcery/providers/base.rb +38 -0
  44. data/lib/sorcery/providers/facebook.rb +63 -0
  45. data/lib/sorcery/providers/github.rb +51 -0
  46. data/lib/sorcery/providers/google.rb +51 -0
  47. data/lib/sorcery/providers/heroku.rb +57 -0
  48. data/lib/sorcery/providers/jira.rb +77 -0
  49. data/lib/sorcery/providers/linkedin.rb +66 -0
  50. data/lib/sorcery/providers/liveid.rb +53 -0
  51. data/lib/sorcery/providers/salesforce.rb +50 -0
  52. data/lib/sorcery/providers/twitter.rb +59 -0
  53. data/lib/sorcery/providers/vk.rb +63 -0
  54. data/lib/sorcery/providers/xing.rb +64 -0
  55. data/lib/sorcery/test_helpers/internal/rails.rb +14 -3
  56. data/lib/sorcery/test_helpers/internal.rb +7 -3
  57. data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
  58. data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
  59. data/lib/sorcery/version.rb +3 -0
  60. data/lib/sorcery.rb +82 -58
  61. data/sorcery.gemspec +19 -19
  62. data/spec/active_record/user_activation_spec.rb +1 -1
  63. data/spec/active_record/user_activity_logging_spec.rb +10 -1
  64. data/spec/active_record/user_brute_force_protection_spec.rb +1 -1
  65. data/spec/active_record/user_oauth_spec.rb +1 -1
  66. data/spec/active_record/user_remember_me_spec.rb +1 -1
  67. data/spec/active_record/user_reset_password_spec.rb +1 -1
  68. data/spec/active_record/user_spec.rb +7 -8
  69. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  70. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  71. data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
  72. data/spec/controllers/controller_oauth2_spec.rb +414 -0
  73. data/spec/controllers/controller_oauth_spec.rb +240 -0
  74. data/spec/controllers/controller_remember_me_spec.rb +117 -0
  75. data/spec/controllers/controller_session_timeout_spec.rb +80 -0
  76. data/spec/controllers/controller_spec.rb +218 -0
  77. data/spec/data_mapper/user_activation_spec.rb +10 -0
  78. data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
  79. data/spec/data_mapper/user_brute_force_protection_spec.rb +9 -0
  80. data/spec/data_mapper/user_oauth_spec.rb +9 -0
  81. data/spec/data_mapper/user_remember_me_spec.rb +8 -0
  82. data/spec/data_mapper/user_reset_password_spec.rb +8 -0
  83. data/spec/data_mapper/user_spec.rb +27 -0
  84. data/spec/mongo_mapper/user_activation_spec.rb +1 -2
  85. data/spec/mongo_mapper/user_activity_logging_spec.rb +1 -1
  86. data/spec/mongo_mapper/user_brute_force_protection_spec.rb +1 -1
  87. data/spec/mongo_mapper/user_oauth_spec.rb +1 -1
  88. data/spec/mongo_mapper/user_remember_me_spec.rb +1 -1
  89. data/spec/mongo_mapper/user_reset_password_spec.rb +1 -1
  90. data/spec/mongo_mapper/user_spec.rb +7 -8
  91. data/spec/mongoid/user_activation_spec.rb +1 -2
  92. data/spec/mongoid/user_activity_logging_spec.rb +1 -2
  93. data/spec/mongoid/user_brute_force_protection_spec.rb +1 -2
  94. data/spec/mongoid/user_oauth_spec.rb +1 -2
  95. data/spec/mongoid/user_remember_me_spec.rb +1 -2
  96. data/spec/mongoid/user_reset_password_spec.rb +1 -2
  97. data/spec/mongoid/user_spec.rb +21 -9
  98. data/spec/orm/active_record.rb +14 -0
  99. data/spec/orm/data_mapper.rb +48 -0
  100. data/spec/orm/mongo_mapper.rb +1 -1
  101. data/spec/orm/mongoid.rb +5 -0
  102. data/spec/rails_app/app/controllers/sorcery_controller.rb +125 -59
  103. data/spec/rails_app/app/data_mapper/authentication.rb +8 -0
  104. data/spec/rails_app/app/data_mapper/user.rb +7 -0
  105. data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
  106. data/spec/rails_app/config/routes.rb +27 -13
  107. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
  108. data/spec/shared_examples/user_activation_shared_examples.rb +108 -91
  109. data/spec/shared_examples/user_activity_logging_shared_examples.rb +83 -15
  110. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +140 -21
  111. data/spec/shared_examples/user_oauth_shared_examples.rb +21 -16
  112. data/spec/shared_examples/user_remember_me_shared_examples.rb +36 -24
  113. data/spec/shared_examples/user_reset_password_shared_examples.rb +138 -117
  114. data/spec/shared_examples/user_shared_examples.rb +297 -150
  115. data/spec/sorcery_crypto_providers_spec.rb +28 -28
  116. data/spec/spec_helper.rb +12 -18
  117. metadata +99 -165
  118. data/Gemfile.rails4 +0 -24
  119. data/VERSION +0 -1
  120. data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +0 -46
  121. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +0 -50
  122. data/lib/sorcery/controller/submodules/external/providers/base.rb +0 -21
  123. data/lib/sorcery/controller/submodules/external/providers/facebook.rb +0 -99
  124. data/lib/sorcery/controller/submodules/external/providers/github.rb +0 -93
  125. data/lib/sorcery/controller/submodules/external/providers/google.rb +0 -92
  126. data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +0 -103
  127. data/lib/sorcery/controller/submodules/external/providers/liveid.rb +0 -93
  128. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +0 -94
  129. data/lib/sorcery/controller/submodules/external/providers/vk.rb +0 -101
  130. data/lib/sorcery/controller/submodules/external/providers/xing.rb +0 -98
  131. data/lib/sorcery/model/adapters/active_record.rb +0 -49
  132. data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -56
  133. data/lib/sorcery/model/adapters/mongoid.rb +0 -88
  134. data/lib/sorcery/test_helpers/rails.rb +0 -16
  135. data/lib/sorcery/test_helpers.rb +0 -5
  136. data/spec/active_record/controller_activity_logging_spec.rb +0 -140
  137. data/spec/active_record/controller_brute_force_protection_spec.rb +0 -136
  138. data/spec/active_record/controller_http_basic_auth_spec.rb +0 -59
  139. data/spec/active_record/controller_oauth2_spec.rb +0 -417
  140. data/spec/active_record/controller_oauth_spec.rb +0 -212
  141. data/spec/active_record/controller_remember_me_spec.rb +0 -96
  142. data/spec/active_record/controller_session_timeout_spec.rb +0 -55
  143. data/spec/active_record/controller_spec.rb +0 -182
  144. data/spec/active_record/integration_spec.rb +0 -23
  145. data/spec/mongo_mapper/controller_spec.rb +0 -175
  146. data/spec/mongoid/controller_activity_logging_spec.rb +0 -111
  147. data/spec/mongoid/controller_spec.rb +0 -186
  148. data/spec/rails_app/public/404.html +0 -26
  149. data/spec/rails_app/public/422.html +0 -26
  150. data/spec/rails_app/public/500.html +0 -26
  151. data/spec/rails_app/public/favicon.ico +0 -0
  152. data/spec/rails_app/public/images/rails.png +0 -0
  153. data/spec/rails_app/public/javascripts/application.js +0 -2
  154. data/spec/rails_app/public/javascripts/controls.js +0 -965
  155. data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
  156. data/spec/rails_app/public/javascripts/effects.js +0 -1123
  157. data/spec/rails_app/public/javascripts/prototype.js +0 -6001
  158. data/spec/rails_app/public/javascripts/rails.js +0 -175
  159. data/spec/rails_app/public/robots.txt +0 -5
  160. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  161. data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -56
  162. data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -69
  163. /data/lib/sorcery/{controller/submodules/external/protocols → protocols}/certs/ca-bundle.crt +0 -0
@@ -1,98 +0,0 @@
1
- module Sorcery
2
- module Controller
3
- module Submodules
4
- module External
5
- module Providers
6
- # This module adds support for OAuth with xing.com.
7
- # When included in the 'config.providers' option, it adds a new option, 'config.xing'.
8
- # Via this new option you can configure Xing specific settings like your app's key and secret.
9
- #
10
- # config.xing.key = <key>
11
- # config.xing.secret = <secret>
12
- # ...
13
- #
14
- module Xing
15
- def self.included(base)
16
- base.module_eval do
17
- class << self
18
- attr_reader :xing
19
-
20
- def merge_xing_defaults!
21
- @defaults.merge!(:@xing => XingClient)
22
- end
23
- end
24
- merge_xing_defaults!
25
- update!
26
- end
27
- end
28
-
29
- module XingClient
30
- include Base::BaseClient
31
- class << self
32
- attr_accessor :key,
33
- :secret,
34
- :callback_url,
35
- :site,
36
- :authorize_path,
37
- :request_token_path,
38
- :access_token_path,
39
- :user_info_path,
40
- :user_info_mapping,
41
- :state
42
- attr_reader :access_token
43
-
44
- include Protocols::Oauth1
45
-
46
- # Override included get_consumer method to provide authorize_path
47
- def get_consumer
48
- ::OAuth::Consumer.new(@key, @secret, @configuration)
49
- end
50
-
51
- def init
52
- @configuration = {
53
- site: "https://api.xing.com/v1",
54
- authorize_path: '/authorize',
55
- request_token_path: '/request_token',
56
- access_token_path: '/access_token'
57
- }
58
- @user_info_path = "/users/me"
59
- end
60
-
61
- def get_user_hash(access_token)
62
- user_hash = {}
63
- response = access_token.get(@user_info_path)
64
- user_hash[:user_info] = JSON.parse(response.body)['users'].first
65
- user_hash[:uid] = user_hash[:user_info]['id'].to_s
66
- user_hash
67
- end
68
-
69
- def has_callback?
70
- true
71
- end
72
-
73
- # calculates and returns the url to which the user should be redirected,
74
- # to get authenticated at the external provider's site.
75
- def login_url(params,session)
76
- req_token = self.get_request_token
77
- session[:request_token] = req_token.token
78
- session[:request_token_secret] = req_token.secret
79
- self.authorize_url({:request_token => req_token.token, :request_token_secret => req_token.secret})
80
- end
81
-
82
- # tries to login the user from access token
83
- def process_callback(params, session)
84
- args = {}
85
- args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]})
86
- args.merge!({:code => params[:code]}) if params[:code]
87
- return self.get_access_token(args)
88
- end
89
-
90
- end
91
- init
92
- end
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,49 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Adapters
4
- module ActiveRecord
5
- def self.included(klass)
6
- klass.extend ClassMethods
7
- klass.send(:include, InstanceMethods)
8
- end
9
-
10
- module InstanceMethods
11
- def update_many_attributes(attrs)
12
- attrs.each do |name, value|
13
- self.send(:"#{name}=", value)
14
- end
15
- primary_key = self.class.primary_key
16
- self.class.where(:"#{primary_key}" => self.send(:"#{primary_key}")).update_all(attrs)
17
- end
18
-
19
- def update_single_attribute(name, value)
20
- update_many_attributes(name => value)
21
- end
22
- end
23
-
24
- module ClassMethods
25
- def column_name(attribute)
26
- return "LOWER(#{attribute})" if (@sorcery_config.downcase_username_before_authenticating)
27
- return "#{attribute}"
28
- end
29
-
30
- def find_by_credentials(credentials)
31
- sql = @sorcery_config.username_attribute_names.map{|attribute| column_name(attribute) + " = :login"}
32
- where(sql.join(' OR '), :login => credentials[0]).first
33
- end
34
-
35
- def find_by_sorcery_token(token_attr_name, token)
36
- where("#{token_attr_name} = ?", token).first
37
- end
38
-
39
- def get_current_users
40
- config = sorcery_config
41
- where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
42
- .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
43
- .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,56 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Adapters
4
- module MongoMapper
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- include Sorcery::Model
9
- end
10
-
11
- def increment(attr)
12
- self.class.increment(id, attr => 1)
13
- end
14
-
15
- def save!(options = {})
16
- save(options)
17
- end
18
-
19
- def update_many_attributes(attrs)
20
- update_attributes(attrs)
21
- end
22
-
23
- module ClassMethods
24
- def credential_regex(credential)
25
- return { :$regex => /^#{credential}$/i } if (@sorcery_config.downcase_username_before_authenticating)
26
- return credential
27
- end
28
-
29
- def find_by_credentials(credentials)
30
- @sorcery_config.username_attribute_names.each do |attribute|
31
- @user = where(attribute => credential_regex(credentials[0])).first
32
- break if @user
33
- end
34
- @user
35
- end
36
-
37
- def find_by_id(id)
38
- find(id)
39
- end
40
-
41
- def find_by_activation_token(token)
42
- where(sorcery_config.activation_token_attribute_name => token).first
43
- end
44
-
45
- def transaction(&blk)
46
- tap(&blk)
47
- end
48
-
49
- def find_by_sorcery_token(token_attr_name, token)
50
- where(token_attr_name => token).first
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,88 +0,0 @@
1
- module Sorcery
2
- module Model
3
- module Adapters
4
- module Mongoid
5
- def self.included(klass)
6
- klass.extend ClassMethods
7
- klass.send(:include, InstanceMethods)
8
- end
9
-
10
- module InstanceMethods
11
- def increment(attr)
12
- self.inc(attr, 1)
13
- end
14
-
15
- def update_many_attributes(attrs)
16
- attrs.each do |name, value|
17
- attrs[name] = value.utc if value.is_a?(ActiveSupport::TimeWithZone)
18
- self.send(:"#{name}=", value)
19
- end
20
- self.class.where(:_id => self.id).update_all(attrs)
21
- end
22
-
23
- def update_single_attribute(name, value)
24
- update_many_attributes(name => value)
25
- end
26
- end
27
-
28
- module ClassMethods
29
- def credential_regex(credential)
30
- return { :$regex => /^#{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,16 +0,0 @@
1
- module Sorcery
2
- module TestHelpers
3
- module Rails
4
- # logins a user and calls all callbacks
5
- def login_user(user = nil)
6
- user ||= @user
7
- @controller.send(:auto_login, user)
8
- @controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret'])
9
- end
10
-
11
- def logout_user
12
- @controller.send(:logout)
13
- end
14
- end
15
- end
16
- end
@@ -1,5 +0,0 @@
1
- module Sorcery
2
- module TestHelpers
3
-
4
- end
5
- end
@@ -1,140 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SorceryController do
4
- before(:all) do
5
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging")
6
- User.reset_column_information
7
- end
8
-
9
- after(:all) do
10
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activity_logging")
11
-
12
- sorcery_controller_property_set(:register_login_time, true)
13
- sorcery_controller_property_set(:register_logout_time, true)
14
- sorcery_controller_property_set(:register_last_activity_time, true)
15
- # sorcery_controller_property_set(:last_login_from_ip_address_name, true)
16
- end
17
-
18
- # ----------------- ACTIVITY LOGGING -----------------------
19
- describe SorceryController, "with activity logging features" do
20
- before(:all) do
21
- sorcery_reload!([:activity_logging])
22
- end
23
-
24
- before(:each) do
25
- create_new_user
26
- end
27
-
28
- after(:each) do
29
- User.delete_all
30
- end
31
-
32
- specify { subject.should respond_to(:current_users) }
33
-
34
- it "'current_users' should be empty when no users are logged in" do
35
- subject.current_users.size.should == 0
36
- end
37
-
38
- it "should log login time on login" do
39
- now = Time.now.in_time_zone
40
- login_user
41
- @user.last_login_at.should_not be_nil
42
- @user.last_login_at.to_s(:db).should >= now.to_s(:db)
43
- @user.last_login_at.to_s(:db).should <= (now+2).to_s(:db)
44
- end
45
-
46
- it "should log logout time on logout" do
47
- login_user
48
- now = Time.now.in_time_zone
49
- logout_user
50
-
51
- User.last.last_logout_at.should_not be_nil
52
-
53
- User.last.last_logout_at.to_s(:db).should >= now.to_s(:db)
54
- User.last.last_logout_at.to_s(:db).should <= (now+2).to_s(:db)
55
- end
56
-
57
- it "should log last activity time when logged in" do
58
- sorcery_controller_property_set(:register_last_activity_time, true)
59
-
60
- login_user
61
- now = Time.now.in_time_zone
62
- get :some_action
63
-
64
- last_activity_at = User.last.last_activity_at
65
-
66
- last_activity_at.should be_present
67
- last_activity_at.to_s(:db).should >= now.to_s(:db)
68
- last_activity_at.to_s(:db).should <= (now+2).to_s(:db)
69
- end
70
-
71
- it "should log last IP address when logged in" do
72
- login_user
73
- get :some_action
74
- User.last.last_login_from_ip_address.should == "0.0.0.0"
75
- end
76
-
77
- it "should update nothing but activity fields" do
78
- original_user_name = User.last.username
79
- login_user
80
- get :some_action_making_a_non_persisted_change_to_the_user
81
- User.last.username.should == original_user_name
82
- end
83
-
84
- it "'current_users' should hold the user object when 1 user is logged in" do
85
- login_user
86
- get :some_action
87
- subject.current_users.size.should == 1
88
- subject.current_users[0].should == @user
89
- end
90
-
91
- it "'current_users' should show all current_users, whether they have logged out before or not." do
92
- user1 = create_new_user({:username => 'gizmo1', :email => "bla1@bla.com", :password => 'secret1'})
93
- login_user(user1)
94
- get :some_action
95
- clear_user_without_logout
96
- user2 = create_new_user({:username => 'gizmo2', :email => "bla2@bla.com", :password => 'secret2'})
97
- login_user(user2)
98
- get :some_action
99
- clear_user_without_logout
100
- user3 = create_new_user({:username => 'gizmo3', :email => "bla3@bla.com", :password => 'secret3'})
101
- login_user(user3)
102
- get :some_action
103
- subject.current_users.size.should == 3
104
- subject.current_users[0].should == user1
105
- subject.current_users[1].should == user2
106
- subject.current_users[2].should == user3
107
- end
108
-
109
- it "should not register login time if configured so" do
110
- sorcery_controller_property_set(:register_login_time, false)
111
- now = Time.now.in_time_zone
112
- login_user
113
- @user.last_login_at.should be_nil
114
- end
115
-
116
- it "should not register logout time if configured so" do
117
- sorcery_controller_property_set(:register_logout_time, false)
118
- now = Time.now.in_time_zone
119
- login_user
120
- logout_user
121
- @user.last_logout_at.should be_nil
122
- end
123
-
124
- it "should not register last activity time if configured so" do
125
- sorcery_controller_property_set(:register_last_activity_time, false)
126
- now = Time.now.in_time_zone
127
- login_user
128
- get :some_action
129
- @user.last_activity_at.should be_nil
130
- end
131
-
132
- it "should not register last IP address if configured so" do
133
- sorcery_controller_property_set(:register_last_ip_address, false)
134
- ip_address = "127.0.0.1"
135
- login_user
136
- get :some_action
137
- @user.last_activity_at.should be_nil
138
- end
139
- end
140
- end
@@ -1,136 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SorceryController do
4
- before(:all) do
5
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
6
- User.reset_column_information
7
- end
8
-
9
- after(:all) do
10
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
11
- end
12
-
13
- # ----------------- SESSION TIMEOUT -----------------------
14
- describe SorceryController, "with brute force protection features" do
15
- before(:all) do
16
- sorcery_reload!([:brute_force_protection])
17
- create_new_user
18
- end
19
-
20
- after(:each) do
21
- Sorcery::Controller::Config.reset!
22
- sorcery_controller_property_set(:user_class, User)
23
- Timecop.return
24
- end
25
-
26
- it "should count login retries" do
27
- 3.times {get :test_login, :email => 'bla@bla.com', :password => 'blabla'}
28
- User.find_by_email('bla@bla.com').failed_logins_count.should == 3
29
- end
30
-
31
- it "should generate unlock token before mail is sent" do
32
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
33
- sorcery_model_property_set(:login_lock_time_period, 0)
34
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
35
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
36
- ActionMailer::Base.deliveries.last.body.to_s.match(User.find_by_email('bla@bla.com').unlock_token).should_not be_nil
37
- end
38
-
39
- it "should unlock after entering unlock token" do
40
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
41
- sorcery_model_property_set(:login_lock_time_period, 0)
42
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
43
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
44
- User.find_by_email('bla@bla.com').unlock_token.should_not be_nil
45
- token = User.find_by_email('bla@bla.com').unlock_token
46
- user = User.load_from_unlock_token(token)
47
- user.should_not be_nil
48
- user.unlock!
49
- User.load_from_unlock_token(token).should be_nil
50
- end
51
-
52
- it "should reset the counter on a good login" do
53
- # dirty hack for rails 4
54
- @controller.stub(:register_last_activity_time_to_db)
55
-
56
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 5)
57
- 3.times {get :test_login, :email => 'bla@bla.com', :password => 'blabla'}
58
- get :test_login, :email => 'bla@bla.com', :password => 'secret'
59
- User.find_by_email('bla@bla.com').failed_logins_count.should == 0
60
- end
61
-
62
- it "should lock user when number of retries reached the limit" do
63
- User.find_by_email('bla@bla.com').lock_expires_at.should be_nil
64
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
65
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
66
- User.find_by_email('bla@bla.com').lock_expires_at.should_not be_nil
67
- end
68
-
69
- it "should unlock after lock time period passes" do
70
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
71
- sorcery_model_property_set(:login_lock_time_period, 0.2)
72
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
73
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
74
- User.find_by_email('bla@bla.com').lock_expires_at.should_not be_nil
75
- Timecop.travel(Time.now.in_time_zone + 0.3)
76
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
77
- User.find_by_email('bla@bla.com').lock_expires_at.should be_nil
78
- end
79
-
80
- it "should not unlock if time period is 0 (permanent lock)" do
81
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
82
- sorcery_model_property_set(:login_lock_time_period, 0)
83
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
84
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
85
- unlock_date = User.find_by_email('bla@bla.com').lock_expires_at
86
- Timecop.travel(Time.now.in_time_zone + 1)
87
- get :test_login, :email => 'bla@bla.com', :password => 'blabla'
88
- User.find_by_email('bla@bla.com').lock_expires_at.to_s.should == unlock_date.to_s
89
- end
90
-
91
- context "unlock_token_mailer_disabled is true" do
92
-
93
- before(:each) do
94
- sorcery_model_property_set(:unlock_token_mailer_disabled, true)
95
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
96
- sorcery_model_property_set(:login_lock_time_period, 0)
97
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
98
- end
99
-
100
- it "should generate unlock token after user locked" do
101
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
102
- User.find_by_email('bla@bla.com').unlock_token.should_not be_nil
103
- end
104
-
105
- it "should *not* automatically send unlock mail" do
106
- old_size = ActionMailer::Base.deliveries.size
107
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
108
- ActionMailer::Base.deliveries.size.should == old_size
109
- end
110
-
111
- end
112
-
113
- context "unlock_token_mailer_disabled is false" do
114
-
115
- before(:each) do
116
- sorcery_model_property_set(:unlock_token_mailer_disabled, false)
117
- sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
118
- sorcery_model_property_set(:login_lock_time_period, 0)
119
- sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
120
- end
121
-
122
- it "should set the unlock token after user locked" do
123
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
124
- User.find_by_email('bla@bla.com').unlock_token.should_not be_nil
125
- end
126
-
127
- it "should automatically send unlock mail" do
128
- old_size = ActionMailer::Base.deliveries.size
129
- 3.times {get :test_login, :email => "bla@bla.com", :password => "blabla"}
130
- ActionMailer::Base.deliveries.size.should == old_size + 1
131
- end
132
-
133
- end
134
-
135
- end
136
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SorceryController do
4
-
5
- # ----------------- HTTP BASIC AUTH -----------------------
6
- describe SorceryController, "with http basic auth features" do
7
- before(:all) do
8
- sorcery_reload!([:http_basic_auth])
9
-
10
- sorcery_controller_property_set(:controller_to_realm_map, {"sorcery" => "sorcery"})
11
- create_new_user
12
- end
13
-
14
- after(:each) do
15
- logout_user
16
- end
17
-
18
- it "requests basic authentication when before_filter is used" do
19
- get :test_http_basic_auth
20
- response.code.should == "401"
21
- end
22
-
23
- it "authenticates from http basic if credentials are sent" do
24
- # dirty hack for rails 4
25
- @controller.stub(:register_last_activity_time_to_db)
26
-
27
- @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{@user.email}:secret")
28
- get :test_http_basic_auth, nil, :http_authentication_used => true
29
- response.should be_a_success
30
- end
31
-
32
- it "fails authentication if credentials are wrong" do
33
- @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{@user.email}:wrong!")
34
- get :test_http_basic_auth, nil, :http_authentication_used => true
35
- response.code.should redirect_to root_url
36
- end
37
-
38
- it "should allow configuration option 'controller_to_realm_map'" do
39
- sorcery_controller_property_set(:controller_to_realm_map, {"1" => "2"})
40
- Sorcery::Controller::Config.controller_to_realm_map.should == {"1" => "2"}
41
- end
42
-
43
- it "should display the correct realm name configured for the controller" do
44
- sorcery_controller_property_set(:controller_to_realm_map, {"sorcery" => "Salad"})
45
-
46
- get :test_http_basic_auth
47
- response.headers["WWW-Authenticate"].should == "Basic realm=\"Salad\""
48
- end
49
-
50
- it "should sign in the user's session on successful login" do
51
- # dirty hack for rails 4
52
- @controller.stub(:register_last_activity_time_to_db)
53
-
54
- @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{@user.email}:secret")
55
- get :test_http_basic_auth, nil, :http_authentication_used => true
56
- session[:user_id].should == User.find_by_email(@user.email).id
57
- end
58
- end
59
- end