sorcery 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +122 -5
  4. data/CHANGELOG.md +37 -1
  5. data/Gemfile +10 -18
  6. data/README.md +159 -88
  7. data/gemfiles/active_record-rails40.gemfile +7 -0
  8. data/gemfiles/active_record-rails41.gemfile +7 -0
  9. data/gemfiles/mongo_mapper-rails40.gemfile +9 -0
  10. data/gemfiles/mongo_mapper-rails41.gemfile +9 -0
  11. data/gemfiles/mongoid-rails40.gemfile +9 -0
  12. data/gemfiles/mongoid-rails41.gemfile +9 -0
  13. data/gemfiles/mongoid3-rails32.gemfile +9 -0
  14. data/lib/generators/sorcery/USAGE +1 -1
  15. data/lib/generators/sorcery/install_generator.rb +19 -5
  16. data/lib/generators/sorcery/templates/initializer.rb +34 -9
  17. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +3 -1
  18. data/lib/generators/sorcery/templates/migration/core.rb +2 -2
  19. data/lib/generators/sorcery/templates/migration/external.rb +3 -1
  20. data/lib/sorcery/adapters/active_record_adapter.rb +120 -0
  21. data/lib/sorcery/adapters/base_adapter.rb +30 -0
  22. data/lib/sorcery/adapters/data_mapper_adapter.rb +176 -0
  23. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +110 -0
  24. data/lib/sorcery/adapters/mongoid_adapter.rb +97 -0
  25. data/lib/sorcery/controller/config.rb +65 -0
  26. data/lib/sorcery/controller/submodules/activity_logging.rb +16 -21
  27. data/lib/sorcery/controller/submodules/brute_force_protection.rb +6 -6
  28. data/lib/sorcery/controller/submodules/external.rb +35 -40
  29. data/lib/sorcery/controller/submodules/remember_me.rb +4 -4
  30. data/lib/sorcery/controller/submodules/session_timeout.rb +10 -6
  31. data/lib/sorcery/controller.rb +10 -74
  32. data/lib/sorcery/model/config.rb +96 -0
  33. data/lib/sorcery/model/submodules/activity_logging.rb +30 -13
  34. data/lib/sorcery/model/submodules/brute_force_protection.rb +21 -21
  35. data/lib/sorcery/model/submodules/external.rb +53 -9
  36. data/lib/sorcery/model/submodules/remember_me.rb +15 -19
  37. data/lib/sorcery/model/submodules/reset_password.rb +33 -34
  38. data/lib/sorcery/model/submodules/user_activation.rb +36 -47
  39. data/lib/sorcery/model/temporary_token.rb +4 -4
  40. data/lib/sorcery/model.rb +73 -173
  41. data/lib/sorcery/protocols/oauth.rb +42 -0
  42. data/lib/sorcery/protocols/oauth2.rb +47 -0
  43. data/lib/sorcery/providers/base.rb +38 -0
  44. data/lib/sorcery/providers/facebook.rb +63 -0
  45. data/lib/sorcery/providers/github.rb +51 -0
  46. data/lib/sorcery/providers/google.rb +51 -0
  47. data/lib/sorcery/providers/heroku.rb +57 -0
  48. data/lib/sorcery/providers/jira.rb +77 -0
  49. data/lib/sorcery/providers/linkedin.rb +66 -0
  50. data/lib/sorcery/providers/liveid.rb +53 -0
  51. data/lib/sorcery/providers/salesforce.rb +50 -0
  52. data/lib/sorcery/providers/twitter.rb +59 -0
  53. data/lib/sorcery/providers/vk.rb +63 -0
  54. data/lib/sorcery/providers/xing.rb +64 -0
  55. data/lib/sorcery/test_helpers/internal/rails.rb +14 -3
  56. data/lib/sorcery/test_helpers/internal.rb +7 -3
  57. data/lib/sorcery/test_helpers/rails/controller.rb +21 -0
  58. data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
  59. data/lib/sorcery/version.rb +3 -0
  60. data/lib/sorcery.rb +82 -58
  61. data/sorcery.gemspec +19 -19
  62. data/spec/active_record/user_activation_spec.rb +1 -1
  63. data/spec/active_record/user_activity_logging_spec.rb +10 -1
  64. data/spec/active_record/user_brute_force_protection_spec.rb +1 -1
  65. data/spec/active_record/user_oauth_spec.rb +1 -1
  66. data/spec/active_record/user_remember_me_spec.rb +1 -1
  67. data/spec/active_record/user_reset_password_spec.rb +1 -1
  68. data/spec/active_record/user_spec.rb +7 -8
  69. data/spec/controllers/controller_activity_logging_spec.rb +124 -0
  70. data/spec/controllers/controller_brute_force_protection_spec.rb +43 -0
  71. data/spec/controllers/controller_http_basic_auth_spec.rb +68 -0
  72. data/spec/controllers/controller_oauth2_spec.rb +414 -0
  73. data/spec/controllers/controller_oauth_spec.rb +240 -0
  74. data/spec/controllers/controller_remember_me_spec.rb +117 -0
  75. data/spec/controllers/controller_session_timeout_spec.rb +80 -0
  76. data/spec/controllers/controller_spec.rb +218 -0
  77. data/spec/data_mapper/user_activation_spec.rb +10 -0
  78. data/spec/data_mapper/user_activity_logging_spec.rb +14 -0
  79. data/spec/data_mapper/user_brute_force_protection_spec.rb +9 -0
  80. data/spec/data_mapper/user_oauth_spec.rb +9 -0
  81. data/spec/data_mapper/user_remember_me_spec.rb +8 -0
  82. data/spec/data_mapper/user_reset_password_spec.rb +8 -0
  83. data/spec/data_mapper/user_spec.rb +27 -0
  84. data/spec/mongo_mapper/user_activation_spec.rb +1 -2
  85. data/spec/mongo_mapper/user_activity_logging_spec.rb +1 -1
  86. data/spec/mongo_mapper/user_brute_force_protection_spec.rb +1 -1
  87. data/spec/mongo_mapper/user_oauth_spec.rb +1 -1
  88. data/spec/mongo_mapper/user_remember_me_spec.rb +1 -1
  89. data/spec/mongo_mapper/user_reset_password_spec.rb +1 -1
  90. data/spec/mongo_mapper/user_spec.rb +7 -8
  91. data/spec/mongoid/user_activation_spec.rb +1 -2
  92. data/spec/mongoid/user_activity_logging_spec.rb +1 -2
  93. data/spec/mongoid/user_brute_force_protection_spec.rb +1 -2
  94. data/spec/mongoid/user_oauth_spec.rb +1 -2
  95. data/spec/mongoid/user_remember_me_spec.rb +1 -2
  96. data/spec/mongoid/user_reset_password_spec.rb +1 -2
  97. data/spec/mongoid/user_spec.rb +21 -9
  98. data/spec/orm/active_record.rb +14 -0
  99. data/spec/orm/data_mapper.rb +48 -0
  100. data/spec/orm/mongo_mapper.rb +1 -1
  101. data/spec/orm/mongoid.rb +5 -0
  102. data/spec/rails_app/app/controllers/sorcery_controller.rb +125 -59
  103. data/spec/rails_app/app/data_mapper/authentication.rb +8 -0
  104. data/spec/rails_app/app/data_mapper/user.rb +7 -0
  105. data/spec/rails_app/app/mongo_mapper/user.rb +2 -0
  106. data/spec/rails_app/config/routes.rb +27 -13
  107. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +2 -2
  108. data/spec/shared_examples/user_activation_shared_examples.rb +108 -91
  109. data/spec/shared_examples/user_activity_logging_shared_examples.rb +83 -15
  110. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +140 -21
  111. data/spec/shared_examples/user_oauth_shared_examples.rb +21 -16
  112. data/spec/shared_examples/user_remember_me_shared_examples.rb +36 -24
  113. data/spec/shared_examples/user_reset_password_shared_examples.rb +138 -117
  114. data/spec/shared_examples/user_shared_examples.rb +297 -150
  115. data/spec/sorcery_crypto_providers_spec.rb +28 -28
  116. data/spec/spec_helper.rb +12 -18
  117. metadata +99 -165
  118. data/Gemfile.rails4 +0 -24
  119. data/VERSION +0 -1
  120. data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +0 -46
  121. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +0 -50
  122. data/lib/sorcery/controller/submodules/external/providers/base.rb +0 -21
  123. data/lib/sorcery/controller/submodules/external/providers/facebook.rb +0 -99
  124. data/lib/sorcery/controller/submodules/external/providers/github.rb +0 -93
  125. data/lib/sorcery/controller/submodules/external/providers/google.rb +0 -92
  126. data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +0 -103
  127. data/lib/sorcery/controller/submodules/external/providers/liveid.rb +0 -93
  128. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +0 -94
  129. data/lib/sorcery/controller/submodules/external/providers/vk.rb +0 -101
  130. data/lib/sorcery/controller/submodules/external/providers/xing.rb +0 -98
  131. data/lib/sorcery/model/adapters/active_record.rb +0 -49
  132. data/lib/sorcery/model/adapters/mongo_mapper.rb +0 -56
  133. data/lib/sorcery/model/adapters/mongoid.rb +0 -88
  134. data/lib/sorcery/test_helpers/rails.rb +0 -16
  135. data/lib/sorcery/test_helpers.rb +0 -5
  136. data/spec/active_record/controller_activity_logging_spec.rb +0 -140
  137. data/spec/active_record/controller_brute_force_protection_spec.rb +0 -136
  138. data/spec/active_record/controller_http_basic_auth_spec.rb +0 -59
  139. data/spec/active_record/controller_oauth2_spec.rb +0 -417
  140. data/spec/active_record/controller_oauth_spec.rb +0 -212
  141. data/spec/active_record/controller_remember_me_spec.rb +0 -96
  142. data/spec/active_record/controller_session_timeout_spec.rb +0 -55
  143. data/spec/active_record/controller_spec.rb +0 -182
  144. data/spec/active_record/integration_spec.rb +0 -23
  145. data/spec/mongo_mapper/controller_spec.rb +0 -175
  146. data/spec/mongoid/controller_activity_logging_spec.rb +0 -111
  147. data/spec/mongoid/controller_spec.rb +0 -186
  148. data/spec/rails_app/public/404.html +0 -26
  149. data/spec/rails_app/public/422.html +0 -26
  150. data/spec/rails_app/public/500.html +0 -26
  151. data/spec/rails_app/public/favicon.ico +0 -0
  152. data/spec/rails_app/public/images/rails.png +0 -0
  153. data/spec/rails_app/public/javascripts/application.js +0 -2
  154. data/spec/rails_app/public/javascripts/controls.js +0 -965
  155. data/spec/rails_app/public/javascripts/dragdrop.js +0 -974
  156. data/spec/rails_app/public/javascripts/effects.js +0 -1123
  157. data/spec/rails_app/public/javascripts/prototype.js +0 -6001
  158. data/spec/rails_app/public/javascripts/rails.js +0 -175
  159. data/spec/rails_app/public/robots.txt +0 -5
  160. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  161. data/spec/shared_examples/controller_oauth2_shared_examples.rb +0 -56
  162. data/spec/shared_examples/controller_oauth_shared_examples.rb +0 -69
  163. /data/lib/sorcery/{controller/submodules/external/protocols → protocols}/certs/ca-bundle.crt +0 -0
@@ -0,0 +1,63 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with facebook.com.
4
+ #
5
+ # config.facebook.key = <key>
6
+ # config.facebook.secret = <secret>
7
+ # ...
8
+ #
9
+ class Facebook < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_reader :mode, :param_name, :parse
14
+ attr_accessor :access_permissions, :display, :scope, :token_url,
15
+ :user_info_path
16
+
17
+ def initialize
18
+ super
19
+
20
+ @site = 'https://graph.facebook.com'
21
+ @user_info_path = '/me'
22
+ @scope = 'email,offline_access'
23
+ @display = 'page'
24
+ @token_url = 'oauth/access_token'
25
+ @mode = :query
26
+ @parse = :query
27
+ @param_name = 'access_token'
28
+ end
29
+
30
+ def get_user_hash(access_token)
31
+ response = access_token.get(user_info_path)
32
+
33
+ auth_hash(access_token).tap do |h|
34
+ h[:user_info] = JSON.parse(response.body)
35
+ h[:uid] = h[:user_info]['id']
36
+ end
37
+ end
38
+
39
+ # calculates and returns the url to which the user should be redirected,
40
+ # to get authenticated at the external provider's site.
41
+ def login_url(params, session)
42
+ authorize_url
43
+ end
44
+
45
+ # overrides oauth2#authorize_url to allow customized scope.
46
+ def authorize_url
47
+ @scope = access_permissions.present? ? access_permissions.join(',') : scope
48
+ super
49
+ end
50
+
51
+ # tries to login the user from access token
52
+ def process_callback(params, session)
53
+ args = {}.tap do |a|
54
+ a[:code] = params[:code] if params[:code]
55
+ end
56
+
57
+ get_access_token(args, token_url: token_url, mode: mode,
58
+ param_name: param_name, parse: parse)
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with github.com.
4
+ #
5
+ # config.github.key = <key>
6
+ # config.github.secret = <secret>
7
+ # ...
8
+ #
9
+ class Github < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_path, :scope, :token_url, :user_info_path
14
+
15
+ def initialize
16
+ super
17
+
18
+ @scope = nil
19
+ @site = 'https://github.com/'
20
+ @user_info_path = 'https://api.github.com/user'
21
+ @auth_path = '/login/oauth/authorize'
22
+ @token_url = '/login/oauth/access_token'
23
+ end
24
+
25
+ def get_user_hash(access_token)
26
+ response = access_token.get(user_info_path)
27
+
28
+ auth_hash(access_token).tap do |h|
29
+ h[:user_info] = JSON.parse(response.body)
30
+ h[:uid] = h[:user_info]['id']
31
+ end
32
+ end
33
+
34
+ # calculates and returns the url to which the user should be redirected,
35
+ # to get authenticated at the external provider's site.
36
+ def login_url(params, session)
37
+ authorize_url({ authorize_url: auth_path })
38
+ end
39
+
40
+ # tries to login the user from access token
41
+ def process_callback(params, session)
42
+ args = {}.tap do |a|
43
+ a[:code] = params[:code] if params[:code]
44
+ end
45
+
46
+ get_access_token(args, token_url: token_url, token_method: :post)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with google.com.
4
+ #
5
+ # config.google.key = <key>
6
+ # config.google.secret = <secret>
7
+ # ...
8
+ #
9
+ class Google < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_url, :scope, :token_url, :user_info_url
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://accounts.google.com'
19
+ @auth_url = '/o/oauth2/auth'
20
+ @token_url = '/o/oauth2/token'
21
+ @user_info_url = 'https://www.googleapis.com/oauth2/v1/userinfo'
22
+ @scope = 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
23
+ end
24
+
25
+ def get_user_hash(access_token)
26
+ response = access_token.get(user_info_url)
27
+
28
+ auth_hash(access_token).tap do |h|
29
+ h[:user_info] = JSON.parse(response.body)
30
+ h[:uid] = h[:user_info]['id']
31
+ end
32
+ end
33
+
34
+ # calculates and returns the url to which the user should be redirected,
35
+ # to get authenticated at the external provider's site.
36
+ def login_url(params, session)
37
+ authorize_url({ authorize_url: auth_url })
38
+ end
39
+
40
+ # tries to login the user from access token
41
+ def process_callback(params, session)
42
+ args = {}.tap do |a|
43
+ a[:code] = params[:code] if params[:code]
44
+ end
45
+
46
+ get_access_token(args, token_url: token_url, token_method: :post)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,57 @@
1
+ module Sorcery
2
+ module Providers
3
+
4
+ # This class adds support for OAuth with heroku.com.
5
+
6
+ # config.heroku.key = <key>
7
+ # config.heroku.secret = <secret>
8
+ # config.heroku.callback_url = "<host>/oauth/callback?provider=heroku"
9
+ # config.heroku.scope = "read"
10
+ # config.heroku.user_info_mapping = {:email => "email", :name => "email" }
11
+
12
+ # NOTE:
13
+ # The full path must be set for OAuth Callback URL when configuring the API Client Information on Heroku.
14
+
15
+ class Heroku < Base
16
+
17
+ include Protocols::Oauth2
18
+
19
+ attr_accessor :auth_path, :scope, :token_url, :user_info_path
20
+
21
+ def initialize
22
+ super
23
+
24
+ @scope = nil
25
+ @site = 'https://id.heroku.com'
26
+ @user_info_path = 'https://api.heroku.com/account'
27
+ @auth_path = '/oauth/authorize'
28
+ @token_url = '/oauth/token'
29
+ @user_info_path = '/account'
30
+ @state = SecureRandom.hex(16)
31
+ end
32
+
33
+ def get_user_hash(access_token)
34
+ response = access_token.get(user_info_path)
35
+ body = JSON.parse(response.body)
36
+ auth_hash(access_token).tap do |h|
37
+ h[:user_info] = body
38
+ h[:uid] = body['id'].to_s
39
+ h[:email] = body['email'].to_s
40
+ end
41
+ end
42
+
43
+ def login_url(params, session)
44
+ authorize_url({ authorize_url: auth_path })
45
+ end
46
+
47
+ # tries to login the user from access token
48
+ def process_callback(params, session)
49
+ raise "Invalid state. Potential Cross Site Forgery" if params[:state] != state
50
+ args = { }.tap do |a|
51
+ a[:code] = params[:code] if params[:code]
52
+ end
53
+ get_access_token(args, token_url: token_url, token_method: :post)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,77 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with Jira
4
+ #
5
+ # config.jira.key = <key>
6
+ # config.jira.secret = <secret>
7
+ # ...
8
+ #
9
+ class Jira < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :access_token_path, :authorize_path, :request_token_path,
14
+ :user_info_path, :site, :signature_method, :private_key_file, :callback_url
15
+
16
+
17
+ def initialize
18
+ @configuration = {
19
+ authorize_path: '/authorize',
20
+ request_token_path: '/request-token',
21
+ access_token_path: '/access-token'
22
+ }
23
+ @user_info_path = '/users/me'
24
+ end
25
+
26
+ # Override included get_consumer method to provide authorize_path
27
+ #read extra configurations
28
+ def get_consumer
29
+ @configuration = @configuration.merge({
30
+ site: site,
31
+ signature_method: signature_method,
32
+ consumer_key: key,
33
+ private_key_file: private_key_file
34
+ })
35
+ ::OAuth::Consumer.new(@key, @secret, @configuration)
36
+ end
37
+
38
+ def get_user_hash(access_token)
39
+ response = access_token.get(user_info_path)
40
+
41
+ auth_hash(access_token).tap do |h|
42
+ h[:user_info] = JSON.parse(response.body)['users'].first
43
+ h[:uid] = user_hash[:user_info]['id'].to_s
44
+ end
45
+ end
46
+
47
+ # calculates and returns the url to which the user should be redirected,
48
+ # to get authenticated at the external provider's site.
49
+ def login_url(params, session)
50
+ req_token = get_request_token
51
+ session[:request_token] = req_token.token
52
+ session[:request_token_secret] = req_token.secret
53
+
54
+ #it was like that -> redirect_to authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
55
+ #for some reason Jira does not need these parameters
56
+
57
+ get_request_token(
58
+ session[:request_token],
59
+ session[:request_token_secret]
60
+ ).authorize_url
61
+ end
62
+
63
+ # tries to login the user from access token
64
+ def process_callback(params, session)
65
+ args = {
66
+ oauth_verifier: params[:oauth_verifier],
67
+ request_token: session[:request_token],
68
+ request_token_secret: session[:request_token_secret]
69
+ }
70
+
71
+ args.merge!({ code: params[:code] }) if params[:code]
72
+ get_access_token(args)
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,66 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with Linkedin.com.
4
+ #
5
+ # config.linkedin.key = <key>
6
+ # config.linkedin.secret = <secret>
7
+ # ...
8
+ #
9
+ class Linkedin < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :authorize_path, :access_permissions, :access_token_path,
14
+ :request_token_path, :user_info_fields, :user_info_path
15
+
16
+ def initialize
17
+ @configuration = {
18
+ site: 'https://api.linkedin.com',
19
+ authorize_path: '/uas/oauth/authenticate',
20
+ request_token_path: '/uas/oauth/requestToken',
21
+ access_token_path: '/uas/oauth/accessToken'
22
+ }
23
+ @user_info_path = '/v1/people/~'
24
+ end
25
+
26
+ # Override included get_consumer method to provide authorize_path
27
+ def get_consumer
28
+ # Add access permissions to request token path
29
+ @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? or @configuration[:request_token_path].include? '?scope='
30
+ ::OAuth::Consumer.new(@key, @secret, @configuration)
31
+ end
32
+
33
+ def get_user_hash(access_token)
34
+ fields = self.user_info_fields.join(',')
35
+ response = access_token.get("#{@user_info_path}:(#{fields})", 'x-li-format' => 'json')
36
+
37
+ auth_hash(access_token).tap do |h|
38
+ h[:user_info] = JSON.parse(response.body)
39
+ h[:uid] = h[:user_info]['id'].to_s
40
+ end
41
+ end
42
+
43
+ # calculates and returns the url to which the user should be redirected,
44
+ # to get authenticated at the external provider's site.
45
+ def login_url(params, session)
46
+ req_token = get_request_token
47
+ session[:request_token] = req_token.token
48
+ session[:request_token_secret] = req_token.secret
49
+ authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
50
+ end
51
+
52
+ # tries to login the user from access token
53
+ def process_callback(params, session)
54
+ args = {
55
+ oauth_verifier: params[:oauth_verifier],
56
+ request_token: session[:request_token],
57
+ request_token_secret: session[:request_token_secret]
58
+ }
59
+
60
+ args.merge!({ code: params[:code] }) if params[:code]
61
+ get_access_token(args)
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,53 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with microsoft liveid.
4
+ #
5
+ # config.liveid.key = <key>
6
+ # config.liveid.secret = <secret>
7
+ # ...
8
+ #
9
+ class Liveid < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_url, :token_path, :user_info_url, :scope
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://oauth.live.com/'
19
+ @auth_url = '/authorize'
20
+ @token_path = '/token'
21
+ @user_info_url = 'https://apis.live.net/v5.0/me'
22
+ @scope = 'wl.basic wl.emails wl.offline_access'
23
+ end
24
+
25
+ def get_user_hash(access_token)
26
+ access_token.token_param = 'access_token'
27
+ response = access_token.get(user_info_url)
28
+
29
+ auth_hash(access_token).tap do |h|
30
+ h[:user_info] = JSON.parse(response.body)
31
+ h[:uid] = h[:user_info]['id']
32
+ end
33
+ end
34
+
35
+ # calculates and returns the url to which the user should be redirected,
36
+ # to get authenticated at the external provider's site.
37
+ def login_url(params, session)
38
+ self.authorize_url({ authorize_url: auth_url })
39
+ end
40
+
41
+ # tries to login the user from access token
42
+ def process_callback(params, session)
43
+ args = {}.tap do |a|
44
+ a[:code] = params[:code] if params[:code]
45
+ end
46
+
47
+ get_access_token(args, access_token_path: token_path,
48
+ access_token_method: :post)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with salesforce.com.
4
+ #
5
+ # config.salesforce.key = <key>
6
+ # config.salesforce.secret = <secret>
7
+ # ...
8
+ #
9
+ class Salesforce < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_url, :token_url, :scope
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://login.salesforce.com'
19
+ @auth_url = '/services/oauth2/authorize'
20
+ @token_url = '/services/oauth2/token'
21
+ end
22
+
23
+ def get_user_hash(access_token)
24
+ user_info_url = access_token.params['id']
25
+ response = access_token.get(user_info_url)
26
+
27
+ auth_hash(access_token).tap do |h|
28
+ h[:user_info] = JSON.parse(response.body)
29
+ h[:uid] = h[:user_info]['user_id']
30
+ end
31
+ end
32
+
33
+ # calculates and returns the url to which the user should be redirected,
34
+ # to get authenticated at the external provider's site.
35
+ def login_url(params, session)
36
+ authorize_url({ authorize_url: auth_url })
37
+ end
38
+
39
+ # tries to login the user from access token
40
+ def process_callback(params, session)
41
+ args = {}.tap do |a|
42
+ a[:code] = params[:code] if params[:code]
43
+ end
44
+
45
+ get_access_token(args, token_url: token_url, token_method: :post)
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,59 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with Twitter.com.
4
+ #
5
+ # config.twitter.key = <key>
6
+ # config.twitter.secret = <secret>
7
+ # ...
8
+ #
9
+ class Twitter < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :state, :user_info_path
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://api.twitter.com'
19
+ @user_info_path = '/1.1/account/verify_credentials.json'
20
+ end
21
+
22
+ # Override included get_consumer method to provide authorize_path
23
+ def get_consumer
24
+ ::OAuth::Consumer.new(@key, secret, site: site, authorize_path: '/oauth/authenticate')
25
+ end
26
+
27
+ def get_user_hash(access_token)
28
+ response = access_token.get(user_info_path)
29
+
30
+ auth_hash(access_token).tap do |h|
31
+ h[:user_info] = JSON.parse(response.body)
32
+ h[:uid] = h[:user_info]['id'].to_s
33
+ end
34
+ end
35
+
36
+ # calculates and returns the url to which the user should be redirected,
37
+ # to get authenticated at the external provider's site.
38
+ def login_url(params, session)
39
+ req_token = self.get_request_token
40
+ session[:request_token] = req_token.token
41
+ session[:request_token_secret] = req_token.secret
42
+ self.authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
43
+ end
44
+
45
+ # tries to login the user from access token
46
+ def process_callback(params, session)
47
+ args = {
48
+ oauth_verifier: params[:oauth_verifier],
49
+ request_token: session[:request_token],
50
+ request_token_secret: session[:request_token_secret]
51
+ }
52
+
53
+ args.merge!({ code: params[:code] }) if params[:code]
54
+ get_access_token(args)
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with vk.com.
4
+ #
5
+ # config.vk.key = <key>
6
+ # config.vk.secret = <secret>
7
+ # ...
8
+ #
9
+ class Vk < Base
10
+
11
+ include Protocols::Oauth2
12
+
13
+ attr_accessor :auth_path, :token_path, :user_info_url, :scope
14
+
15
+ def initialize
16
+ super
17
+
18
+ @site = 'https://oauth.vk.com/'
19
+ @user_info_url = 'https://api.vk.com/method/getProfiles'
20
+ @auth_path = '/authorize'
21
+ @token_path = '/access_token'
22
+ @scope = 'email'
23
+ end
24
+
25
+ def get_user_hash(access_token)
26
+ user_hash = auth_hash(access_token)
27
+
28
+ params = {
29
+ access_token: access_token.token,
30
+ uids: access_token.params['user_id'],
31
+ fields: user_info_mapping.values.join(','),
32
+ scope: scope
33
+ }
34
+
35
+ response = access_token.get(user_info_url, params: params)
36
+ if user_hash[:user_info] = JSON.parse(response.body)
37
+ user_hash[:user_info] = user_hash[:user_info]['response'][0]
38
+ user_hash[:user_info]['full_name'] = [user_hash[:user_info]['first_name'], user_hash[:user_info]['last_name']].join(' ')
39
+
40
+ user_hash[:uid] = user_hash[:user_info]['uid']
41
+ user_hash[:user_info]['email'] = access_token.params['email']
42
+ end
43
+ user_hash
44
+ end
45
+
46
+ # calculates and returns the url to which the user should be redirected,
47
+ # to get authenticated at the external provider's site.
48
+ def login_url(params, session)
49
+ self.authorize_url({ authorize_url: auth_path })
50
+ end
51
+
52
+ # tries to login the user from access token
53
+ def process_callback(params, session)
54
+ args = {}.tap do |a|
55
+ a[:code] = params[:code] if params[:code]
56
+ end
57
+
58
+ get_access_token(args, token_url: token_path, token_method: :post)
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,64 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with xing.com.
4
+ #
5
+ # config.xing.key = <key>
6
+ # config.xing.secret = <secret>
7
+ # ...
8
+ #
9
+ class Xing < Base
10
+
11
+ include Protocols::Oauth
12
+
13
+ attr_accessor :access_token_path, :authorize_path, :request_token_path,
14
+ :user_info_path
15
+
16
+
17
+ def initialize
18
+ @configuration = {
19
+ site: 'https://api.xing.com/v1',
20
+ authorize_path: '/authorize',
21
+ request_token_path: '/request_token',
22
+ access_token_path: '/access_token'
23
+ }
24
+ @user_info_path = '/users/me'
25
+ end
26
+
27
+ # Override included get_consumer method to provide authorize_path
28
+ def get_consumer
29
+ ::OAuth::Consumer.new(@key, @secret, @configuration)
30
+ end
31
+
32
+ def get_user_hash(access_token)
33
+ response = access_token.get(user_info_path)
34
+
35
+ auth_hash(access_token).tap do |h|
36
+ h[:user_info] = JSON.parse(response.body)['users'].first
37
+ h[:uid] = user_hash[:user_info]['id'].to_s
38
+ end
39
+ end
40
+
41
+ # calculates and returns the url to which the user should be redirected,
42
+ # to get authenticated at the external provider's site.
43
+ def login_url(params, session)
44
+ req_token = get_request_token
45
+ session[:request_token] = req_token.token
46
+ session[:request_token_secret] = req_token.secret
47
+ authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
48
+ end
49
+
50
+ # tries to login the user from access token
51
+ def process_callback(params, session)
52
+ args = {
53
+ oauth_verifier: params[:oauth_verifier],
54
+ request_token: session[:request_token],
55
+ request_token_secret: session[:request_token_secret]
56
+ }
57
+
58
+ args.merge!({ code: params[:code] }) if params[:code]
59
+ get_access_token(args)
60
+ end
61
+
62
+ end
63
+ end
64
+ end