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.
- data/Gemfile +2 -2
- data/Gemfile.lock +96 -81
- data/README.rdoc +9 -1
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/sorcery/controller/submodules/activity_logging.rb +11 -7
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +8 -5
- data/lib/sorcery/controller/submodules/external.rb +11 -6
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +11 -6
- data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
- data/lib/sorcery/controller/submodules/session_timeout.rb +3 -1
- data/lib/sorcery/controller.rb +12 -9
- data/lib/sorcery/crypto_providers/aes256.rb +8 -5
- data/lib/sorcery/crypto_providers/bcrypt.rb +12 -6
- data/lib/sorcery/crypto_providers/sha256.rb +2 -1
- data/lib/sorcery/crypto_providers/sha512.rb +2 -1
- data/lib/sorcery/initializers/initializer.rb +125 -36
- data/lib/sorcery/model/adapters/active_record.rb +2 -2
- data/lib/sorcery/model/adapters/mongoid.rb +4 -4
- data/lib/sorcery/model/submodules/activity_logging.rb +7 -6
- data/lib/sorcery/model/submodules/brute_force_protection.rb +10 -6
- data/lib/sorcery/model/submodules/external.rb +4 -2
- data/lib/sorcery/model/submodules/remember_me.rb +4 -3
- data/lib/sorcery/model/submodules/reset_password.rb +16 -8
- data/lib/sorcery/model/submodules/user_activation.rb +23 -10
- data/lib/sorcery/model/temporary_token.rb +3 -2
- data/lib/sorcery/model.rb +58 -26
- data/lib/sorcery/test_helpers/internal/rails.rb +6 -2
- data/lib/sorcery/test_helpers/internal/sinatra.rb +1 -1
- data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +1 -1
- data/lib/sorcery/test_helpers/internal.rb +2 -1
- data/sorcery.gemspec +41 -23
- data/spec/Gemfile +2 -2
- data/spec/Gemfile.lock +33 -32
- data/spec/rails3/Gemfile.lock +7 -7
- data/spec/rails3/spec/controller_oauth2_spec.rb +4 -25
- data/spec/rails3/spec/controller_oauth_spec.rb +3 -24
- data/spec/rails3/spec/controller_spec.rb +2 -2
- data/spec/rails3/spec/user_activation_spec.rb +2 -168
- data/spec/rails3/spec/user_activity_logging_spec.rb +2 -30
- data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -35
- data/spec/rails3/spec/user_oauth_spec.rb +2 -26
- data/spec/rails3/spec/user_remember_me_spec.rb +2 -45
- data/spec/rails3/spec/user_reset_password_spec.rb +3 -168
- data/spec/rails3/spec/user_spec.rb +3 -283
- data/spec/rails3_mongoid/Gemfile.lock +7 -7
- data/spec/rails3_mongoid/app/models/authentication.rb +3 -3
- data/spec/rails3_mongoid/spec/user_activation_spec.rb +2 -171
- data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +2 -25
- data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +2 -35
- data/spec/rails3_mongoid/spec/user_oauth_spec.rb +2 -28
- data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +2 -45
- data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +2 -176
- data/spec/rails3_mongoid/spec/user_spec.rb +3 -285
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +37 -0
- data/spec/shared_examples/controller_oauth_shared_examples.rb +37 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +173 -0
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +27 -0
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +37 -0
- data/spec/shared_examples/user_oauth_shared_examples.rb +31 -0
- data/spec/shared_examples/user_remember_me_shared_examples.rb +47 -0
- data/spec/shared_examples/user_reset_password_shared_examples.rb +177 -0
- data/spec/shared_examples/user_shared_examples.rb +292 -0
- data/spec/sinatra/Gemfile.lock +7 -7
- data/spec/sinatra/spec/controller_oauth2_spec.rb +3 -24
- data/spec/sinatra/spec/controller_oauth_spec.rb +3 -24
- data/spec/sinatra/spec/controller_spec.rb +2 -2
- data/spec/sinatra_modular/Gemfile.lock +7 -7
- data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +3 -24
- data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +3 -24
- data/spec/sinatra_modular/spec_modular/controller_spec.rb +2 -2
- 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', "
|
|
6
|
-
gem 'oauth2', "
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
rack (~> 1.
|
|
15
|
-
rack-mount (~> 0.
|
|
16
|
-
rack-test (~> 0.
|
|
17
|
-
|
|
18
|
-
activemodel (3.0
|
|
19
|
-
activesupport (= 3.0
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
faraday (0.
|
|
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
|
-
|
|
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.
|
|
52
|
-
linecache19 (0.5.
|
|
54
|
+
json (1.5.4)
|
|
55
|
+
linecache19 (0.5.12)
|
|
53
56
|
ruby_core_source (>= 0.1.4)
|
|
54
|
-
mail (2.
|
|
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.
|
|
61
|
-
bson (>= 1.3.
|
|
62
|
-
mongoid (2.0
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
rack (1.
|
|
75
|
-
|
|
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-
|
|
80
|
+
rack-ssl (1.3.2)
|
|
81
|
+
rack
|
|
82
|
+
rack-test (0.6.1)
|
|
78
83
|
rack (>= 1.0)
|
|
79
|
-
rails (3.0
|
|
80
|
-
actionmailer (= 3.0
|
|
81
|
-
actionpack (= 3.0
|
|
82
|
-
activerecord (= 3.0
|
|
83
|
-
activeresource (= 3.0
|
|
84
|
-
activesupport (= 3.0
|
|
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
|
|
87
|
-
railties (3.0
|
|
88
|
-
actionpack (= 3.0
|
|
89
|
-
activesupport (= 3.0
|
|
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
|
-
|
|
92
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
122
|
+
ruby_core_source (0.1.5)
|
|
115
123
|
archive-tar-minitar (>= 0.5.2)
|
|
116
|
-
simplecov (0.
|
|
117
|
-
simplecov-html (
|
|
118
|
-
simplecov-html (0.
|
|
119
|
-
|
|
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.
|
|
137
|
+
treetop (1.4.10)
|
|
138
|
+
polyglot
|
|
123
139
|
polyglot (>= 0.3.1)
|
|
124
|
-
tzinfo (0.3.
|
|
125
|
-
|
|
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 (
|
|
138
|
-
oauth2 (
|
|
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.
|
|
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', '~>
|
|
29
|
-
gem.add_runtime_dependency 'oauth', '
|
|
30
|
-
gem.add_runtime_dependency 'oauth2', '
|
|
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.
|
|
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,
|
|
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
|
|
7
|
-
|
|
8
|
-
# This is the controller part of the submodule, which adds hooks
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
5
|
-
#
|
|
6
|
-
#
|
|
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 =
|
|
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!(
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
74
|
-
@user =
|
|
75
|
-
|
|
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,
|
|
6
|
-
#
|
|
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
|
|
32
|
-
#
|
|
33
|
-
#
|
|
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 = (
|
|
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
|
|
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
|
-
|
|
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
|
|
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] &&
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/lib/sorcery/controller.rb
CHANGED
|
@@ -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 =
|
|
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,
|
|
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 = (
|
|
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
|
|
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.
|
|
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,
|
|
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
|
|
15
|
-
#
|
|
16
|
-
#
|
|
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
|
|
6
|
-
#
|
|
7
|
-
#
|
|
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.
|
|
41
|
-
#
|
|
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
|
|
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.
|
|
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.
|
|
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
|