sorcery 0.2.1 → 0.4.2
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 +157 -61
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +24 -0
- data/lib/generators/sorcery_migration/templates/activity_logging.rb +17 -0
- data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +11 -0
- data/lib/generators/sorcery_migration/templates/core.rb +16 -0
- data/lib/generators/sorcery_migration/templates/external.rb +14 -0
- data/lib/generators/sorcery_migration/templates/remember_me.rb +15 -0
- data/lib/generators/sorcery_migration/templates/reset_password.rb +13 -0
- data/lib/generators/sorcery_migration/templates/user_activation.rb +17 -0
- data/lib/sorcery/controller/adapters/sinatra.rb +97 -0
- 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 -27
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +11 -7
- data/lib/sorcery/controller.rb +21 -21
- data/lib/sorcery/crypto_providers/bcrypt.rb +3 -5
- 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/activity_logging.rb +2 -2
- data/lib/sorcery/model/submodules/brute_force_protection.rb +1 -5
- data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
- data/lib/sorcery/model/submodules/reset_password.rb +1 -1
- data/lib/sorcery/model.rb +34 -9
- data/lib/sorcery/railties/tasks.rake +10 -0
- data/lib/sorcery/sinatra.rb +5 -0
- data/lib/sorcery/test_helpers/internal/rails.rb +52 -0
- data/lib/sorcery/test_helpers/internal/sinatra.rb +122 -0
- data/lib/sorcery/test_helpers/internal.rb +55 -0
- data/lib/sorcery/test_helpers/rails.rb +16 -0
- data/lib/sorcery/test_helpers/sinatra.rb +85 -0
- data/lib/sorcery/test_helpers.rb +0 -79
- data/lib/sorcery.rb +25 -7
- data/sorcery.gemspec +207 -137
- data/spec/Gemfile +2 -2
- data/spec/Gemfile.lock +20 -12
- data/spec/Rakefile +1 -0
- data/spec/rails3/.rspec +1 -1
- data/spec/rails3/{app_root/Gemfile → Gemfile} +5 -7
- data/spec/rails3/{app_root/Gemfile.lock → Gemfile.lock} +20 -23
- 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_activity_logging_spec.rb +2 -4
- 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 +25 -22
- data/spec/rails3/{app_root/spec → spec}/controller_oauth_spec.rb +24 -19
- data/spec/rails3/spec/controller_session_timeout_spec.rb +55 -0
- data/spec/rails3/{app_root/spec → spec}/controller_spec.rb +6 -16
- 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 +7 -13
- data/spec/rails3/{app_root/spec → spec}/user_brute_force_protection_spec.rb +2 -30
- data/spec/rails3/{app_root/spec → spec}/user_oauth_spec.rb +7 -7
- data/spec/rails3/{app_root/spec → spec}/user_remember_me_spec.rb +3 -11
- data/spec/rails3/{app_root/spec → spec}/user_reset_password_spec.rb +20 -17
- data/spec/rails3/{app_root/spec → spec}/user_spec.rb +21 -11
- data/spec/sinatra/Gemfile +12 -0
- data/spec/sinatra/Gemfile.lock +134 -0
- data/spec/sinatra/Rakefile +11 -0
- data/spec/sinatra/authentication.rb +3 -0
- data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
- data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
- data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
- data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +14 -0
- data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/sinatra/filters.rb +21 -0
- data/spec/sinatra/myapp.rb +133 -0
- data/spec/sinatra/sorcery_mailer.rb +25 -0
- data/spec/sinatra/spec/controller_activity_logging_spec.rb +85 -0
- data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +70 -0
- data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +53 -0
- data/spec/sinatra/spec/controller_oauth2_spec.rb +120 -0
- data/spec/sinatra/spec/controller_oauth_spec.rb +121 -0
- data/spec/sinatra/spec/controller_remember_me_spec.rb +64 -0
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +57 -0
- data/spec/sinatra/spec/controller_spec.rb +120 -0
- data/spec/sinatra/spec/spec.opts +2 -0
- data/spec/sinatra/spec/spec_helper.rb +46 -0
- data/spec/sinatra/user.rb +6 -0
- data/spec/sinatra/views/test_login.erb +4 -0
- data/spec/sorcery_crypto_providers_spec.rb +5 -4
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +3 -4
- data/spec/untitled folder +18 -0
- metadata +217 -139
- data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -26
- 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/controller_session_timeout_spec.rb +0 -50
- data/spec/rails3/app_root/spec/spec_helper.rb +0 -61
- /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_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}/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/vendor → vendor}/plugins/.gitkeep +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
module
|
|
4
|
+
module External
|
|
5
5
|
module Providers
|
|
6
6
|
# This module adds support for OAuth with facebook.com.
|
|
7
7
|
# When included in the 'config.providers' option, it adds a new option, 'config.facebook'.
|
|
@@ -16,7 +16,7 @@ module Sorcery
|
|
|
16
16
|
base.module_eval do
|
|
17
17
|
class << self
|
|
18
18
|
attr_reader :facebook # access to facebook_client.
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
def merge_facebook_defaults!
|
|
21
21
|
@defaults.merge!(:@facebook => FacebookClient)
|
|
22
22
|
end
|
|
@@ -36,7 +36,7 @@ module Sorcery
|
|
|
36
36
|
:scope,
|
|
37
37
|
:user_info_mapping
|
|
38
38
|
|
|
39
|
-
include Oauth2
|
|
39
|
+
include Protocols::Oauth2
|
|
40
40
|
|
|
41
41
|
def init
|
|
42
42
|
@site = "https://graph.facebook.com"
|
|
@@ -45,13 +45,31 @@ module Sorcery
|
|
|
45
45
|
@user_info_mapping = {}
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def get_user_hash
|
|
48
|
+
def get_user_hash
|
|
49
49
|
user_hash = {}
|
|
50
|
-
response = access_token.get(@user_info_path)
|
|
50
|
+
response = @access_token.get(@user_info_path)
|
|
51
51
|
user_hash[:user_info] = JSON.parse(response)
|
|
52
|
-
user_hash[:uid] = user_hash[:user_info]['id']
|
|
52
|
+
user_hash[:uid] = user_hash[:user_info]['id']
|
|
53
53
|
user_hash
|
|
54
54
|
end
|
|
55
|
+
|
|
56
|
+
def has_callback?
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# calculates and returns the url to which the user should be redirected,
|
|
61
|
+
# to get authenticated at the external provider's site.
|
|
62
|
+
def login_url(params,session)
|
|
63
|
+
self.authorize_url
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# tries to login the user from access token
|
|
67
|
+
def process_callback(params,session)
|
|
68
|
+
args = {}
|
|
69
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
70
|
+
@access_token = self.get_access_token(args)
|
|
71
|
+
end
|
|
72
|
+
|
|
55
73
|
end
|
|
56
74
|
init
|
|
57
75
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
module
|
|
4
|
+
module External
|
|
5
5
|
module Providers
|
|
6
6
|
# This module adds support for OAuth with Twitter.com.
|
|
7
7
|
# When included in the 'config.providers' option, it adds a new option, 'config.twitter'.
|
|
@@ -15,7 +15,10 @@ module Sorcery
|
|
|
15
15
|
def self.included(base)
|
|
16
16
|
base.module_eval do
|
|
17
17
|
class << self
|
|
18
|
-
attr_reader :twitter
|
|
18
|
+
attr_reader :twitter
|
|
19
|
+
# def twitter(&blk) # allows block syntax.
|
|
20
|
+
# yield @twitter
|
|
21
|
+
# end
|
|
19
22
|
|
|
20
23
|
def merge_twitter_defaults!
|
|
21
24
|
@defaults.merge!(:@twitter => TwitterClient)
|
|
@@ -25,7 +28,7 @@ module Sorcery
|
|
|
25
28
|
update!
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
|
-
|
|
31
|
+
|
|
29
32
|
module TwitterClient
|
|
30
33
|
class << self
|
|
31
34
|
attr_accessor :key,
|
|
@@ -35,7 +38,7 @@ module Sorcery
|
|
|
35
38
|
:user_info_path,
|
|
36
39
|
:user_info_mapping
|
|
37
40
|
|
|
38
|
-
include Oauth1
|
|
41
|
+
include Protocols::Oauth1
|
|
39
42
|
|
|
40
43
|
def init
|
|
41
44
|
@site = "https://api.twitter.com"
|
|
@@ -43,13 +46,35 @@ module Sorcery
|
|
|
43
46
|
@user_info_mapping = {}
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
def get_user_hash
|
|
49
|
+
def get_user_hash
|
|
47
50
|
user_hash = {}
|
|
48
|
-
response = access_token.get(@user_info_path)
|
|
51
|
+
response = @access_token.get(@user_info_path)
|
|
49
52
|
user_hash[:user_info] = JSON.parse(response.body)
|
|
50
53
|
user_hash[:uid] = user_hash[:user_info]['id']
|
|
51
54
|
user_hash
|
|
52
55
|
end
|
|
56
|
+
|
|
57
|
+
def has_callback?
|
|
58
|
+
true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# calculates and returns the url to which the user should be redirected,
|
|
62
|
+
# to get authenticated at the external provider's site.
|
|
63
|
+
def login_url(params,session)
|
|
64
|
+
req_token = self.get_request_token
|
|
65
|
+
session[:request_token] = req_token.token
|
|
66
|
+
session[:request_token_secret] = req_token.secret
|
|
67
|
+
self.authorize_url({:request_token => req_token.token, :request_token_secret => req_token.secret})
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# tries to login the user from access token
|
|
71
|
+
def process_callback(params,session)
|
|
72
|
+
args = {}
|
|
73
|
+
args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]})
|
|
74
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
75
|
+
@access_token = self.get_access_token(args)
|
|
76
|
+
end
|
|
77
|
+
|
|
53
78
|
end
|
|
54
79
|
init
|
|
55
80
|
end
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
# This submodule helps you login users from
|
|
4
|
+
# This submodule helps you login users from external auth providers such as Twitter.
|
|
5
5
|
# This is the controller part which handles the http requests and tokens passed between the app and the provider.
|
|
6
|
-
|
|
7
|
-
module Oauth
|
|
6
|
+
module External
|
|
8
7
|
def self.included(base)
|
|
9
8
|
base.send(:include, InstanceMethods)
|
|
10
9
|
Config.module_eval do
|
|
11
10
|
class << self
|
|
12
|
-
attr_reader :
|
|
11
|
+
attr_reader :external_providers # external providers like twitter.
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
@defaults.merge!(:@
|
|
13
|
+
def merge_external_defaults!
|
|
14
|
+
@defaults.merge!(:@external_providers => [])
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
def
|
|
17
|
+
def external_providers=(providers)
|
|
19
18
|
providers.each do |provider|
|
|
20
19
|
include Providers.const_get(provider.to_s.split("_").map {|p| p.capitalize}.join(""))
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
|
-
|
|
23
|
+
merge_external_defaults!
|
|
25
24
|
end
|
|
26
25
|
end
|
|
27
26
|
|
|
@@ -30,23 +29,20 @@ module Sorcery
|
|
|
30
29
|
|
|
31
30
|
# sends user to authenticate at the provider's website.
|
|
32
31
|
# after authentication the user is redirected to the callback defined in the provider config
|
|
33
|
-
def
|
|
32
|
+
def login_at(provider, args = {})
|
|
34
33
|
@provider = Config.send(provider)
|
|
35
|
-
if @provider.
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
if @provider.has_callback?
|
|
35
|
+
redirect_to @provider.login_url(params,session)
|
|
36
|
+
else
|
|
37
|
+
#@provider.login(args)
|
|
38
38
|
end
|
|
39
|
-
redirect_to @provider.authorize_url(args)
|
|
40
39
|
end
|
|
41
40
|
|
|
42
|
-
# tries to login the user from
|
|
43
|
-
def
|
|
41
|
+
# tries to login the user from provider's callback
|
|
42
|
+
def login_from(provider)
|
|
44
43
|
@provider = Config.send(provider)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
args.merge!({:code => params[:code]}) if params[:code]
|
|
48
|
-
@access_token = @provider.get_access_token(args)
|
|
49
|
-
@user_hash = @provider.get_user_hash(@access_token)
|
|
44
|
+
@provider.process_callback(params,session)
|
|
45
|
+
@user_hash = @provider.get_user_hash
|
|
50
46
|
if user = Config.user_class.load_from_provider(provider,@user_hash[:uid])
|
|
51
47
|
reset_session
|
|
52
48
|
login_user(user)
|
|
@@ -54,11 +50,6 @@ module Sorcery
|
|
|
54
50
|
end
|
|
55
51
|
end
|
|
56
52
|
|
|
57
|
-
def get_user_hash(provider)
|
|
58
|
-
@provider = Config.send(provider)
|
|
59
|
-
@provider.get_user_hash(@access_token)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
53
|
# this method automatically creates a new user from the data in the external user hash.
|
|
63
54
|
# The mappings from user hash fields to user db fields are set at controller config.
|
|
64
55
|
# If the hash field you would like to map is nested, use slashes. For example, Given a hash like:
|
|
@@ -70,10 +61,10 @@ module Sorcery
|
|
|
70
61
|
# {:username => "user/name"}
|
|
71
62
|
#
|
|
72
63
|
# And this will cause 'moishe' to be set as the value of :username field.
|
|
73
|
-
def
|
|
64
|
+
def create_from(provider)
|
|
74
65
|
provider = provider.to_sym
|
|
75
66
|
@provider = Config.send(provider)
|
|
76
|
-
@user_hash = get_user_hash
|
|
67
|
+
@user_hash = @provider.get_user_hash
|
|
77
68
|
config = Config.user_class.sorcery_config
|
|
78
69
|
attrs = {}
|
|
79
70
|
@provider.user_info_mapping.each do |k,v|
|
|
@@ -9,7 +9,7 @@ module Sorcery
|
|
|
9
9
|
base.send(:include, InstanceMethods)
|
|
10
10
|
Config.module_eval do
|
|
11
11
|
class << self
|
|
12
|
-
attr_accessor :controller_to_realm_map #
|
|
12
|
+
attr_accessor :controller_to_realm_map # What realm to display for which controller name.
|
|
13
13
|
|
|
14
14
|
def merge_http_basic_auth_defaults!
|
|
15
15
|
@defaults.merge!(:@controller_to_realm_map => {"application" => "Application"})
|
|
@@ -48,13 +48,17 @@ module Sorcery
|
|
|
48
48
|
|
|
49
49
|
# Sets the realm name by searching the controller name in the hash given at configuration time.
|
|
50
50
|
def realm_name_by_controller
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
if defined?(ActionController::Base)
|
|
52
|
+
current_controller = self.class
|
|
53
|
+
while current_controller != ActionController::Base
|
|
54
|
+
result = Config.controller_to_realm_map[current_controller.controller_name]
|
|
55
|
+
return result if result
|
|
56
|
+
current_controller = self.class.superclass
|
|
57
|
+
end
|
|
58
|
+
nil
|
|
59
|
+
else
|
|
60
|
+
Config.controller_to_realm_map["application"]
|
|
56
61
|
end
|
|
57
|
-
nil
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
end
|
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!
|
|
@@ -30,11 +30,9 @@ module Sorcery
|
|
|
30
30
|
#
|
|
31
31
|
# gem install bcrypt-ruby
|
|
32
32
|
#
|
|
33
|
-
#
|
|
33
|
+
# Update your initializer to use it:
|
|
34
34
|
#
|
|
35
|
-
#
|
|
36
|
-
# c.encryption_algorithm = :bcrypt
|
|
37
|
-
# end
|
|
35
|
+
# config.encryption_algorithm = :bcrypt
|
|
38
36
|
#
|
|
39
37
|
# You are good to go!
|
|
40
38
|
class BCrypt
|
|
@@ -42,7 +40,7 @@ module Sorcery
|
|
|
42
40
|
# This is the :cost option for the BCrpyt library. The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
|
|
43
41
|
# Set this to whatever you want, play around with it to get that perfect balance between security and performance.
|
|
44
42
|
def cost
|
|
45
|
-
@cost ||=
|
|
43
|
+
@cost ||= 10
|
|
46
44
|
end
|
|
47
45
|
attr_writer :cost
|
|
48
46
|
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
|
+
Rails.application.config.sorcery.submodules = []
|
|
5
|
+
|
|
6
|
+
# Here you can configure each submodule's features.
|
|
7
|
+
Rails.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
|
+
# subclasses_inherit_config = false # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
|
|
13
|
+
|
|
14
|
+
# -- session timeout --
|
|
15
|
+
# config.session_timeout = 3600 # how long in seconds to keep the session alive.
|
|
16
|
+
# config.session_timeout_from_last_action = false # use the last action as the beginning of session timeout.
|
|
17
|
+
|
|
18
|
+
# -- http_basic_auth --
|
|
19
|
+
# config.controller_to_realm_map = {"application" => "Application"} # What realm to display for which controller name.
|
|
20
|
+
# For example {"My App" => "Application"}
|
|
21
|
+
|
|
22
|
+
# -- external --
|
|
23
|
+
# config.external_providers = [] # What providers are supported by this app, i.e. [:twitter, :facebook] .
|
|
24
|
+
#
|
|
25
|
+
# config.twitter.key = "eYVNBjBDi33aa9GkA3w"
|
|
26
|
+
# config.twitter.secret = "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8"
|
|
27
|
+
# config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
|
|
28
|
+
# config.twitter.user_info_mapping = {:email => "screen_name"}
|
|
29
|
+
#
|
|
30
|
+
# config.facebook.key = "34cebc81c08a521bc66e212f947d73ec"
|
|
31
|
+
# config.facebook.secret = "5b458d179f61d4f036ee66a497ffbcd0"
|
|
32
|
+
# config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
|
|
33
|
+
# config.facebook.user_info_mapping = {:email => "name"}
|
|
34
|
+
|
|
35
|
+
# --- user config ---
|
|
36
|
+
config.user_config do |user|
|
|
37
|
+
# -- core --
|
|
38
|
+
# user.username_attribute_name = :username # change default username attribute, for example, to use :email as the login.
|
|
39
|
+
# user.password_attribute_name = :password # change *virtual* password attribute, the one which is used until an encrypted one is generated.
|
|
40
|
+
# user.email_attribute_name = :email # change default email attribute.
|
|
41
|
+
# user.crypted_password_attribute_name = :crypted_password # change default crypted_password attribute.
|
|
42
|
+
# user.salt_join_token = "" # what pattern to use to join the password with the salt
|
|
43
|
+
# user.salt_attribute_name = :salt # change default salt attribute.
|
|
44
|
+
# user.stretches = nil # how many times to apply encryption to the password.
|
|
45
|
+
# user.encryption_key = nil # encryption key used to encrypt reversible encryptions such as AES256.
|
|
46
|
+
# user.custom_encryption_provider = nil # use an external encryption class.
|
|
47
|
+
# user.encryption_algorithm = :bcrypt # encryption algorithm name. See 'encryption_algorithm=' for available options.
|
|
48
|
+
|
|
49
|
+
# -- user_activation --
|
|
50
|
+
# user.activation_state_attribute_name = :activation_state # the attribute name to hold activation state (active/pending).
|
|
51
|
+
# user.activation_token_attribute_name = :activation_token # the attribute name to hold activation code (sent by email).
|
|
52
|
+
# user.activation_token_expires_at_attribute_name = :activation_token_expires_at # the attribute name to hold activation code expiration date.
|
|
53
|
+
# user.activation_token_expiration_period = nil # how many seconds before the activation code expires. nil for never expires.
|
|
54
|
+
# user.user_activation_mailer = nil # your mailer class. Required.
|
|
55
|
+
# user.activation_needed_email_method_name = :activation_needed_email # activation needed email method on your mailer class.
|
|
56
|
+
# user.activation_success_email_method_name = :activation_success_email # activation success email method on your mailer class.
|
|
57
|
+
# user.prevent_non_active_users_to_login = true # 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_token # reset password code attribute name.
|
|
61
|
+
# user.reset_password_token_expires_at_attribute_name = :reset_password_token_expires_at # expires at attribute name.
|
|
62
|
+
# user.reset_password_email_sent_at_attribute_name = :reset_password_email_sent_at # when was email sent, used for hammering protection.
|
|
63
|
+
# user.reset_password_mailer = nil # mailer class. Needed.
|
|
64
|
+
# user.reset_password_email_method_name = :reset_password_email # reset password email method on your mailer class.
|
|
65
|
+
# user.reset_password_expiration_period = nil # how many seconds before the reset request expires. nil for never expires.
|
|
66
|
+
# user.reset_password_time_between_emails = 5 * 60 # 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_count # failed logins attribute name.
|
|
70
|
+
# user.lock_expires_at_attribute_name = :lock_expires_at # this field indicates whether user is banned and when it will be active again.
|
|
71
|
+
# user.consecutive_login_retries_amount_limit = 50 # how many failed logins allowed.
|
|
72
|
+
# user.login_lock_time_period = 60 * 60 # 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_at # last login attribute name.
|
|
76
|
+
# user.last_logout_at_attribute_name = :last_logout_at # last logout attribute name.
|
|
77
|
+
# user.last_activity_at_attribute_name = :last_activity_at # last activity attribute name.
|
|
78
|
+
# user.activity_timeout = 10 * 60 # how long since last activity is the user defined logged out?
|
|
79
|
+
|
|
80
|
+
# -- external --
|
|
81
|
+
# user.authentications_class = nil # class which holds the various external provider data for this user.
|
|
82
|
+
# user.authentications_user_id_attribute_name = :user_id # user's identifier in authentications class.
|
|
83
|
+
# user.provider_attribute_name = :provider # provider's identifier in authentications class.
|
|
84
|
+
# user.provider_uid_attribute_name = :uid # user's external unique identifier in authentications class.
|
|
85
|
+
end
|
|
86
|
+
end
|