authpwn_rails 0.16.2 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
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