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.
Files changed (205) hide show
  1. data/.travis.yml +2 -0
  2. data/Gemfile +2 -23
  3. data/Gemfile.lock +105 -77
  4. data/README.rdoc +32 -59
  5. data/Rakefile +29 -1
  6. data/VERSION +1 -1
  7. data/lib/generators/sorcery/USAGE +22 -0
  8. data/lib/generators/sorcery/install_generator.rb +77 -0
  9. data/lib/generators/sorcery/templates/initializer.rb +406 -0
  10. data/lib/generators/sorcery/templates/migration/activity_logging.rb +17 -0
  11. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +13 -0
  12. data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/core.rb +3 -3
  13. data/lib/generators/{sorcery_migration/templates → sorcery/templates/migration}/external.rb +1 -1
  14. data/lib/generators/sorcery/templates/migration/remember_me.rb +15 -0
  15. data/lib/generators/sorcery/templates/migration/reset_password.rb +17 -0
  16. data/lib/generators/sorcery/templates/migration/user_activation.rb +17 -0
  17. data/lib/sorcery/controller/submodules/activity_logging.rb +24 -10
  18. data/lib/sorcery/controller/submodules/brute_force_protection.rb +3 -2
  19. data/lib/sorcery/controller/submodules/external/protocols/certs/ca-bundle.crt +5182 -0
  20. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +28 -9
  21. data/lib/sorcery/controller/submodules/external/providers/facebook.rb +12 -4
  22. data/lib/sorcery/controller/submodules/external/providers/github.rb +89 -0
  23. data/lib/sorcery/controller/submodules/external/providers/google.rb +90 -0
  24. data/lib/sorcery/controller/submodules/external/providers/liveid.rb +91 -0
  25. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +8 -2
  26. data/lib/sorcery/controller/submodules/external.rb +17 -4
  27. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  28. data/lib/sorcery/controller/submodules/remember_me.rb +26 -15
  29. data/lib/sorcery/controller/submodules/session_timeout.rb +4 -4
  30. data/lib/sorcery/controller.rb +61 -38
  31. data/lib/sorcery/crypto_providers/aes256.rb +7 -3
  32. data/lib/sorcery/engine.rb +1 -0
  33. data/lib/sorcery/model/adapters/active_record.rb +17 -1
  34. data/lib/sorcery/model/adapters/mongo_mapper.rb +54 -0
  35. data/lib/sorcery/model/adapters/mongoid.rb +22 -4
  36. data/lib/sorcery/model/submodules/activity_logging.rb +4 -4
  37. data/lib/sorcery/model/submodules/brute_force_protection.rb +53 -14
  38. data/lib/sorcery/model/submodules/remember_me.rb +10 -3
  39. data/lib/sorcery/model/submodules/reset_password.rb +26 -11
  40. data/lib/sorcery/model/submodules/user_activation.rb +28 -10
  41. data/lib/sorcery/model/temporary_token.rb +8 -1
  42. data/lib/sorcery/model.rb +51 -19
  43. data/lib/sorcery/test_helpers/internal/rails.rb +1 -1
  44. data/lib/sorcery/test_helpers/rails.rb +2 -2
  45. data/lib/sorcery.rb +8 -7
  46. data/sorcery.gemspec +110 -223
  47. data/spec/Gemfile +1 -1
  48. data/spec/Gemfile.lock +26 -26
  49. data/spec/README.md +31 -0
  50. data/spec/rails3/Gemfile +5 -3
  51. data/spec/rails3/Gemfile.lock +74 -48
  52. data/spec/rails3/app/controllers/application_controller.rb +70 -23
  53. data/spec/rails3/app/mailers/sorcery_mailer.rb +7 -0
  54. data/spec/rails3/app/views/application/index.html.erb +17 -0
  55. data/spec/rails3/app/views/sorcery_mailer/send_unlock_token_email.text.erb +1 -0
  56. data/spec/rails3/config/environments/in_memory.rb +35 -0
  57. data/spec/rails3/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +2 -0
  58. data/spec/rails3/spec/controller_activity_logging_spec.rb +33 -3
  59. data/spec/rails3/spec/controller_brute_force_protection_spec.rb +25 -3
  60. data/spec/rails3/spec/controller_oauth2_spec.rb +170 -25
  61. data/spec/rails3/spec/controller_remember_me_spec.rb +37 -6
  62. data/spec/rails3/spec/controller_session_timeout_spec.rb +4 -4
  63. data/spec/rails3/spec/controller_spec.rb +60 -2
  64. data/spec/rails3/spec/integration_spec.rb +23 -0
  65. data/spec/rails3/spec/spec_helper.rb +6 -5
  66. data/spec/rails3_mongo_mapper/.gitignore +4 -0
  67. data/spec/rails3_mongo_mapper/.rspec +1 -0
  68. data/spec/{sinatra_modular → rails3_mongo_mapper}/Gemfile +6 -5
  69. data/spec/rails3_mongo_mapper/Gemfile.lock +154 -0
  70. data/spec/{sinatra → rails3_mongo_mapper}/Rakefile +3 -3
  71. data/spec/rails3_mongo_mapper/app/controllers/application_controller.rb +108 -0
  72. data/spec/rails3_mongo_mapper/app/helpers/application_helper.rb +2 -0
  73. data/spec/rails3_mongo_mapper/app/models/authentication.rb +6 -0
  74. data/spec/rails3_mongo_mapper/app/models/user.rb +5 -0
  75. data/spec/rails3_mongo_mapper/app/views/layouts/application.html.erb +14 -0
  76. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  77. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  78. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  79. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  80. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  81. data/spec/rails3_mongo_mapper/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  82. data/spec/rails3_mongo_mapper/config/application.rb +51 -0
  83. data/spec/rails3_mongo_mapper/config/boot.rb +13 -0
  84. data/spec/rails3_mongo_mapper/config/environment.rb +5 -0
  85. data/spec/rails3_mongo_mapper/config/environments/development.rb +30 -0
  86. data/spec/rails3_mongo_mapper/config/environments/in_memory.rb +0 -0
  87. data/spec/rails3_mongo_mapper/config/environments/production.rb +49 -0
  88. data/spec/rails3_mongo_mapper/config/environments/test.rb +35 -0
  89. data/spec/rails3_mongo_mapper/config/initializers/backtrace_silencers.rb +7 -0
  90. data/spec/rails3_mongo_mapper/config/initializers/inflections.rb +10 -0
  91. data/spec/rails3_mongo_mapper/config/initializers/mime_types.rb +5 -0
  92. data/spec/rails3_mongo_mapper/config/initializers/mongo.rb +2 -0
  93. data/spec/rails3_mongo_mapper/config/initializers/secret_token.rb +7 -0
  94. data/spec/rails3_mongo_mapper/config/initializers/session_store.rb +8 -0
  95. data/spec/rails3_mongo_mapper/config/locales/en.yml +5 -0
  96. data/spec/rails3_mongo_mapper/config/routes.rb +59 -0
  97. data/spec/rails3_mongo_mapper/config.ru +4 -0
  98. data/spec/rails3_mongo_mapper/db/schema.rb +23 -0
  99. data/spec/rails3_mongo_mapper/db/seeds.rb +7 -0
  100. data/spec/rails3_mongo_mapper/lib/tasks/.gitkeep +0 -0
  101. data/spec/rails3_mongo_mapper/public/404.html +26 -0
  102. data/spec/rails3_mongo_mapper/public/422.html +26 -0
  103. data/spec/rails3_mongo_mapper/public/500.html +26 -0
  104. data/spec/rails3_mongo_mapper/public/favicon.ico +0 -0
  105. data/spec/rails3_mongo_mapper/public/images/rails.png +0 -0
  106. data/spec/rails3_mongo_mapper/public/javascripts/application.js +2 -0
  107. data/spec/rails3_mongo_mapper/public/javascripts/controls.js +965 -0
  108. data/spec/rails3_mongo_mapper/public/javascripts/dragdrop.js +974 -0
  109. data/spec/rails3_mongo_mapper/public/javascripts/effects.js +1123 -0
  110. data/spec/rails3_mongo_mapper/public/javascripts/prototype.js +6001 -0
  111. data/spec/rails3_mongo_mapper/public/javascripts/rails.js +175 -0
  112. data/spec/rails3_mongo_mapper/public/robots.txt +5 -0
  113. data/spec/rails3_mongo_mapper/public/stylesheets/.gitkeep +0 -0
  114. data/spec/rails3_mongo_mapper/script/rails +6 -0
  115. data/spec/rails3_mongo_mapper/spec/controller_spec.rb +163 -0
  116. data/spec/rails3_mongo_mapper/spec/spec_helper.orig.rb +27 -0
  117. data/spec/rails3_mongo_mapper/spec/spec_helper.rb +55 -0
  118. data/spec/rails3_mongo_mapper/spec/user_activation_spec.rb +9 -0
  119. data/spec/rails3_mongo_mapper/spec/user_activity_logging_spec.rb +8 -0
  120. data/spec/rails3_mongo_mapper/spec/user_brute_force_protection_spec.rb +8 -0
  121. data/spec/rails3_mongo_mapper/spec/user_oauth_spec.rb +8 -0
  122. data/spec/rails3_mongo_mapper/spec/user_remember_me_spec.rb +8 -0
  123. data/spec/rails3_mongo_mapper/spec/user_reset_password_spec.rb +8 -0
  124. data/spec/rails3_mongo_mapper/spec/user_spec.rb +37 -0
  125. data/spec/rails3_mongo_mapper/vendor/plugins/.gitkeep +0 -0
  126. data/spec/rails3_mongoid/Gemfile +2 -1
  127. data/spec/rails3_mongoid/Gemfile.lock +46 -45
  128. data/spec/rails3_mongoid/app/controllers/application_controller.rb +5 -0
  129. data/spec/rails3_mongoid/config/mongoid.yml +1 -1
  130. data/spec/rails3_mongoid/script/rails +0 -0
  131. data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +105 -0
  132. data/spec/rails3_mongoid/spec/controller_spec.rb +174 -0
  133. data/spec/rails3_mongoid/spec/user_spec.rb +1 -0
  134. data/spec/shared_examples/user_activation_shared_examples.rb +72 -42
  135. data/spec/shared_examples/user_remember_me_shared_examples.rb +2 -1
  136. data/spec/shared_examples/user_reset_password_shared_examples.rb +81 -28
  137. data/spec/shared_examples/user_shared_examples.rb +36 -8
  138. data/spec/sorcery_crypto_providers_spec.rb +5 -1
  139. metadata +239 -346
  140. data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +0 -24
  141. data/lib/generators/sorcery_migration/templates/activity_logging.rb +0 -17
  142. data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +0 -11
  143. data/lib/generators/sorcery_migration/templates/remember_me.rb +0 -15
  144. data/lib/generators/sorcery_migration/templates/reset_password.rb +0 -13
  145. data/lib/generators/sorcery_migration/templates/user_activation.rb +0 -17
  146. data/lib/sorcery/controller/adapters/sinatra.rb +0 -104
  147. data/lib/sorcery/initializers/initializer.rb +0 -178
  148. data/lib/sorcery/sinatra.rb +0 -4
  149. data/lib/sorcery/test_helpers/internal/sinatra.rb +0 -74
  150. data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +0 -74
  151. data/lib/sorcery/test_helpers/sinatra.rb +0 -88
  152. data/spec/rails3/Rakefile.unused +0 -7
  153. data/spec/rails3/public/index.html +0 -239
  154. data/spec/sinatra/Gemfile +0 -15
  155. data/spec/sinatra/Gemfile.lock +0 -117
  156. data/spec/sinatra/authentication.rb +0 -3
  157. data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
  158. data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
  159. data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
  160. data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +0 -16
  161. data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +0 -14
  162. data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
  163. data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
  164. data/spec/sinatra/filters.rb +0 -27
  165. data/spec/sinatra/modular.rb +0 -157
  166. data/spec/sinatra/myapp.rb +0 -133
  167. data/spec/sinatra/spec/controller_activity_logging_spec.rb +0 -85
  168. data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +0 -70
  169. data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +0 -53
  170. data/spec/sinatra/spec/controller_oauth2_spec.rb +0 -99
  171. data/spec/sinatra/spec/controller_oauth_spec.rb +0 -100
  172. data/spec/sinatra/spec/controller_remember_me_spec.rb +0 -64
  173. data/spec/sinatra/spec/controller_session_timeout_spec.rb +0 -57
  174. data/spec/sinatra/spec/controller_spec.rb +0 -120
  175. data/spec/sinatra/spec/spec_helper.rb +0 -45
  176. data/spec/sinatra/user.rb +0 -6
  177. data/spec/sinatra/views/test_login.erb +0 -4
  178. data/spec/sinatra_modular/Gemfile.lock +0 -117
  179. data/spec/sinatra_modular/Rakefile +0 -11
  180. data/spec/sinatra_modular/authentication.rb +0 -3
  181. data/spec/sinatra_modular/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
  182. data/spec/sinatra_modular/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -17
  183. data/spec/sinatra_modular/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -11
  184. data/spec/sinatra_modular/db/migrate/core/20101224223620_create_users.rb +0 -16
  185. data/spec/sinatra_modular/db/migrate/external/20101224223628_create_authentications.rb +0 -14
  186. data/spec/sinatra_modular/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
  187. data/spec/sinatra_modular/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -13
  188. data/spec/sinatra_modular/filters.rb +0 -27
  189. data/spec/sinatra_modular/modular.rb +0 -157
  190. data/spec/sinatra_modular/myapp.rb +0 -133
  191. data/spec/sinatra_modular/sorcery_mailer.rb +0 -25
  192. data/spec/sinatra_modular/spec_modular/controller_activity_logging_spec.rb +0 -85
  193. data/spec/sinatra_modular/spec_modular/controller_brute_force_protection_spec.rb +0 -70
  194. data/spec/sinatra_modular/spec_modular/controller_http_basic_auth_spec.rb +0 -53
  195. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +0 -99
  196. data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +0 -100
  197. data/spec/sinatra_modular/spec_modular/controller_remember_me_spec.rb +0 -64
  198. data/spec/sinatra_modular/spec_modular/controller_session_timeout_spec.rb +0 -57
  199. data/spec/sinatra_modular/spec_modular/controller_spec.rb +0 -116
  200. data/spec/sinatra_modular/spec_modular/spec.opts +0 -2
  201. data/spec/sinatra_modular/spec_modular/spec_helper.rb +0 -51
  202. data/spec/sinatra_modular/user.rb +0 -6
  203. data/spec/sinatra_modular/views/test_login.erb +0 -4
  204. /data/spec/{sinatra → rails3_mongo_mapper/app/mailers}/sorcery_mailer.rb +0 -0
  205. /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(*args)
13
- client = ::OAuth2::Client.new(@key, @secret, :site => @site)
14
- client.web_server.authorize_url(:redirect_uri => @callback_url, :scope => @scope)
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 = ::OAuth2::Client.new(@key, @secret, :site => @site)
19
- client.web_server.get_access_token(args[:code], :redirect_uri => @callback_url)
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
- login_user(user)
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.create!(attrs)
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
- login_user(@current_user) if @current_user
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[:remember_me_token] = nil
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.utc
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.utc - session_to_use > Config.session_timeout)
40
+ if session_to_use && (Time.now.in_time_zone - session_to_use > Config.session_timeout)
41
41
  reset_session
42
- @current_user = false
42
+ @current_user = nil
43
43
  else
44
- session[:last_action_time] = Time.now.utc
44
+ session[:last_action_time] = Time.now.in_time_zone
45
45
  end
46
46
  end
47
47