rodauth 2.18.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60f279e15751f9a0915c72e919726cae392844137ddabd98cb5a973815ada935
4
- data.tar.gz: ae841728e69f0fdf1d2c67de55f52ed535971a349ecc6dbddeaf6250e573515f
3
+ metadata.gz: 0defa94cb0c58b317997853eda1775694a8b0bb89e3bb75f8de50af57a2223fe
4
+ data.tar.gz: 977738446cb7d8ac53a7edeab2587c07e7a9b9407d2584daa80fe6d47147f395
5
5
  SHA512:
6
- metadata.gz: 7490aded0f6e506fff03b445d569709ec77d1dc7e36193d8939c36d706a95f4b9bbd2ad0a05feaa7f4e2c309ce03ceeff302de81546a23f8c26bbd1c62f12c88
7
- data.tar.gz: bb437de6fd56ee88a2acdccc6058eefe05c856d3bc0569b473d968aa7c8c2eae64817944dade3987b612322e61c7351808765e7dfa897267e4966a7b4c8c4206
6
+ metadata.gz: 0e8833fc2ac01f3a917b8c267642b92472969531df33dc90dcae6e90d5b62befbf2f948ca75cafcd84353b4b9d629f1dec8d70e3e77cc2387cc0791cee551773
7
+ data.tar.gz: 03ff22811e9679b26f1dc83c676ca19145c762d26c216a9aafae816d3bad67cd39a68430fbd72c55f17e77117fbcd65690eb6d71f3b05f72860833a2205f2fe7
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ === 2.19.0 (2021-12-22)
2
+
3
+ * Add login_maximum_bytes, setting the maximum number of bytes in a login, 255 by default (jeremyevans)
4
+
5
+ * Add password_maximum_bytes, setting the maximum number of bytes in a password, nil by default for no limit (jeremyevans)
6
+
7
+ * Add password_maximum_length, setting the maximum number of characters in a password, nil by default for no limit (jeremyevans)
8
+
9
+ * Support multi-level inheritance of Rodauth::Auth (janko) (#191)
10
+
11
+ * Allow internal_request feature to work correctly when loaded into custom Rodauth::Auth subclasses before loading into a Roda application (janko) (#190)
12
+
13
+ * Assign internal subclass created by internal_request feature to the InternalRequest constant (janko) (#187)
14
+
1
15
  === 2.18.0 (2021-11-23)
2
16
 
3
17
  * Allow JSON API access to /multifactor-manage to get links to setup/disable multifactor authentication endpoints (jeremyevans)
data/README.rdoc CHANGED
@@ -69,7 +69,8 @@ Website :: http://rodauth.jeremyevans.net
69
69
  Demo Site :: http://rodauth-demo.jeremyevans.net
70
70
  Source :: http://github.com/jeremyevans/rodauth
71
71
  Bugs :: http://github.com/jeremyevans/rodauth/issues
72
- Google Group :: https://groups.google.com/forum/#!forum/rodauth
72
+ Discussion Forum (GitHub Discussions) :: https://github.com/jeremyevans/rodauth/discussions
73
+ Alternate Discussion Forum (Google Groups) :: https://groups.google.com/forum/#!forum/rodauth
73
74
 
74
75
  == Dependencies
75
76
 
@@ -44,6 +44,7 @@ Rodauth will call +set_error_reason+ with:
44
44
  * :login_not_valid_email
45
45
  * :login_required
46
46
  * :login_too_long
47
+ * :login_too_many_bytes
47
48
  * :login_too_short
48
49
  * :logins_do_not_match
49
50
  * :no_current_sms_code
@@ -56,6 +57,8 @@ Rodauth will call +set_error_reason+ with:
56
57
  * :password_in_dictionary
57
58
  * :password_is_one_of_the_most_common
58
59
  * :password_same_as_previous_password
60
+ * :password_too_long
61
+ * :password_too_many_bytes
59
62
  * :password_too_short
60
63
  * :passwords_do_not_match
61
64
  * :same_as_current_login
@@ -0,0 +1,19 @@
1
+ = Change table and column names
2
+
3
+ All tables that Rodauth uses will have a configuration method that ends with
4
+ +_table+ for configuring the table name. For example, if you store user accounts
5
+ in the +users+ table instead of +accounts+ table, you can use the following
6
+ in your configuration:
7
+
8
+ accounts_table :users
9
+
10
+ All columns that Rodauth uses will have a configuration method that ends with
11
+ +_column+ for configuring the column name. For example, if you are storing the
12
+ login for accounts in the +login+ column instead of the +email+ column, you
13
+ can use the following in your configuration:
14
+
15
+ login_column :login
16
+
17
+ Please see the documentation for Rodauth features for the names of the
18
+ configuration methods that you can use. You can see the default values for
19
+ the tables and columns in the {"Creating tables" section of the README}[rdoc-ref:README.rdoc].
@@ -0,0 +1,34 @@
1
+ = Share configuration via inheritance
2
+
3
+ If you have multiple configurations that needs to share some amount of
4
+ authentication behaviour, you can do so through inheritance. For example:
5
+
6
+ require "rodauth"
7
+
8
+ class RodauthBase < Rodauth::Auth
9
+ configure do
10
+ # common authentication configuration
11
+ end
12
+ end
13
+
14
+ class RodauthMain < RodauthBase # inherit common configuration
15
+ configure do
16
+ # main-specific authentication configuration
17
+ end
18
+ end
19
+
20
+ class RodauthAdmin < RodauthBase # inherit common configuration
21
+ configure do
22
+ # admin-specific authentication configuration
23
+ end
24
+ end
25
+
26
+ class RodauthApp < Roda
27
+ plugin :rodauth, auth_class: RodauthMain
28
+ plugin :rodauth, auth_class: RodauthAdmin, name: :admin
29
+ # ...
30
+ end
31
+
32
+ However, when doing this, you need to be careful that you do not use a
33
+ configuration method in a superclass, and then load a feature in a subclass
34
+ that overrides the configuration you set in the superclass.
@@ -11,17 +11,23 @@ login_confirm_label :: The label to use for login confirmations.
11
11
  login_confirm_param :: The parameter name to use for login confirmations.
12
12
  login_does_not_meet_requirements_message :: The error message to display when the login does not meet the requirements you have set.
13
13
  login_email_regexp :: The regular expression used to validate whether login is a valid email address.
14
- login_maximum_length :: The maximum length for logins, 255 by default.
15
- login_minimum_length :: The minimum length for logins, 3 by default.
14
+ login_maximum_bytes :: The maximum length for logins in bytes, 255 by default.
15
+ login_maximum_length :: The maximum length for logins in characters, 255 by default.
16
+ login_minimum_length :: The minimum length for logins in characters, 3 by default.
16
17
  login_not_valid_email_message :: The error message to display when login is not a valid email address.
17
18
  login_too_long_message :: The error message fragment to show if the login is too long.
19
+ login_too_many_bytes_message :: The error message fragment to show if the login has too many bytes.
18
20
  login_too_short_message :: The error message fragment to show if the login is too short.
19
21
  logins_do_not_match_message :: The error message to display when login and login confirmation do not match.
20
22
  password_confirm_label :: The label to use for password confirmations.
21
23
  password_confirm_param :: The parameter name to use for password confirmations.
22
24
  password_does_not_meet_requirements_message :: The error message to display when the password does not meet the requirements you have set.
23
25
  password_hash_cost :: The cost to use for the password hash algorithm. This should be an integer when using bcrypt (the default), and a hash if using argon2 (supported by the argon2 feature).
24
- password_minimum_length :: The minimum length for passwords, 6 by default.
26
+ password_maximum_bytes :: The maximum length for passwords in bytes, nil by default for no limit. bcrypt only uses the first 72 bytes of the password when creating the password hash, so if you are using bcrypt as the password hash function, you may want to set this to 72.
27
+ password_maximum_length :: The maximum length for passwords in characters, nil by default for no limit.
28
+ password_minimum_length :: The minimum length for passwords in characters, 6 by default.
29
+ password_too_long_message :: The error message fragment to show if the password is too long.
30
+ password_too_many_bytes_message :: The error message fragment to show if the password is has too many bytes.
25
31
  password_too_short_message :: The error message fragment to show if the password is too short.
26
32
  passwords_do_not_match_message :: The error message to display when password and password confirmation do not match.
27
33
  require_email_address_logins? :: Whether logins need to be valid email addresses, true by default.
@@ -0,0 +1,61 @@
1
+ = New Features
2
+
3
+ * A login_maximum_bytes configuration method has been added, setting
4
+ the maximum bytes allowed in a login. This was added as
5
+ login_maximum_length sets the maximum length in characters. It's
6
+ possible a different number of maximum bytes than maximum
7
+ characters is desired by some applications, and since the database
8
+ column size may be enforced in bytes, it's useful to have a check
9
+ before trying a database query that would raise an exception. This
10
+ default value for login_maximum_bytes is 255, the same as the
11
+ default value for login_maximum_length.
12
+
13
+ A login_too_many_bytes_message configuration method has been added
14
+ for customizing the error message if a login has too many bytes.
15
+
16
+ * password_maximum_length and password_maximum_bytes configuration
17
+ methods have been added, specifying the maximum size of passwords
18
+ in characters and bytes, respectively. Both configurations default
19
+ to nil, meaning no limit, so there is no change in default behavior.
20
+
21
+ The bcrypt algorithm only uses the first 72 bytes of a password, and
22
+ in some environments it may be desirable to reject passwords over
23
+ that limit. password_too_long_message and
24
+ password_too_many_bytes_message configuration methods have been
25
+ added for customizing the error messages used for passwords that are
26
+ too long.
27
+
28
+ Note that in most environments, if you want to support passwords
29
+ over 72 bytes and have the entire password be considered, you should
30
+ probably use the argon2 feature.
31
+
32
+ = Other Improvements
33
+
34
+ * The subclass created by the internal_request feature is now set
35
+ to the InternalRequest constant on the superclass, mostly to
36
+ make identifying it easier in inspect output.
37
+
38
+ * Support has been improved for custom Rodauth::Auth subclasses that
39
+ load features before the subclass is loaded into Roda, by delaying
40
+ the call to post_configure until the subclass is loaded into Roda.
41
+ Among other things, this fixes the use of the internal_request
42
+ feature in such classes.
43
+
44
+ * Multi-level inheritance of Rodauth::Auth is now supported. This can
45
+ be useful as a way to share custom authentication settings between
46
+ multiple Rodauth configurations. However, users of multi-level
47
+ inheritance should be careful not to load features in subclasses
48
+ that override custom settings in superclasses.
49
+
50
+ = Other
51
+
52
+ * Rodauth's primary discussion forum is now GitHub Discussions. The
53
+ rodauth Google Group is still available for users who would prefer
54
+ to use that instead.
55
+
56
+ = Backwards Compatibility
57
+
58
+ * The addition of login_maximum_bytes with a default value of 255 is
59
+ backwards incompatible for applications that want to support logins
60
+ with multibyte characters where the number of characters in the
61
+ login is at or below 255, but the number of bytes is above 255.
@@ -339,14 +339,7 @@ module Rodauth
339
339
  return if is_a?(InternalRequestMethods)
340
340
 
341
341
  klass = self.class
342
- internal_class = Class.new(klass) do
343
- @roda_class = klass.roda_class
344
- @features = klass.features.clone
345
- @routes = klass.routes.clone
346
- @route_hash = klass.route_hash.clone
347
- @configuration = klass.configuration.clone
348
- @configuration.instance_variable_set(:@auth, self)
349
- end
342
+ internal_class = Class.new(klass)
350
343
 
351
344
  if blocks = klass.instance_variable_get(:@internal_request_configuration_blocks)
352
345
  configuration = internal_class.configuration
@@ -366,6 +359,9 @@ module Rodauth
366
359
  end
367
360
  end
368
361
  end
362
+
363
+ klass.const_set(:InternalRequest, internal_class)
364
+ klass.private_constant :InternalRequest
369
365
  end
370
366
  end
371
367
  end
@@ -7,10 +7,13 @@ module Rodauth
7
7
  auth_value_method :login_email_regexp, /\A[^,;@ \r\n]+@[^,@; \r\n]+\.[^,@; \r\n]+\z/
8
8
  auth_value_method :login_minimum_length, 3
9
9
  auth_value_method :login_maximum_length, 255
10
+ auth_value_method :login_maximum_bytes, 255
10
11
  translatable_method :login_not_valid_email_message, 'not a valid email address'
11
12
  translatable_method :logins_do_not_match_message, 'logins do not match'
12
13
  auth_value_method :password_confirm_param, 'password-confirm'
13
14
  auth_value_method :password_minimum_length, 6
15
+ auth_value_method :password_maximum_bytes, nil
16
+ auth_value_method :password_maximum_length, nil
14
17
  translatable_method :passwords_do_not_match_message, 'passwords do not match'
15
18
  auth_value_method :require_email_address_logins?, true
16
19
  auth_value_method :require_login_confirmation?, true
@@ -22,10 +25,13 @@ module Rodauth
22
25
  :login_confirm_label,
23
26
  :login_does_not_meet_requirements_message,
24
27
  :login_too_long_message,
28
+ :login_too_many_bytes_message,
25
29
  :login_too_short_message,
26
30
  :password_confirm_label,
27
31
  :password_does_not_meet_requirements_message,
28
32
  :password_hash_cost,
33
+ :password_too_long_message,
34
+ :password_too_many_bytes_message,
29
35
  :password_too_short_message
30
36
  )
31
37
 
@@ -78,6 +84,14 @@ module Rodauth
78
84
  "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
79
85
  end
80
86
 
87
+ def password_too_long_message
88
+ "maximum #{password_maximum_length} characters"
89
+ end
90
+
91
+ def password_too_many_bytes_message
92
+ "maximum #{password_maximum_bytes} bytes"
93
+ end
94
+
81
95
  def password_too_short_message
82
96
  "minimum #{password_minimum_length} characters"
83
97
  end
@@ -95,6 +109,10 @@ module Rodauth
95
109
  "maximum #{login_maximum_length} characters"
96
110
  end
97
111
 
112
+ def login_too_many_bytes_message
113
+ "maximum #{login_maximum_bytes} bytes"
114
+ end
115
+
98
116
  def login_too_short_message
99
117
  "minimum #{login_minimum_length} characters"
100
118
  end
@@ -111,6 +129,9 @@ module Rodauth
111
129
  elsif login_maximum_length < login.length
112
130
  set_login_requirement_error_message(:login_too_long, login_too_long_message)
113
131
  false
132
+ elsif login_maximum_bytes < login.bytesize
133
+ set_login_requirement_error_message(:login_too_many_bytes, login_too_many_bytes_message)
134
+ false
114
135
  else
115
136
  true
116
137
  end
@@ -128,9 +149,18 @@ module Rodauth
128
149
  end
129
150
 
130
151
  def password_meets_length_requirements?(password)
131
- return true if password_minimum_length <= password.length
132
- set_password_requirement_error_message(:password_too_short, password_too_short_message)
133
- false
152
+ if password_minimum_length > password.length
153
+ set_password_requirement_error_message(:password_too_short, password_too_short_message)
154
+ false
155
+ elsif password_maximum_length && password_maximum_length < password.length
156
+ set_password_requirement_error_message(:password_too_long, password_too_long_message)
157
+ false
158
+ elsif password_maximum_bytes && password_maximum_bytes < password.bytesize
159
+ set_password_requirement_error_message(:password_too_many_bytes, password_too_many_bytes_message)
160
+ false
161
+ else
162
+ true
163
+ end
134
164
  end
135
165
 
136
166
  def password_does_not_contain_null_byte?(password)
@@ -6,7 +6,7 @@ module Rodauth
6
6
  MAJOR = 2
7
7
 
8
8
  # The minor version of Rodauth, updated for new feature releases of Rodauth.
9
- MINOR = 18
9
+ MINOR = 19
10
10
 
11
11
  # The patch version of Rodauth, updated only for bug fixes from the last
12
12
  # feature release.
data/lib/rodauth.rb CHANGED
@@ -59,6 +59,7 @@ module Rodauth
59
59
  end
60
60
  auth_class.class_eval{@configuration_name = opts[:name] unless defined?(@configuration_name)}
61
61
  auth_class.configure(&block) if block
62
+ auth_class.allocate.post_configure if auth_class.method_defined?(:post_configure)
62
63
  end
63
64
 
64
65
  FEATURES = {}
@@ -271,38 +272,6 @@ module Rodauth
271
272
  end
272
273
  end
273
274
 
274
- class Auth
275
- class << self
276
- attr_accessor :roda_class
277
- attr_reader :features
278
- attr_reader :routes
279
- attr_accessor :route_hash
280
- attr_reader :configuration_name
281
- attr_reader :configuration
282
- end
283
-
284
- def self.inherited(subclass)
285
- super
286
- subclass.instance_exec do
287
- @features = []
288
- @routes = []
289
- @route_hash = {}
290
- @configuration = Configuration.new(self)
291
- end
292
- end
293
-
294
- def self.configure(&block)
295
- @configuration.apply(&block)
296
- end
297
-
298
- def self.freeze
299
- @features.freeze
300
- @routes.freeze
301
- @route_hash.freeze
302
- super
303
- end
304
- end
305
-
306
275
  class Configuration
307
276
  attr_reader :auth
308
277
 
@@ -318,7 +287,6 @@ module Rodauth
318
287
  def apply(&block)
319
288
  load_feature(:base)
320
289
  instance_exec(&block)
321
- auth.allocate.post_configure
322
290
  end
323
291
 
324
292
  def enable(*features)
@@ -342,6 +310,46 @@ module Rodauth
342
310
  end
343
311
  end
344
312
 
313
+ class Auth
314
+ @features = []
315
+ @routes = []
316
+ @route_hash = {}
317
+ @configuration = Configuration.new(self)
318
+
319
+ class << self
320
+ attr_accessor :roda_class
321
+ attr_reader :features
322
+ attr_reader :routes
323
+ attr_accessor :route_hash
324
+ attr_reader :configuration_name
325
+ attr_reader :configuration
326
+ end
327
+
328
+ def self.inherited(subclass)
329
+ super
330
+ superclass = self
331
+ subclass.instance_exec do
332
+ @roda_class = superclass.roda_class
333
+ @features = superclass.features.clone
334
+ @routes = superclass.routes.clone
335
+ @route_hash = superclass.route_hash.clone
336
+ @configuration = superclass.configuration.clone
337
+ @configuration.instance_variable_set(:@auth, self)
338
+ end
339
+ end
340
+
341
+ def self.configure(&block)
342
+ @configuration.apply(&block)
343
+ end
344
+
345
+ def self.freeze
346
+ @features.freeze
347
+ @routes.freeze
348
+ @route_hash.freeze
349
+ super
350
+ end
351
+ end
352
+
345
353
  module InstanceMethods
346
354
  def rodauth(name=nil)
347
355
  if name
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: 2.18.0
4
+ version: 2.19.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: 2021-11-23 00:00:00.000000000 Z
11
+ date: 2021-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -332,6 +332,7 @@ extra_rdoc_files:
332
332
  - doc/release_notes/2.16.0.txt
333
333
  - doc/release_notes/2.17.0.txt
334
334
  - doc/release_notes/2.18.0.txt
335
+ - doc/release_notes/2.19.0.txt
335
336
  - doc/release_notes/2.2.0.txt
336
337
  - doc/release_notes/2.3.0.txt
337
338
  - doc/release_notes/2.4.0.txt
@@ -364,6 +365,7 @@ files:
364
365
  - doc/guides/admin_activation.rdoc
365
366
  - doc/guides/already_authenticated.rdoc
366
367
  - doc/guides/alternative_login.rdoc
368
+ - doc/guides/change_table_and_column_names.rdoc
367
369
  - doc/guides/create_account_programmatically.rdoc
368
370
  - doc/guides/delay_password.rdoc
369
371
  - doc/guides/email_only.rdoc
@@ -381,6 +383,7 @@ files:
381
383
  - doc/guides/registration_field.rdoc
382
384
  - doc/guides/require_mfa.rdoc
383
385
  - doc/guides/reset_password_autologin.rdoc
386
+ - doc/guides/share_configuration.rdoc
384
387
  - doc/guides/status_column.rdoc
385
388
  - doc/guides/totp_or_recovery.rdoc
386
389
  - doc/http_basic_auth.rdoc
@@ -435,6 +438,7 @@ files:
435
438
  - doc/release_notes/2.16.0.txt
436
439
  - doc/release_notes/2.17.0.txt
437
440
  - doc/release_notes/2.18.0.txt
441
+ - doc/release_notes/2.19.0.txt
438
442
  - doc/release_notes/2.2.0.txt
439
443
  - doc/release_notes/2.3.0.txt
440
444
  - doc/release_notes/2.4.0.txt
@@ -566,7 +570,7 @@ metadata:
566
570
  bug_tracker_uri: https://github.com/jeremyevans/rodauth/issues
567
571
  changelog_uri: http://rodauth.jeremyevans.net/rdoc/files/CHANGELOG.html
568
572
  documentation_uri: http://rodauth.jeremyevans.net/documentation.html
569
- mailing_list_uri: https://groups.google.com/forum/#!forum/rodauth
573
+ mailing_list_uri: https://github.com/jeremyevans/rodauth/discussions
570
574
  source_code_uri: https://github.com/jeremyevans/rodauth
571
575
  post_install_message:
572
576
  rdoc_options:
@@ -590,7 +594,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
590
594
  - !ruby/object:Gem::Version
591
595
  version: '0'
592
596
  requirements: []
593
- rubygems_version: 3.2.22
597
+ rubygems_version: 3.2.32
594
598
  signing_key:
595
599
  specification_version: 4
596
600
  summary: Authentication and Account Management Framework for Rack Applications