sorcery 0.6.1 → 0.7.10
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/.travis.yml +2 -0
- data/Gemfile +2 -23
- data/Gemfile.lock +105 -77
- data/README.rdoc +32 -59
- data/Rakefile +29 -1
- data/VERSION +1 -1
- data/lib/generators/sorcery/USAGE +22 -0
- data/lib/generators/sorcery/install_generator.rb +77 -0
- data/lib/generators/sorcery/templates/initializer.rb +406 -0
- data/lib/generators/sorcery/templates/migration/activity_logging.rb +17 -0
- data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +13 -0
- data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/core.rb +3 -3
- 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 +24 -10
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +3 -2
- data/lib/sorcery/controller/submodules/external/protocols/certs/ca-bundle.crt +5182 -0
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +28 -9
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +12 -4
- data/lib/sorcery/controller/submodules/external/providers/github.rb +89 -0
- data/lib/sorcery/controller/submodules/external/providers/google.rb +90 -0
- data/lib/sorcery/controller/submodules/external/providers/liveid.rb +91 -0
- data/lib/sorcery/controller/submodules/external/providers/twitter.rb +8 -2
- data/lib/sorcery/controller/submodules/external.rb +17 -4
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
- data/lib/sorcery/controller/submodules/remember_me.rb +26 -15
- data/lib/sorcery/controller/submodules/session_timeout.rb +4 -4
- data/lib/sorcery/controller.rb +61 -38
- data/lib/sorcery/crypto_providers/aes256.rb +7 -3
- data/lib/sorcery/engine.rb +1 -0
- data/lib/sorcery/model/adapters/active_record.rb +17 -1
- data/lib/sorcery/model/adapters/mongo_mapper.rb +54 -0
- data/lib/sorcery/model/adapters/mongoid.rb +22 -4
- data/lib/sorcery/model/submodules/activity_logging.rb +4 -4
- data/lib/sorcery/model/submodules/brute_force_protection.rb +53 -14
- data/lib/sorcery/model/submodules/remember_me.rb +10 -3
- data/lib/sorcery/model/submodules/reset_password.rb +26 -11
- data/lib/sorcery/model/submodules/user_activation.rb +28 -10
- data/lib/sorcery/model/temporary_token.rb +8 -1
- data/lib/sorcery/model.rb +51 -19
- data/lib/sorcery/test_helpers/internal/rails.rb +1 -1
- data/lib/sorcery/test_helpers/rails.rb +2 -2
- data/lib/sorcery.rb +8 -7
- data/sorcery.gemspec +110 -223
- data/spec/Gemfile +1 -1
- data/spec/Gemfile.lock +26 -26
- data/spec/README.md +31 -0
- data/spec/rails3/Gemfile +5 -3
- data/spec/rails3/Gemfile.lock +74 -48
- data/spec/rails3/app/controllers/application_controller.rb +70 -23
- data/spec/rails3/app/mailers/sorcery_mailer.rb +7 -0
- data/spec/rails3/app/views/application/index.html.erb +17 -0
- data/spec/rails3/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
- data/spec/rails3/config/environments/in_memory.rb +35 -0
- data/spec/rails3/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +2 -0
- data/spec/rails3/spec/controller_activity_logging_spec.rb +33 -3
- data/spec/rails3/spec/controller_brute_force_protection_spec.rb +25 -3
- data/spec/rails3/spec/controller_oauth2_spec.rb +170 -25
- data/spec/rails3/spec/controller_remember_me_spec.rb +37 -6
- data/spec/rails3/spec/controller_session_timeout_spec.rb +4 -4
- data/spec/rails3/spec/controller_spec.rb +60 -2
- data/spec/rails3/spec/integration_spec.rb +23 -0
- data/spec/rails3/spec/spec_helper.rb +6 -5
- data/spec/rails3_mongo_mapper/.gitignore +4 -0
- data/spec/rails3_mongo_mapper/.rspec +1 -0
- data/spec/{sinatra_modular → rails3_mongo_mapper}/Gemfile +6 -5
- data/spec/rails3_mongo_mapper/Gemfile.lock +154 -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/rails3_mongo_mapper/spec/controller_spec.rb +163 -0
- 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 +2 -1
- data/spec/rails3_mongoid/Gemfile.lock +46 -45
- data/spec/rails3_mongoid/app/controllers/application_controller.rb +5 -0
- data/spec/rails3_mongoid/config/mongoid.yml +1 -1
- data/spec/rails3_mongoid/script/rails +0 -0
- data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +105 -0
- data/spec/rails3_mongoid/spec/controller_spec.rb +174 -0
- data/spec/rails3_mongoid/spec/user_spec.rb +1 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +72 -42
- data/spec/shared_examples/user_remember_me_shared_examples.rb +2 -1
- data/spec/shared_examples/user_reset_password_shared_examples.rb +81 -28
- data/spec/shared_examples/user_shared_examples.rb +36 -8
- data/spec/sorcery_crypto_providers_spec.rb +5 -1
- metadata +239 -346
- 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 -13
- data/lib/generators/sorcery_migration/templates/user_activation.rb +0 -17
- data/lib/sorcery/controller/adapters/sinatra.rb +0 -104
- data/lib/sorcery/initializers/initializer.rb +0 -178
- 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/rails3/public/index.html +0 -239
- data/spec/sinatra/Gemfile +0 -15
- data/spec/sinatra/Gemfile.lock +0 -117
- 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 -99
- 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/controller_spec.rb +0 -120
- 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 -117
- 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 -99
- 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,38 @@ module Sorcery
|
|
|
8
8
|
def oauth_version
|
|
9
9
|
"2.0"
|
|
10
10
|
end
|
|
11
|
-
|
|
12
|
-
def authorize_url(
|
|
13
|
-
client =
|
|
14
|
-
client.
|
|
11
|
+
|
|
12
|
+
def authorize_url(options = {})
|
|
13
|
+
client = build_client(options)
|
|
14
|
+
client.auth_code.authorize_url(
|
|
15
|
+
:redirect_uri => @callback_url,
|
|
16
|
+
:scope => @scope,
|
|
17
|
+
:display => @display
|
|
18
|
+
)
|
|
15
19
|
end
|
|
16
|
-
|
|
17
|
-
def get_access_token(args)
|
|
18
|
-
client =
|
|
19
|
-
client.
|
|
20
|
+
|
|
21
|
+
def get_access_token(args, options = {})
|
|
22
|
+
client = build_client(options)
|
|
23
|
+
client.auth_code.get_token(
|
|
24
|
+
args[:code],
|
|
25
|
+
{ :redirect_uri => @callback_url, :parse => options.delete(:parse) }, options
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def build_client(options = {})
|
|
30
|
+
defaults = {
|
|
31
|
+
:site => @site,
|
|
32
|
+
:ssl => { :ca_file => Config.ca_file }
|
|
33
|
+
}
|
|
34
|
+
::OAuth2::Client.new(
|
|
35
|
+
@key,
|
|
36
|
+
@secret,
|
|
37
|
+
defaults.merge!(options)
|
|
38
|
+
)
|
|
20
39
|
end
|
|
21
40
|
end
|
|
22
41
|
end
|
|
23
42
|
end
|
|
24
43
|
end
|
|
25
44
|
end
|
|
26
|
-
end
|
|
45
|
+
end
|
|
@@ -34,8 +34,10 @@ module Sorcery
|
|
|
34
34
|
:site,
|
|
35
35
|
:user_info_path,
|
|
36
36
|
:scope,
|
|
37
|
-
:user_info_mapping
|
|
38
|
-
|
|
37
|
+
:user_info_mapping,
|
|
38
|
+
:display
|
|
39
|
+
attr_reader :access_token
|
|
40
|
+
|
|
39
41
|
include Protocols::Oauth2
|
|
40
42
|
|
|
41
43
|
def init
|
|
@@ -43,12 +45,17 @@ module Sorcery
|
|
|
43
45
|
@user_info_path = "/me"
|
|
44
46
|
@scope = "email,offline_access"
|
|
45
47
|
@user_info_mapping = {}
|
|
48
|
+
@display = "page"
|
|
49
|
+
@token_url = "oauth/access_token"
|
|
50
|
+
@mode = :query
|
|
51
|
+
@parse = :query
|
|
52
|
+
@param_name = "access_token"
|
|
46
53
|
end
|
|
47
54
|
|
|
48
55
|
def get_user_hash
|
|
49
56
|
user_hash = {}
|
|
50
57
|
response = @access_token.get(@user_info_path)
|
|
51
|
-
user_hash[:user_info] = JSON.parse(response)
|
|
58
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
|
52
59
|
user_hash[:uid] = user_hash[:user_info]['id']
|
|
53
60
|
user_hash
|
|
54
61
|
end
|
|
@@ -66,8 +73,9 @@ module Sorcery
|
|
|
66
73
|
# tries to login the user from access token
|
|
67
74
|
def process_callback(params,session)
|
|
68
75
|
args = {}
|
|
76
|
+
options = { :token_url => @token_url, :mode => @mode, :param_name => @param_name, :parse => @parse }
|
|
69
77
|
args.merge!({:code => params[:code]}) if params[:code]
|
|
70
|
-
@access_token = self.get_access_token(args)
|
|
78
|
+
@access_token = self.get_access_token(args, options)
|
|
71
79
|
end
|
|
72
80
|
|
|
73
81
|
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Controller
|
|
3
|
+
module Submodules
|
|
4
|
+
module External
|
|
5
|
+
module Providers
|
|
6
|
+
# This module adds support for OAuth with github.com.
|
|
7
|
+
# When included in the 'config.providers' option, it adds a new option, 'config.github'.
|
|
8
|
+
# Via this new option you can configure Github specific settings like your app's key and secret.
|
|
9
|
+
#
|
|
10
|
+
# config.github.key = <key>
|
|
11
|
+
# config.github.secret = <secret>
|
|
12
|
+
# ...
|
|
13
|
+
#
|
|
14
|
+
module Github
|
|
15
|
+
def self.included(base)
|
|
16
|
+
base.module_eval do
|
|
17
|
+
class << self
|
|
18
|
+
attr_reader :github # access to github_client.
|
|
19
|
+
|
|
20
|
+
def merge_github_defaults!
|
|
21
|
+
@defaults.merge!(:@github => GithubClient)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
merge_github_defaults!
|
|
25
|
+
update!
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module GithubClient
|
|
30
|
+
class << self
|
|
31
|
+
attr_accessor :key,
|
|
32
|
+
:secret,
|
|
33
|
+
:callback_url,
|
|
34
|
+
:auth_path,
|
|
35
|
+
:token_path,
|
|
36
|
+
:site,
|
|
37
|
+
:user_info_path,
|
|
38
|
+
:user_info_mapping
|
|
39
|
+
attr_reader :access_token
|
|
40
|
+
|
|
41
|
+
include Protocols::Oauth2
|
|
42
|
+
|
|
43
|
+
def init
|
|
44
|
+
@site = "https://github.com/"
|
|
45
|
+
@user_info_path = "https://api.github.com/user"
|
|
46
|
+
@auth_path = "/login/oauth/authorize"
|
|
47
|
+
@token_path = "/login/oauth/access_token"
|
|
48
|
+
@user_info_mapping = {}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def get_user_hash
|
|
52
|
+
user_hash = {}
|
|
53
|
+
response = @access_token.get(@user_info_path)
|
|
54
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
|
55
|
+
user_hash[:uid] = user_hash[:user_info]['id']
|
|
56
|
+
user_hash
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def has_callback?
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# calculates and returns the url to which the user should be redirected,
|
|
64
|
+
# to get authenticated at the external provider's site.
|
|
65
|
+
def login_url(params,session)
|
|
66
|
+
self.authorize_url({:authorize_url => @auth_path})
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# tries to login the user from access token
|
|
70
|
+
def process_callback(params,session)
|
|
71
|
+
args = {}
|
|
72
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
73
|
+
options = {
|
|
74
|
+
:token_url => @token_path,
|
|
75
|
+
:token_method => :post
|
|
76
|
+
}
|
|
77
|
+
@access_token = self.get_access_token(args, options)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
init
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Controller
|
|
3
|
+
module Submodules
|
|
4
|
+
module External
|
|
5
|
+
module Providers
|
|
6
|
+
# This module adds support for OAuth with google.com.
|
|
7
|
+
# When included in the 'config.providers' option, it adds a new option, 'config.google'.
|
|
8
|
+
# Via this new option you can configure Google specific settings like your app's key and secret.
|
|
9
|
+
#
|
|
10
|
+
# config.google.key = <key>
|
|
11
|
+
# config.google.secret = <secret>
|
|
12
|
+
# ...
|
|
13
|
+
#
|
|
14
|
+
module Google
|
|
15
|
+
def self.included(base)
|
|
16
|
+
base.module_eval do
|
|
17
|
+
class << self
|
|
18
|
+
attr_reader :google # access to google_client.
|
|
19
|
+
|
|
20
|
+
def merge_google_defaults!
|
|
21
|
+
@defaults.merge!(:@google => GoogleClient)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
merge_google_defaults!
|
|
25
|
+
update!
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module GoogleClient
|
|
30
|
+
class << self
|
|
31
|
+
attr_accessor :key,
|
|
32
|
+
:secret,
|
|
33
|
+
:callback_url,
|
|
34
|
+
:site,
|
|
35
|
+
:auth_url,
|
|
36
|
+
:token_path,
|
|
37
|
+
:user_info_url,
|
|
38
|
+
:scope,
|
|
39
|
+
:user_info_mapping
|
|
40
|
+
attr_reader :access_token
|
|
41
|
+
|
|
42
|
+
include Protocols::Oauth2
|
|
43
|
+
|
|
44
|
+
def init
|
|
45
|
+
@site = "https://accounts.google.com"
|
|
46
|
+
@auth_url = "/o/oauth2/auth"
|
|
47
|
+
@token_url = "/o/oauth2/token"
|
|
48
|
+
@user_info_url = "https://www.googleapis.com/oauth2/v1/userinfo"
|
|
49
|
+
@scope = "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
|
50
|
+
@user_info_mapping = {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_user_hash
|
|
54
|
+
user_hash = {}
|
|
55
|
+
response = @access_token.get(@user_info_url)
|
|
56
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
|
57
|
+
user_hash[:uid] = user_hash[:user_info]['id']
|
|
58
|
+
user_hash
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def has_callback?
|
|
62
|
+
true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# calculates and returns the url to which the user should be redirected,
|
|
66
|
+
# to get authenticated at the external provider's site.
|
|
67
|
+
def login_url(params,session)
|
|
68
|
+
self.authorize_url({:authorize_url => @auth_url})
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# tries to login the user from access token
|
|
72
|
+
def process_callback(params,session)
|
|
73
|
+
args = {}
|
|
74
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
75
|
+
options = {
|
|
76
|
+
:token_url => @token_url,
|
|
77
|
+
:token_method => :post
|
|
78
|
+
}
|
|
79
|
+
@access_token = self.get_access_token(args, options)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
init
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Controller
|
|
3
|
+
module Submodules
|
|
4
|
+
module External
|
|
5
|
+
module Providers
|
|
6
|
+
# This module adds support for OAuth with microsoft liveid
|
|
7
|
+
# When included in the 'config.providers' option, it adds a new option, 'config.liveid'.
|
|
8
|
+
# Via this new option you can configure LiveId specific settings like your app's key and secret.
|
|
9
|
+
#
|
|
10
|
+
# config.liveid.key = <key>
|
|
11
|
+
# config.liveid.secret = <secret>
|
|
12
|
+
# ...
|
|
13
|
+
#
|
|
14
|
+
module Liveid
|
|
15
|
+
def self.included(base)
|
|
16
|
+
base.module_eval do
|
|
17
|
+
class << self
|
|
18
|
+
attr_reader :liveid # access to liveid_client.
|
|
19
|
+
|
|
20
|
+
def merge_liveid_defaults!
|
|
21
|
+
@defaults.merge!(:@liveid => LiveidClient)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
merge_liveid_defaults!
|
|
25
|
+
update!
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module LiveidClient
|
|
30
|
+
class << self
|
|
31
|
+
attr_accessor :key,
|
|
32
|
+
:secret,
|
|
33
|
+
:callback_url,
|
|
34
|
+
:site,
|
|
35
|
+
:auth_url,
|
|
36
|
+
:token_path,
|
|
37
|
+
:user_info_url,
|
|
38
|
+
:scope,
|
|
39
|
+
:user_info_mapping
|
|
40
|
+
attr_reader :access_token
|
|
41
|
+
|
|
42
|
+
include Protocols::Oauth2
|
|
43
|
+
|
|
44
|
+
def init
|
|
45
|
+
@site = "https://oauth.live.com/"
|
|
46
|
+
@auth_url = "/authorize"
|
|
47
|
+
@token_path = "/token"
|
|
48
|
+
@user_info_url = "https://apis.live.net/v5.0/me"
|
|
49
|
+
@scope = "wl.basic wl.emails wl.offline_access"
|
|
50
|
+
@user_info_mapping = {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_user_hash
|
|
54
|
+
user_hash = {}
|
|
55
|
+
@access_token.token_param = "access_token"
|
|
56
|
+
response = @access_token.get(@user_info_url)
|
|
57
|
+
user_hash[:user_info] = JSON.parse(response.body)
|
|
58
|
+
user_hash[:uid] = user_hash[:user_info]['id']
|
|
59
|
+
user_hash
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def has_callback?
|
|
63
|
+
true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# calculates and returns the url to which the user should be redirected,
|
|
67
|
+
# to get authenticated at the external provider's site.
|
|
68
|
+
def login_url(params,session)
|
|
69
|
+
self.authorize_url({:authorize_url => @auth_url})
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# tries to login the user from access token
|
|
73
|
+
def process_callback(params,session)
|
|
74
|
+
args = {}
|
|
75
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
76
|
+
options = {
|
|
77
|
+
:access_token_path => @token_path,
|
|
78
|
+
:access_token_method => :post
|
|
79
|
+
}
|
|
80
|
+
@access_token = self.get_access_token(args, options)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
init
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -37,8 +37,14 @@ module Sorcery
|
|
|
37
37
|
:site,
|
|
38
38
|
:user_info_path,
|
|
39
39
|
:user_info_mapping
|
|
40
|
-
|
|
40
|
+
attr_reader :access_token
|
|
41
|
+
|
|
41
42
|
include Protocols::Oauth1
|
|
43
|
+
|
|
44
|
+
# Override included get_consumer method to provide authorize_path
|
|
45
|
+
def get_consumer
|
|
46
|
+
::OAuth::Consumer.new(@key, @secret, :site => @site, :authorize_path => "/oauth/authenticate")
|
|
47
|
+
end
|
|
42
48
|
|
|
43
49
|
def init
|
|
44
50
|
@site = "https://api.twitter.com"
|
|
@@ -50,7 +56,7 @@ module Sorcery
|
|
|
50
56
|
user_hash = {}
|
|
51
57
|
response = @access_token.get(@user_info_path)
|
|
52
58
|
user_hash[:user_info] = JSON.parse(response.body)
|
|
53
|
-
user_hash[:uid] = user_hash[:user_info]['id']
|
|
59
|
+
user_hash[:uid] = user_hash[:user_info]['id'].to_s
|
|
54
60
|
user_hash
|
|
55
61
|
end
|
|
56
62
|
|
|
@@ -9,9 +9,11 @@ module Sorcery
|
|
|
9
9
|
Config.module_eval do
|
|
10
10
|
class << self
|
|
11
11
|
attr_reader :external_providers # external providers like twitter.
|
|
12
|
+
attr_accessor :ca_file # path to ca_file. By default use a internal ca-bundle.crt.
|
|
12
13
|
|
|
13
14
|
def merge_external_defaults!
|
|
14
|
-
@defaults.merge!(:@external_providers => []
|
|
15
|
+
@defaults.merge!(:@external_providers => [],
|
|
16
|
+
:@ca_file => File.join(File.expand_path(File.dirname(__FILE__)), 'external/protocols/certs/ca-bundle.crt'))
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def external_providers=(providers)
|
|
@@ -43,12 +45,18 @@ module Sorcery
|
|
|
43
45
|
@provider = Config.send(provider)
|
|
44
46
|
@provider.process_callback(params,session)
|
|
45
47
|
@user_hash = @provider.get_user_hash
|
|
46
|
-
if user = user_class.load_from_provider(provider,@user_hash[:uid])
|
|
48
|
+
if user = user_class.load_from_provider(provider,@user_hash[:uid].to_s)
|
|
47
49
|
reset_session
|
|
48
|
-
|
|
50
|
+
auto_login(user)
|
|
49
51
|
user
|
|
50
52
|
end
|
|
51
53
|
end
|
|
54
|
+
|
|
55
|
+
# get provider access account
|
|
56
|
+
def access_token(provider)
|
|
57
|
+
@provider = Config.send(provider)
|
|
58
|
+
@provider.access_token
|
|
59
|
+
end
|
|
52
60
|
|
|
53
61
|
# this method automatically creates a new user from the data in the external user hash.
|
|
54
62
|
# The mappings from user hash fields to user db fields are set at controller config.
|
|
@@ -61,6 +69,7 @@ module Sorcery
|
|
|
61
69
|
# {:username => "user/name"}
|
|
62
70
|
#
|
|
63
71
|
# And this will cause 'moishe' to be set as the value of :username field.
|
|
72
|
+
# Note: Be careful. This method skips validations model.
|
|
64
73
|
def create_from(provider)
|
|
65
74
|
provider = provider.to_sym
|
|
66
75
|
@provider = Config.send(provider)
|
|
@@ -76,7 +85,11 @@ module Sorcery
|
|
|
76
85
|
end
|
|
77
86
|
end
|
|
78
87
|
user_class.transaction do
|
|
79
|
-
@user = user_class.
|
|
88
|
+
@user = user_class.new()
|
|
89
|
+
attrs.each do |k,v|
|
|
90
|
+
@user.send(:"#{k}=", v)
|
|
91
|
+
end
|
|
92
|
+
@user.save(:validate => false)
|
|
80
93
|
user_class.sorcery_config.authentications_class.create!({config.authentications_user_id_attribute_name => @user.id, config.provider_attribute_name => provider, config.provider_uid_attribute_name => @user_hash[:uid]})
|
|
81
94
|
end
|
|
82
95
|
@user
|
|
@@ -46,7 +46,7 @@ module Sorcery
|
|
|
46
46
|
def login_from_basic_auth
|
|
47
47
|
authenticate_with_http_basic do |username, password|
|
|
48
48
|
@current_user = (user_class.authenticate(username, password) if session[:http_authentication_used]) || false
|
|
49
|
-
|
|
49
|
+
auto_login(@current_user) if @current_user
|
|
50
50
|
@current_user
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -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,45 +12,56 @@ 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
|
+
end
|
|
28
|
+
|
|
29
|
+
# Override.
|
|
30
|
+
# logins a user instance, and optionally remembers him.
|
|
31
|
+
def auto_login(user, should_remember = false)
|
|
32
|
+
session[:user_id] = user.id
|
|
33
|
+
@current_user = user
|
|
34
|
+
remember_me! if should_remember
|
|
27
35
|
end
|
|
28
|
-
|
|
36
|
+
|
|
29
37
|
protected
|
|
30
|
-
|
|
38
|
+
|
|
31
39
|
# calls remember_me! if a third credential was passed to the login method.
|
|
32
40
|
# Runs as a hook after login.
|
|
33
41
|
def remember_me_if_asked_to(user, credentials)
|
|
34
|
-
remember_me! if credentials.size == 3 && credentials[2]
|
|
42
|
+
remember_me! if ( credentials.size == 3 && credentials[2] && credentials[2] != "0" )
|
|
35
43
|
end
|
|
36
|
-
|
|
37
|
-
# 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
|
|
38
46
|
# and logs the user in if found.
|
|
39
47
|
# Runs as a login source. See 'current_user' method for how it is used.
|
|
40
48
|
def login_from_cookie
|
|
41
|
-
user = cookies[:remember_me_token] && user_class.find_by_remember_me_token(cookies[:remember_me_token])
|
|
49
|
+
user = cookies.signed[:remember_me_token] && user_class.find_by_remember_me_token(cookies.signed[:remember_me_token])
|
|
42
50
|
if user && user.remember_me_token?
|
|
43
51
|
set_remember_me_cookie!(user)
|
|
52
|
+
session[:user_id] = user.id
|
|
44
53
|
@current_user = user
|
|
45
54
|
else
|
|
46
55
|
@current_user = false
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
|
-
|
|
58
|
+
|
|
50
59
|
def set_remember_me_cookie!(user)
|
|
51
|
-
cookies[:remember_me_token] = {
|
|
52
|
-
:value => user.send(user.sorcery_config.remember_me_token_attribute_name),
|
|
53
|
-
:expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name)
|
|
60
|
+
cookies.signed[:remember_me_token] = {
|
|
61
|
+
:value => user.send(user.sorcery_config.remember_me_token_attribute_name),
|
|
62
|
+
:expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name),
|
|
63
|
+
:httponly => true,
|
|
64
|
+
:domain => Config.cookie_domain
|
|
54
65
|
}
|
|
55
66
|
end
|
|
56
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
|
-
@current_user =
|
|
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
|
|