sorcery 0.3.0 → 0.4.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.
- data/Gemfile +3 -2
- data/Gemfile.lock +13 -11
- data/README.rdoc +99 -33
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/lib/generators/sorcery_migration/templates/core.rb +2 -2
- data/lib/generators/sorcery_migration/templates/{oauth.rb → external.rb} +1 -1
- data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +35 -0
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +26 -0
- data/lib/sorcery/controller/submodules/{oauth → external}/providers/facebook.rb +24 -6
- data/lib/sorcery/controller/submodules/{oauth → external}/providers/twitter.rb +31 -6
- data/lib/sorcery/controller/submodules/{oauth.rb → external.rb} +18 -30
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
- data/lib/sorcery/controller.rb +21 -21
- data/lib/sorcery/crypto_providers/bcrypt.rb +1 -1
- data/lib/sorcery/crypto_providers/common.rb +35 -0
- data/lib/sorcery/crypto_providers/md5.rb +3 -23
- data/lib/sorcery/crypto_providers/sha1.rb +4 -16
- data/lib/sorcery/crypto_providers/sha256.rb +3 -23
- data/lib/sorcery/crypto_providers/sha512.rb +3 -23
- data/lib/sorcery/engine.rb +4 -0
- data/lib/sorcery/initializers/initializer.rb +86 -0
- data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
- data/lib/sorcery/model.rb +13 -8
- data/lib/sorcery/railties/tasks.rake +10 -0
- data/lib/sorcery/sinatra.rb +0 -9
- data/lib/sorcery/test_helpers/rails.rb +6 -9
- data/lib/sorcery/test_helpers/sinatra.rb +6 -9
- data/lib/sorcery/test_helpers.rb +12 -0
- data/lib/sorcery.rb +10 -7
- data/sorcery.gemspec +146 -153
- data/spec/Gemfile +2 -2
- data/spec/Gemfile.lock +10 -10
- data/spec/Rakefile +1 -0
- data/spec/rails3/.rspec +1 -1
- data/spec/rails3/{app_root/Gemfile → Gemfile} +4 -4
- data/spec/rails3/{app_root/Gemfile.lock → Gemfile.lock} +20 -20
- data/spec/rails3/{app_root/Rakefile → Rakefile} +1 -0
- data/spec/rails3/{app_root/app → app}/controllers/application_controller.rb +11 -11
- data/spec/rails3/config/database.yml +27 -0
- data/spec/rails3/{app_root/spec → spec}/controller_brute_force_protection_spec.rb +3 -2
- data/spec/rails3/{app_root/spec → spec}/controller_oauth2_spec.rb +23 -22
- data/spec/rails3/{app_root/spec → spec}/controller_oauth_spec.rb +17 -17
- data/spec/rails3/{app_root/spec → spec}/controller_session_timeout_spec.rb +8 -4
- data/spec/rails3/spec/spec.opts +2 -0
- data/spec/rails3/spec/spec_helper.rb +70 -0
- data/spec/rails3/{app_root/spec → spec}/user_activation_spec.rb +5 -1
- data/spec/{sinatra → rails3}/spec/user_oauth_spec.rb +7 -7
- data/spec/rails3/{app_root/spec → spec}/user_reset_password_spec.rb +7 -3
- data/spec/rails3/{app_root/spec → spec}/user_spec.rb +5 -11
- data/spec/sinatra/Gemfile +3 -3
- data/spec/sinatra/Gemfile.lock +17 -17
- data/spec/sinatra/Rakefile +1 -0
- data/spec/sinatra/myapp.rb +11 -11
- data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +3 -2
- data/spec/sinatra/spec/controller_oauth2_spec.rb +23 -22
- data/spec/sinatra/spec/controller_oauth_spec.rb +17 -17
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +8 -4
- data/spec/sinatra/spec/spec.opts +2 -4
- data/spec/sinatra/spec/spec_helper.rb +2 -1
- data/spec/sorcery_crypto_providers_spec.rb +5 -4
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +3 -4
- metadata +157 -156
- data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -33
- data/lib/sorcery/controller/submodules/oauth/oauth2.rb +0 -24
- data/spec/rails3/app_root/.rspec +0 -1
- data/spec/rails3/app_root/config/database.yml +0 -27
- data/spec/rails3/app_root/spec/spec_helper.rb +0 -62
- data/spec/rails3/app_root/spec/user_oauth_spec.rb +0 -39
- data/spec/sinatra/spec/user_activation_spec.rb +0 -188
- data/spec/sinatra/spec/user_activity_logging_spec.rb +0 -36
- data/spec/sinatra/spec/user_brute_force_protection_spec.rb +0 -76
- data/spec/sinatra/spec/user_remember_me_spec.rb +0 -66
- data/spec/sinatra/spec/user_reset_password_spec.rb +0 -178
- data/spec/sinatra/spec/user_spec.rb +0 -317
- /data/spec/rails3/{app_root/.gitignore → .gitignore} +0 -0
- /data/spec/rails3/{app_root/README → README} +0 -0
- /data/spec/rails3/{app_root/Rakefile.unused → Rakefile.unused} +0 -0
- /data/spec/rails3/{app_root/app → app}/helpers/application_helper.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/mailers/sorcery_mailer.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/models/authentication.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/models/user.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/layouts/application.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.text.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.text.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.text.erb +0 -0
- /data/spec/rails3/{app_root/config → config}/application.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/boot.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environment.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/development.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/in_memory.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/production.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/test.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/backtrace_silencers.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/inflections.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/mime_types.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/secret_token.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/session_store.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/locales/en.yml +0 -0
- /data/spec/rails3/{app_root/config → config}/routes.rb +0 -0
- /data/spec/rails3/{app_root/config.ru → config.ru} +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/activation/20101224223622_add_activation_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/core/20101224223620_create_users.rb +0 -0
- /data/spec/rails3/{app_root/db/migrate/oauth → db/migrate/external}/20101224223628_create_authentications.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/schema.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/seeds.rb +0 -0
- /data/spec/rails3/{app_root/lib → lib}/tasks/.gitkeep +0 -0
- /data/spec/rails3/{app_root/public → public}/404.html +0 -0
- /data/spec/rails3/{app_root/public → public}/422.html +0 -0
- /data/spec/rails3/{app_root/public → public}/500.html +0 -0
- /data/spec/rails3/{app_root/public → public}/favicon.ico +0 -0
- /data/spec/rails3/{app_root/public → public}/images/rails.png +0 -0
- /data/spec/rails3/{app_root/public → public}/index.html +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/application.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/controls.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/dragdrop.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/effects.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/prototype.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/rails.js +0 -0
- /data/spec/rails3/{app_root/public → public}/robots.txt +0 -0
- /data/spec/rails3/{app_root/public → public}/stylesheets/.gitkeep +0 -0
- /data/spec/rails3/{app_root/script → script}/rails +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_activity_logging_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_http_basic_auth_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_remember_me_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/spec_helper.orig.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_activity_logging_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_brute_force_protection_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_remember_me_spec.rb +0 -0
- /data/spec/rails3/{app_root/vendor → vendor}/plugins/.gitkeep +0 -0
- /data/spec/sinatra/db/migrate/{oauth → external}/20101224223628_create_authentications.rb +0 -0
data/lib/sorcery/controller.rb
CHANGED
|
@@ -2,28 +2,17 @@ module Sorcery
|
|
|
2
2
|
module Controller
|
|
3
3
|
def self.included(klass)
|
|
4
4
|
klass.class_eval do
|
|
5
|
-
extend ClassMethods
|
|
6
5
|
include InstanceMethods
|
|
7
6
|
Config.submodules.each do |mod|
|
|
8
|
-
begin
|
|
7
|
+
begin
|
|
9
8
|
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
|
10
9
|
rescue NameError
|
|
11
10
|
# don't stop on a missing submodule.
|
|
12
11
|
end
|
|
13
12
|
end
|
|
14
|
-
Config.update!
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
module ClassMethods
|
|
19
|
-
def activate_sorcery!(&block)
|
|
20
|
-
yield Config if block_given?
|
|
21
|
-
after_config!
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def after_config!
|
|
25
|
-
Config.after_config.each {|c| send(c)}
|
|
26
13
|
end
|
|
14
|
+
Config.update!
|
|
15
|
+
Config.configure!
|
|
27
16
|
end
|
|
28
17
|
|
|
29
18
|
module InstanceMethods
|
|
@@ -73,12 +62,14 @@ module Sorcery
|
|
|
73
62
|
@current_user ||= login_from_session || login_from_other_sources unless @current_user == false
|
|
74
63
|
end
|
|
75
64
|
|
|
76
|
-
|
|
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.
|
|
66
|
+
def redirect_back_or_to(url, flash_hash = {})
|
|
77
67
|
redirect_to(session[:return_to_url] || url, :flash => flash_hash)
|
|
78
68
|
end
|
|
79
69
|
|
|
80
70
|
# The default action for denying non-authenticated users.
|
|
81
|
-
# You can override this method in your controllers
|
|
71
|
+
# You can override this method in your controllers,
|
|
72
|
+
# or provide a different method in the configuration.
|
|
82
73
|
def not_authenticated
|
|
83
74
|
redirect_to root_path
|
|
84
75
|
end
|
|
@@ -124,7 +115,7 @@ module Sorcery
|
|
|
124
115
|
class << self
|
|
125
116
|
attr_accessor :submodules,
|
|
126
117
|
|
|
127
|
-
:user_class, # what class to use as the user class. Set automatically when you call
|
|
118
|
+
:user_class, # what class to use as the user class. Set automatically when you call authenticates_with_sorcery! in the User class.
|
|
128
119
|
|
|
129
120
|
:not_authenticated_action, # what controller action to call for non-authenticated users.
|
|
130
121
|
|
|
@@ -135,9 +126,7 @@ module Sorcery
|
|
|
135
126
|
:after_login,
|
|
136
127
|
:after_failed_login,
|
|
137
128
|
:before_logout,
|
|
138
|
-
:after_logout
|
|
139
|
-
:after_config
|
|
140
|
-
|
|
129
|
+
:after_logout
|
|
141
130
|
|
|
142
131
|
def init!
|
|
143
132
|
@defaults = {
|
|
@@ -149,7 +138,6 @@ module Sorcery
|
|
|
149
138
|
:@after_failed_login => [],
|
|
150
139
|
:@before_logout => [],
|
|
151
140
|
:@after_logout => [],
|
|
152
|
-
:@after_config => [],
|
|
153
141
|
:@save_return_to_url => true
|
|
154
142
|
}
|
|
155
143
|
end
|
|
@@ -166,6 +154,18 @@ module Sorcery
|
|
|
166
154
|
instance_variable_set(k,v) if !instance_variable_defined?(k)
|
|
167
155
|
end
|
|
168
156
|
end
|
|
157
|
+
|
|
158
|
+
def user_config(&blk)
|
|
159
|
+
block_given? ? @user_config = blk : @user_config
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def configure(&blk)
|
|
163
|
+
@configure_blk = blk
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def configure!
|
|
167
|
+
@configure_blk.call(self) if @configure_blk
|
|
168
|
+
end
|
|
169
169
|
end
|
|
170
170
|
init!
|
|
171
171
|
reset!
|
|
@@ -42,7 +42,7 @@ module Sorcery
|
|
|
42
42
|
# 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.
|
|
43
43
|
# Set this to whatever you want, play around with it to get that perfect balance between security and performance.
|
|
44
44
|
def cost
|
|
45
|
-
@cost ||=
|
|
45
|
+
@cost ||= 10
|
|
46
46
|
end
|
|
47
47
|
attr_writer :cost
|
|
48
48
|
alias :stretches= :cost=
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module CryptoProviders
|
|
3
|
+
module Common
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.class_eval do
|
|
6
|
+
class << self
|
|
7
|
+
attr_accessor :join_token
|
|
8
|
+
|
|
9
|
+
# The number of times to loop through the encryption.
|
|
10
|
+
def stretches
|
|
11
|
+
@stretches ||= 1
|
|
12
|
+
end
|
|
13
|
+
attr_writer :stretches
|
|
14
|
+
|
|
15
|
+
def encrypt(*tokens)
|
|
16
|
+
digest = tokens.flatten.join(join_token)
|
|
17
|
+
stretches.times { digest = secure_digest(digest) }
|
|
18
|
+
digest
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
|
22
|
+
def matches?(crypted, *tokens)
|
|
23
|
+
encrypt(*tokens) == crypted
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def reset!
|
|
27
|
+
@stretches = 1
|
|
28
|
+
@join_token = nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -8,30 +8,10 @@ module Sorcery
|
|
|
8
8
|
#
|
|
9
9
|
# Please use any other provider offered by Sorcery.
|
|
10
10
|
class MD5
|
|
11
|
+
include Common
|
|
11
12
|
class << self
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# The number of times to loop through the encryption.
|
|
15
|
-
def stretches
|
|
16
|
-
@stretches ||= 1
|
|
17
|
-
end
|
|
18
|
-
attr_writer :stretches
|
|
19
|
-
|
|
20
|
-
# Turns your raw password into a MD5 hash.
|
|
21
|
-
def encrypt(*tokens)
|
|
22
|
-
digest = tokens.flatten.join(join_token)
|
|
23
|
-
stretches.times { digest = Digest::MD5.hexdigest(digest) }
|
|
24
|
-
digest
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
|
28
|
-
def matches?(crypted, *tokens)
|
|
29
|
-
encrypt(*tokens) == crypted
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def reset!
|
|
33
|
-
@stretches = 1
|
|
34
|
-
@join_token = nil
|
|
13
|
+
def secure_digest(digest)
|
|
14
|
+
Digest::MD5.hexdigest(digest)
|
|
35
15
|
end
|
|
36
16
|
end
|
|
37
17
|
end
|
|
@@ -5,34 +5,22 @@ module Sorcery
|
|
|
5
5
|
# This class was made for the users transitioning from restful_authentication. I highly discourage using this
|
|
6
6
|
# crypto provider as it inferior to your other options. Please use any other provider offered by Sorcery.
|
|
7
7
|
class SHA1
|
|
8
|
+
include Common
|
|
8
9
|
class << self
|
|
9
10
|
def join_token
|
|
10
11
|
@join_token ||= "--"
|
|
11
12
|
end
|
|
12
|
-
attr_writer :join_token
|
|
13
|
-
|
|
14
|
-
# The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
|
|
15
|
-
def stretches
|
|
16
|
-
@stretches ||= 10
|
|
17
|
-
end
|
|
18
|
-
attr_writer :stretches
|
|
19
13
|
|
|
20
14
|
# Turns your raw password into a Sha1 hash.
|
|
21
15
|
def encrypt(*tokens)
|
|
22
16
|
tokens = tokens.flatten
|
|
23
17
|
digest = tokens.shift
|
|
24
|
-
stretches.times { digest =
|
|
18
|
+
stretches.times { digest = secure_digest([digest, *tokens].join(join_token)) }
|
|
25
19
|
digest
|
|
26
20
|
end
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
encrypt(*tokens) == crypted
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def reset!
|
|
34
|
-
@stretches = 10
|
|
35
|
-
@join_token = nil
|
|
22
|
+
def secure_digest(digest)
|
|
23
|
+
Digest::SHA1.hexdigest(digest)
|
|
36
24
|
end
|
|
37
25
|
end
|
|
38
26
|
end
|
|
@@ -24,30 +24,10 @@ module Sorcery
|
|
|
24
24
|
#
|
|
25
25
|
# Uses the Sha256 hash algorithm to encrypt passwords.
|
|
26
26
|
class SHA256
|
|
27
|
+
include Common
|
|
27
28
|
class << self
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# The number of times to loop through the encryption.
|
|
31
|
-
def stretches
|
|
32
|
-
@stretches ||= 20
|
|
33
|
-
end
|
|
34
|
-
attr_writer :stretches
|
|
35
|
-
|
|
36
|
-
# Turns your raw password into a Sha256 hash.
|
|
37
|
-
def encrypt(*tokens)
|
|
38
|
-
digest = tokens.flatten.join(join_token)
|
|
39
|
-
stretches.times { digest = Digest::SHA256.hexdigest(digest) }
|
|
40
|
-
digest
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
|
44
|
-
def matches?(crypted, *tokens)
|
|
45
|
-
encrypt(*tokens) == crypted
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def reset!
|
|
49
|
-
@stretches = 20
|
|
50
|
-
@join_token = nil
|
|
29
|
+
def secure_digest(digest)
|
|
30
|
+
Digest::SHA256.hexdigest(digest)
|
|
51
31
|
end
|
|
52
32
|
end
|
|
53
33
|
end
|
|
@@ -24,30 +24,10 @@ module Sorcery
|
|
|
24
24
|
#
|
|
25
25
|
# Uses the Sha512 hash algorithm to encrypt passwords.
|
|
26
26
|
class SHA512
|
|
27
|
+
include Common
|
|
27
28
|
class << self
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# The number of times to loop through the encryption.
|
|
31
|
-
def stretches
|
|
32
|
-
@stretches ||= 20
|
|
33
|
-
end
|
|
34
|
-
attr_writer :stretches
|
|
35
|
-
|
|
36
|
-
# Turns your raw password into a Sha512 hash.
|
|
37
|
-
def encrypt(*tokens)
|
|
38
|
-
digest = tokens.flatten.join(join_token)
|
|
39
|
-
stretches.times { digest = Digest::SHA512.hexdigest(digest) }
|
|
40
|
-
digest
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
|
44
|
-
def matches?(crypted, *tokens)
|
|
45
|
-
encrypt(*tokens) == crypted
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def reset!
|
|
49
|
-
@stretches = 20
|
|
50
|
-
@join_token = nil
|
|
29
|
+
def secure_digest(digest)
|
|
30
|
+
Digest::SHA512.hexdigest(digest)
|
|
51
31
|
end
|
|
52
32
|
end
|
|
53
33
|
end
|
data/lib/sorcery/engine.rb
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# The first thing you need to configure is which modules you need in your app.
|
|
2
|
+
# The default is nothing which will include only core features (password encryption, login/logout).
|
|
3
|
+
# Available submodules are: :user_activation, :http_basic_auth, :remember_me, :reset_password, :session_timeout, :brute_force_protection, :activity_logging, :external
|
|
4
|
+
Collaboration::Application.config.sorcery.submodules = []
|
|
5
|
+
|
|
6
|
+
# Here you can configure each submodule's features.
|
|
7
|
+
Collaboration::Application.config.sorcery.configure do |config|
|
|
8
|
+
# -- core --
|
|
9
|
+
# config.not_authenticated_action = :not_authenticated # what controller action to call for non-authenticated users. You can also override 'not_authenticated' instead.
|
|
10
|
+
# config.save_return_to_url = true # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
|
|
11
|
+
# and send him there after login, using 'redirect_back_or_to'.
|
|
12
|
+
|
|
13
|
+
# -- session timeout --
|
|
14
|
+
# config.session_timeout = 3600 # how long in seconds to keep the session alive.
|
|
15
|
+
# config.session_timeout_from_last_action = false # use the last action as the beginning of session timeout.
|
|
16
|
+
|
|
17
|
+
# -- http_basic_auth --
|
|
18
|
+
# config.controller_to_realm_map = {"application" => "Application"} # What realm to display for which controller name.
|
|
19
|
+
# For example {"My App" => "Application"}
|
|
20
|
+
|
|
21
|
+
# -- external --
|
|
22
|
+
# config.external_providers = [] # What providers are supported by this app, i.e. [:twitter, :facebook] .
|
|
23
|
+
#
|
|
24
|
+
# config.twitter.key = "eYVNBjBDi33aa9GkA3w"
|
|
25
|
+
# config.twitter.secret = "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8"
|
|
26
|
+
# config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
|
|
27
|
+
# config.twitter.user_info_mapping = {:email => "screen_name"}
|
|
28
|
+
#
|
|
29
|
+
# config.facebook.key = "34cebc81c08a521bc66e212f947d73ec"
|
|
30
|
+
# config.facebook.secret = "5b458d179f61d4f036ee66a497ffbcd0"
|
|
31
|
+
# config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
|
|
32
|
+
# config.facebook.user_info_mapping = {:email => "name"}
|
|
33
|
+
|
|
34
|
+
# --- user config ---
|
|
35
|
+
config.user_config do |user|
|
|
36
|
+
# -- core --
|
|
37
|
+
# user.username_attribute_name = # change default username attribute, for example, to use :email as the login.
|
|
38
|
+
# user.password_attribute_name = # change *virtual* password attribute, the one which is used until an encrypted one is generated.
|
|
39
|
+
# user.email_attribute_name = # change default email attribute.
|
|
40
|
+
# user.crypted_password_attribute_name = # change default crypted_password attribute.
|
|
41
|
+
# user.salt_join_token = # what pattern to use to join the password with the salt
|
|
42
|
+
# user.salt_attribute_name = # change default salt attribute.
|
|
43
|
+
# user.stretches = # how many times to apply encryption to the password.
|
|
44
|
+
# user.encryption_key = # encryption key used to encrypt reversible encryptions such as AES256.
|
|
45
|
+
# user.encryption_provider = # change default encryption_provider.
|
|
46
|
+
# user.custom_encryption_provider = # use an external encryption class.
|
|
47
|
+
# user.encryption_algorithm = # encryption algorithm name. See 'encryption_algorithm=' for available options.
|
|
48
|
+
|
|
49
|
+
# -- user_activation --
|
|
50
|
+
# user.activation_state_attribute_name = # the attribute name to hold activation state (active/pending).
|
|
51
|
+
# user.activation_token_attribute_name = # the attribute name to hold activation code (sent by email).
|
|
52
|
+
# user.activation_token_expires_at_attribute_name = # the attribute name to hold activation code expiration date.
|
|
53
|
+
# user.activation_token_expiration_period = # how many seconds before the activation code expires. nil for never expires.
|
|
54
|
+
# user.user_activation_mailer = # your mailer class. Required.
|
|
55
|
+
# user.activation_needed_email_method_name = # activation needed email method on your mailer class.
|
|
56
|
+
# user.activation_success_email_method_name = # activation success email method on your mailer class.
|
|
57
|
+
# user.prevent_non_active_users_to_login = # do you want to prevent or allow users that did not activate by email to login?
|
|
58
|
+
|
|
59
|
+
# -- reset_password --
|
|
60
|
+
# user.reset_password_token_attribute_name = # reset password code attribute name.
|
|
61
|
+
# user.reset_password_token_expires_at_attribute_name = # expires at attribute name.
|
|
62
|
+
# user.reset_password_email_sent_at_attribute_name = # when was email sent, used for hammering protection.
|
|
63
|
+
# user.reset_password_mailer = # mailer class. Needed.
|
|
64
|
+
# user.reset_password_email_method_name = # reset password email method on your mailer class.
|
|
65
|
+
# user.reset_password_expiration_period = # how many seconds before the reset request expires. nil for never expires.
|
|
66
|
+
# user.reset_password_time_between_emails = # hammering protection, how long to wait before allowing another email to be sent.
|
|
67
|
+
|
|
68
|
+
# -- brute_force_protection --
|
|
69
|
+
# user.failed_logins_count_attribute_name = # failed logins attribute name.
|
|
70
|
+
# user.lock_expires_at_attribute_name = # this field indicates whether user is banned and when it will be active again.
|
|
71
|
+
# user.consecutive_login_retries_amount_limit = # how many failed logins allowed.
|
|
72
|
+
# user.login_lock_time_period = # how long the user should be banned. in seconds. 0 for permanent.
|
|
73
|
+
|
|
74
|
+
# -- activity logging --
|
|
75
|
+
# user.last_login_at_attribute_name = # last login attribute name.
|
|
76
|
+
# user.last_logout_at_attribute_name = # last logout attribute name.
|
|
77
|
+
# user.last_activity_at_attribute_name = # last activity attribute name.
|
|
78
|
+
# user.activity_timeout = # how long since last activity is the user defined logged out?
|
|
79
|
+
|
|
80
|
+
# -- external --
|
|
81
|
+
# user.authentications_class = # class which holds the various external provider data for this user.
|
|
82
|
+
# user.authentications_user_id_attribute_name = # user's identifier in authentications class.
|
|
83
|
+
# user.provider_attribute_name = # provider's identifier in authentications class.
|
|
84
|
+
# user.provider_uid_attribute_name = # user's external unique identifier in authentications class.
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Model
|
|
3
3
|
module Submodules
|
|
4
|
-
# This submodule helps you login users from
|
|
4
|
+
# This submodule helps you login users from external providers such as Twitter.
|
|
5
5
|
# This is the model part which handles finding the user using access tokens.
|
|
6
|
-
# For the controller options see Sorcery::Controller::
|
|
6
|
+
# For the controller options see Sorcery::Controller::External.
|
|
7
7
|
#
|
|
8
8
|
# Socery assumes (read: requires) you will create external users in the same table where you keep your regular users,
|
|
9
9
|
# but that you will have a separate table for keeping their external authentication data,
|
|
@@ -11,7 +11,7 @@ module Sorcery
|
|
|
11
11
|
#
|
|
12
12
|
# External users will have a null crypted_password field, since we do not hold their password.
|
|
13
13
|
# They will not be sent activation emails on creation.
|
|
14
|
-
module
|
|
14
|
+
module External
|
|
15
15
|
def self.included(base)
|
|
16
16
|
base.sorcery_config.class_eval do
|
|
17
17
|
attr_accessor :authentications_class,
|
data/lib/sorcery/model.rb
CHANGED
|
@@ -9,11 +9,13 @@ module Sorcery
|
|
|
9
9
|
def self.included(klass)
|
|
10
10
|
klass.class_eval do
|
|
11
11
|
class << self
|
|
12
|
-
def
|
|
12
|
+
def authenticates_with_sorcery!
|
|
13
13
|
@sorcery_config = Config.new
|
|
14
14
|
self.class_eval do
|
|
15
15
|
extend ClassMethods # included here, before submodules, so they can be overriden by them.
|
|
16
16
|
include InstanceMethods
|
|
17
|
+
|
|
18
|
+
# set the user_class for the controller methods which call it
|
|
17
19
|
::Sorcery::Controller::Config.user_class = self
|
|
18
20
|
@sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
|
|
19
21
|
@sorcery_config.submodules.each do |mod|
|
|
@@ -25,7 +27,7 @@ module Sorcery
|
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
|
|
29
31
|
|
|
30
32
|
self.class_eval do
|
|
31
33
|
attr_accessor @sorcery_config.password_attribute_name
|
|
@@ -56,12 +58,6 @@ module Sorcery
|
|
|
56
58
|
user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && credentials_match?(user.send(@sorcery_config.crypted_password_attribute_name),credentials[1],_salt)
|
|
57
59
|
end
|
|
58
60
|
|
|
59
|
-
# Calls the configured encryption provider to compare the supplied password with the encrypted one.
|
|
60
|
-
def credentials_match?(crypted, *tokens)
|
|
61
|
-
return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
|
|
62
|
-
@sorcery_config.encryption_provider.matches?(crypted, *tokens)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
61
|
# encrypt tokens using current encryption_provider.
|
|
66
62
|
def encrypt(*tokens)
|
|
67
63
|
return tokens.first if @sorcery_config.encryption_provider.nil?
|
|
@@ -71,6 +67,15 @@ module Sorcery
|
|
|
71
67
|
CryptoProviders::AES256.key = @sorcery_config.encryption_key if @sorcery_config.encryption_algorithm == :aes256
|
|
72
68
|
@sorcery_config.encryption_provider.encrypt(*tokens)
|
|
73
69
|
end
|
|
70
|
+
|
|
71
|
+
protected
|
|
72
|
+
|
|
73
|
+
# Calls the configured encryption provider to compare the supplied password with the encrypted one.
|
|
74
|
+
def credentials_match?(crypted, *tokens)
|
|
75
|
+
return crypted == tokens.join if @sorcery_config.encryption_provider.nil?
|
|
76
|
+
@sorcery_config.encryption_provider.matches?(crypted, *tokens)
|
|
77
|
+
end
|
|
78
|
+
|
|
74
79
|
end
|
|
75
80
|
|
|
76
81
|
module InstanceMethods
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
namespace :sorcery do
|
|
4
|
+
desc "Adds sorcery's initializer file"
|
|
5
|
+
task :bootstrap do
|
|
6
|
+
src = File.join(File.dirname(__FILE__), '..', 'initializers', 'initializer.rb')
|
|
7
|
+
target = File.join(Rails.root, "config", "initializers", "sorcery.rb")
|
|
8
|
+
FileUtils.cp(src, target)
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/sorcery/sinatra.rb
CHANGED
|
@@ -2,13 +2,4 @@ ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
|
|
|
2
2
|
if defined?(Sinatra::Base)
|
|
3
3
|
Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
|
|
4
4
|
Sinatra::Base.send(:include, Sorcery::Controller)
|
|
5
|
-
# Sorcery::Controller::Config.class_eval do
|
|
6
|
-
# class << self
|
|
7
|
-
# def submodules=(mods)
|
|
8
|
-
# @submodules = mods
|
|
9
|
-
# Sinatra::Base.send(:include, Sorcery::Controller::Adapters::Sinatra)
|
|
10
|
-
# Sinatra::Base.send(:include, Sorcery::Controller)
|
|
11
|
-
# end
|
|
12
|
-
# end
|
|
13
|
-
# end
|
|
14
5
|
end
|
|
@@ -20,23 +20,20 @@ module Sorcery
|
|
|
20
20
|
::Sorcery::Controller::Config.user_class = nil
|
|
21
21
|
ActionController::Base.send(:include,::Sorcery::Controller)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
::Sorcery::Controller::Config.user_config do |user|
|
|
24
24
|
options.each do |property,value|
|
|
25
|
-
|
|
25
|
+
user.send(:"#{property}=", value)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
+
User.authenticates_with_sorcery!
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def sorcery_controller_property_set(property, value)
|
|
31
|
-
|
|
32
|
-
config.send(:"#{property}=", value)
|
|
33
|
-
end
|
|
32
|
+
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
|
34
33
|
end
|
|
35
34
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
config.send(provider).send(:"#{property}=", value)
|
|
39
|
-
end
|
|
35
|
+
def sorcery_controller_external_property_set(provider, property, value)
|
|
36
|
+
::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
|
|
40
37
|
end
|
|
41
38
|
|
|
42
39
|
def login_user(user = nil)
|
|
@@ -108,23 +108,20 @@ module Sorcery
|
|
|
108
108
|
::Sinatra::Application.send(:include, Sorcery::Controller::Adapters::Sinatra)
|
|
109
109
|
::Sinatra::Application.send(:include, Sorcery::Controller)
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
::Sorcery::Controller::Config.user_config do |user|
|
|
112
112
|
options.each do |property,value|
|
|
113
|
-
|
|
113
|
+
user.send(:"#{property}=", value)
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
|
+
User.authenticates_with_sorcery!
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
def sorcery_controller_property_set(property, value)
|
|
119
|
-
::
|
|
120
|
-
config.send(:"#{property}=", value)
|
|
121
|
-
end
|
|
120
|
+
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
|
122
121
|
end
|
|
123
122
|
|
|
124
|
-
def
|
|
125
|
-
::
|
|
126
|
-
config.send(provider).send(:"#{property}=", value)
|
|
127
|
-
end
|
|
123
|
+
def sorcery_controller_external_property_set(provider, property, value)
|
|
124
|
+
::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
|
|
128
125
|
end
|
|
129
126
|
end
|
|
130
127
|
end
|
data/lib/sorcery/test_helpers.rb
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
module Sorcery
|
|
2
|
+
# This file will be included in the spec_helper file.
|
|
2
3
|
module TestHelpers
|
|
4
|
+
def self.included(base)
|
|
5
|
+
# reducing default cost for specs speed
|
|
6
|
+
CryptoProviders::BCrypt.class_eval do
|
|
7
|
+
class << self
|
|
8
|
+
def cost
|
|
9
|
+
1
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
3
15
|
# a patch to fix a bug in testing that happens when you 'destroy' a session twice.
|
|
4
16
|
# After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
|
|
5
17
|
class ::Hash
|
data/lib/sorcery.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Sorcery
|
|
|
8
8
|
autoload :RememberMe, 'sorcery/model/submodules/remember_me'
|
|
9
9
|
autoload :ActivityLogging, 'sorcery/model/submodules/activity_logging'
|
|
10
10
|
autoload :BruteForceProtection, 'sorcery/model/submodules/brute_force_protection'
|
|
11
|
-
autoload :
|
|
11
|
+
autoload :External, 'sorcery/model/submodules/external'
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
autoload :Controller, 'sorcery/controller'
|
|
@@ -19,13 +19,15 @@ module Sorcery
|
|
|
19
19
|
autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
|
|
20
20
|
autoload :HttpBasicAuth, 'sorcery/controller/submodules/http_basic_auth'
|
|
21
21
|
autoload :ActivityLogging, 'sorcery/controller/submodules/activity_logging'
|
|
22
|
-
autoload :
|
|
23
|
-
module
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
autoload :External, 'sorcery/controller/submodules/external'
|
|
23
|
+
module External
|
|
24
|
+
module Protocols
|
|
25
|
+
autoload :Oauth1, 'sorcery/controller/submodules/external/protocols/oauth1'
|
|
26
|
+
autoload :Oauth2, 'sorcery/controller/submodules/external/protocols/oauth2'
|
|
27
|
+
end
|
|
26
28
|
module Providers
|
|
27
|
-
autoload :Twitter, 'sorcery/controller/submodules/
|
|
28
|
-
autoload :Facebook, 'sorcery/controller/submodules/
|
|
29
|
+
autoload :Twitter, 'sorcery/controller/submodules/external/providers/twitter'
|
|
30
|
+
autoload :Facebook, 'sorcery/controller/submodules/external/providers/facebook'
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -34,6 +36,7 @@ module Sorcery
|
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
module CryptoProviders
|
|
39
|
+
autoload :Common, 'sorcery/crypto_providers/common'
|
|
37
40
|
autoload :AES256, 'sorcery/crypto_providers/aes256'
|
|
38
41
|
autoload :BCrypt, 'sorcery/crypto_providers/bcrypt'
|
|
39
42
|
autoload :MD5, 'sorcery/crypto_providers/md5'
|