authpwn_rails 0.13.4 → 0.14.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.
- data/.travis.yml +4 -2
- data/Gemfile +5 -5
- data/Gemfile.lock +47 -45
- data/Gemfile.rails3 +15 -0
- data/Gemfile.rails4 +15 -0
- data/VERSION +1 -1
- data/app/models/credentials/email.rb +35 -19
- data/app/models/credentials/facebook.rb +11 -9
- data/app/models/credentials/password.rb +7 -5
- data/app/models/tokens/base.rb +27 -14
- data/app/models/tokens/email_verification.rb +1 -1
- data/app/models/tokens/session_uid.rb +5 -5
- data/authpwn_rails.gemspec +15 -15
- data/lib/authpwn_rails/credential_model.rb +8 -6
- data/lib/authpwn_rails/expires.rb +1 -1
- data/lib/authpwn_rails/generators/templates/001_create_users.rb +4 -4
- data/lib/authpwn_rails/generators/templates/003_create_credentials.rb +8 -10
- data/lib/authpwn_rails/generators/templates/session/password_change.html.erb +1 -1
- data/lib/authpwn_rails/generators/templates/session_controller.rb +1 -1
- data/lib/authpwn_rails/generators/templates/session_controller_test.rb +9 -9
- data/lib/authpwn_rails/http_basic.rb +2 -2
- data/lib/authpwn_rails/routes.rb +18 -18
- data/lib/authpwn_rails/session.rb +3 -3
- data/lib/authpwn_rails/session_controller.rb +39 -25
- data/lib/authpwn_rails/session_mailer.rb +5 -5
- data/lib/authpwn_rails/test_extensions.rb +6 -6
- data/lib/authpwn_rails/user_extensions/email_field.rb +33 -16
- data/lib/authpwn_rails/user_extensions/facebook_fields.rb +1 -1
- data/lib/authpwn_rails/user_extensions/password_field.rb +17 -14
- data/lib/authpwn_rails/user_model.rb +9 -7
- data/test/cookie_controller_test.rb +22 -16
- data/test/credentials/facebook_credential_test.rb +17 -17
- data/test/credentials/password_credential_test.rb +1 -1
- data/test/credentials/password_reset_token_test.rb +1 -1
- data/test/credentials/session_uid_token_test.rb +1 -0
- data/test/credentials/token_crendential_test.rb +2 -4
- data/test/facebook_controller_test.rb +14 -14
- data/test/helpers/action_controller.rb +8 -0
- data/test/helpers/db_setup.rb +11 -9
- data/test/helpers/routes.rb +14 -9
- data/test/http_basic_controller_test.rb +35 -20
- data/test/routes_test.rb +18 -18
- data/test/session_controller_api_test.rb +76 -83
- data/test/test_helper.rb +4 -1
- data/test/user_extensions/email_field_test.rb +1 -1
- data/test/user_extensions/facebook_fields_test.rb +5 -5
- data/test/user_extensions/password_field_test.rb +2 -2
- metadata +14 -27
@@ -1,22 +1,20 @@
|
|
1
1
|
class CreateCredentials < ActiveRecord::Migration
|
2
2
|
def change
|
3
3
|
create_table :credentials do |t|
|
4
|
-
t.references :user, :
|
5
|
-
t.string :type, :
|
6
|
-
t.string :name, :
|
4
|
+
t.references :user, null: false
|
5
|
+
t.string :type, limit: 32, null: false
|
6
|
+
t.string :name, limit: 128, null: true
|
7
7
|
|
8
|
-
t.timestamp :updated_at, :
|
8
|
+
t.timestamp :updated_at, null: false
|
9
9
|
|
10
|
-
t.binary :key, :
|
10
|
+
t.binary :key, limit: 2.kilobytes, null: true
|
11
11
|
end
|
12
12
|
|
13
13
|
# All the credentials (maybe of a specific type) belonging to a user.
|
14
|
-
add_index :credentials, [:user_id, :type], :
|
15
|
-
:null => false
|
14
|
+
add_index :credentials, [:user_id, :type], unique: false
|
16
15
|
# A specific credential, to find out what user it belongs to.
|
17
|
-
add_index :credentials, [:type, :name],
|
16
|
+
add_index :credentials, [:type, :name], unique: true
|
18
17
|
# Expired credentials (particularly useful for tokens).
|
19
|
-
add_index :credentials, [:type, :updated_at], :
|
20
|
-
:null => false
|
18
|
+
add_index :credentials, [:type, :updated_at], unique: false
|
21
19
|
end
|
22
20
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<p class="password_age_notice">
|
12
12
|
Your have been using the same password for
|
13
13
|
<span class="password_age">
|
14
|
-
<%= time_ago_in_words @credential.updated_at, true %>.
|
14
|
+
<%= time_ago_in_words @credential.updated_at, :include_seconds => true %>.
|
15
15
|
</span>
|
16
16
|
</p>
|
17
17
|
<% end %>
|
@@ -34,7 +34,7 @@ class SessionController < ApplicationController
|
|
34
34
|
format.html do
|
35
35
|
case token
|
36
36
|
when Tokens::EmailVerification
|
37
|
-
redirect_to session_url, :
|
37
|
+
redirect_to session_url, notice: 'E-mail address confirmed'
|
38
38
|
when Tokens::PasswordReset
|
39
39
|
redirect_to change_password_session_url
|
40
40
|
# Handle other token types here.
|
@@ -20,7 +20,7 @@ class SessionControllerTest < ActionController::TestCase
|
|
20
20
|
old_token = credentials(:jane_session_token)
|
21
21
|
old_token.updated_at = Time.now - 1.year
|
22
22
|
old_token.save!
|
23
|
-
post :create, :
|
23
|
+
post :create, email: @email_credential.email, password: 'password'
|
24
24
|
assert_equal @user, session_current_user, 'session'
|
25
25
|
assert_redirected_to session_url
|
26
26
|
assert_nil Tokens::Base.with_code(old_token.code).first,
|
@@ -29,7 +29,7 @@ class SessionControllerTest < ActionController::TestCase
|
|
29
29
|
|
30
30
|
test "user logged in JSON request" do
|
31
31
|
set_session_current_user @user
|
32
|
-
get :show, :
|
32
|
+
get :show, format: 'json'
|
33
33
|
|
34
34
|
assert_equal @user.exuid,
|
35
35
|
ActiveSupport::JSON.decode(response.body)['user']['exuid']
|
@@ -43,7 +43,7 @@ class SessionControllerTest < ActionController::TestCase
|
|
43
43
|
end
|
44
44
|
|
45
45
|
test "user not logged in with JSON request" do
|
46
|
-
get :show, :
|
46
|
+
get :show, format: 'json'
|
47
47
|
|
48
48
|
assert_equal({}, ActiveSupport::JSON.decode(response.body))
|
49
49
|
end
|
@@ -61,16 +61,16 @@ class SessionControllerTest < ActionController::TestCase
|
|
61
61
|
end
|
62
62
|
|
63
63
|
test "e-mail verification link" do
|
64
|
-
get :token, :
|
64
|
+
get :token, code: @token_credential.code
|
65
65
|
assert_redirected_to session_url
|
66
66
|
assert @email_credential.reload.verified?, 'Email not verified'
|
67
67
|
end
|
68
68
|
|
69
69
|
test "password reset link" do
|
70
70
|
password_credential = credentials(:jane_password)
|
71
|
-
get :token, :
|
71
|
+
get :token, code: credentials(:jane_password_token).code
|
72
72
|
assert_redirected_to change_password_session_url
|
73
|
-
assert_nil Credential.where(:
|
73
|
+
assert_nil Credential.where(id: password_credential.id).first,
|
74
74
|
'Password not cleared'
|
75
75
|
end
|
76
76
|
|
@@ -93,10 +93,10 @@ class SessionControllerTest < ActionController::TestCase
|
|
93
93
|
@password_credential.destroy
|
94
94
|
get :password_change
|
95
95
|
|
96
|
-
assert_select 'span[class="password_age"]', :
|
96
|
+
assert_select 'span[class="password_age"]', count: 0
|
97
97
|
assert_select 'form[action=?][method="post"]',
|
98
98
|
change_password_session_path do
|
99
|
-
assert_select 'input[name="old_password"]', :
|
99
|
+
assert_select 'input[name="old_password"]', count: 0
|
100
100
|
assert_select 'input[name=?]', 'credential[password]'
|
101
101
|
assert_select 'input[name=?]', 'credential[password_confirmation]'
|
102
102
|
assert_select 'input[type=submit]'
|
@@ -107,7 +107,7 @@ class SessionControllerTest < ActionController::TestCase
|
|
107
107
|
ActionMailer::Base.deliveries = []
|
108
108
|
|
109
109
|
assert_difference 'Credential.count', 1 do
|
110
|
-
post :reset_password, :
|
110
|
+
post :reset_password, email: @email_credential.email
|
111
111
|
end
|
112
112
|
|
113
113
|
assert !ActionMailer::Base.deliveries.empty?, 'email generated'
|
@@ -51,10 +51,10 @@ module HttpBasicControllerInstanceMethods
|
|
51
51
|
|
52
52
|
respond_to do |format|
|
53
53
|
format.html do
|
54
|
-
render 'session/forbidden', :
|
54
|
+
render 'session/forbidden', status: :forbidden
|
55
55
|
end
|
56
56
|
format.json do
|
57
|
-
render :
|
57
|
+
render json: { error: "You're not allowed to access that" }
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
data/lib/authpwn_rails/routes.rb
CHANGED
@@ -22,24 +22,24 @@ module MapperMixin
|
|
22
22
|
paths = options[:paths] || controller
|
23
23
|
methods = options[:method_names] || 'session'
|
24
24
|
|
25
|
-
get "/#{paths}/token/:code", :
|
26
|
-
:
|
27
|
-
|
28
|
-
get "/#{paths}", :
|
29
|
-
:
|
30
|
-
get "/#{paths}/new", :
|
31
|
-
:
|
32
|
-
post "/#{paths}", :
|
33
|
-
delete "/#{paths}", :
|
34
|
-
|
35
|
-
get "/#{paths}/change_password", :
|
36
|
-
:
|
37
|
-
:
|
38
|
-
post "/#{paths}/change_password", :
|
39
|
-
:
|
40
|
-
post "/#{paths}/reset_password", :
|
41
|
-
:
|
42
|
-
:
|
25
|
+
get "/#{paths}/token/:code", controller: controller, action: 'token',
|
26
|
+
as: :"token_#{methods}"
|
27
|
+
|
28
|
+
get "/#{paths}", controller: controller, action: 'show',
|
29
|
+
as: :"#{methods}"
|
30
|
+
get "/#{paths}/new", controller: controller, action: 'new',
|
31
|
+
as: :"new_#{methods}"
|
32
|
+
post "/#{paths}", controller: controller, action: 'create'
|
33
|
+
delete "/#{paths}", controller: controller, action: 'destroy'
|
34
|
+
|
35
|
+
get "/#{paths}/change_password", controller: controller,
|
36
|
+
action: 'password_change',
|
37
|
+
as: "change_password_#{methods}"
|
38
|
+
post "/#{paths}/change_password", controller: controller,
|
39
|
+
action: 'change_password'
|
40
|
+
post "/#{paths}/reset_password", controller: controller,
|
41
|
+
action: 'reset_password',
|
42
|
+
as: "reset_password_#{methods}"
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -78,16 +78,16 @@ module ControllerInstanceMethods
|
|
78
78
|
format.html do
|
79
79
|
@redirect_url = redirect_url
|
80
80
|
if current_user
|
81
|
-
render 'session/forbidden', :
|
81
|
+
render 'session/forbidden', status: :forbidden
|
82
82
|
else
|
83
83
|
flash[:auth_redirect_url] = redirect_url
|
84
|
-
render 'session/forbidden', :
|
84
|
+
render 'session/forbidden', status: :forbidden
|
85
85
|
end
|
86
86
|
end
|
87
87
|
format.json do
|
88
88
|
message = current_user ? "You're not allowed to access that" :
|
89
89
|
'Please sign in'
|
90
|
-
render :
|
90
|
+
render json: { error: message }
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -12,7 +12,7 @@ module SessionController
|
|
12
12
|
|
13
13
|
included do
|
14
14
|
skip_filter :authenticate_using_session
|
15
|
-
authenticates_using_session :
|
15
|
+
authenticates_using_session except: [:create, :reset_password, :token]
|
16
16
|
|
17
17
|
# If set, every successful login will cause a database purge.
|
18
18
|
class_attribute :auto_purge_sessions
|
@@ -33,20 +33,19 @@ module SessionController
|
|
33
33
|
welcome
|
34
34
|
unless performed?
|
35
35
|
respond_to do |format|
|
36
|
-
format.html { render :
|
37
|
-
format.json { render :
|
36
|
+
format.html { render action: :welcome }
|
37
|
+
format.json { render json: {} }
|
38
38
|
end
|
39
39
|
end
|
40
40
|
else
|
41
41
|
home
|
42
42
|
unless performed?
|
43
43
|
respond_to do |format|
|
44
|
-
format.html { render :
|
44
|
+
format.html { render action: :home }
|
45
45
|
format.json do
|
46
46
|
user_data = @user.as_json
|
47
47
|
user_data = user_data['user'] if @user.class.include_root_in_json
|
48
|
-
render :
|
49
|
-
:csrf => form_authenticity_token }
|
48
|
+
render json: { user: user_data, csrf: form_authenticity_token }
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
@@ -74,16 +73,15 @@ module SessionController
|
|
74
73
|
if current_user.class.include_root_in_json
|
75
74
|
user_data = user_data['user']
|
76
75
|
end
|
77
|
-
render :
|
78
|
-
:csrf => form_authenticity_token }
|
76
|
+
render json: { user: user_data, csrf: form_authenticity_token }
|
79
77
|
end
|
80
78
|
else
|
81
79
|
error_text = bounce_notice_text auth
|
82
80
|
format.html do
|
83
|
-
redirect_to new_session_url, :
|
84
|
-
:
|
81
|
+
redirect_to new_session_url, flash: { alert: error_text,
|
82
|
+
auth_redirect_url: @redirect_url }
|
85
83
|
end
|
86
|
-
format.json { render :
|
84
|
+
format.json { render json: { error: auth, text: error_text } }
|
87
85
|
end
|
88
86
|
end
|
89
87
|
end
|
@@ -101,17 +99,17 @@ module SessionController
|
|
101
99
|
respond_to do |format|
|
102
100
|
if user
|
103
101
|
format.html do
|
104
|
-
redirect_to new_session_url, :
|
102
|
+
redirect_to new_session_url, alert:
|
105
103
|
'Please check your e-mail for instructions'
|
106
104
|
end
|
107
|
-
format.json { render :
|
105
|
+
format.json { render json: { } }
|
108
106
|
else
|
109
107
|
error_text = 'Invalid e-mail'
|
110
108
|
format.html do
|
111
|
-
redirect_to new_session_url, :
|
109
|
+
redirect_to new_session_url, alert: error_text
|
112
110
|
end
|
113
111
|
format.json do
|
114
|
-
render :
|
112
|
+
render json: { error: :not_found, text: notice }
|
115
113
|
end
|
116
114
|
end
|
117
115
|
end
|
@@ -129,10 +127,10 @@ module SessionController
|
|
129
127
|
error_text = bounce_notice_text auth
|
130
128
|
respond_to do |format|
|
131
129
|
format.html do
|
132
|
-
redirect_to new_session_url, :
|
133
|
-
:
|
130
|
+
redirect_to new_session_url, flash: { alert: error_text,
|
131
|
+
auth_redirect_url: session_url }
|
134
132
|
end
|
135
|
-
format.json { render :
|
133
|
+
format.json { render json: { error: auth, text: error_text } }
|
136
134
|
end
|
137
135
|
else
|
138
136
|
self.set_session_current_user auth
|
@@ -145,8 +143,7 @@ module SessionController
|
|
145
143
|
if current_user.class.include_root_in_json
|
146
144
|
user_data = user_data['user']
|
147
145
|
end
|
148
|
-
render :
|
149
|
-
:csrf => form_authenticity_token }
|
146
|
+
render json: { user: user_data, csrf: form_authenticity_token }
|
150
147
|
end
|
151
148
|
end
|
152
149
|
end
|
@@ -194,29 +191,46 @@ module SessionController
|
|
194
191
|
if @credential
|
195
192
|
# An old password is set, must verify it.
|
196
193
|
if @credential.check_password params[:old_password]
|
197
|
-
success = @credential.update_attributes
|
194
|
+
success = @credential.update_attributes(
|
195
|
+
change_password_params[:credential])
|
198
196
|
else
|
199
197
|
success = false
|
200
198
|
flash[:alert] = 'Incorrect old password. Please try again.'
|
201
199
|
end
|
202
200
|
else
|
203
|
-
@credential = Credentials::Password.new
|
201
|
+
@credential = Credentials::Password.new(
|
202
|
+
change_password_params[:credential])
|
204
203
|
@credential.user = current_user
|
205
204
|
success = @credential.save
|
206
205
|
end
|
207
206
|
respond_to do |format|
|
208
207
|
if success
|
209
208
|
format.html do
|
210
|
-
redirect_to session_url, :
|
209
|
+
redirect_to session_url, notice: 'Password updated'
|
211
210
|
end
|
212
211
|
format.json { head :ok }
|
213
212
|
else
|
214
|
-
format.html { render :
|
215
|
-
format.json { render :
|
213
|
+
format.html { render action: :password_change }
|
214
|
+
format.json { render json: { error: :invalid } }
|
216
215
|
end
|
217
216
|
end
|
218
217
|
end
|
219
218
|
|
219
|
+
if defined? ActiveModel::ForbiddenAttributesProtection
|
220
|
+
# Rails 4.
|
221
|
+
|
222
|
+
# Parameters used to change the user's password.
|
223
|
+
def change_password_params
|
224
|
+
params.permit :format, :old_password,
|
225
|
+
credential: [ :password, :password_confirmation ]
|
226
|
+
end
|
227
|
+
else
|
228
|
+
# Rails 3.
|
229
|
+
def change_password_params
|
230
|
+
params
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
220
234
|
# True for controllers belonging to the authentication implementation.
|
221
235
|
#
|
222
236
|
# Controllers that return true here are responsible for performing their own
|
@@ -16,9 +16,9 @@ module SessionMailer
|
|
16
16
|
@host.slice! -1 if @host[-1] == ?/
|
17
17
|
hostname = @host.split(':', 2).first # Strip out any port.
|
18
18
|
|
19
|
-
mail :
|
20
|
-
:
|
21
|
-
:
|
19
|
+
mail to: @token.email,
|
20
|
+
subject: email_verification_subject(token, hostname, @protocol),
|
21
|
+
from: email_verification_from(token, hostname, @protocol)
|
22
22
|
end
|
23
23
|
|
24
24
|
# The subject line in an e-mail verification e-mail.
|
@@ -48,8 +48,8 @@ module SessionMailer
|
|
48
48
|
@host.slice! -1 if @host[-1] == ?/
|
49
49
|
|
50
50
|
hostname = @host.split(':', 2).first # Strip out any port.
|
51
|
-
mail :
|
52
|
-
:
|
51
|
+
mail to: email, from: reset_password_from(token, hostname, @protocol),
|
52
|
+
subject: reset_password_subject(token, hostname, @protocol)
|
53
53
|
end
|
54
54
|
|
55
55
|
# The subject line in a password reset e-mail.
|
@@ -11,7 +11,7 @@ module TestExtensions
|
|
11
11
|
# the credential matches the given argument, and nil otherwise.
|
12
12
|
def with_blocked_credential(blocked_credential, reason = :blocked, &block)
|
13
13
|
# Stub a method in all User instances for this test only.
|
14
|
-
#
|
14
|
+
# mocha.any_instance doesn't work because ActiveRecord doesn't use new
|
15
15
|
# to instantiate records.
|
16
16
|
::User.class_eval do
|
17
17
|
alias_method :_auth_bounce_reason_wbc_stub, :auth_bounce_reason
|
@@ -42,7 +42,7 @@ module ControllerTestExtensions
|
|
42
42
|
def set_session_current_user(user)
|
43
43
|
if user
|
44
44
|
# Avoid database inserts, if at all possible.
|
45
|
-
if token = Tokens::SessionUid.where(:
|
45
|
+
if token = Tokens::SessionUid.where(user_id: user.id).first
|
46
46
|
token.spend # Only bump updated_at if necessary.
|
47
47
|
else
|
48
48
|
token = Tokens::SessionUid.random_for user, '127.0.0.1', 'UnitTests'
|
@@ -75,17 +75,17 @@ module ControllerTestExtensions
|
|
75
75
|
|
76
76
|
if password.nil?
|
77
77
|
password = 'password'
|
78
|
-
credential = Credentials::Password.where(:
|
78
|
+
credential = Credentials::Password.where(user_id: user.id).first
|
79
79
|
if credential
|
80
|
-
credential.update_attributes! :
|
80
|
+
credential.update_attributes! password: password
|
81
81
|
else
|
82
|
-
credential = Credentials::Password.new :
|
82
|
+
credential = Credentials::Password.new password: password
|
83
83
|
credential.user_id = user.id
|
84
84
|
credential.save!
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
credential = Credentials::Email.where(:
|
88
|
+
credential = Credentials::Email.where(user_id: user.id).first
|
89
89
|
unless credential
|
90
90
|
raise RuntimeError, "Can't specify an user without an e-mail"
|
91
91
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_model'
|
2
|
+
require 'active_record'
|
2
3
|
require 'active_support'
|
3
4
|
|
4
5
|
# :nodoc: namespace
|
@@ -6,30 +7,46 @@ module Authpwn
|
|
6
7
|
|
7
8
|
# :nodoc: namespace
|
8
9
|
module UserExtensions
|
9
|
-
|
10
|
+
|
10
11
|
# Augments the User model with an email virtual attribute.
|
11
12
|
module EmailField
|
12
13
|
extend ActiveSupport::Concern
|
13
|
-
|
14
|
+
|
14
15
|
included do
|
15
|
-
validates :email, :
|
16
|
-
:
|
17
|
-
|
16
|
+
validates :email, format: /\A[A-Za-z0-9.+_]+@[^@]*\.(\w+)\Z/,
|
17
|
+
presence: true
|
18
|
+
if ActiveRecord::Base.respond_to? :mass_assignment_sanitizer=
|
19
|
+
attr_accessible :email
|
20
|
+
end
|
18
21
|
end
|
19
|
-
|
22
|
+
|
20
23
|
module ClassMethods
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
begin
|
25
|
+
ActiveRecord::QueryMethods.instance_method :references
|
26
|
+
# Rails 4.
|
27
|
+
|
28
|
+
# The user who has a certain e-mail, or nil if the e-mail is unclaimed.
|
29
|
+
def with_email(email)
|
30
|
+
credential = Credentials::Email.where(name: email).
|
31
|
+
includes(:user).references(:user).first
|
32
|
+
credential && credential.user
|
33
|
+
end
|
34
|
+
rescue NameError
|
35
|
+
# Rails 3.
|
36
|
+
|
37
|
+
def with_email(email)
|
38
|
+
credential = Credentials::Email.where(name: email).includes(:user).
|
39
|
+
first
|
40
|
+
credential && credential.user
|
41
|
+
end
|
25
42
|
end
|
26
43
|
end
|
27
|
-
|
44
|
+
|
28
45
|
# Credentials::Email instance associated with this user.
|
29
46
|
def email_credential
|
30
47
|
credentials.find { |c| c.instance_of?(Credentials::Email) }
|
31
48
|
end
|
32
|
-
|
49
|
+
|
33
50
|
# The e-mail from the user's Email credential.
|
34
51
|
#
|
35
52
|
# Returns nil if this user has no Email credential.
|
@@ -37,7 +54,7 @@ module EmailField
|
|
37
54
|
credential = self.email_credential
|
38
55
|
credential && credential.email
|
39
56
|
end
|
40
|
-
|
57
|
+
|
41
58
|
# Sets the e-mail on the user's Email credential.
|
42
59
|
#
|
43
60
|
# Creates a new Credentials::Email instance if necessary.
|
@@ -45,12 +62,12 @@ module EmailField
|
|
45
62
|
if credential = self.email_credential
|
46
63
|
credential.email = new_email
|
47
64
|
else
|
48
|
-
credentials << Credentials::Email.new(:
|
65
|
+
credentials << Credentials::Email.new(email: new_email)
|
49
66
|
end
|
50
67
|
new_email
|
51
68
|
end
|
52
69
|
end # module Authpwn::UserExtensions::EmailField
|
53
|
-
|
70
|
+
|
54
71
|
end # module Authpwn::UserExtensions
|
55
|
-
|
72
|
+
|
56
73
|
end # module Authpwn
|
@@ -22,7 +22,7 @@ module FacebookFields
|
|
22
22
|
|
23
23
|
# The user who has a certain e-mail, or nil if the e-mail is unclaimed.
|
24
24
|
def with_facebook_uid(facebook_uid)
|
25
|
-
credential = Credentials::Facebook.where(:
|
25
|
+
credential = Credentials::Facebook.where(name: facebook_uid).
|
26
26
|
includes(:user).first
|
27
27
|
credential && credential.user
|
28
28
|
end
|
@@ -6,30 +6,33 @@ module Authpwn
|
|
6
6
|
|
7
7
|
# :nodoc: namespace
|
8
8
|
module UserExtensions
|
9
|
-
|
9
|
+
|
10
10
|
# Augments the User model with a password virtual attribute.
|
11
11
|
module PasswordField
|
12
12
|
extend ActiveSupport::Concern
|
13
|
-
|
13
|
+
|
14
14
|
included do
|
15
|
-
validates :password, :
|
16
|
-
:
|
17
|
-
|
15
|
+
validates :password, presence: { on: :create },
|
16
|
+
confirmation: { allow_nil: true }
|
17
|
+
|
18
|
+
if ActiveRecord::Base.respond_to? :mass_assignment_sanitizer=
|
19
|
+
attr_accessible :password, :password_confirmation
|
20
|
+
end
|
18
21
|
end
|
19
|
-
|
22
|
+
|
20
23
|
module ClassMethods
|
21
24
|
# The user who has a certain e-mail, or nil if the e-mail is unclaimed.
|
22
25
|
def with_email(email)
|
23
|
-
credential = Credentials::Email.where(:
|
26
|
+
credential = Credentials::Email.where(name: email).includes(:user).first
|
24
27
|
credential && credential.user
|
25
28
|
end
|
26
29
|
end
|
27
|
-
|
30
|
+
|
28
31
|
# Credentials::Password instance associated with this user.
|
29
32
|
def password_credential
|
30
33
|
credentials.find { |c| c.instance_of?(Credentials::Password) }
|
31
34
|
end
|
32
|
-
|
35
|
+
|
33
36
|
# The password from the user's Password credential, or nil.
|
34
37
|
#
|
35
38
|
# Returns nil if this user has no Password credential.
|
@@ -37,7 +40,7 @@ module PasswordField
|
|
37
40
|
credential = self.password_credential
|
38
41
|
credential && credential.password
|
39
42
|
end
|
40
|
-
|
43
|
+
|
41
44
|
# The password_confirmation from the user's Password credential, or nil.
|
42
45
|
#
|
43
46
|
# Returns nil if this user has no Password credential.
|
@@ -53,7 +56,7 @@ module PasswordField
|
|
53
56
|
if credential = self.password_credential
|
54
57
|
credential.password = new_password
|
55
58
|
else
|
56
|
-
credentials << Credentials::Password.new(:
|
59
|
+
credentials << Credentials::Password.new(password: new_password)
|
57
60
|
end
|
58
61
|
new_password
|
59
62
|
end
|
@@ -65,13 +68,13 @@ module PasswordField
|
|
65
68
|
if credential = self.password_credential
|
66
69
|
credential.password_confirmation = new_password_confirmation
|
67
70
|
else
|
68
|
-
credentials << Credentials::Password.new(:
|
71
|
+
credentials << Credentials::Password.new(password_confirmation:
|
69
72
|
new_password_confirmation)
|
70
73
|
end
|
71
74
|
new_password_confirmation
|
72
75
|
end
|
73
76
|
end # module Authpwn::UserExtensions::PasswordField
|
74
|
-
|
77
|
+
|
75
78
|
end # module Authpwn::UserExtensions
|
76
|
-
|
79
|
+
|
77
80
|
end # module Authpwn
|
@@ -17,18 +17,20 @@ module UserModel
|
|
17
17
|
#
|
18
18
|
# This is decoupled from "id" column to avoid leaking information about
|
19
19
|
# the application's usage.
|
20
|
-
validates :exuid, :
|
20
|
+
validates :exuid, presence: true, length: 1..32, uniqueness: true
|
21
21
|
|
22
22
|
# Credentials used to authenticate the user.
|
23
|
-
has_many :credentials, :
|
24
|
-
:
|
23
|
+
has_many :credentials, dependent: :destroy, inverse_of: :user,
|
24
|
+
autosave: true
|
25
25
|
validates_associated :credentials
|
26
26
|
|
27
27
|
# Automatically assign exuid.
|
28
|
-
before_validation :set_default_exuid, :
|
28
|
+
before_validation :set_default_exuid, on: :create
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
if ActiveRecord::Base.respond_to? :mass_assignment_sanitizer=
|
31
|
+
# Forms should not be able to touch any attribute.
|
32
|
+
attr_accessible :credentials_attributes
|
33
|
+
end
|
32
34
|
end
|
33
35
|
|
34
36
|
# Class methods on models that include Authpwn::UserModel.
|
@@ -38,7 +40,7 @@ module UserModel
|
|
38
40
|
# @param [String] param value returned by User#to_param
|
39
41
|
# @return [ActiveRecord::Relation]
|
40
42
|
def with_param(param)
|
41
|
-
where(:
|
43
|
+
where(exuid: param)
|
42
44
|
end
|
43
45
|
|
44
46
|
# Queries the database using the value returned by User#to_param.
|