rodauth 1.6.0 → 1.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8be62d375631a0d62337cc9da83782e1a765ecc1
4
- data.tar.gz: e5cc52f5bec8e0f7820b1b16ac11d96d385e0187
3
+ metadata.gz: 72d21867a8a5d725cfe2331b979ffbe31f3e9e9a
4
+ data.tar.gz: b204b666ab3b52ab94c291a660af0c6f6741772b
5
5
  SHA512:
6
- metadata.gz: cd373d957b4b636afab06b24a7c782c9b3e605de844f0083c7eb2953779715dc4fec20418984ef4cdbce93d9f65e4848eed11a8318985d52d03ecdb9b2f1301f
7
- data.tar.gz: d156aaad0e89d164a467e44c946088f28487db41a4b0cb1ec57dda6584ca36ffbb8c87daf02bcc868dcfe8322bf56fc4fa005ab9fdfd2cd0b8620bce6334d593
6
+ metadata.gz: 6e7ec902dd360cf3687097e3c8934687f8915f277334270b2acbf3a02e33314e83cb42631ae3539d8edfaa87dc50aaebeef5b184f0fdc601c1d0c8ee196156be
7
+ data.tar.gz: 49de39a38e7cb00f6869c4c0bc25f7df521f541615373d21530d802b5d390924a178b86274620ed6b08517157bd704eaad1dc5c7847e9ee2ef5df1d2ae25ac44
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.7.0 (2016-11-22)
2
+
3
+ * Make reset password, unlock account, and verify account pages not leak keys to external servers via Referer header (jeremyevans)
4
+
1
5
  === 1.6.0 (2016-10-24)
2
6
 
3
7
  * Add http_basic_auth feature (TiagoCardoso1983, jeremyevans) (#12)
@@ -161,9 +161,10 @@ Example:
161
161
  psql -U postgres -c "CREATE EXTENSION citext" ${DATABASE_NAME}
162
162
 
163
163
  Note that on Heroku, this extension can be loaded using a standard database
164
- account. If you don't want to support case sensitive logins, you don't
165
- need to use the PostgreSQL citext extension. Just remember to modify the
166
- migration below to use +String+ instead of +citext+ for the email.
164
+ account. If you want logins to be case sensitive (generally considered a
165
+ bad idea), you don't need to use the PostgreSQL citext extension. Just
166
+ remember to modify the migration below to use +String+ instead of +citext+
167
+ for the email in that case.
167
168
 
168
169
  === Create database accounts
169
170
 
data/Rakefile CHANGED
@@ -61,9 +61,10 @@ end
61
61
 
62
62
  desc "Run specs with -w, some warnings filtered"
63
63
  task "spec_w" do
64
- ENV['RUBYOPT'] ? (ENV['RUBYOPT'] += " -w") : (ENV['RUBYOPT'] = '-w')
65
- rake = ENV['RAKE'] || "#{FileUtils::RUBY} -S rake"
66
- sh %{#{rake} 2>&1 | egrep -v \": warning: instance variable @.* not initialized|: warning: method redefined; discarding old|: warning: previous definition of|: warning: statement not reached"}
64
+ rubyopt = ENV['RUBYOPT']
65
+ ENV['RUBYOPT'] = "#{rubyopt} -w"
66
+ spec.call('WARNING'=>'1')
67
+ ENV['RUBYOPT'] = rubyopt
67
68
  end
68
69
 
69
70
  desc "Setup database used for testing on PostgreSQL"
@@ -51,6 +51,7 @@ unlock_account_requires_password? :: Whether a password is required when unlocki
51
51
  false by default. May want to set to true if not
52
52
  allowing password resets.
53
53
  unlock_account_route :: Alias for lockout_route.
54
+ unlock_account_session_key :: The key in the session to hold the unlock account key temporarily.
54
55
 
55
56
  == Auth Methods
56
57
 
@@ -0,0 +1,6 @@
1
+ = Improvements
2
+
3
+ * The reset password, unlock account, and verify account features now
4
+ temporarily store the feature-specific keys in the session instead
5
+ of keeping them as parameters, which avoids leaking the keys to
6
+ asset hosts or other external servers via the HTTP Referer header.
@@ -40,6 +40,7 @@ reset_password_request_error_flash :: The flash error to show if not able to sen
40
40
  password email.
41
41
  reset_password_request_route :: The route to the reset password request action.
42
42
  reset_password_route :: The route to the reset password action.
43
+ reset_password_session_key :: The key in the session to hold the reset password key temporarily.
43
44
  reset_password_table :: The name of the reset password keys table.
44
45
 
45
46
  == Auth Methods
@@ -40,6 +40,7 @@ verify_account_resend_error_flash :: The flash error to show if unable to resend
40
40
  verify account email.
41
41
  verify_account_resend_route :: The route to the verify account resend action.
42
42
  verify_account_route :: The route to the verify account action.
43
+ verify_account_session_key :: The key in the session to hold the verify account key temporarily.
43
44
  verify_account_table :: The name of the verify account keys table.
44
45
 
45
46
  == Auth Methods
@@ -43,7 +43,6 @@ module Rodauth
43
43
  private
44
44
 
45
45
  def password_doesnt_match_previous_password?(password)
46
- id = account_id
47
46
  match = if use_database_authentication_functions?
48
47
  salts = previous_password_ds.
49
48
  select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
@@ -35,6 +35,7 @@ module Rodauth
35
35
  auth_value_method :unlock_account_email_subject, 'Unlock Account'
36
36
  auth_value_method :unlock_account_key_param, 'key'
37
37
  auth_value_method :unlock_account_requires_password?, false
38
+ auth_value_method :unlock_account_session_key, :unlock_account_key
38
39
 
39
40
  auth_value_methods(
40
41
  :unlock_account_redirect,
@@ -81,16 +82,24 @@ module Rodauth
81
82
  before_unlock_account_route
82
83
 
83
84
  r.get do
84
- if account_from_unlock_key(param(unlock_account_key_param))
85
- unlock_account_view
86
- else
87
- set_redirect_error_flash no_matching_unlock_account_key_message
88
- redirect require_login_redirect
85
+ if key = param_or_nil(unlock_account_key_param)
86
+ session[unlock_account_session_key] = key
87
+ redirect(r.path)
88
+ end
89
+
90
+ if key = session[unlock_account_session_key]
91
+ if account_from_unlock_key(key)
92
+ unlock_account_view
93
+ else
94
+ session[unlock_account_session_key] = nil
95
+ set_redirect_error_flash no_matching_unlock_account_key_message
96
+ redirect require_login_redirect
97
+ end
89
98
  end
90
99
  end
91
100
 
92
101
  r.post do
93
- key = param(unlock_account_key_param)
102
+ key = session[unlock_account_session_key] || param(unlock_account_key_param)
94
103
  unless account_from_unlock_key(key)
95
104
  set_redirect_error_flash no_matching_unlock_account_key_message
96
105
  redirect unlock_account_request_redirect
@@ -106,6 +115,7 @@ module Rodauth
106
115
  end
107
116
  end
108
117
 
118
+ session[unlock_account_session_key] = nil
109
119
  set_notice_flash unlock_account_notice_flash
110
120
  redirect unlock_account_redirect
111
121
  else
@@ -31,7 +31,7 @@ module Rodauth
31
31
  super
32
32
  return if singleton_methods.map(&:to_sym).include?(:password_dictionary)
33
33
 
34
- case dictionary_file = password_dictionary_file
34
+ case password_dictionary_file
35
35
  when false
36
36
  return
37
37
  when nil
@@ -29,6 +29,7 @@ module Rodauth
29
29
  auth_value_method :reset_password_table, :account_password_reset_keys
30
30
  auth_value_method :reset_password_id_column, :id
31
31
  auth_value_method :reset_password_key_column, :key
32
+ auth_value_method :reset_password_session_key, :reset_password_key
32
33
 
33
34
  auth_value_methods :reset_password_email_sent_redirect
34
35
 
@@ -76,9 +77,15 @@ module Rodauth
76
77
 
77
78
  r.get do
78
79
  if key = param_or_nil(reset_password_key_param)
80
+ session[reset_password_session_key] = key
81
+ redirect(r.path)
82
+ end
83
+
84
+ if key = session[reset_password_session_key]
79
85
  if account_from_reset_password_key(key)
80
86
  reset_password_view
81
87
  else
88
+ session[reset_password_session_key] = nil
82
89
  set_redirect_error_flash no_matching_reset_password_key_message
83
90
  redirect require_login_redirect
84
91
  end
@@ -86,7 +93,7 @@ module Rodauth
86
93
  end
87
94
 
88
95
  r.post do
89
- key = param(reset_password_key_param)
96
+ key = session[reset_password_session_key] || param(reset_password_key_param)
90
97
  unless account_from_reset_password_key(key)
91
98
  set_redirect_error_flash reset_password_error_flash
92
99
  redirect reset_password_email_sent_redirect
@@ -117,6 +124,7 @@ module Rodauth
117
124
  update_session
118
125
  end
119
126
 
127
+ session[reset_password_session_key] = nil
120
128
  set_notice_flash reset_password_notice_flash
121
129
  redirect reset_password_redirect
122
130
  end
@@ -30,6 +30,7 @@ module Rodauth
30
30
  auth_value_method :verify_account_table, :account_verification_keys
31
31
  auth_value_method :verify_account_id_column, :id
32
32
  auth_value_method :verify_account_key_column, :key
33
+ auth_value_method :verify_account_session_key, :verify_account_key
33
34
 
34
35
  auth_value_methods :verify_account_key_value
35
36
 
@@ -76,9 +77,15 @@ module Rodauth
76
77
 
77
78
  r.get do
78
79
  if key = param_or_nil(verify_account_key_param)
80
+ session[verify_account_session_key] = key
81
+ redirect(r.path)
82
+ end
83
+
84
+ if key = session[verify_account_session_key]
79
85
  if account_from_verify_account_key(key)
80
86
  verify_account_view
81
87
  else
88
+ session[verify_account_session_key] = nil
82
89
  set_redirect_error_flash no_matching_verify_account_key_message
83
90
  redirect require_login_redirect
84
91
  end
@@ -86,7 +93,7 @@ module Rodauth
86
93
  end
87
94
 
88
95
  r.post do
89
- key = param(verify_account_key_param)
96
+ key = session[verify_account_session_key] || param(verify_account_key_param)
90
97
  unless account_from_verify_account_key(key)
91
98
  set_redirect_error_flash verify_account_error_flash
92
99
  redirect verify_account_redirect
@@ -103,6 +110,7 @@ module Rodauth
103
110
  update_session
104
111
  end
105
112
 
113
+ session[verify_account_session_key] = nil
106
114
  set_notice_flash verify_account_notice_flash
107
115
  redirect verify_account_redirect
108
116
  end
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Rodauth
4
- VERSION = '1.6.0'.freeze
4
+ VERSION = '1.7.0'.freeze
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -48,7 +48,9 @@ describe 'Rodauth password complexity feature' do
48
48
  it "should support default dictionary" do
49
49
  default_dictionary = '/usr/share/dict/words'
50
50
  skip("#{default_dictionary} not present") unless File.file?(default_dictionary)
51
- password = File.read(default_dictionary).split.sort_by{|w| w.length}.last
51
+ pass = File.read(default_dictionary).split.sort_by{|w| w.length}.last
52
+ skip("#{default_dictionary} empty") unless pass
53
+ pass = pass.downcase.gsub(/[^a-z]/, '')
52
54
 
53
55
  rodauth do
54
56
  enable :login, :change_password, :password_complexity
@@ -78,7 +80,6 @@ describe 'Rodauth password complexity feature' do
78
80
  it "should support no dictionary" do
79
81
  default_dictionary = '/usr/share/dict/words'
80
82
  skip("#{default_dictionary} not present") unless File.file?(default_dictionary)
81
- password = File.read(default_dictionary).split.sort_by{|w| w.length}.last
82
83
 
83
84
  rodauth do
84
85
  enable :login, :change_password, :password_complexity
@@ -113,7 +113,7 @@ describe 'Rodauth reset_password feature' do
113
113
 
114
114
  login(:pass=>'01234567')
115
115
  click_button 'Request Password Reset'
116
- link = email_link(/(\/reset-password\?key=.+)$/)
116
+ email_link(/(\/reset-password\?key=.+)$/)
117
117
 
118
118
  login
119
119
 
@@ -187,7 +187,6 @@ describe 'Rodauth' do
187
187
  end
188
188
 
189
189
  it "should support account_select setting for choosing account columns" do
190
- warning = nil
191
190
  rodauth do
192
191
  enable :login
193
192
  account_select [:id, :email]
@@ -1,5 +1,12 @@
1
1
  $: << 'lib'
2
2
 
3
+ if ENV['WARNING']
4
+ require 'warning'
5
+ Warning.ignore([:missing_ivar, :missing_gvar, :fixnum])
6
+ #Warning.ignore(/warning: URI\.escape is obsolete\n\z/)
7
+ Warning.ignore(:method_redefined, File.dirname(File.dirname(__FILE__)))
8
+ end
9
+
3
10
  if ENV['COVERAGE']
4
11
  require 'coverage'
5
12
  require 'simplecov'
@@ -1,6 +1,5 @@
1
1
  <form method="post" class="rodauth form-horizontal" role="form" id="reset-password-form">
2
2
  #{rodauth.reset_password_additional_form_tags}
3
- <input type="hidden" name="#{rodauth.reset_password_key_param}" value="#{h request[rodauth.reset_password_key_param]}" />
4
3
  #{rodauth.csrf_tag}
5
4
  #{rodauth.render('password-field')}
6
5
  #{rodauth.render('password-confirm-field') if rodauth.require_password_confirmation?}
@@ -1,7 +1,6 @@
1
1
  <form method="post" class="rodauth form-horizontal" role="form" id="unlock-account-form">
2
2
  #{rodauth.unlock_account_additional_form_tags}
3
3
  #{rodauth.csrf_tag}
4
- <input type="hidden" name="#{rodauth.unlock_account_key_param}" value="#{h request[rodauth.unlock_account_key_param]}"/>
5
4
  <p>This account is currently locked out. You can unlock the account.</p>
6
5
  #{rodauth.render('password-field') if rodauth.unlock_account_requires_password?}
7
6
  #{rodauth.button(rodauth.unlock_account_button)}
@@ -1,6 +1,5 @@
1
1
  <form method="post" class="rodauth form-horizontal" role="form" id="verify-account-form">
2
2
  #{rodauth.verify_account_additional_form_tags}
3
- <input type="hidden" name="#{rodauth.verify_account_key_param}" value="#{h request[rodauth.verify_account_key_param]}" />
4
3
  #{rodauth.csrf_tag}
5
4
  #{rodauth.button(rodauth.verify_account_button)}
6
5
  </form>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-24 00:00:00.000000000 Z
11
+ date: 2016-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -233,6 +233,7 @@ extra_rdoc_files:
233
233
  - doc/release_notes/1.4.0.txt
234
234
  - doc/release_notes/1.5.0.txt
235
235
  - doc/release_notes/1.6.0.txt
236
+ - doc/release_notes/1.7.0.txt
236
237
  files:
237
238
  - CHANGELOG
238
239
  - MIT-LICENSE
@@ -265,6 +266,7 @@ files:
265
266
  - doc/release_notes/1.4.0.txt
266
267
  - doc/release_notes/1.5.0.txt
267
268
  - doc/release_notes/1.6.0.txt
269
+ - doc/release_notes/1.7.0.txt
268
270
  - doc/remember.rdoc
269
271
  - doc/reset_password.rdoc
270
272
  - doc/session_expiration.rdoc
@@ -404,7 +406,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
404
406
  version: '0'
405
407
  requirements: []
406
408
  rubyforge_project:
407
- rubygems_version: 2.6.6
409
+ rubygems_version: 2.6.8
408
410
  signing_key:
409
411
  specification_version: 4
410
412
  summary: Authentication and Account Management Framework for Rack Applications