sorcery 0.5.21 → 0.6.1

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 (72) hide show
  1. data/Gemfile +2 -2
  2. data/Gemfile.lock +96 -81
  3. data/README.rdoc +9 -1
  4. data/Rakefile +3 -3
  5. data/VERSION +1 -1
  6. data/lib/sorcery/controller/submodules/activity_logging.rb +11 -7
  7. data/lib/sorcery/controller/submodules/brute_force_protection.rb +8 -5
  8. data/lib/sorcery/controller/submodules/external.rb +11 -6
  9. data/lib/sorcery/controller/submodules/http_basic_auth.rb +11 -6
  10. data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
  11. data/lib/sorcery/controller/submodules/session_timeout.rb +3 -1
  12. data/lib/sorcery/controller.rb +12 -9
  13. data/lib/sorcery/crypto_providers/aes256.rb +8 -5
  14. data/lib/sorcery/crypto_providers/bcrypt.rb +12 -6
  15. data/lib/sorcery/crypto_providers/sha256.rb +2 -1
  16. data/lib/sorcery/crypto_providers/sha512.rb +2 -1
  17. data/lib/sorcery/initializers/initializer.rb +125 -36
  18. data/lib/sorcery/model/adapters/active_record.rb +2 -2
  19. data/lib/sorcery/model/adapters/mongoid.rb +4 -4
  20. data/lib/sorcery/model/submodules/activity_logging.rb +7 -6
  21. data/lib/sorcery/model/submodules/brute_force_protection.rb +10 -6
  22. data/lib/sorcery/model/submodules/external.rb +4 -2
  23. data/lib/sorcery/model/submodules/remember_me.rb +4 -3
  24. data/lib/sorcery/model/submodules/reset_password.rb +16 -8
  25. data/lib/sorcery/model/submodules/user_activation.rb +23 -10
  26. data/lib/sorcery/model/temporary_token.rb +3 -2
  27. data/lib/sorcery/model.rb +58 -26
  28. data/lib/sorcery/test_helpers/internal/rails.rb +6 -2
  29. data/lib/sorcery/test_helpers/internal/sinatra.rb +1 -1
  30. data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +1 -1
  31. data/lib/sorcery/test_helpers/internal.rb +2 -1
  32. data/sorcery.gemspec +41 -23
  33. data/spec/Gemfile +2 -2
  34. data/spec/Gemfile.lock +33 -32
  35. data/spec/rails3/Gemfile.lock +7 -7
  36. data/spec/rails3/spec/controller_oauth2_spec.rb +4 -25
  37. data/spec/rails3/spec/controller_oauth_spec.rb +3 -24
  38. data/spec/rails3/spec/controller_spec.rb +2 -2
  39. data/spec/rails3/spec/user_activation_spec.rb +2 -168
  40. data/spec/rails3/spec/user_activity_logging_spec.rb +2 -30
  41. data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -35
  42. data/spec/rails3/spec/user_oauth_spec.rb +2 -26
  43. data/spec/rails3/spec/user_remember_me_spec.rb +2 -45
  44. data/spec/rails3/spec/user_reset_password_spec.rb +3 -168
  45. data/spec/rails3/spec/user_spec.rb +3 -283
  46. data/spec/rails3_mongoid/Gemfile.lock +7 -7
  47. data/spec/rails3_mongoid/app/models/authentication.rb +3 -3
  48. data/spec/rails3_mongoid/spec/user_activation_spec.rb +2 -171
  49. data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +2 -25
  50. data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +2 -35
  51. data/spec/rails3_mongoid/spec/user_oauth_spec.rb +2 -28
  52. data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +2 -45
  53. data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +2 -176
  54. data/spec/rails3_mongoid/spec/user_spec.rb +3 -285
  55. data/spec/shared_examples/controller_oauth2_shared_examples.rb +37 -0
  56. data/spec/shared_examples/controller_oauth_shared_examples.rb +37 -0
  57. data/spec/shared_examples/user_activation_shared_examples.rb +173 -0
  58. data/spec/shared_examples/user_activity_logging_shared_examples.rb +27 -0
  59. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +37 -0
  60. data/spec/shared_examples/user_oauth_shared_examples.rb +31 -0
  61. data/spec/shared_examples/user_remember_me_shared_examples.rb +47 -0
  62. data/spec/shared_examples/user_reset_password_shared_examples.rb +177 -0
  63. data/spec/shared_examples/user_shared_examples.rb +292 -0
  64. data/spec/sinatra/Gemfile.lock +7 -7
  65. data/spec/sinatra/spec/controller_oauth2_spec.rb +3 -24
  66. data/spec/sinatra/spec/controller_oauth_spec.rb +3 -24
  67. data/spec/sinatra/spec/controller_spec.rb +2 -2
  68. data/spec/sinatra_modular/Gemfile.lock +7 -7
  69. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +3 -24
  70. data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +3 -24
  71. data/spec/sinatra_modular/spec_modular/controller_spec.rb +2 -2
  72. metadata +28 -12
data/Gemfile CHANGED
@@ -2,8 +2,8 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem 'oauth', ">= 0.4.4"
6
- gem 'oauth2', ">= 0.1.1"
5
+ gem 'oauth', "~> 0.4.4"
6
+ gem 'oauth2', "~> 0.4.1"
7
7
 
8
8
  # Add dependencies to develop your gem here.
9
9
  # Include everything needed to run rake, tests, features, etc.
data/Gemfile.lock CHANGED
@@ -1,100 +1,108 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- abstract (1.0.0)
5
- actionmailer (3.0.3)
6
- actionpack (= 3.0.3)
7
- mail (~> 2.2.9)
8
- actionpack (3.0.3)
9
- activemodel (= 3.0.3)
10
- activesupport (= 3.0.3)
11
- builder (~> 2.1.2)
12
- erubis (~> 2.6.6)
13
- i18n (~> 0.4)
14
- rack (~> 1.2.1)
15
- rack-mount (~> 0.6.13)
16
- rack-test (~> 0.5.6)
17
- tzinfo (~> 0.3.23)
18
- activemodel (3.0.3)
19
- activesupport (= 3.0.3)
20
- builder (~> 2.1.2)
21
- i18n (~> 0.4)
22
- activerecord (3.0.3)
23
- activemodel (= 3.0.3)
24
- activesupport (= 3.0.3)
25
- arel (~> 2.0.2)
26
- tzinfo (~> 0.3.23)
27
- activeresource (3.0.3)
28
- activemodel (= 3.0.3)
29
- activesupport (= 3.0.3)
30
- activesupport (3.0.3)
31
- addressable (2.2.4)
4
+ actionmailer (3.1.0)
5
+ actionpack (= 3.1.0)
6
+ mail (~> 2.3.0)
7
+ actionpack (3.1.0)
8
+ activemodel (= 3.1.0)
9
+ activesupport (= 3.1.0)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ i18n (~> 0.6)
13
+ rack (~> 1.3.2)
14
+ rack-cache (~> 1.0.3)
15
+ rack-mount (~> 0.8.2)
16
+ rack-test (~> 0.6.1)
17
+ sprockets (~> 2.0.0)
18
+ activemodel (3.1.0)
19
+ activesupport (= 3.1.0)
20
+ bcrypt-ruby (~> 3.0.0)
21
+ builder (~> 3.0.0)
22
+ i18n (~> 0.6)
23
+ activerecord (3.1.0)
24
+ activemodel (= 3.1.0)
25
+ activesupport (= 3.1.0)
26
+ arel (~> 2.2.1)
27
+ tzinfo (~> 0.3.29)
28
+ activeresource (3.1.0)
29
+ activemodel (= 3.1.0)
30
+ activesupport (= 3.1.0)
31
+ activesupport (3.1.0)
32
+ multi_json (~> 1.0)
33
+ addressable (2.2.6)
32
34
  archive-tar-minitar (0.5.2)
33
- arel (2.0.6)
34
- bson (1.3.0)
35
- bson_ext (1.3.0)
36
- builder (2.1.2)
37
- columnize (0.3.2)
38
- diff-lcs (1.1.2)
39
- erubis (2.6.6)
40
- abstract (>= 1.0.0)
41
- faraday (0.5.5)
35
+ arel (2.2.1)
36
+ bcrypt-ruby (3.0.0)
37
+ bson (1.3.1)
38
+ bson_ext (1.3.1)
39
+ builder (3.0.0)
40
+ columnize (0.3.4)
41
+ diff-lcs (1.1.3)
42
+ erubis (2.7.0)
43
+ faraday (0.6.1)
42
44
  addressable (~> 2.2.4)
43
45
  multipart-post (~> 1.1.0)
44
46
  rack (< 2, >= 1.1.0)
45
47
  git (1.2.5)
46
- i18n (0.5.0)
48
+ hike (1.2.1)
49
+ i18n (0.6.0)
47
50
  jeweler (1.5.2)
48
51
  bundler (~> 1.0.0)
49
52
  git (>= 1.2.5)
50
53
  rake
51
- json (1.5.1)
52
- linecache19 (0.5.11)
54
+ json (1.5.4)
55
+ linecache19 (0.5.12)
53
56
  ruby_core_source (>= 0.1.4)
54
- mail (2.2.13)
55
- activesupport (>= 2.3.6)
57
+ mail (2.3.0)
56
58
  i18n (>= 0.4.0)
57
59
  mime-types (~> 1.16)
58
60
  treetop (~> 1.4.8)
59
61
  mime-types (1.16)
60
- mongo (1.3.0)
61
- bson (>= 1.3.0)
62
- mongoid (2.0.1)
62
+ mongo (1.3.1)
63
+ bson (>= 1.3.1)
64
+ mongoid (2.2.0)
63
65
  activemodel (~> 3.0)
64
66
  mongo (~> 1.3)
65
67
  tzinfo (~> 0.3.22)
66
- will_paginate (~> 3.0.pre)
67
- multi_json (0.0.5)
68
- multipart-post (1.1.0)
69
- oauth (0.4.4)
70
- oauth2 (0.1.1)
71
- faraday (~> 0.5.0)
72
- multi_json (~> 0.0.4)
73
- polyglot (0.3.1)
74
- rack (1.2.1)
75
- rack-mount (0.6.13)
68
+ multi_json (1.0.3)
69
+ multipart-post (1.1.3)
70
+ oauth (0.4.5)
71
+ oauth2 (0.4.1)
72
+ faraday (~> 0.6.1)
73
+ multi_json (>= 0.0.5)
74
+ polyglot (0.3.2)
75
+ rack (1.3.2)
76
+ rack-cache (1.0.3)
77
+ rack (>= 0.4)
78
+ rack-mount (0.8.3)
76
79
  rack (>= 1.0.0)
77
- rack-test (0.5.6)
80
+ rack-ssl (1.3.2)
81
+ rack
82
+ rack-test (0.6.1)
78
83
  rack (>= 1.0)
79
- rails (3.0.3)
80
- actionmailer (= 3.0.3)
81
- actionpack (= 3.0.3)
82
- activerecord (= 3.0.3)
83
- activeresource (= 3.0.3)
84
- activesupport (= 3.0.3)
84
+ rails (3.1.0)
85
+ actionmailer (= 3.1.0)
86
+ actionpack (= 3.1.0)
87
+ activerecord (= 3.1.0)
88
+ activeresource (= 3.1.0)
89
+ activesupport (= 3.1.0)
85
90
  bundler (~> 1.0)
86
- railties (= 3.0.3)
87
- railties (3.0.3)
88
- actionpack (= 3.0.3)
89
- activesupport (= 3.0.3)
91
+ railties (= 3.1.0)
92
+ railties (3.1.0)
93
+ actionpack (= 3.1.0)
94
+ activesupport (= 3.1.0)
95
+ rack-ssl (~> 1.3.2)
90
96
  rake (>= 0.8.7)
91
- thor (~> 0.14.4)
92
- rake (0.8.7)
97
+ rdoc (~> 3.4)
98
+ thor (~> 0.14.6)
99
+ rake (0.9.2)
100
+ rdoc (3.9.4)
93
101
  rspec (2.5.0)
94
102
  rspec-core (~> 2.5.0)
95
103
  rspec-expectations (~> 2.5.0)
96
104
  rspec-mocks (~> 2.5.0)
97
- rspec-core (2.5.1)
105
+ rspec-core (2.5.2)
98
106
  rspec-expectations (2.5.0)
99
107
  diff-lcs (~> 1.1.2)
100
108
  rspec-mocks (2.5.0)
@@ -103,7 +111,7 @@ GEM
103
111
  activesupport (~> 3.0)
104
112
  railties (~> 3.0)
105
113
  rspec (~> 2.5.0)
106
- ruby-debug-base19 (0.11.24)
114
+ ruby-debug-base19 (0.11.25)
107
115
  columnize (>= 0.3.1)
108
116
  linecache19 (>= 0.5.11)
109
117
  ruby_core_source (>= 0.1.4)
@@ -111,19 +119,26 @@ GEM
111
119
  columnize (>= 0.3.1)
112
120
  linecache19 (>= 0.5.11)
113
121
  ruby-debug-base19 (>= 0.11.19)
114
- ruby_core_source (0.1.4)
122
+ ruby_core_source (0.1.5)
115
123
  archive-tar-minitar (>= 0.5.2)
116
- simplecov (0.3.9)
117
- simplecov-html (>= 0.3.7)
118
- simplecov-html (0.3.9)
119
- sqlite3-ruby (1.3.2)
124
+ simplecov (0.4.2)
125
+ simplecov-html (~> 0.4.4)
126
+ simplecov-html (0.4.5)
127
+ sprockets (2.0.0)
128
+ hike (~> 1.2)
129
+ rack (~> 1.0)
130
+ tilt (!= 1.3.0, ~> 1.1)
131
+ sqlite3 (1.3.4)
132
+ sqlite3-ruby (1.3.3)
133
+ sqlite3 (>= 1.3.3)
120
134
  thor (0.14.6)
135
+ tilt (1.3.3)
121
136
  timecop (0.3.5)
122
- treetop (1.4.9)
137
+ treetop (1.4.10)
138
+ polyglot
123
139
  polyglot (>= 0.3.1)
124
- tzinfo (0.3.23)
125
- will_paginate (3.0.pre2)
126
- yard (0.6.4)
140
+ tzinfo (0.3.29)
141
+ yard (0.6.8)
127
142
 
128
143
  PLATFORMS
129
144
  ruby
@@ -134,8 +149,8 @@ DEPENDENCIES
134
149
  jeweler (~> 1.5.2)
135
150
  json (>= 1.5.1)
136
151
  mongoid (~> 2.0)
137
- oauth (>= 0.4.4)
138
- oauth2 (>= 0.1.1)
152
+ oauth (~> 0.4.4)
153
+ oauth2 (~> 0.4.1)
139
154
  rails (>= 3.0.0)
140
155
  rspec (~> 2.5.0)
141
156
  rspec-rails (~> 2.5.0)
data/README.rdoc CHANGED
@@ -29,7 +29,7 @@ Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
29
29
 
30
30
  Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
31
31
 
32
- Documentation: http://rubydoc.info/gems/sorcery/0.5.21/frames
32
+ Documentation: http://rubydoc.info/gems/sorcery/0.6.0/frames
33
33
 
34
34
  Check out the tutorials in the github wiki!
35
35
 
@@ -224,6 +224,14 @@ The patch version changes are backward compatible.
224
224
  In short, an app that works with x.3.1 should be able to upgrade to x.3.2 with no code changes.
225
225
  The same cannot be said about upgrading to x.4.0 and above, however.
226
226
 
227
+ == Upgrading
228
+
229
+ Important notes while upgrading:
230
+
231
+ * If upgrading from <= v0.5.1 to >= v0.5.2 you need to explicitly set your user_class model in the initializer file.
232
+
233
+ # This line must come after the 'user config' block.
234
+ config.user_class = User
227
235
 
228
236
  == Contributing to sorcery
229
237
 
data/Rakefile CHANGED
@@ -25,9 +25,9 @@ Jeweler::Tasks.new do |gem|
25
25
  # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
26
26
  # gem.add_runtime_dependency 'jabber4r', '> 0.1'
27
27
  # gem.add_development_dependency 'rspec', '> 1.2.3'
28
- gem.add_runtime_dependency 'bcrypt-ruby', '~> 2.1.4'
29
- gem.add_runtime_dependency 'oauth', '>= 0.4.4'
30
- gem.add_runtime_dependency 'oauth2', '>= 0.1.1'
28
+ gem.add_runtime_dependency 'bcrypt-ruby', '~> 3.0.0'
29
+ gem.add_runtime_dependency 'oauth', '~> 0.4.4'
30
+ gem.add_runtime_dependency 'oauth2', '~> 0.4.1'
31
31
  end
32
32
  Jeweler::RubygemsDotOrgTasks.new
33
33
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.21
1
+ 0.6.1
@@ -1,13 +1,16 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
- # This submodule keeps track of events such as login, logout, and last activity time, per user.
4
+ # This submodule keeps track of events such as login, logout,
5
+ # and last activity time, per user.
5
6
  # It helps in estimating which users are active now in the site.
6
- # This cannot be determined absolutely because a user might be reading a page without clicking anything for a while.
7
-
8
- # This is the controller part of the submodule, which adds hooks to register user events,
7
+ # This cannot be determined absolutely because a user might be
8
+ # reading a page without clicking anything for a while.
9
+ # This is the controller part of the submodule, which adds hooks
10
+ # to register user events,
9
11
  # and methods to collect active users data for use in the app.
10
- # see Socery::Model::Submodules::ActivityLogging for configuration options.
12
+ # see Socery::Model::Submodules::ActivityLogging for configuration
13
+ # options.
11
14
  module ActivityLogging
12
15
  def self.included(base)
13
16
  base.send(:include, InstanceMethods)
@@ -19,9 +22,10 @@ module Sorcery
19
22
  module InstanceMethods
20
23
  # Returns an array of the active users.
21
24
  def current_users
22
- Config.user_class.current_users
25
+ user_class.current_users
23
26
  # A possible patch here:
24
- # we'll add the current_user to the users list if he's not in it (can happen when he was inactive for more than activity timeout):
27
+ # we'll add the current_user to the users list if he's not in it
28
+ # (can happen when he was inactive for more than activity timeout):
25
29
  #
26
30
  # users.unshift!(current_user) if logged_in? && users.find {|u| u.id == current_user.id}.nil?
27
31
  #
@@ -1,9 +1,12 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
- # This module helps protect user accounts by locking them down after too many failed attemps to login were detected.
5
- # This is the controller part of the submodule which takes care of updating the failed logins and resetting them.
6
- # See Sorcery::Model::Submodules::BruteForceProtection for configuration options.
4
+ # This module helps protect user accounts by locking them down after too
5
+ # many failed attemps to login were detected.
6
+ # This is the controller part of the submodule which takes care of
7
+ # updating the failed logins and resetting them.
8
+ # See Sorcery::Model::Submodules::BruteForceProtection for configuration
9
+ # options.
7
10
  module BruteForceProtection
8
11
  def self.included(base)
9
12
  base.send(:include, InstanceMethods)
@@ -19,14 +22,14 @@ module Sorcery
19
22
  # Increments the failed logins counter on every failed login.
20
23
  # Runs as a hook after a failed login.
21
24
  def update_failed_logins_count!(credentials)
22
- user = Config.user_class.find_by_credentials(credentials)
25
+ user = user_class.find_by_credentials(credentials)
23
26
  user.register_failed_login! if user
24
27
  end
25
28
 
26
29
  # Resets the failed logins counter.
27
30
  # Runs as a hook after a successful login.
28
31
  def reset_failed_logins_count!(user, credentials)
29
- user.update_attributes!(Config.user_class.sorcery_config.failed_logins_count_attribute_name => 0)
32
+ user.update_attributes!(user_class.sorcery_config.failed_logins_count_attribute_name => 0)
30
33
  end
31
34
  end
32
35
  end
@@ -43,7 +43,7 @@ module Sorcery
43
43
  @provider = Config.send(provider)
44
44
  @provider.process_callback(params,session)
45
45
  @user_hash = @provider.get_user_hash
46
- if user = Config.user_class.load_from_provider(provider,@user_hash[:uid])
46
+ if user = user_class.load_from_provider(provider,@user_hash[:uid])
47
47
  reset_session
48
48
  login_user(user)
49
49
  user
@@ -65,14 +65,19 @@ module Sorcery
65
65
  provider = provider.to_sym
66
66
  @provider = Config.send(provider)
67
67
  @user_hash = @provider.get_user_hash
68
- config = Config.user_class.sorcery_config
68
+ config = user_class.sorcery_config
69
69
  attrs = {}
70
70
  @provider.user_info_mapping.each do |k,v|
71
- (varr = v.split("/")).size > 1 ? attrs.merge!(k => varr.inject(@user_hash[:user_info]) {|hsh,v| hsh[v] }) : attrs.merge!(k => @user_hash[:user_info][v])
71
+ if (varr = v.split("/")).size > 1
72
+ attribute_value = varr.inject(@user_hash[:user_info]) {|hsh,v| hsh[v] } rescue nil
73
+ attribute_value.nil? ? attrs : attrs.merge!(k => attribute_value)
74
+ else
75
+ attrs.merge!(k => @user_hash[:user_info][v])
76
+ end
72
77
  end
73
- Config.user_class.transaction do
74
- @user = Config.user_class.create!(attrs)
75
- Config.user_class.sorcery_config.authentications_class.create!({config.authentications_user_id_attribute_name => @user.id, config.provider_attribute_name => provider, config.provider_uid_attribute_name => @user_hash[:uid]})
78
+ user_class.transaction do
79
+ @user = user_class.create!(attrs)
80
+ user_class.sorcery_config.authentications_class.create!({config.authentications_user_id_attribute_name => @user.id, config.provider_attribute_name => provider, config.provider_uid_attribute_name => @user_hash[:uid]})
76
81
  end
77
82
  @user
78
83
  end
@@ -2,8 +2,10 @@ module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
4
  # This submodule integrates HTTP Basic authentication into sorcery.
5
- # You are provided with a before filter, require_login_from_http_basic, which requests the browser for authentication.
6
- # Then the rest of the submodule takes care of logging the user in into the session, so that the next requests will keep him logged in.
5
+ # You are provided with a before filter, require_login_from_http_basic,
6
+ # which requests the browser for authentication.
7
+ # Then the rest of the submodule takes care of logging the user in
8
+ # into the session, so that the next requests will keep him logged in.
7
9
  module HttpBasicAuth
8
10
  def self.included(base)
9
11
  base.send(:include, InstanceMethods)
@@ -28,9 +30,12 @@ module Sorcery
28
30
  # The method sets a session when requesting the user's credentials.
29
31
  # This is a trick to overcome the way HTTP authentication works (explained below):
30
32
  #
31
- # Once the user fills the credentials once, the browser will always send it to the server when visiting the website, until the browser is closed.
32
- # This causes wierd behaviour if the user logs out. The session is reset, yet the user is re-logged in by the before_filter calling 'login_from_basic_auth'.
33
- # To overcome this, we set a session when requesting the password, which logout will reset, and that's how we know if we need to request for HTTP auth again.
33
+ # Once the user fills the credentials once, the browser will always send it to the
34
+ # server when visiting the website, until the browser is closed.
35
+ # This causes wierd behaviour if the user logs out. The session is reset, yet the
36
+ # user is re-logged in by the before_filter calling 'login_from_basic_auth'.
37
+ # To overcome this, we set a session when requesting the password, which logout will
38
+ # reset, and that's how we know if we need to request for HTTP auth again.
34
39
  def require_login_from_http_basic
35
40
  (request_http_basic_authentication(realm_name_by_controller) and (session[:http_authentication_used] = true) and return) if (request.authorization.nil? || session[:http_authentication_used].nil?)
36
41
  require_login
@@ -40,7 +45,7 @@ module Sorcery
40
45
  # given to main controller module as a login source callback
41
46
  def login_from_basic_auth
42
47
  authenticate_with_http_basic do |username, password|
43
- @current_user = (Config.user_class.authenticate(username, password) if session[:http_authentication_used]) || false
48
+ @current_user = (user_class.authenticate(username, password) if session[:http_authentication_used]) || false
44
49
  login_user(@current_user) if @current_user
45
50
  @current_user
46
51
  end
@@ -1,7 +1,8 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
- # The Remember Me submodule takes care of setting the user's cookie so that he will be automatically logged in to the site on every visit,
4
+ # The Remember Me submodule takes care of setting the user's cookie so that he will
5
+ # be automatically logged in to the site on every visit,
5
6
  # until the cookie expires.
6
7
  # See Sorcery::Model::Submodules::RememberMe for configuration options.
7
8
  module RememberMe
@@ -16,7 +17,7 @@ module Sorcery
16
17
  # This method sets the cookie and calls the user to save the token and the expiration to db.
17
18
  def remember_me!
18
19
  current_user.remember_me!
19
- cookies[:remember_me_token] = { :value => current_user.remember_me_token, :expires => current_user.remember_me_token_expires_at }
20
+ set_remember_me_cookie!(current_user)
20
21
  end
21
22
 
22
23
  # Clears the cookie and clears the token from the db.
@@ -33,17 +34,25 @@ module Sorcery
33
34
  remember_me! if credentials.size == 3 && credentials[2]
34
35
  end
35
36
 
36
- # Checks the cookie for a remember me token, tried to find a user with that token and logs the user in if found.
37
+ # Checks the cookie for a remember me token, tried to find a user with that token
38
+ # and logs the user in if found.
37
39
  # Runs as a login source. See 'current_user' method for how it is used.
38
40
  def login_from_cookie
39
- user = cookies[:remember_me_token] && Config.user_class.find_by_remember_me_token(cookies[:remember_me_token])
41
+ user = cookies[:remember_me_token] && user_class.find_by_remember_me_token(cookies[:remember_me_token])
40
42
  if user && user.remember_me_token?
41
- cookies[:remember_me_token] = { :value => user.remember_me_token, :expires => user.remember_me_token_expires_at }
43
+ set_remember_me_cookie!(user)
42
44
  @current_user = user
43
45
  else
44
46
  @current_user = false
45
47
  end
46
48
  end
49
+
50
+ def set_remember_me_cookie!(user)
51
+ cookies[:remember_me_token] = {
52
+ :value => user.send(user.sorcery_config.remember_me_token_attribute_name),
53
+ :expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name)
54
+ }
55
+ end
47
56
  end
48
57
 
49
58
  end
@@ -9,7 +9,9 @@ module Sorcery
9
9
  Config.module_eval do
10
10
  class << self
11
11
  attr_accessor :session_timeout, # how long in seconds to keep the session alive.
12
- :session_timeout_from_last_action # use the last action as the beginning of session timeout.
12
+
13
+ :session_timeout_from_last_action # use the last action as the beginning of session
14
+ # timeout.
13
15
 
14
16
  def merge_session_timeout_defaults!
15
17
  @defaults.merge!(:@session_timeout => 3600, # 1.hour
@@ -29,7 +29,7 @@ module Sorcery
29
29
  # Takes credentials and returns a user on successful authentication.
30
30
  # Runs hooks after login or failed login.
31
31
  def login(*credentials)
32
- user = Config.user_class.authenticate(*credentials)
32
+ user = user_class.authenticate(*credentials)
33
33
  if user
34
34
  return_to_url = session[:return_to_url]
35
35
  reset_session # protect from session fixation attacks
@@ -62,7 +62,8 @@ module Sorcery
62
62
  @current_user ||= login_from_session || login_from_other_sources unless @current_user == false
63
63
  end
64
64
 
65
- # used when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted.
65
+ # used when a user tries to access a page while logged out, is asked to login,
66
+ # and we want to return him back to the page he originally wanted.
66
67
  def redirect_back_or_to(url, flash_hash = {})
67
68
  redirect_to(session[:return_to_url] || url, :flash => flash_hash)
68
69
  end
@@ -90,7 +91,7 @@ module Sorcery
90
91
  end
91
92
 
92
93
  def login_from_session
93
- @current_user = (Config.user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
94
+ @current_user = (user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
94
95
  end
95
96
 
96
97
  def after_login!(user, credentials)
@@ -109,25 +110,27 @@ module Sorcery
109
110
  Config.after_logout.each {|c| self.send(c)}
110
111
  end
111
112
 
113
+ def user_class
114
+ @user_class ||= Config.user_class.to_s.constantize
115
+ end
112
116
  end
113
117
 
114
118
  module Config
115
119
  class << self
116
120
  attr_accessor :submodules,
117
-
118
- :user_class, # what class to use as the user class. Set automatically when you call authenticates_with_sorcery! in the User class.
119
-
121
+ :user_class, # what class to use as the user class.
120
122
  :not_authenticated_action, # what controller action to call for non-authenticated users.
121
123
 
122
- :save_return_to_url, # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
124
+ :save_return_to_url, # when a non logged in user tries to enter a page that requires
125
+ # login, save the URL he wanted to reach,
123
126
  # and send him there after login.
124
127
 
125
128
  :login_sources,
126
129
  :after_login,
127
130
  :after_failed_login,
128
131
  :before_logout,
129
- :after_logout
130
-
132
+ :after_logout
133
+
131
134
  def init!
132
135
  @defaults = {
133
136
  :@user_class => nil,
@@ -2,18 +2,21 @@ require "openssl"
2
2
 
3
3
  module Sorcery
4
4
  module CryptoProviders
5
- # This encryption method is reversible if you have the supplied key. So in order to use this encryption method you must supply it with a key first.
5
+ # This encryption method is reversible if you have the supplied key.
6
+ # So in order to use this encryption method you must supply it with a key first.
6
7
  # In an initializer, or before your application initializes, you should do the following:
7
8
  #
8
9
  # Sorcery::Model::ConfigAES256.key = "my 32 bytes long key"
9
10
  #
10
- # My final comment is that this is a strong encryption method, but its main weakness is that its reversible. If you do not need to reverse the hash
11
+ # My final comment is that this is a strong encryption method,
12
+ # but its main weakness is that its reversible. If you do not need to reverse the hash
11
13
  # then you should consider Sha512 or BCrypt instead.
12
14
  #
13
15
  # Keep your key in a safe place, some even say the key should be stored on a separate server.
14
- # This won't hurt performance because the only time it will try and access the key on the separate server is during initialization, which only
15
- # happens once. The reasoning behind this is if someone does compromise your server they won't have the key also. Basically, you don't want to
16
- # store the key with the lock.
16
+ # This won't hurt performance because the only time it will try and access the key on the
17
+ # separate server is during initialization, which only
18
+ # happens once. The reasoning behind this is if someone does compromise your server they
19
+ # won't have the key also. Basically, you don't want to store the key with the lock.
17
20
  class AES256
18
21
  class << self
19
22
  attr_writer :key
@@ -2,9 +2,12 @@ require 'bcrypt'
2
2
 
3
3
  module Sorcery
4
4
  module CryptoProviders
5
- # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear launch codes you might want to consier BCrypt. This is an extremely
6
- # secure hashing algorithm, mainly because it is slow. A brute force attack on a BCrypt encrypted password would take much longer than a brute force attack on a
7
- # password encrypted with a Sha algorithm. Keep in mind you are sacrificing performance by using this, generating a password takes exponentially longer than any
5
+ # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear
6
+ # launch codes you might want to consier BCrypt. This is an extremely
7
+ # secure hashing algorithm, mainly because it is slow.
8
+ # A brute force attack on a BCrypt encrypted password would take much longer than a brute force attack on a
9
+ # password encrypted with a Sha algorithm. Keep in mind you are sacrificing performance by using this,
10
+ # generating a password takes exponentially longer than any
8
11
  # of the Sha algorithms. I did some benchmarking to save you some time with your decision:
9
12
  #
10
13
  # require "bcrypt"
@@ -37,8 +40,10 @@ module Sorcery
37
40
  # You are good to go!
38
41
  class BCrypt
39
42
  class << self
40
- # This is the :cost option for the BCrpyt library. The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
41
- # Set this to whatever you want, play around with it to get that perfect balance between security and performance.
43
+ # This is the :cost option for the BCrpyt library.
44
+ # The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
45
+ # Set this to whatever you want, play around with it to get that perfect balance between
46
+ # security and performance.
42
47
  def cost
43
48
  @cost ||= 10
44
49
  end
@@ -57,7 +62,8 @@ module Sorcery
57
62
  hash == join_tokens(tokens)
58
63
  end
59
64
 
60
- # This method is used as a flag to tell Sorcery to "resave" the password upon a successful login, using the new cost
65
+ # This method is used as a flag to tell Sorcery to "resave" the password
66
+ # upon a successful login, using the new cost
61
67
  def cost_matches?(hash)
62
68
  hash = new_from_hash(hash)
63
69
  if hash.nil? || hash == {}
@@ -1,7 +1,8 @@
1
1
  require "digest/sha2"
2
2
 
3
3
  module Sorcery
4
- # The activate_sorcery method has a custom_crypto_provider configuration option. This allows you to use any type of encryption you like.
4
+ # The activate_sorcery method has a custom_crypto_provider configuration option.
5
+ # This allows you to use any type of encryption you like.
5
6
  # Just create a class with a class level encrypt and matches? method. See example below.
6
7
  #
7
8
  # === Example
@@ -1,7 +1,8 @@
1
1
  require "digest/sha2"
2
2
 
3
3
  module Sorcery
4
- # The activate_sorcery method has a custom_crypto_provider configuration option. This allows you to use any type of encryption you like.
4
+ # The activate_sorcery method has a custom_crypto_provider configuration option.
5
+ # This allows you to use any type of encryption you like.
5
6
  # Just create a class with a class level encrypt and matches? method. See example below.
6
7
  #
7
8
  # === Example