sorcery 0.7.4 → 0.7.6

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 (46) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +41 -41
  3. data/README.rdoc +1 -1
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/lib/generators/sorcery/install_generator.rb +6 -3
  7. data/lib/generators/sorcery/templates/initializer.rb +25 -4
  8. data/lib/generators/sorcery/templates/migration/reset_password.rb +1 -1
  9. data/lib/sorcery/controller/submodules/activity_logging.rb +3 -3
  10. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +19 -19
  11. data/lib/sorcery/controller/submodules/external/providers/facebook.rb +5 -2
  12. data/lib/sorcery/controller/submodules/external/providers/github.rb +12 -3
  13. data/lib/sorcery/controller/submodules/external/providers/google.rb +90 -0
  14. data/lib/sorcery/controller/submodules/external/providers/liveid.rb +91 -0
  15. data/lib/sorcery/controller/submodules/external/providers/twitter.rb +2 -1
  16. data/lib/sorcery/controller/submodules/external.rb +6 -0
  17. data/lib/sorcery/model/adapters/active_record.rb +16 -1
  18. data/lib/sorcery/model/adapters/mongo_mapper.rb +6 -1
  19. data/lib/sorcery/model/adapters/mongoid.rb +12 -1
  20. data/lib/sorcery/model/submodules/activity_logging.rb +4 -4
  21. data/lib/sorcery/model/submodules/brute_force_protection.rb +5 -5
  22. data/lib/sorcery/model/submodules/reset_password.rb +4 -5
  23. data/lib/sorcery/model/submodules/user_activation.rb +1 -2
  24. data/lib/sorcery/model.rb +17 -4
  25. data/lib/sorcery.rb +2 -0
  26. data/sorcery.gemspec +131 -9
  27. data/spec/Gemfile +1 -1
  28. data/spec/Gemfile.lock +14 -14
  29. data/spec/rails3/Gemfile +2 -3
  30. data/spec/rails3/Gemfile.lock +45 -26
  31. data/spec/rails3/app/controllers/application_controller.rb +31 -2
  32. data/spec/rails3/config/environments/in_memory.rb +35 -0
  33. data/spec/rails3/spec/controller_activity_logging_spec.rb +7 -0
  34. data/spec/rails3/spec/controller_oauth2_spec.rb +111 -11
  35. data/spec/rails3/spec/controller_spec.rb +30 -2
  36. data/spec/rails3/spec/integration_spec.rb +15 -15
  37. data/spec/rails3/spec/spec_helper.rb +1 -1
  38. data/spec/rails3_mongo_mapper/Gemfile.lock +22 -22
  39. data/spec/rails3_mongo_mapper/spec/controller_spec.rb +34 -1
  40. data/spec/rails3_mongoid/Gemfile.lock +18 -18
  41. data/spec/rails3_mongoid/app/controllers/application_controller.rb +5 -0
  42. data/spec/rails3_mongoid/spec/controller_activity_logging_spec.rb +10 -3
  43. data/spec/rails3_mongoid/spec/controller_spec.rb +34 -1
  44. data/spec/shared_examples/user_reset_password_shared_examples.rb +9 -1
  45. data/spec/sorcery_crypto_providers_spec.rb +5 -1
  46. metadata +235 -120
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
  gem 'oauth', "~> 0.4.4"
6
- gem 'oauth2', "~> 0.4.1"
6
+ gem 'oauth2', "~> 0.5.1"
7
7
 
8
8
  # Add dependencies to develop your gem here.
9
9
  # Include everything needed to run rake, tests, features, etc.
data/Gemfile.lock CHANGED
@@ -1,44 +1,44 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- actionmailer (3.1.1)
5
- actionpack (= 3.1.1)
4
+ actionmailer (3.1.3)
5
+ actionpack (= 3.1.3)
6
6
  mail (~> 2.3.0)
7
- actionpack (3.1.1)
8
- activemodel (= 3.1.1)
9
- activesupport (= 3.1.1)
7
+ actionpack (3.1.3)
8
+ activemodel (= 3.1.3)
9
+ activesupport (= 3.1.3)
10
10
  builder (~> 3.0.0)
11
11
  erubis (~> 2.7.0)
12
12
  i18n (~> 0.6)
13
- rack (~> 1.3.2)
13
+ rack (~> 1.3.5)
14
14
  rack-cache (~> 1.1)
15
15
  rack-mount (~> 0.8.2)
16
16
  rack-test (~> 0.6.1)
17
- sprockets (~> 2.0.2)
18
- activemodel (3.1.1)
19
- activesupport (= 3.1.1)
17
+ sprockets (~> 2.0.3)
18
+ activemodel (3.1.3)
19
+ activesupport (= 3.1.3)
20
20
  builder (~> 3.0.0)
21
21
  i18n (~> 0.6)
22
- activerecord (3.1.1)
23
- activemodel (= 3.1.1)
24
- activesupport (= 3.1.1)
22
+ activerecord (3.1.3)
23
+ activemodel (= 3.1.3)
24
+ activesupport (= 3.1.3)
25
25
  arel (~> 2.2.1)
26
26
  tzinfo (~> 0.3.29)
27
- activeresource (3.1.1)
28
- activemodel (= 3.1.1)
29
- activesupport (= 3.1.1)
30
- activesupport (3.1.1)
27
+ activeresource (3.1.3)
28
+ activemodel (= 3.1.3)
29
+ activesupport (= 3.1.3)
30
+ activesupport (3.1.3)
31
31
  multi_json (~> 1.0)
32
32
  addressable (2.2.6)
33
33
  archive-tar-minitar (0.5.2)
34
34
  arel (2.2.1)
35
35
  builder (3.0.0)
36
- columnize (0.3.4)
36
+ columnize (0.3.6)
37
37
  diff-lcs (1.1.3)
38
38
  erubis (2.7.0)
39
- faraday (0.6.1)
40
- addressable (~> 2.2.4)
41
- multipart-post (~> 1.1.0)
39
+ faraday (0.7.5)
40
+ addressable (~> 2.2.6)
41
+ multipart-post (~> 1.1.3)
42
42
  rack (>= 1.1.0, < 2)
43
43
  git (1.2.5)
44
44
  hike (1.2.1)
@@ -47,7 +47,7 @@ GEM
47
47
  bundler (~> 1.0.0)
48
48
  git (>= 1.2.5)
49
49
  rake
50
- json (1.6.1)
50
+ json (1.6.3)
51
51
  linecache19 (0.5.12)
52
52
  ruby_core_source (>= 0.1.4)
53
53
  mail (2.3.0)
@@ -55,13 +55,13 @@ GEM
55
55
  mime-types (~> 1.16)
56
56
  treetop (~> 1.4.8)
57
57
  mime-types (1.17.2)
58
- multi_json (1.0.3)
59
- multipart-post (1.1.3)
58
+ multi_json (1.0.4)
59
+ multipart-post (1.1.4)
60
60
  oauth (0.4.5)
61
- oauth2 (0.4.1)
62
- faraday (~> 0.6.1)
63
- multi_json (>= 0.0.5)
64
- polyglot (0.3.2)
61
+ oauth2 (0.5.1)
62
+ faraday (~> 0.7.4)
63
+ multi_json (~> 1.0.3)
64
+ polyglot (0.3.3)
65
65
  rack (1.3.5)
66
66
  rack-cache (1.1)
67
67
  rack (>= 0.4)
@@ -71,23 +71,23 @@ GEM
71
71
  rack
72
72
  rack-test (0.6.1)
73
73
  rack (>= 1.0)
74
- rails (3.1.1)
75
- actionmailer (= 3.1.1)
76
- actionpack (= 3.1.1)
77
- activerecord (= 3.1.1)
78
- activeresource (= 3.1.1)
79
- activesupport (= 3.1.1)
74
+ rails (3.1.3)
75
+ actionmailer (= 3.1.3)
76
+ actionpack (= 3.1.3)
77
+ activerecord (= 3.1.3)
78
+ activeresource (= 3.1.3)
79
+ activesupport (= 3.1.3)
80
80
  bundler (~> 1.0)
81
- railties (= 3.1.1)
82
- railties (3.1.1)
83
- actionpack (= 3.1.1)
84
- activesupport (= 3.1.1)
81
+ railties (= 3.1.3)
82
+ railties (3.1.3)
83
+ actionpack (= 3.1.3)
84
+ activesupport (= 3.1.3)
85
85
  rack-ssl (~> 1.3.2)
86
86
  rake (>= 0.8.7)
87
87
  rdoc (~> 3.4)
88
88
  thor (~> 0.14.6)
89
89
  rake (0.9.2.2)
90
- rdoc (3.11)
90
+ rdoc (3.12)
91
91
  json (~> 1.4)
92
92
  rspec (2.5.0)
93
93
  rspec-core (~> 2.5.0)
@@ -120,7 +120,7 @@ GEM
120
120
  hike (~> 1.2)
121
121
  rack (~> 1.0)
122
122
  tilt (~> 1.1, != 1.3.0)
123
- sqlite3 (1.3.4)
123
+ sqlite3 (1.3.5)
124
124
  sqlite3-ruby (1.3.3)
125
125
  sqlite3 (>= 1.3.3)
126
126
  thor (0.14.6)
@@ -129,7 +129,7 @@ GEM
129
129
  treetop (1.4.10)
130
130
  polyglot
131
131
  polyglot (>= 0.3.1)
132
- tzinfo (0.3.30)
132
+ tzinfo (0.3.31)
133
133
  yard (0.6.8)
134
134
 
135
135
  PLATFORMS
@@ -140,7 +140,7 @@ DEPENDENCIES
140
140
  jeweler (~> 1.5.2)
141
141
  json (>= 1.5.1)
142
142
  oauth (~> 0.4.4)
143
- oauth2 (~> 0.4.1)
143
+ oauth2 (~> 0.5.1)
144
144
  rails (>= 3.0.0)
145
145
  rspec (~> 2.5.0)
146
146
  rspec-rails (~> 2.5.0)
data/README.rdoc CHANGED
@@ -28,7 +28,7 @@ Railscast: http://railscasts.com/episodes/283-authentication-with-sorcery
28
28
 
29
29
  Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
30
30
 
31
- Documentation: http://rubydoc.info/gems/sorcery/0.7.4/frames
31
+ Documentation: http://rubydoc.info/gems/sorcery/0.7.6/frames
32
32
 
33
33
  Check out the tutorials in the github wiki!
34
34
 
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ Jeweler::Tasks.new do |gem|
27
27
  # gem.add_development_dependency 'rspec', '> 1.2.3'
28
28
  gem.add_runtime_dependency 'bcrypt-ruby', '~> 3.0.0'
29
29
  gem.add_runtime_dependency 'oauth', '~> 0.4.4'
30
- gem.add_runtime_dependency 'oauth2', '~> 0.4.1'
30
+ gem.add_runtime_dependency 'oauth2', '~> 0.5.1'
31
31
  end
32
32
  Jeweler::RubygemsDotOrgTasks.new
33
33
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.4
1
+ 0.7.6
@@ -39,6 +39,10 @@ module Sorcery
39
39
 
40
40
  # Copy the migrations files to db/migrate folder
41
41
  def copy_migration_files
42
+ # Copy core migration file in all cases except when you pass --migrations.
43
+ return unless defined?(Sorcery::Generators::InstallGenerator::ActiveRecord)
44
+ migration_template "migration/core.rb", "db/migrate/sorcery_core.rb" unless options[:migrations]
45
+
42
46
  if submodules
43
47
  submodules.each do |submodule|
44
48
  unless submodule == "http_basic_auth" || submodule == "session_timeout"
@@ -47,8 +51,7 @@ module Sorcery
47
51
  end
48
52
  end
49
53
 
50
- # Copy core migration file in all cases except when you pass --migrations.
51
- migration_template "migration/core.rb", "db/migrate/sorcery_core.rb" unless options[:migrations]
54
+
52
55
  end
53
56
 
54
57
  # Define the next_migration_number method (necessary for the migration_template method to work)
@@ -69,4 +72,4 @@ module Sorcery
69
72
  end
70
73
  end
71
74
  end
72
- end
75
+ end
@@ -29,19 +29,22 @@ Rails.application.config.sorcery.configure do |config|
29
29
  # -- http_basic_auth --
30
30
  # config.controller_to_realm_map = {"application" => "Application"} # What realm to display for which controller name.
31
31
  # For example {"My App" => "Application"}
32
-
32
+
33
33
  # -- activity logging --
34
34
  # config.register_login_time = true # will register the time of last user login, every login.
35
35
  # config.register_logout_time = true # will register the time of last user logout, every logout.
36
36
  # config.register_last_activity_time = true # will register the time of last user action, every action.
37
-
37
+
38
38
  # -- external --
39
39
  # config.external_providers = [] # What providers are supported by this app,
40
- # i.e. [:twitter, :facebook, :github] .
40
+ # i.e. [:twitter, :facebook, :github, :google, :liveid] .
41
41
  # config.ca_file = 'path/to/ca_file' # Path to ca_file. By default use a internal ca-bundle.crt.
42
42
  # You can change it by your local ca_file.
43
43
  # i.e. '/etc/pki/tls/certs/ca-bundle.crt'
44
44
 
45
+ # Twitter wil not accept any requests nor redirect uri containing localhost,
46
+ # make sure you use 0.0.0.0:3000 to access your app in development
47
+ #
45
48
  # config.twitter.key = "eYVNBjBDi33aa9GkA3w"
46
49
  # config.twitter.secret = "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8"
47
50
  # config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
@@ -56,6 +59,20 @@ Rails.application.config.sorcery.configure do |config|
56
59
  # config.github.secret = ""
57
60
  # config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github"
58
61
  # config.github.user_info_mapping = {:email => "name"}
62
+ #
63
+ # config.google.key = "491253340633.apps.googleusercontent.com"
64
+ # config.google.secret = "4oE6kXqbL_LN-VGcGcg7qgdL"
65
+ # config.google.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=google"
66
+ # config.google.user_info_mapping = {:email => "email", :username => "name"}
67
+ #
68
+ # To use liveid in development mode you have to replace mydomain.com with
69
+ # a valid domain even in development. To use a valid domain in development
70
+ # simply add your domain in your /etc/hosts file in front of 127.0.0.1
71
+ #
72
+ # config.liveid.key = ""
73
+ # config.liveid.secret = ""
74
+ # config.liveid.callback_url = "http://mydomain.com:3000/oauth/callback?provider=liveid"
75
+ # config.liveid.user_info_mapping = {:username => "name"}
59
76
 
60
77
  # --- user config ---
61
78
  config.user_config do |user|
@@ -69,6 +86,10 @@ Rails.application.config.sorcery.configure do |config|
69
86
  # until an encrypted one is
70
87
  # generated.
71
88
 
89
+ # user.downcase_username_before_authenticating = false # downcase the username before
90
+ # trying to authenticate, default
91
+ # is false
92
+
72
93
  # user.email_attribute_name = :email # change default email attribute.
73
94
 
74
95
  # user.crypted_password_attribute_name = :crypted_password # change default crypted_password
@@ -88,7 +109,7 @@ Rails.application.config.sorcery.configure do |config|
88
109
  #
89
110
  # WARNING:
90
111
  #
91
- # If used for users' passwords, changing this key
112
+ # If used for users' passwords, changing this key
92
113
  # will leave passwords undecryptable!
93
114
 
94
115
  # user.custom_encryption_provider = nil # use an external encryption
@@ -8,7 +8,7 @@ class SorceryResetPassword < ActiveRecord::Migration
8
8
  end
9
9
 
10
10
  def self.down
11
- remove_index :users, :reset_password_token
11
+ remove_index :<%= model_class_name.tableize %>, :reset_password_token
12
12
 
13
13
  remove_column :<%= model_class_name.tableize %>, :reset_password_email_sent_at
14
14
  remove_column :<%= model_class_name.tableize %>, :reset_password_token_expires_at
@@ -52,14 +52,14 @@ module Sorcery
52
52
  # This runs as a hook just after a successful login.
53
53
  def register_login_time_to_db(user, credentials)
54
54
  return unless Config.register_login_time
55
- user.update_attribute(user.sorcery_config.last_login_at_attribute_name, Time.now.in_time_zone)
55
+ user.update_single_attribute(user.sorcery_config.last_login_at_attribute_name, Time.now.in_time_zone)
56
56
  end
57
57
 
58
58
  # registers last logout time on every logout.
59
59
  # This runs as a hook just before a logout.
60
60
  def register_logout_time_to_db(user)
61
61
  return unless Config.register_logout_time
62
- user.update_attribute(user.sorcery_config.last_logout_at_attribute_name, Time.now.in_time_zone)
62
+ user.update_single_attribute(user.sorcery_config.last_logout_at_attribute_name, Time.now.in_time_zone)
63
63
  end
64
64
 
65
65
  # Updates last activity time on every request.
@@ -67,7 +67,7 @@ module Sorcery
67
67
  def register_last_activity_time_to_db
68
68
  return unless Config.register_last_activity_time
69
69
  return unless logged_in?
70
- current_user.update_attribute(current_user.sorcery_config.last_activity_at_attribute_name, Time.now.in_time_zone)
70
+ current_user.update_single_attribute(current_user.sorcery_config.last_activity_at_attribute_name, Time.now.in_time_zone)
71
71
  end
72
72
  end
73
73
  end
@@ -8,34 +8,34 @@ module Sorcery
8
8
  def oauth_version
9
9
  "2.0"
10
10
  end
11
-
11
+
12
12
  def authorize_url(options = {})
13
+ client = build_client(options)
14
+ client.auth_code.authorize_url(
15
+ :redirect_uri => @callback_url,
16
+ :scope => @scope,
17
+ :display => @display
18
+ )
19
+ end
20
+
21
+ def get_access_token(args, options = {})
22
+ client = build_client(options)
23
+ client.auth_code.get_access_token(
24
+ args[:code],
25
+ :redirect_uri => @callback_url
26
+ )
27
+ end
28
+
29
+ def build_client(options = {})
13
30
  defaults = {
14
31
  :site => @site,
15
32
  :ssl => { :ca_file => Config.ca_file }
16
33
  }
17
- client = ::OAuth2::Client.new(
34
+ ::OAuth2::Client.new(
18
35
  @key,
19
36
  @secret,
20
37
  defaults.merge!(options)
21
38
  )
22
- client.web_server.authorize_url(
23
- :redirect_uri => @callback_url,
24
- :scope => @scope
25
- )
26
- end
27
-
28
- def get_access_token(args)
29
- client = ::OAuth2::Client.new(
30
- @key,
31
- @secret,
32
- :site => @site,
33
- :ssl => { :ca_file => Config.ca_file }
34
- )
35
- client.web_server.get_access_token(
36
- args[:code],
37
- :redirect_uri => @callback_url
38
- )
39
39
  end
40
40
  end
41
41
  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,6 +45,7 @@ module Sorcery
43
45
  @user_info_path = "/me"
44
46
  @scope = "email,offline_access"
45
47
  @user_info_mapping = {}
48
+ @display = "page"
46
49
  end
47
50
 
48
51
  def get_user_hash
@@ -31,15 +31,20 @@ module Sorcery
31
31
  attr_accessor :key,
32
32
  :secret,
33
33
  :callback_url,
34
+ :auth_path,
35
+ :token_path,
34
36
  :site,
35
37
  :user_info_path,
36
38
  :user_info_mapping
39
+ attr_reader :access_token
37
40
 
38
41
  include Protocols::Oauth2
39
42
 
40
43
  def init
41
44
  @site = "https://github.com/"
42
- @user_info_path = "/api/v2/json/user/show"
45
+ @user_info_path = "https://api.github.com/user"
46
+ @auth_path = "/login/oauth/authorize"
47
+ @token_path = "/login/oauth/access_token"
43
48
  @user_info_mapping = {}
44
49
  end
45
50
 
@@ -58,14 +63,18 @@ module Sorcery
58
63
  # calculates and returns the url to which the user should be redirected,
59
64
  # to get authenticated at the external provider's site.
60
65
  def login_url(params,session)
61
- self.authorize_url({:authorize_path => '/login/oauth/authorize'})
66
+ self.authorize_url({:authorize_path => @auth_path})
62
67
  end
63
68
 
64
69
  # tries to login the user from access token
65
70
  def process_callback(params,session)
66
71
  args = {}
67
72
  args.merge!({:code => params[:code]}) if params[:code]
68
- @access_token = self.get_access_token(args)
73
+ options = {
74
+ :access_token_path => @token_path,
75
+ :access_token_method => :post
76
+ }
77
+ @access_token = self.get_access_token(args, options)
69
78
  end
70
79
 
71
80
  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_path = "/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)
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
+ :access_token_path => @token_path,
77
+ :access_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)
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,7 +37,8 @@ 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
42
43
 
43
44
  # Override included get_consumer method to provide authorize_path
@@ -51,6 +51,12 @@ module Sorcery
51
51
  user
52
52
  end
53
53
  end
54
+
55
+ # get provider access account
56
+ def access_token(provider)
57
+ @provider = Config.send(provider)
58
+ @provider.access_token
59
+ end
54
60
 
55
61
  # this method automatically creates a new user from the data in the external user hash.
56
62
  # The mappings from user hash fields to user db fields are set at controller config.
@@ -4,11 +4,26 @@ module Sorcery
4
4
  module ActiveRecord
5
5
  def self.included(klass)
6
6
  klass.extend ClassMethods
7
+ klass.send(:include, InstanceMethods)
7
8
  end
8
9
 
10
+ module InstanceMethods
11
+ def update_single_attribute(name, value)
12
+ self.send(:"#{name}=", value)
13
+
14
+ primary_key = self.class.primary_key
15
+ self.class.where(:"#{primary_key}" => self.send(:"#{primary_key}")).update_all(name => value)
16
+ end
17
+ end
18
+
9
19
  module ClassMethods
20
+ def column_name(attribute)
21
+ return "LOWER(#{attribute})" if (@sorcery_config.downcase_username_before_authenticating)
22
+ return "#{attribute}"
23
+ end
24
+
10
25
  def find_by_credentials(credentials)
11
- sql = @sorcery_config.username_attribute_names.map{|attribute| "#{attribute} = :login"}
26
+ sql = @sorcery_config.username_attribute_names.map{|attribute| column_name(attribute) + " = :login"}
12
27
  where(sql.join(' OR '), :login => credentials[0]).first
13
28
  end
14
29