authpwn_rails 0.16.2 → 0.17.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -6
  3. data/Gemfile +7 -8
  4. data/Gemfile.lock +97 -113
  5. data/Gemfile.rails4 +8 -9
  6. data/{Gemfile.rails3 → Gemfile.rails41} +6 -7
  7. data/Gemfile.rails42 +17 -0
  8. data/README.rdoc +1 -2
  9. data/Rakefile +1 -1
  10. data/VERSION +1 -1
  11. data/app/models/credentials/email.rb +15 -37
  12. data/app/models/credentials/omni_auth_uid.rb +96 -0
  13. data/app/models/credentials/password.rb +0 -5
  14. data/app/models/tokens/base.rb +11 -38
  15. data/authpwn_rails.gemspec +35 -33
  16. data/lib/authpwn_rails/credential_model.rb +1 -5
  17. data/lib/authpwn_rails/generators/all_generator.rb +3 -1
  18. data/lib/authpwn_rails/generators/templates/001_create_users.rb +3 -3
  19. data/lib/authpwn_rails/generators/templates/003_create_credentials.rb +7 -7
  20. data/lib/authpwn_rails/generators/templates/credentials.yml +13 -13
  21. data/lib/authpwn_rails/generators/templates/omniauth_initializer.rb +13 -0
  22. data/lib/authpwn_rails/generators/templates/session_controller_test.rb +22 -0
  23. data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.html.erb +3 -3
  24. data/lib/authpwn_rails/generators/templates/session_mailer/email_verification_email.text.erb +1 -1
  25. data/lib/authpwn_rails/generators/templates/session_mailer/reset_password_email.html.erb +3 -3
  26. data/lib/authpwn_rails/generators/templates/session_mailer/reset_password_email.text.erb +1 -1
  27. data/lib/authpwn_rails/generators/templates/session_mailer.rb +1 -1
  28. data/lib/authpwn_rails/generators/templates/session_mailer_test.rb +14 -4
  29. data/lib/authpwn_rails/generators/templates/user.rb +40 -5
  30. data/lib/authpwn_rails/http_basic.rb +6 -5
  31. data/lib/authpwn_rails/routes.rb +20 -7
  32. data/lib/authpwn_rails/session.rb +1 -1
  33. data/lib/authpwn_rails/session_controller.rb +48 -12
  34. data/lib/authpwn_rails/session_mailer.rb +13 -14
  35. data/lib/authpwn_rails/session_model.rb +4 -24
  36. data/lib/authpwn_rails/user_extensions/email_field.rb +5 -21
  37. data/lib/authpwn_rails/user_extensions/password_field.rb +0 -4
  38. data/lib/authpwn_rails/user_model.rb +46 -12
  39. data/lib/authpwn_rails.rb +0 -2
  40. data/test/cookie_controller_test.rb +1 -7
  41. data/test/credentials/omni_auth_uid_credential_test.rb +141 -0
  42. data/test/helpers/action_controller.rb +2 -8
  43. data/test/helpers/db_setup.rb +8 -16
  44. data/test/helpers/routes.rb +35 -30
  45. data/test/helpers/test_order.rb +3 -0
  46. data/test/http_basic_controller_test.rb +7 -18
  47. data/test/routes_test.rb +19 -10
  48. data/test/session_controller_api_test.rb +181 -30
  49. data/test/session_controller_test.rb +6 -0
  50. data/test/session_mailer_api_test.rb +18 -13
  51. data/test/session_mailer_test.rb +6 -0
  52. data/test/test_helper.rb +3 -3
  53. data/test/user_test.rb +54 -7
  54. metadata +65 -64
  55. data/app/models/credentials/facebook.rb +0 -63
  56. data/lib/authpwn_rails/facebook_session.rb +0 -33
  57. data/lib/authpwn_rails/user_extensions/facebook_fields.rb +0 -63
  58. data/test/credentials/facebook_credential_test.rb +0 -64
  59. data/test/facebook_controller_test.rb +0 -65
  60. data/test/user_extensions/facebook_fields_test.rb +0 -61
@@ -1,19 +1,5 @@
1
1
  require 'securerandom'
2
2
 
3
- # :nodoc: Backport urlsafe_base64 to 1.8.7.
4
- unless SecureRandom.respond_to? :urlsafe_base64
5
- SecureRandom.class_eval do
6
- # :nodoc: lifted from 1.9.3 securerandom.rb, line 190
7
- def self.urlsafe_base64(n=nil, padding=false)
8
- s = [random_bytes(n)].pack("m*")
9
- s.delete!("\n")
10
- s.tr!("+/", "-_")
11
- s.delete!("=") if !padding
12
- s
13
- end
14
- end
15
- end
16
-
17
3
  # :namespace
18
4
  module Tokens
19
5
 
@@ -45,30 +31,17 @@ class Base < ::Credential
45
31
  credential ? credential.authenticate : :invalid
46
32
  end
47
33
 
48
-
49
- begin
50
- ActiveRecord::QueryMethods.instance_method :references
51
- # Rails 4.
52
-
53
- # Scope that uses a secret code.
54
- def self.with_code(code)
55
- # NOTE 1: The where query must be performed off the root type, otherwise
56
- # Rails will try to guess the right values for the 'type' column,
57
- # and will sometimes get them wrong.
58
- # NOTE 2: After using this method, it's likely that the user's other
59
- # tokens (e.g., email or Facebook OAuth token) will be required,
60
- # so we pre-fetch them.
61
- Credential.where(name: code).includes(user: :credentials).
62
- where(Credential.arel_table[:type].matches('Tokens::%')).
63
- references(:credential)
64
- end
65
- rescue NameError
66
- # Rails 3.
67
-
68
- def self.with_code(code)
69
- Credential.where(name: code).includes(user: :credentials).
70
- where(Credential.arel_table[:type].matches('Tokens::%'))
71
- end
34
+ # Scope that uses a secret code.
35
+ def self.with_code(code)
36
+ # NOTE 1: The where query must be performed off the root type, otherwise
37
+ # Rails will try to guess the right values for the 'type' column,
38
+ # and will sometimes get them wrong.
39
+ # NOTE 2: After using this method, it's likely that the user's other
40
+ # tokens (e.g., email or Facebook OAuth token) will be required,
41
+ # so we pre-fetch them.
42
+ Credential.where(name: code).includes(user: :credentials).
43
+ where(Credential.arel_table[:type].matches('Tokens::%')).
44
+ references(:credential)
72
45
  end
73
46
 
74
47
  # Authenticates a user using this token.
@@ -2,14 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: authpwn_rails 0.17.0 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "authpwn_rails"
8
- s.version = "0.16.2"
9
+ s.version = "0.17.0"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Victor Costan"]
12
- s.date = "2014-02-20"
14
+ s.date = "2014-11-07"
13
15
  s.description = "Works with Facebook."
14
16
  s.email = "victor@costan.us"
15
17
  s.extra_rdoc_files = [
@@ -22,15 +24,16 @@ Gem::Specification.new do |s|
22
24
  ".travis.yml",
23
25
  "Gemfile",
24
26
  "Gemfile.lock",
25
- "Gemfile.rails3",
26
27
  "Gemfile.rails4",
28
+ "Gemfile.rails41",
29
+ "Gemfile.rails42",
27
30
  "LICENSE",
28
31
  "README.rdoc",
29
32
  "Rakefile",
30
33
  "VERSION",
31
34
  "app/helpers/session_helper.rb",
32
35
  "app/models/credentials/email.rb",
33
- "app/models/credentials/facebook.rb",
36
+ "app/models/credentials/omni_auth_uid.rb",
34
37
  "app/models/credentials/password.rb",
35
38
  "app/models/tokens/base.rb",
36
39
  "app/models/tokens/email_verification.rb",
@@ -45,13 +48,13 @@ Gem::Specification.new do |s|
45
48
  "lib/authpwn_rails/current_user.rb",
46
49
  "lib/authpwn_rails/engine.rb",
47
50
  "lib/authpwn_rails/expires.rb",
48
- "lib/authpwn_rails/facebook_session.rb",
49
51
  "lib/authpwn_rails/generators/all_generator.rb",
50
52
  "lib/authpwn_rails/generators/templates/001_create_users.rb",
51
53
  "lib/authpwn_rails/generators/templates/003_create_credentials.rb",
52
54
  "lib/authpwn_rails/generators/templates/credential.rb",
53
55
  "lib/authpwn_rails/generators/templates/credentials.yml",
54
56
  "lib/authpwn_rails/generators/templates/initializer.rb",
57
+ "lib/authpwn_rails/generators/templates/omniauth_initializer.rb",
55
58
  "lib/authpwn_rails/generators/templates/session.rb",
56
59
  "lib/authpwn_rails/generators/templates/session/forbidden.html.erb",
57
60
  "lib/authpwn_rails/generators/templates/session/home.html.erb",
@@ -76,19 +79,17 @@ Gem::Specification.new do |s|
76
79
  "lib/authpwn_rails/session_model.rb",
77
80
  "lib/authpwn_rails/test_extensions.rb",
78
81
  "lib/authpwn_rails/user_extensions/email_field.rb",
79
- "lib/authpwn_rails/user_extensions/facebook_fields.rb",
80
82
  "lib/authpwn_rails/user_extensions/password_field.rb",
81
83
  "lib/authpwn_rails/user_model.rb",
82
84
  "test/cookie_controller_test.rb",
83
85
  "test/credentials/email_credential_test.rb",
84
86
  "test/credentials/email_verification_token_test.rb",
85
- "test/credentials/facebook_credential_test.rb",
87
+ "test/credentials/omni_auth_uid_credential_test.rb",
86
88
  "test/credentials/one_time_token_credential_test.rb",
87
89
  "test/credentials/password_credential_test.rb",
88
90
  "test/credentials/password_reset_token_test.rb",
89
91
  "test/credentials/session_uid_token_test.rb",
90
92
  "test/credentials/token_crendential_test.rb",
91
- "test/facebook_controller_test.rb",
92
93
  "test/fixtures/bare_session/forbidden.html.erb",
93
94
  "test/fixtures/bare_session/home.html.erb",
94
95
  "test/fixtures/bare_session/new.html.erb",
@@ -104,66 +105,67 @@ Gem::Specification.new do |s|
104
105
  "test/helpers/rails.rb",
105
106
  "test/helpers/rails_undo.rb",
106
107
  "test/helpers/routes.rb",
108
+ "test/helpers/test_order.rb",
107
109
  "test/helpers/view_helpers.rb",
108
110
  "test/http_basic_controller_test.rb",
109
111
  "test/initializer_test.rb",
110
112
  "test/routes_test.rb",
111
113
  "test/session_controller_api_test.rb",
114
+ "test/session_controller_test.rb",
112
115
  "test/session_mailer_api_test.rb",
116
+ "test/session_mailer_test.rb",
113
117
  "test/session_test.rb",
114
118
  "test/test_extensions_test.rb",
115
119
  "test/test_helper.rb",
116
120
  "test/user_extensions/email_field_test.rb",
117
- "test/user_extensions/facebook_fields_test.rb",
118
121
  "test/user_extensions/password_field_test.rb",
119
122
  "test/user_test.rb"
120
123
  ]
121
124
  s.homepage = "http://github.com/pwnall/authpwn_rails"
122
125
  s.licenses = ["MIT"]
123
- s.require_paths = ["lib"]
124
- s.rubygems_version = "2.0.14"
125
- s.summary = "User authentication for Rails 3 and 4 applications."
126
+ s.rubygems_version = "2.2.2"
127
+ s.summary = "User authentication for Rails 4 applications."
126
128
 
127
129
  if s.respond_to? :specification_version then
128
130
  s.specification_version = 4
129
131
 
130
132
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
131
- s.add_runtime_dependency(%q<fbgraph_rails>, [">= 0.2.2"])
132
- s.add_runtime_dependency(%q<rails>, [">= 3.2.17"])
133
- s.add_development_dependency(%q<bundler>, [">= 1.3.5"])
133
+ s.add_runtime_dependency(%q<rails>, [">= 4.0.9"])
134
+ s.add_development_dependency(%q<bundler>, [">= 1.7.3"])
134
135
  s.add_development_dependency(%q<mocha>, [">= 0.14.0"])
135
- s.add_development_dependency(%q<jeweler>, [">= 1.8.8"])
136
+ s.add_development_dependency(%q<jeweler>, [">= 2.0.1"])
136
137
  s.add_development_dependency(%q<simplecov>, [">= 0"])
137
- s.add_development_dependency(%q<mysql2>, [">= 0.3.14"])
138
- s.add_development_dependency(%q<pg>, [">= 0.17.0"])
139
- s.add_development_dependency(%q<sqlite3>, [">= 1.3.8"])
138
+ s.add_development_dependency(%q<mysql2>, [">= 0.3.16"])
139
+ s.add_development_dependency(%q<omniauth>, [">= 1.2.2"])
140
+ s.add_development_dependency(%q<pg>, [">= 0.17.1"])
141
+ s.add_development_dependency(%q<sqlite3>, [">= 1.3.9"])
140
142
  s.add_development_dependency(%q<rubysl>, [">= 0"])
141
143
  s.add_development_dependency(%q<rubysl-bundler>, [">= 0"])
142
144
  s.add_development_dependency(%q<rubysl-rake>, [">= 0"])
143
145
  else
144
- s.add_dependency(%q<fbgraph_rails>, [">= 0.2.2"])
145
- s.add_dependency(%q<rails>, [">= 3.2.17"])
146
- s.add_dependency(%q<bundler>, [">= 1.3.5"])
146
+ s.add_dependency(%q<rails>, [">= 4.0.9"])
147
+ s.add_dependency(%q<bundler>, [">= 1.7.3"])
147
148
  s.add_dependency(%q<mocha>, [">= 0.14.0"])
148
- s.add_dependency(%q<jeweler>, [">= 1.8.8"])
149
+ s.add_dependency(%q<jeweler>, [">= 2.0.1"])
149
150
  s.add_dependency(%q<simplecov>, [">= 0"])
150
- s.add_dependency(%q<mysql2>, [">= 0.3.14"])
151
- s.add_dependency(%q<pg>, [">= 0.17.0"])
152
- s.add_dependency(%q<sqlite3>, [">= 1.3.8"])
151
+ s.add_dependency(%q<mysql2>, [">= 0.3.16"])
152
+ s.add_dependency(%q<omniauth>, [">= 1.2.2"])
153
+ s.add_dependency(%q<pg>, [">= 0.17.1"])
154
+ s.add_dependency(%q<sqlite3>, [">= 1.3.9"])
153
155
  s.add_dependency(%q<rubysl>, [">= 0"])
154
156
  s.add_dependency(%q<rubysl-bundler>, [">= 0"])
155
157
  s.add_dependency(%q<rubysl-rake>, [">= 0"])
156
158
  end
157
159
  else
158
- s.add_dependency(%q<fbgraph_rails>, [">= 0.2.2"])
159
- s.add_dependency(%q<rails>, [">= 3.2.17"])
160
- s.add_dependency(%q<bundler>, [">= 1.3.5"])
160
+ s.add_dependency(%q<rails>, [">= 4.0.9"])
161
+ s.add_dependency(%q<bundler>, [">= 1.7.3"])
161
162
  s.add_dependency(%q<mocha>, [">= 0.14.0"])
162
- s.add_dependency(%q<jeweler>, [">= 1.8.8"])
163
+ s.add_dependency(%q<jeweler>, [">= 2.0.1"])
163
164
  s.add_dependency(%q<simplecov>, [">= 0"])
164
- s.add_dependency(%q<mysql2>, [">= 0.3.14"])
165
- s.add_dependency(%q<pg>, [">= 0.17.0"])
166
- s.add_dependency(%q<sqlite3>, [">= 1.3.8"])
165
+ s.add_dependency(%q<mysql2>, [">= 0.3.16"])
166
+ s.add_dependency(%q<omniauth>, [">= 1.2.2"])
167
+ s.add_dependency(%q<pg>, [">= 0.17.1"])
168
+ s.add_dependency(%q<sqlite3>, [">= 1.3.9"])
167
169
  s.add_dependency(%q<rubysl>, [">= 0"])
168
170
  s.add_dependency(%q<rubysl-bundler>, [">= 0"])
169
171
  s.add_dependency(%q<rubysl-rake>, [">= 0"])
@@ -20,13 +20,9 @@ module CredentialModel
20
20
 
21
21
  # Secret information associated with the token.
22
22
  validates :key, length: { in: 1..2.kilobytes, allow_nil: true }
23
-
24
- if ActiveRecord::Base.respond_to? :mass_assignment_sanitizer=
25
- attr_accessible
26
- end
27
23
  end
28
24
 
29
- # Included in the metaclass of models that call pwnauth_facebook_token_model.
25
+ # Class methods on models that include Authpwn::CredentialModel.
30
26
  module ClassMethods
31
27
 
32
28
  end # module Authpwn::FacebookTokenModel::ClassMethods
@@ -66,9 +66,11 @@ class AllGenerator < Rails::Generators::Base
66
66
  'reset_password_email.text.erb')
67
67
  end
68
68
 
69
- def create_initializer
69
+ def create_initializers
70
70
  copy_file 'initializer.rb',
71
71
  File.join('config', 'initializers', 'authpwn.rb')
72
+ copy_file 'omniauth_initializer.rb',
73
+ File.join('config', 'initializers', 'authpwn_omniauth.rb')
72
74
  end
73
75
  end # class Authpwn::AllGenerator
74
76
 
@@ -3,9 +3,9 @@ class CreateUsers < ActiveRecord::Migration
3
3
  create_table :users do |t|
4
4
  t.string :exuid, limit: 32, null: false
5
5
 
6
- t.timestamps
7
- end
6
+ t.timestamps null: false
8
7
 
9
- add_index :users, :exuid, unique: true
8
+ t.index :exuid, unique: true
9
+ end
10
10
  end
11
11
  end
@@ -8,13 +8,13 @@ class CreateCredentials < ActiveRecord::Migration
8
8
  t.timestamp :updated_at, null: false
9
9
 
10
10
  t.binary :key, limit: 2.kilobytes, null: true
11
- end
12
11
 
13
- # All the credentials (maybe of a specific type) belonging to a user.
14
- add_index :credentials, [:user_id, :type], unique: false
15
- # A specific credential, to find out what user it belongs to.
16
- add_index :credentials, [:type, :name], unique: true
17
- # Expired credentials (particularly useful for tokens).
18
- add_index :credentials, [:type, :updated_at], unique: false
12
+ # All the credentials (maybe of a specific type) belonging to a user.
13
+ t.index [:user_id, :type], unique: false
14
+ # A specific credential, to find out what user it belongs to.
15
+ t.index [:type, :name], unique: true
16
+ # Expired credentials (particularly useful for tokens).
17
+ t.index [:type, :updated_at], unique: false
18
+ end
19
19
  end
20
20
  end
@@ -20,19 +20,6 @@ john_password:
20
20
  user: john
21
21
  key: <%= Credentials::Password.hash_password('password', '1234').inspect %>
22
22
 
23
- # Test account vic.tor@costan.us
24
- jane_facebook:
25
- user: jane
26
- type: Credentials::Facebook
27
- name: 1011950666
28
- key: AAAEj8jKX2a8BAA4kNheRhOs6SlECVcZCE9o5pPKMytOjjoiNAoZBGZAwuL4KrrxXWesfJRhzDZCJiqrcQG3UdjRRNtyMJQMZD
29
-
30
- john_facebook:
31
- user: john
32
- type: Credentials::Facebook
33
- name: 702659
34
- key: 702659|ffffffffffffffffffffffff-702659|ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
35
-
36
23
  jane_token:
37
24
  user: jane
38
25
  type: Tokens::OneTime
@@ -69,3 +56,16 @@ jane_session_token:
69
56
  key: <%= { :browser_ip => '18.70.0.160',
70
57
  :browser_ua => 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1'
71
58
  }.to_yaml.inspect %>
59
+
60
+ john_omniauth_developer:
61
+ user: john
62
+ type: Credentials::OmniAuthUid
63
+ name: developer,john@gmail.com
64
+ key: "0"
65
+
66
+ jane_omniauth_developer:
67
+ user: jane
68
+ type: Credentials::OmniAuthUid
69
+ name: developer,jane@gmail.com
70
+ key: "1"
71
+
@@ -0,0 +1,13 @@
1
+ # See the OmniAuth documentation for the contents of this file.
2
+ #
3
+ # https://github.com/intridea/omniauth
4
+ # https://github.com/intridea/omniauth/wiki
5
+
6
+ Rails.application.config.middleware.use OmniAuth::Builder do
7
+ provider :developer unless Rails.env.production?
8
+
9
+ # provider :twitter, Rails.application.secrets.twitter_api_key,
10
+ # Rails.application.secrets.twitter_api_secret
11
+ end
12
+
13
+ OmniAuth.config.logger = Rails.logger
@@ -5,6 +5,7 @@ class SessionControllerTest < ActionController::TestCase
5
5
  @user = users(:jane)
6
6
  @email_credential = credentials(:jane_email)
7
7
  @password_credential = credentials(:jane_password)
8
+ @omniauth_credential = credentials(:jane_omniauth_developer)
8
9
  end
9
10
 
10
11
  test "user home page" do
@@ -118,4 +119,25 @@ class SessionControllerTest < ActionController::TestCase
118
119
 
119
120
  assert_redirected_to new_session_url
120
121
  end
122
+
123
+ test "OmniAuth failure" do
124
+ get :omniauth_failure
125
+
126
+ assert_redirected_to new_session_url
127
+ end
128
+
129
+ test "OmniAuth login via developer strategy and good account" do
130
+ old_token = credentials(:jane_session_token)
131
+ old_token.updated_at = Time.now - 1.year
132
+ old_token.save!
133
+
134
+ request.env['omniauth.auth'] = {
135
+ 'provider' => @omniauth_credential.provider,
136
+ 'uid' => @omniauth_credential.uid }
137
+ post :omniauth, provider: @omniauth_credential.provider
138
+ assert_equal @user, session_current_user, 'session'
139
+ assert_redirected_to session_url
140
+ assert_nil Tokens::Base.with_code(old_token.code).first,
141
+ 'old session not purged'
142
+ end
121
143
  end
@@ -6,14 +6,14 @@
6
6
  <p>
7
7
  You are receiving this e-mail because someone (hopefully you) registered
8
8
  an account at
9
- <%= link_to @host, root_url(:host => @host, :protocol => @protocol) %>
9
+ <%= link_to @host, root_url(host: @host, protocol: @protocol) %>
10
10
  using your e-mail address.
11
11
  </p>
12
12
 
13
13
  <p>
14
14
  Please go
15
- <%= link_to 'here', token_session_url(@token, :host => @host,
16
- :protocol => @protocol) %>
15
+ <%= link_to 'here', token_session_url(@token, host: @host,
16
+ protocol: @protocol) %>
17
17
  to confirm your e-mail address.
18
18
  </p>
19
19
 
@@ -5,7 +5,7 @@ You are receiving this e-mail because someone (hopefully you) registered an
5
5
  account at <%= @host %> using your e-mail address.
6
6
 
7
7
  Please go to the address below to confirm your e-mail address.
8
- <%= token_session_url @token, :host => @host, :protocol => @protocol %>
8
+ <%= token_session_url @token, host: @host, protocol: @protocol %>
9
9
 
10
10
  If you haven't registered an account, please ignore this e-mail. Someone most
11
11
  likely mistyped their e-mail.
@@ -6,14 +6,14 @@
6
6
  <p>
7
7
  You are receiving this e-mail because someone (hopefully you) requested a
8
8
  password reset for your
9
- <%= link_to @host, root_url(:host => @host, :protocol => @protocol) %>
9
+ <%= link_to @host, root_url(host: @host, protocol: @protocol) %>
10
10
  account.
11
11
  </p>
12
12
 
13
13
  <p>
14
14
  Please go
15
- <%= link_to 'here', token_session_url(@token, :host => @host,
16
- :protocol => @protocol) %>
15
+ <%= link_to 'here', token_session_url(@token, host: @host,
16
+ protocol: @protocol) %>
17
17
  to reset your password.
18
18
  </p>
19
19
 
@@ -5,7 +5,7 @@ You are receiving this e-mail because someone (hopefully you) requested a
5
5
  password reset for your <%= @host %> account.
6
6
 
7
7
  Please go to the address below to reset your password.
8
- <%= token_session_url @token, :host => @host, :protocol => @protocol %>
8
+ <%= token_session_url @token, host: @host, protocol: @protocol %>
9
9
 
10
10
  If you haven't requested a password reset, please ignore this e-mail. Someone
11
11
  most likely mistyped their e-mail.
@@ -21,6 +21,6 @@ class SessionMailer < ActionMailer::Base
21
21
  %Q|"#{server_hostname} staff" <admin@#{server_hostname}>|
22
22
  end
23
23
 
24
- # You shouldn't extend the session controller, so you can benefit from future
24
+ # You shouldn't extend the session mailer, so you can benefit from future
25
25
  # features. But, if you must, you can do it here.
26
26
  end
@@ -10,8 +10,13 @@ class SessionMailerTest < ActionMailer::TestCase
10
10
  end
11
11
 
12
12
  test 'email verification email' do
13
- email = SessionMailer.email_verification_email(@verification_token,
14
- @root_url).deliver
13
+ email_draft = SessionMailer.email_verification_email @verification_token,
14
+ @root_url
15
+ if email_draft.respond_to? :deliver_now
16
+ email = email_draft.deliver_now # Rails 4.2+
17
+ else
18
+ email = email_draft.deliver # Rails 4.0 and 4.1
19
+ end
15
20
  assert !ActionMailer::Base.deliveries.empty?
16
21
 
17
22
  assert_equal 'test.host e-mail verification', email.subject
@@ -23,8 +28,13 @@ class SessionMailerTest < ActionMailer::TestCase
23
28
  end
24
29
 
25
30
  test 'password reset email' do
26
- email = SessionMailer.reset_password_email(@reset_email, @reset_token,
27
- @root_url).deliver
31
+ email_draft = SessionMailer.reset_password_email @reset_email,
32
+ @reset_token, @root_url
33
+ if email_draft.respond_to? :deliver_now
34
+ email = email_draft.deliver_now # Rails 4.2+
35
+ else
36
+ email = email_draft.deliver # Rails 4.0 and 4.1
37
+ end
28
38
  assert !ActionMailer::Base.deliveries.empty?
29
39
 
30
40
  assert_equal 'test.host password reset', email.subject
@@ -6,15 +6,50 @@ class User < ActiveRecord::Base
6
6
  # include Authpwn::UserExtensions::EmailField
7
7
  # Virtual password attribute, with confirmation validation.
8
8
  # include Authpwn::UserExtensions::PasswordField
9
- # Convenience Facebook accessors.
10
- # include Authpwn::UserExtensions::FacebookFields
11
9
 
12
- # Change this method to change the way users are looked up when signing in.
10
+ # Change this to customize user lookup in the e-mail/password signin process.
13
11
  #
14
12
  # For example, to implement Facebook / Twitter's ability to log in using
15
13
  # either an e-mail address or a username, look up the user by the username,
16
- # and pass their e-mail to super.
17
- def self.authenticate_signin(email, password)
14
+ # create a new Session with the e-mail and password, and pass it to super
15
+ #
16
+ # @param [Session] signin the information entered in the sign-in form
17
+ # @return [User, Symbol] the authenticated user, or a symbol indicating the
18
+ # reason why the authentication failed
19
+ def self.authenticate_signin(signin)
20
+ super
21
+ end
22
+
23
+ # Change this to customize user lookup in the OmniAuth signup process.
24
+ #
25
+ # This method is called when there is no Credential matching the OmniAuth
26
+ # information, but before {User#create_from_omniauth}. It is an opportunity
27
+ # to identify an existing user who uses a new sign-in method.
28
+ #
29
+ # The default implementation finds an user whose e-mail matches the 'email'
30
+ # value in the OmniAuth hash.
31
+ #
32
+ # @param [Hash] omniauth_hash the hash provided by OmniAuth
33
+ # @return [User] the user who should be signed in, or nil if no such user
34
+ # exists
35
+ def self.related_to_omniauth(omniauth_hash)
36
+ super
37
+ end
38
+
39
+ # Change this to customize on-demand user creation on OmniAuth signup.
40
+ #
41
+ # This method is called when there is no existing user matching the OmniAuth
42
+ # information, and is responsible for creating a user. It is an opportunity
43
+ # to collect the OmniAuth information to populate the user's account.
44
+ #
45
+ # The default implementation creates a user with the e-mail matching the
46
+ # 'email' key in the OmniAuth hash. If no e-mail key is present, no User is
47
+ # created.
48
+ #
49
+ # @param [Hash] omniauth_hash the hash provided by OmniAuth
50
+ # @return [User] a saved User, or nil if the OmniAuth sign-in information
51
+ # should not be used to create a user
52
+ def self.create_from_omniauth(omniauth_hash)
18
53
  super
19
54
  end
20
55
 
@@ -2,14 +2,14 @@ require 'action_controller'
2
2
 
3
3
  # :nodoc: adds authenticates_using_http_basic
4
4
  class ActionController::Base
5
- # Keeps track of the currently authenticated user via the session.
5
+ # Keeps track of the currently authenticated user via the session.
6
6
  #
7
7
  # Assumes the existence of a User model. A bare ActiveModel model will do the
8
8
  # trick. Model instances must implement id, and the model class must implement
9
9
  # find_by_id.
10
10
  def self.authenticates_using_http_basic(options = {})
11
11
  include Authpwn::HttpBasicControllerInstanceMethods
12
- before_filter :authenticate_using_http_basic, options
12
+ before_filter :authenticate_using_http_basic, options
13
13
  end
14
14
  end
15
15
 
@@ -29,17 +29,18 @@ module HttpBasicControllerInstanceMethods
29
29
  def authenticate_using_http_basic
30
30
  return if current_user
31
31
  authenticate_with_http_basic do |email, password|
32
- auth = User.authenticate_signin email, password
32
+ signin = Session.new email: email, password: password
33
+ auth = User.authenticate_signin signin
33
34
  self.current_user = auth unless auth.kind_of? Symbol
34
35
  end
35
36
  end
36
37
  private :authenticate_using_http_basic
37
-
38
+
38
39
  # Inform the user that their request is forbidden.
39
40
  #
40
41
  # If a user is logged on, this renders the session/forbidden view with a HTTP
41
42
  # 403 code.
42
- #
43
+ #
43
44
  # If no user is logged in, a HTTP 403 code is returned, together with an
44
45
  # HTTP Authentication header causing the user-agent (browser) to initiate
45
46
  # http basic authentication.
@@ -10,17 +10,22 @@ module Routes
10
10
  module MapperMixin
11
11
  # Draws the routes for a session controller.
12
12
  #
13
- # The options hash accepts the following keys.
14
- # :controller:: the name of the controller; defaults to "session" for
15
- # SessionController
16
- # :paths:: the prefix of the route paths; defaults to the controller name
17
- # :method_names:: the root of name used in the path methods; defaults to
18
- # "session", which will generate names like session_path,
19
- # new_session_path, and token_session_path
13
+ # @param [Object] options
14
+ # @option options [String] controller the name of the controller; defaults to
15
+ # "session" for SessionController
16
+ # @option options [String] paths the prefix of the route paths; defaults to
17
+ # the controller name
18
+ # @option options [String] method_names the root of name used in the path
19
+ # methods; defaults to "session", which will generate names like
20
+ # session_path, new_session_path, and token_session_path
21
+ # @option options [String] omniauth_path_prefix the prefix of the OmniAuth
22
+ # route paths; defaults to '/auth'; this option should equal
23
+ # OmniAuth.config.path_prefix
20
24
  def authpwn_session(options = {})
21
25
  controller = options[:controller] || 'session'
22
26
  paths = options[:paths] || controller
23
27
  methods = options[:method_names] || 'session'
28
+ oa_prefix = options[:omniauth_path_prefix] || '/auth'
24
29
 
25
30
  get "/#{paths}/token/:code", controller: controller, action: 'token',
26
31
  as: :"token_#{methods}"
@@ -40,6 +45,14 @@ module MapperMixin
40
45
  post "/#{paths}/reset_password", controller: controller,
41
46
  action: 'reset_password',
42
47
  as: "reset_password_#{methods}"
48
+
49
+ match "#{oa_prefix}/:provider/callback", via: [:get, :post],
50
+ controller: controller,
51
+ action: 'omniauth',
52
+ as: "omniauth_#{methods}"
53
+ get "#{oa_prefix}/failure", controller: controller,
54
+ action: 'omniauth_failure',
55
+ as: "omniauth_failure_#{methods}"
43
56
  end
44
57
  end
45
58
 
@@ -45,7 +45,7 @@ module ControllerInstanceMethods
45
45
  end
46
46
  if user
47
47
  session[:authpwn_suid] = Tokens::SessionUid.random_for(user,
48
- request.remote_ip, request.user_agent).suid
48
+ request.remote_ip, request.user_agent || 'N/A').suid
49
49
  else
50
50
  session.delete :authpwn_suid
51
51
  end