sorcery 0.7.0 → 0.7.4
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 +1 -3
- data/Gemfile.lock +47 -57
- data/README.rdoc +19 -57
- data/Rakefile +27 -1
- data/VERSION +1 -1
- data/lib/generators/sorcery/USAGE +22 -0
- data/lib/generators/sorcery/install_generator.rb +72 -0
- data/lib/{sorcery/initializers → generators/sorcery/templates}/initializer.rb +4 -4
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +17 -0
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +11 -0
- data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/core.rb +2 -2
- data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/external.rb +1 -1
- data/lib/generators/sorcery/templates/migration/remember_me.rb +15 -0
- data/lib/generators/sorcery/templates/migration/reset_password.rb +17 -0
- data/lib/generators/sorcery/templates/migration/user_activation.rb +17 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +8 -11
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +2 -2
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +23 -8
- data/lib/sorcery/controller/submodules/external/providers/twitter.rb +1 -1
- data/lib/sorcery/controller/submodules/remember_me.rb +16 -14
- data/lib/sorcery/controller/submodules/session_timeout.rb +3 -3
- data/lib/sorcery/controller.rb +40 -39
- data/lib/sorcery/model/adapters/mongo_mapper.rb +49 -0
- data/lib/sorcery/model/adapters/mongoid.rb +3 -1
- data/lib/sorcery/model/submodules/brute_force_protection.rb +14 -6
- data/lib/sorcery/model/submodules/remember_me.rb +9 -2
- data/lib/sorcery/model/submodules/reset_password.rb +12 -2
- data/lib/sorcery/model/submodules/user_activation.rb +13 -1
- data/lib/sorcery/model/temporary_token.rb +4 -2
- data/lib/sorcery/model.rb +21 -4
- data/lib/sorcery.rb +5 -7
- data/sorcery.gemspec +83 -216
- data/spec/Gemfile +1 -1
- data/spec/Gemfile.lock +20 -17
- data/spec/README.md +6 -1
- data/spec/rails3/Gemfile +2 -2
- data/spec/rails3/Gemfile.lock +36 -51
- data/spec/rails3/spec/controller_activity_logging_spec.rb +6 -6
- data/spec/rails3/spec/controller_brute_force_protection_spec.rb +2 -2
- data/spec/rails3/spec/controller_oauth2_spec.rb +5 -3
- data/spec/rails3/spec/controller_session_timeout_spec.rb +4 -4
- data/spec/rails3/spec/spec_helper.rb +1 -3
- data/spec/rails3_mongo_mapper/.gitignore +4 -0
- data/spec/rails3_mongo_mapper/.rspec +1 -0
- data/spec/{sinatra_modular → rails3_mongo_mapper}/Gemfile +5 -5
- data/spec/rails3_mongo_mapper/Gemfile.lock +158 -0
- data/spec/{sinatra → rails3_mongo_mapper}/Rakefile +3 -3
- data/spec/rails3_mongo_mapper/app/controllers/application_controller.rb +108 -0
- data/spec/rails3_mongo_mapper/app/helpers/application_helper.rb +2 -0
- data/spec/rails3_mongo_mapper/app/models/authentication.rb +6 -0
- data/spec/rails3_mongo_mapper/app/models/user.rb +5 -0
- data/spec/rails3_mongo_mapper/app/views/layouts/application.html.erb +14 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails3_mongo_mapper/config/application.rb +51 -0
- data/spec/rails3_mongo_mapper/config/boot.rb +13 -0
- data/spec/rails3_mongo_mapper/config/environment.rb +5 -0
- data/spec/rails3_mongo_mapper/config/environments/development.rb +30 -0
- data/spec/rails3_mongo_mapper/config/environments/in_memory.rb +0 -0
- data/spec/rails3_mongo_mapper/config/environments/production.rb +49 -0
- data/spec/rails3_mongo_mapper/config/environments/test.rb +35 -0
- data/spec/rails3_mongo_mapper/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails3_mongo_mapper/config/initializers/inflections.rb +10 -0
- data/spec/rails3_mongo_mapper/config/initializers/mime_types.rb +5 -0
- data/spec/rails3_mongo_mapper/config/initializers/mongo.rb +2 -0
- data/spec/rails3_mongo_mapper/config/initializers/secret_token.rb +7 -0
- data/spec/rails3_mongo_mapper/config/initializers/session_store.rb +8 -0
- data/spec/rails3_mongo_mapper/config/locales/en.yml +5 -0
- data/spec/rails3_mongo_mapper/config/routes.rb +59 -0
- data/spec/rails3_mongo_mapper/config.ru +4 -0
- data/spec/rails3_mongo_mapper/db/schema.rb +23 -0
- data/spec/rails3_mongo_mapper/db/seeds.rb +7 -0
- data/spec/rails3_mongo_mapper/lib/tasks/.gitkeep +0 -0
- data/spec/rails3_mongo_mapper/public/404.html +26 -0
- data/spec/rails3_mongo_mapper/public/422.html +26 -0
- data/spec/rails3_mongo_mapper/public/500.html +26 -0
- data/spec/rails3_mongo_mapper/public/favicon.ico +0 -0
- data/spec/rails3_mongo_mapper/public/images/rails.png +0 -0
- data/spec/rails3_mongo_mapper/public/javascripts/application.js +2 -0
- data/spec/rails3_mongo_mapper/public/javascripts/controls.js +965 -0
- data/spec/rails3_mongo_mapper/public/javascripts/dragdrop.js +974 -0
- data/spec/rails3_mongo_mapper/public/javascripts/effects.js +1123 -0
- data/spec/rails3_mongo_mapper/public/javascripts/prototype.js +6001 -0
- data/spec/rails3_mongo_mapper/public/javascripts/rails.js +175 -0
- data/spec/rails3_mongo_mapper/public/robots.txt +5 -0
- data/spec/rails3_mongo_mapper/public/stylesheets/.gitkeep +0 -0
- data/spec/rails3_mongo_mapper/script/rails +6 -0
- data/spec/{sinatra → rails3_mongo_mapper}/spec/controller_spec.rb +45 -42
- data/spec/rails3_mongo_mapper/spec/spec_helper.orig.rb +27 -0
- data/spec/rails3_mongo_mapper/spec/spec_helper.rb +55 -0
- data/spec/rails3_mongo_mapper/spec/user_activation_spec.rb +9 -0
- data/spec/rails3_mongo_mapper/spec/user_activity_logging_spec.rb +8 -0
- data/spec/rails3_mongo_mapper/spec/user_brute_force_protection_spec.rb +8 -0
- data/spec/rails3_mongo_mapper/spec/user_oauth_spec.rb +8 -0
- data/spec/rails3_mongo_mapper/spec/user_remember_me_spec.rb +8 -0
- data/spec/rails3_mongo_mapper/spec/user_reset_password_spec.rb +8 -0
- data/spec/rails3_mongo_mapper/spec/user_spec.rb +37 -0
- data/spec/rails3_mongo_mapper/vendor/plugins/.gitkeep +0 -0
- data/spec/rails3_mongoid/Gemfile +1 -1
- data/spec/rails3_mongoid/Gemfile.lock +38 -36
- data/spec/rails3_mongoid/script/rails +0 -0
- data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +98 -0
- data/spec/rails3_mongoid/spec/controller_spec.rb +11 -0
- data/spec/rails3_mongoid/spec/user_spec.rb +1 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +1 -1
- data/spec/shared_examples/user_remember_me_shared_examples.rb +1 -1
- data/spec/shared_examples/user_reset_password_shared_examples.rb +2 -2
- data/spec/shared_examples/user_shared_examples.rb +29 -1
- metadata +105 -251
- data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +0 -24
- data/lib/generators/sorcery_migration/templates/activity_logging.rb +0 -17
- data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +0 -11
- data/lib/generators/sorcery_migration/templates/remember_me.rb +0 -15
- data/lib/generators/sorcery_migration/templates/reset_password.rb +0 -17
- data/lib/generators/sorcery_migration/templates/user_activation.rb +0 -17
- data/lib/sorcery/controller/adapters/sinatra.rb +0 -115
- data/lib/sorcery/sinatra.rb +0 -4
- data/lib/sorcery/test_helpers/internal/sinatra.rb +0 -74
- data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +0 -74
- data/lib/sorcery/test_helpers/sinatra.rb +0 -88
- data/spec/rails3/Rakefile.unused +0 -7
- data/spec/sinatra/Gemfile +0 -15
- data/spec/sinatra/Gemfile.lock +0 -115
- data/spec/sinatra/authentication.rb +0 -3
- data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
- data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
- data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
- data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +0 -16
- data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +0 -14
- data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
- data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
- data/spec/sinatra/filters.rb +0 -27
- data/spec/sinatra/modular.rb +0 -157
- data/spec/sinatra/myapp.rb +0 -133
- data/spec/sinatra/spec/controller_activity_logging_spec.rb +0 -85
- data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +0 -70
- data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +0 -53
- data/spec/sinatra/spec/controller_oauth2_spec.rb +0 -96
- data/spec/sinatra/spec/controller_oauth_spec.rb +0 -100
- data/spec/sinatra/spec/controller_remember_me_spec.rb +0 -64
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +0 -57
- data/spec/sinatra/spec/spec_helper.rb +0 -45
- data/spec/sinatra/user.rb +0 -6
- data/spec/sinatra/views/test_login.erb +0 -4
- data/spec/sinatra_modular/Gemfile.lock +0 -115
- data/spec/sinatra_modular/Rakefile +0 -11
- data/spec/sinatra_modular/authentication.rb +0 -3
- data/spec/sinatra_modular/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
- data/spec/sinatra_modular/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
- data/spec/sinatra_modular/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
- data/spec/sinatra_modular/db/migrate/core/20101224223620_create_users.rb +0 -16
- data/spec/sinatra_modular/db/migrate/external/20101224223628_create_authentications.rb +0 -14
- data/spec/sinatra_modular/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
- data/spec/sinatra_modular/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
- data/spec/sinatra_modular/filters.rb +0 -27
- data/spec/sinatra_modular/modular.rb +0 -157
- data/spec/sinatra_modular/myapp.rb +0 -133
- data/spec/sinatra_modular/sorcery_mailer.rb +0 -25
- data/spec/sinatra_modular/spec_modular/controller_activity_logging_spec.rb +0 -85
- data/spec/sinatra_modular/spec_modular/controller_brute_force_protection_spec.rb +0 -70
- data/spec/sinatra_modular/spec_modular/controller_http_basic_auth_spec.rb +0 -53
- data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +0 -96
- data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +0 -100
- data/spec/sinatra_modular/spec_modular/controller_remember_me_spec.rb +0 -64
- data/spec/sinatra_modular/spec_modular/controller_session_timeout_spec.rb +0 -57
- data/spec/sinatra_modular/spec_modular/controller_spec.rb +0 -116
- data/spec/sinatra_modular/spec_modular/spec.opts +0 -2
- data/spec/sinatra_modular/spec_modular/spec_helper.rb +0 -51
- data/spec/sinatra_modular/user.rb +0 -6
- data/spec/sinatra_modular/views/test_login.erb +0 -4
- /data/spec/{sinatra → rails3_mongo_mapper/app/mailers}/sorcery_mailer.rb +0 -0
- /data/spec/{sinatra → rails3_mongo_mapper}/spec/spec.opts +0 -0
|
@@ -8,19 +8,34 @@ module Sorcery
|
|
|
8
8
|
def oauth_version
|
|
9
9
|
"2.0"
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
def authorize_url(options = {})
|
|
13
13
|
defaults = {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
:site => @site,
|
|
15
|
+
:ssl => { :ca_file => Config.ca_file }
|
|
16
16
|
}
|
|
17
|
-
client = ::OAuth2::Client.new(
|
|
18
|
-
|
|
17
|
+
client = ::OAuth2::Client.new(
|
|
18
|
+
@key,
|
|
19
|
+
@secret,
|
|
20
|
+
defaults.merge!(options)
|
|
21
|
+
)
|
|
22
|
+
client.web_server.authorize_url(
|
|
23
|
+
:redirect_uri => @callback_url,
|
|
24
|
+
:scope => @scope
|
|
25
|
+
)
|
|
19
26
|
end
|
|
20
|
-
|
|
27
|
+
|
|
21
28
|
def get_access_token(args)
|
|
22
|
-
client = ::OAuth2::Client.new(
|
|
23
|
-
|
|
29
|
+
client = ::OAuth2::Client.new(
|
|
30
|
+
@key,
|
|
31
|
+
@secret,
|
|
32
|
+
:site => @site,
|
|
33
|
+
:ssl => { :ca_file => Config.ca_file }
|
|
34
|
+
)
|
|
35
|
+
client.web_server.get_access_token(
|
|
36
|
+
args[:code],
|
|
37
|
+
:redirect_uri => @callback_url
|
|
38
|
+
)
|
|
24
39
|
end
|
|
25
40
|
end
|
|
26
41
|
end
|
|
@@ -55,7 +55,7 @@ module Sorcery
|
|
|
55
55
|
user_hash = {}
|
|
56
56
|
response = @access_token.get(@user_info_path)
|
|
57
57
|
user_hash[:user_info] = JSON.parse(response.body)
|
|
58
|
-
user_hash[:uid] = user_hash[:user_info]['id']
|
|
58
|
+
user_hash[:uid] = user_hash[:user_info]['id'].to_s
|
|
59
59
|
user_hash
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -1,7 +1,7 @@
|
|
|
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
5
|
# be automatically logged in to the site on every visit,
|
|
6
6
|
# until the cookie expires.
|
|
7
7
|
# See Sorcery::Model::Submodules::RememberMe for configuration options.
|
|
@@ -12,20 +12,20 @@ module Sorcery
|
|
|
12
12
|
Config.after_login << :remember_me_if_asked_to
|
|
13
13
|
Config.after_logout << :forget_me!
|
|
14
14
|
end
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
module InstanceMethods
|
|
17
17
|
# This method sets the cookie and calls the user to save the token and the expiration to db.
|
|
18
18
|
def remember_me!
|
|
19
19
|
current_user.remember_me!
|
|
20
|
-
set_remember_me_cookie!(current_user)
|
|
20
|
+
set_remember_me_cookie!(current_user)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# Clears the cookie and clears the token from the db.
|
|
24
24
|
def forget_me!
|
|
25
|
-
current_user.forget_me!
|
|
26
|
-
cookies
|
|
25
|
+
@current_user.forget_me!
|
|
26
|
+
cookies.delete(:remember_me_token, :domain => Config.cookie_domain)
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
# Override.
|
|
30
30
|
# logins a user instance, and optionally remembers him.
|
|
31
31
|
def auto_login(user, should_remember = false)
|
|
@@ -33,33 +33,35 @@ module Sorcery
|
|
|
33
33
|
@current_user = user
|
|
34
34
|
remember_me! if should_remember
|
|
35
35
|
end
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
protected
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
# calls remember_me! if a third credential was passed to the login method.
|
|
40
40
|
# Runs as a hook after login.
|
|
41
41
|
def remember_me_if_asked_to(user, credentials)
|
|
42
42
|
remember_me! if ( credentials.size == 3 && credentials[2] && credentials[2] != "0" )
|
|
43
43
|
end
|
|
44
|
-
|
|
45
|
-
# Checks the cookie for a remember me token, tried to find a user with that token
|
|
44
|
+
|
|
45
|
+
# Checks the cookie for a remember me token, tried to find a user with that token
|
|
46
46
|
# and logs the user in if found.
|
|
47
47
|
# Runs as a login source. See 'current_user' method for how it is used.
|
|
48
48
|
def login_from_cookie
|
|
49
49
|
user = cookies.signed[:remember_me_token] && user_class.find_by_remember_me_token(cookies.signed[:remember_me_token])
|
|
50
50
|
if user && user.remember_me_token?
|
|
51
51
|
set_remember_me_cookie!(user)
|
|
52
|
+
session[:user_id] = user.id
|
|
52
53
|
@current_user = user
|
|
53
54
|
else
|
|
54
55
|
@current_user = false
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
|
-
|
|
58
|
+
|
|
58
59
|
def set_remember_me_cookie!(user)
|
|
59
|
-
cookies.signed[:remember_me_token] = {
|
|
60
|
-
:value => user.send(user.sorcery_config.remember_me_token_attribute_name),
|
|
60
|
+
cookies.signed[:remember_me_token] = {
|
|
61
|
+
:value => user.send(user.sorcery_config.remember_me_token_attribute_name),
|
|
61
62
|
:expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name),
|
|
62
|
-
:httponly => true
|
|
63
|
+
:httponly => true,
|
|
64
|
+
:domain => Config.cookie_domain
|
|
63
65
|
}
|
|
64
66
|
end
|
|
65
67
|
end
|
|
@@ -30,18 +30,18 @@ module Sorcery
|
|
|
30
30
|
# Registers last login to be used as the timeout starting point.
|
|
31
31
|
# Runs as a hook after a successful login.
|
|
32
32
|
def register_login_time(user, credentials)
|
|
33
|
-
session[:login_time] = session[:last_action_time] = Time.now.
|
|
33
|
+
session[:login_time] = session[:last_action_time] = Time.now.in_time_zone
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Checks if session timeout was reached and expires the current session if so.
|
|
37
37
|
# To be used as a before_filter, before require_login
|
|
38
38
|
def validate_session
|
|
39
39
|
session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time]
|
|
40
|
-
if session_to_use && (Time.now.
|
|
40
|
+
if session_to_use && (Time.now.in_time_zone - session_to_use > Config.session_timeout)
|
|
41
41
|
reset_session
|
|
42
42
|
@current_user = nil
|
|
43
43
|
else
|
|
44
|
-
session[:last_action_time] = Time.now.
|
|
44
|
+
session[:last_action_time] = Time.now.in_time_zone
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
data/lib/sorcery/controller.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Sorcery
|
|
|
5
5
|
include InstanceMethods
|
|
6
6
|
Config.submodules.each do |mod|
|
|
7
7
|
begin
|
|
8
|
-
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
|
8
|
+
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
|
9
9
|
rescue NameError
|
|
10
10
|
# don't stop on a missing submodule.
|
|
11
11
|
end
|
|
@@ -14,7 +14,7 @@ module Sorcery
|
|
|
14
14
|
Config.update!
|
|
15
15
|
Config.configure!
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
module InstanceMethods
|
|
19
19
|
# To be used as before_filter.
|
|
20
20
|
# Will trigger auto-login attempts via the call to logged_in?
|
|
@@ -22,10 +22,10 @@ module Sorcery
|
|
|
22
22
|
def require_login
|
|
23
23
|
if !logged_in?
|
|
24
24
|
session[:return_to_url] = request.url if Config.save_return_to_url
|
|
25
|
-
self.send(Config.not_authenticated_action)
|
|
25
|
+
self.send(Config.not_authenticated_action)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
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)
|
|
@@ -42,43 +42,44 @@ module Sorcery
|
|
|
42
42
|
nil
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
# Resets the session and runs hooks before and after.
|
|
47
47
|
def logout
|
|
48
48
|
if logged_in?
|
|
49
49
|
before_logout!(current_user)
|
|
50
50
|
reset_session
|
|
51
51
|
after_logout!
|
|
52
|
+
@current_user = nil
|
|
52
53
|
end
|
|
53
54
|
end
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
def logged_in?
|
|
56
57
|
!!current_user
|
|
57
58
|
end
|
|
58
|
-
|
|
59
|
+
|
|
59
60
|
# attempts to auto-login from the sources defined (session, basic_auth, cookie, etc.)
|
|
60
61
|
# returns the logged in user if found, false if not (using old restful-authentication trick, nil != false).
|
|
61
62
|
def current_user
|
|
62
63
|
@current_user ||= login_from_session || login_from_other_sources unless @current_user == false
|
|
63
64
|
end
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
def current_user=(user)
|
|
66
67
|
@current_user = user
|
|
67
68
|
end
|
|
68
|
-
|
|
69
|
-
# used when a user tries to access a page while logged out, is asked to login,
|
|
69
|
+
|
|
70
|
+
# used when a user tries to access a page while logged out, is asked to login,
|
|
70
71
|
# and we want to return him back to the page he originally wanted.
|
|
71
72
|
def redirect_back_or_to(url, flash_hash = {})
|
|
72
73
|
redirect_to(session[:return_to_url] || url, :flash => flash_hash)
|
|
73
74
|
end
|
|
74
|
-
|
|
75
|
+
|
|
75
76
|
# The default action for denying non-authenticated users.
|
|
76
77
|
# You can override this method in your controllers,
|
|
77
78
|
# or provide a different method in the configuration.
|
|
78
79
|
def not_authenticated
|
|
79
80
|
redirect_to root_path
|
|
80
81
|
end
|
|
81
|
-
|
|
82
|
+
|
|
82
83
|
# login a user instance
|
|
83
84
|
#
|
|
84
85
|
# @param [<User-Model>] user the user instance.
|
|
@@ -87,16 +88,16 @@ module Sorcery
|
|
|
87
88
|
session[:user_id] = user.id
|
|
88
89
|
@current_user = user
|
|
89
90
|
end
|
|
90
|
-
|
|
91
|
+
|
|
91
92
|
# Overwrite Rails' handle unverified request
|
|
92
93
|
def handle_unverified_request
|
|
93
94
|
cookies[:remember_me_token] = nil
|
|
94
95
|
@current_user = nil
|
|
95
96
|
super # call the default behaviour which resets the session
|
|
96
97
|
end
|
|
97
|
-
|
|
98
|
+
|
|
98
99
|
protected
|
|
99
|
-
|
|
100
|
+
|
|
100
101
|
# Tries all available sources (methods) until one doesn't return false.
|
|
101
102
|
def login_from_other_sources
|
|
102
103
|
result = nil
|
|
@@ -105,51 +106,51 @@ module Sorcery
|
|
|
105
106
|
end
|
|
106
107
|
result || false
|
|
107
108
|
end
|
|
108
|
-
|
|
109
|
+
|
|
109
110
|
def login_from_session
|
|
110
111
|
@current_user = (user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
|
|
111
112
|
end
|
|
112
|
-
|
|
113
|
+
|
|
113
114
|
def after_login!(user, credentials)
|
|
114
115
|
Config.after_login.each {|c| self.send(c, user, credentials)}
|
|
115
116
|
end
|
|
116
|
-
|
|
117
|
+
|
|
117
118
|
def after_failed_login!(credentials)
|
|
118
119
|
Config.after_failed_login.each {|c| self.send(c, credentials)}
|
|
119
120
|
end
|
|
120
|
-
|
|
121
|
+
|
|
121
122
|
def before_logout!(user)
|
|
122
123
|
Config.before_logout.each {|c| self.send(c, user)}
|
|
123
124
|
end
|
|
124
|
-
|
|
125
|
+
|
|
125
126
|
def after_logout!
|
|
126
127
|
Config.after_logout.each {|c| self.send(c)}
|
|
127
128
|
end
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
def user_class
|
|
130
131
|
@user_class ||= Config.user_class.to_s.constantize
|
|
131
132
|
end
|
|
132
|
-
|
|
133
|
+
|
|
133
134
|
end
|
|
134
|
-
|
|
135
|
+
|
|
135
136
|
module Config
|
|
136
137
|
class << self
|
|
137
138
|
attr_accessor :submodules,
|
|
138
|
-
:user_class, # what class to use as the user class.
|
|
139
|
+
:user_class, # what class to use as the user class.
|
|
139
140
|
:not_authenticated_action, # what controller action to call for non-authenticated users.
|
|
140
|
-
|
|
141
|
+
|
|
141
142
|
:save_return_to_url, # when a non logged in user tries to enter a page that requires
|
|
142
|
-
# login, save the URL he wanted to reach,
|
|
143
|
+
# login, save the URL he wanted to reach,
|
|
143
144
|
# and send him there after login.
|
|
144
|
-
|
|
145
|
-
:
|
|
146
|
-
|
|
145
|
+
|
|
146
|
+
:cookie_domain, # set domain option for cookies
|
|
147
|
+
|
|
147
148
|
:login_sources,
|
|
148
149
|
:after_login,
|
|
149
150
|
:after_failed_login,
|
|
150
151
|
:before_logout,
|
|
151
|
-
:after_logout
|
|
152
|
-
|
|
152
|
+
:after_logout
|
|
153
|
+
|
|
153
154
|
def init!
|
|
154
155
|
@defaults = {
|
|
155
156
|
:@user_class => nil,
|
|
@@ -161,31 +162,31 @@ module Sorcery
|
|
|
161
162
|
:@before_logout => [],
|
|
162
163
|
:@after_logout => [],
|
|
163
164
|
:@save_return_to_url => true,
|
|
164
|
-
:@
|
|
165
|
+
:@cookie_domain => nil
|
|
165
166
|
}
|
|
166
167
|
end
|
|
167
|
-
|
|
168
|
+
|
|
168
169
|
# Resets all configuration options to their default values.
|
|
169
170
|
def reset!
|
|
170
171
|
@defaults.each do |k,v|
|
|
171
172
|
instance_variable_set(k,v)
|
|
172
|
-
end
|
|
173
|
+
end
|
|
173
174
|
end
|
|
174
|
-
|
|
175
|
+
|
|
175
176
|
def update!
|
|
176
177
|
@defaults.each do |k,v|
|
|
177
178
|
instance_variable_set(k,v) if !instance_variable_defined?(k)
|
|
178
179
|
end
|
|
179
180
|
end
|
|
180
|
-
|
|
181
|
+
|
|
181
182
|
def user_config(&blk)
|
|
182
183
|
block_given? ? @user_config = blk : @user_config
|
|
183
184
|
end
|
|
184
|
-
|
|
185
|
+
|
|
185
186
|
def configure(&blk)
|
|
186
187
|
@configure_blk = blk
|
|
187
188
|
end
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
def configure!
|
|
190
191
|
@configure_blk.call(self) if @configure_blk
|
|
191
192
|
end
|
|
@@ -194,4 +195,4 @@ module Sorcery
|
|
|
194
195
|
reset!
|
|
195
196
|
end
|
|
196
197
|
end
|
|
197
|
-
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Model
|
|
3
|
+
module Adapters
|
|
4
|
+
module MongoMapper
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
include Sorcery::Model
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module InstanceMethods
|
|
12
|
+
def increment(attr)
|
|
13
|
+
self.inc(attr,1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def save!(options = {})
|
|
17
|
+
save(options)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethods
|
|
22
|
+
def find_by_credentials(credentials)
|
|
23
|
+
@sorcery_config.username_attribute_names.each do |attribute|
|
|
24
|
+
@user = where(attribute => credentials[0]).first
|
|
25
|
+
break if @user
|
|
26
|
+
end
|
|
27
|
+
@user
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def find_by_id(id)
|
|
31
|
+
find(id)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def find_by_activation_token(token)
|
|
35
|
+
where(sorcery_config.activation_token_attribute_name => token).first
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def transaction(&blk)
|
|
39
|
+
tap(&blk)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def find_by_sorcery_token(token_attr_name, token)
|
|
43
|
+
where(token_attr_name => token).first
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -29,6 +29,8 @@ module Sorcery
|
|
|
29
29
|
|
|
30
30
|
def find_by_id(id)
|
|
31
31
|
find(id)
|
|
32
|
+
rescue ::Mongoid::Errors::DocumentNotFound
|
|
33
|
+
nil
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def find_by_activation_token(token)
|
|
@@ -41,7 +43,7 @@ module Sorcery
|
|
|
41
43
|
|
|
42
44
|
def find_by_username(username)
|
|
43
45
|
query = sorcery_config.username_attribute_names.map {|name| {name => username}}
|
|
44
|
-
|
|
46
|
+
any_of(*query).first
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def transaction(&blk)
|
|
@@ -26,6 +26,9 @@ module Sorcery
|
|
|
26
26
|
|
|
27
27
|
base.sorcery_config.before_authenticate << :prevent_locked_user_login
|
|
28
28
|
base.sorcery_config.after_config << :define_brute_force_protection_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
|
29
|
+
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
|
30
|
+
base.sorcery_config.after_config << :define_brute_force_protection_mongo_mapper_fields
|
|
31
|
+
end
|
|
29
32
|
base.extend(ClassMethods)
|
|
30
33
|
base.send(:include, InstanceMethods)
|
|
31
34
|
end
|
|
@@ -37,6 +40,11 @@ module Sorcery
|
|
|
37
40
|
field sorcery_config.failed_logins_count_attribute_name, :type => Integer
|
|
38
41
|
field sorcery_config.lock_expires_at_attribute_name, :type => DateTime
|
|
39
42
|
end
|
|
43
|
+
|
|
44
|
+
def define_brute_force_protection_mongo_mapper_fields
|
|
45
|
+
key sorcery_config.failed_logins_count_attribute_name, Integer
|
|
46
|
+
key sorcery_config.lock_expires_at_attribute_name, DateTime
|
|
47
|
+
end
|
|
40
48
|
end
|
|
41
49
|
|
|
42
50
|
module InstanceMethods
|
|
@@ -46,7 +54,7 @@ module Sorcery
|
|
|
46
54
|
config = sorcery_config
|
|
47
55
|
return if !unlocked?
|
|
48
56
|
self.increment(config.failed_logins_count_attribute_name)
|
|
49
|
-
save!
|
|
57
|
+
save!(:validate => false)
|
|
50
58
|
self.lock! if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
|
|
51
59
|
end
|
|
52
60
|
|
|
@@ -54,15 +62,15 @@ module Sorcery
|
|
|
54
62
|
|
|
55
63
|
def lock!
|
|
56
64
|
config = sorcery_config
|
|
57
|
-
self.send(:"#{config.lock_expires_at_attribute_name}=", Time.now.
|
|
58
|
-
self.save!
|
|
65
|
+
self.send(:"#{config.lock_expires_at_attribute_name}=", Time.now.in_time_zone + config.login_lock_time_period)
|
|
66
|
+
self.save!(validate: false)
|
|
59
67
|
end
|
|
60
68
|
|
|
61
69
|
def unlock!
|
|
62
70
|
config = sorcery_config
|
|
63
71
|
self.send(:"#{config.lock_expires_at_attribute_name}=", nil)
|
|
64
72
|
self.send(:"#{config.failed_logins_count_attribute_name}=", 0)
|
|
65
|
-
self.save!
|
|
73
|
+
self.save!(validate: false)
|
|
66
74
|
end
|
|
67
75
|
|
|
68
76
|
def unlocked?
|
|
@@ -75,7 +83,7 @@ module Sorcery
|
|
|
75
83
|
def prevent_locked_user_login
|
|
76
84
|
config = sorcery_config
|
|
77
85
|
if !self.unlocked? && config.login_lock_time_period != 0
|
|
78
|
-
self.unlock! if self.send(config.lock_expires_at_attribute_name) <= Time.now.
|
|
86
|
+
self.unlock! if self.send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone
|
|
79
87
|
end
|
|
80
88
|
unlocked?
|
|
81
89
|
end
|
|
@@ -83,4 +91,4 @@ module Sorcery
|
|
|
83
91
|
end
|
|
84
92
|
end
|
|
85
93
|
end
|
|
86
|
-
end
|
|
94
|
+
end
|
|
@@ -24,7 +24,10 @@ module Sorcery
|
|
|
24
24
|
base.send(:include, InstanceMethods)
|
|
25
25
|
|
|
26
26
|
base.sorcery_config.after_config << :define_remember_me_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
|
27
|
-
|
|
27
|
+
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
|
28
|
+
base.sorcery_config.after_config << :define_remember_me_mongo_mapper_fields
|
|
29
|
+
end
|
|
30
|
+
|
|
28
31
|
base.extend(ClassMethods)
|
|
29
32
|
end
|
|
30
33
|
|
|
@@ -36,6 +39,10 @@ module Sorcery
|
|
|
36
39
|
field sorcery_config.remember_me_token_expires_at_attribute_name, :type => Time
|
|
37
40
|
end
|
|
38
41
|
|
|
42
|
+
def define_remember_me_mongo_mapper_fields
|
|
43
|
+
key sorcery_config.remember_me_token_attribute_name, String
|
|
44
|
+
key sorcery_config.remember_me_token_expires_at_attribute_name, Time
|
|
45
|
+
end
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
module InstanceMethods
|
|
@@ -43,7 +50,7 @@ module Sorcery
|
|
|
43
50
|
def remember_me!
|
|
44
51
|
config = sorcery_config
|
|
45
52
|
self.send(:"#{config.remember_me_token_attribute_name}=", TemporaryToken.generate_random_token)
|
|
46
|
-
self.send(:"#{config.remember_me_token_expires_at_attribute_name}=", Time.now + config.remember_me_for)
|
|
53
|
+
self.send(:"#{config.remember_me_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.remember_me_for)
|
|
47
54
|
self.save!(:validate => false)
|
|
48
55
|
end
|
|
49
56
|
|
|
@@ -45,6 +45,9 @@ module Sorcery
|
|
|
45
45
|
|
|
46
46
|
base.sorcery_config.after_config << :validate_mailer_defined
|
|
47
47
|
base.sorcery_config.after_config << :define_reset_password_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
|
48
|
+
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
|
49
|
+
base.sorcery_config.after_config << :define_reset_password_mongo_mapper_fields
|
|
50
|
+
end
|
|
48
51
|
|
|
49
52
|
base.send(:include, InstanceMethods)
|
|
50
53
|
|
|
@@ -72,6 +75,13 @@ module Sorcery
|
|
|
72
75
|
field sorcery_config.reset_password_token_expires_at_attribute_name, :type => DateTime
|
|
73
76
|
field sorcery_config.reset_password_email_sent_at_attribute_name, :type => DateTime
|
|
74
77
|
end
|
|
78
|
+
|
|
79
|
+
def define_reset_password_mongo_mapper_fields
|
|
80
|
+
key sorcery_config.reset_password_token_attribute_name, String
|
|
81
|
+
# no DateTime in MM
|
|
82
|
+
key sorcery_config.reset_password_token_expires_at_attribute_name, Time
|
|
83
|
+
key sorcery_config.reset_password_email_sent_at_attribute_name, Time
|
|
84
|
+
end
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
module InstanceMethods
|
|
@@ -81,8 +91,8 @@ module Sorcery
|
|
|
81
91
|
# hammering protection
|
|
82
92
|
return if config.reset_password_time_between_emails && self.send(config.reset_password_email_sent_at_attribute_name) && self.send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.ago.utc
|
|
83
93
|
self.send(:"#{config.reset_password_token_attribute_name}=", TemporaryToken.generate_random_token)
|
|
84
|
-
self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", Time.now.
|
|
85
|
-
self.send(:"#{config.reset_password_email_sent_at_attribute_name}=", Time.now.
|
|
94
|
+
self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.reset_password_expiration_period) if config.reset_password_expiration_period
|
|
95
|
+
self.send(:"#{config.reset_password_email_sent_at_attribute_name}=", Time.now.in_time_zone)
|
|
86
96
|
self.class.transaction do
|
|
87
97
|
self.save!(:validate => false)
|
|
88
98
|
generic_send_email(:reset_password_email_method_name, :reset_password_mailer)
|
|
@@ -52,6 +52,9 @@ module Sorcery
|
|
|
52
52
|
|
|
53
53
|
base.sorcery_config.after_config << :validate_mailer_defined
|
|
54
54
|
base.sorcery_config.after_config << :define_user_activation_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
|
|
55
|
+
if defined?(MongoMapper) and base.ancestors.include?(MongoMapper::Document)
|
|
56
|
+
base.sorcery_config.after_config << :define_user_activation_mongo_mapper_fields
|
|
57
|
+
end
|
|
55
58
|
base.sorcery_config.before_authenticate << :prevent_non_active_login
|
|
56
59
|
|
|
57
60
|
base.extend(ClassMethods)
|
|
@@ -84,6 +87,15 @@ module Sorcery
|
|
|
84
87
|
field sorcery_config.activation_token_expires_at_attribute_name, :type => DateTime
|
|
85
88
|
end
|
|
86
89
|
end
|
|
90
|
+
|
|
91
|
+
def define_user_activation_mongo_mapper_fields
|
|
92
|
+
self.class_eval do
|
|
93
|
+
key sorcery_config.activation_state_attribute_name, String
|
|
94
|
+
key sorcery_config.activation_token_attribute_name, String
|
|
95
|
+
# no DateTime in MM
|
|
96
|
+
key sorcery_config.activation_token_expires_at_attribute_name, Time
|
|
97
|
+
end
|
|
98
|
+
end
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
module InstanceMethods
|
|
@@ -103,7 +115,7 @@ module Sorcery
|
|
|
103
115
|
generated_activation_token = TemporaryToken.generate_random_token
|
|
104
116
|
self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
|
|
105
117
|
self.send(:"#{config.activation_state_attribute_name}=", "pending")
|
|
106
|
-
self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.
|
|
118
|
+
self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.activation_token_expiration_period) if config.activation_token_expiration_period
|
|
107
119
|
end
|
|
108
120
|
|
|
109
121
|
# called automatically after user initial creation.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
|
|
1
3
|
module Sorcery
|
|
2
4
|
module Model
|
|
3
5
|
# This module encapsulates the logic for temporary token.
|
|
@@ -10,7 +12,7 @@ module Sorcery
|
|
|
10
12
|
|
|
11
13
|
# Random code, used for salt and temporary tokens.
|
|
12
14
|
def self.generate_random_token
|
|
13
|
-
|
|
15
|
+
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
module ClassMethods
|
|
@@ -18,7 +20,7 @@ module Sorcery
|
|
|
18
20
|
return nil if token.blank?
|
|
19
21
|
user = find_by_sorcery_token(token_attr_name,token)
|
|
20
22
|
if !user.blank? && !user.send(token_expiration_date_attr).nil?
|
|
21
|
-
return Time.now.
|
|
23
|
+
return Time.now.in_time_zone < user.send(token_expiration_date_attr) ? user : nil
|
|
22
24
|
end
|
|
23
25
|
user
|
|
24
26
|
end
|