mirror of https://github.com/rails/rails
Change `has_secure_token` default to `on: :initialize`
Follow-up to [#47420][] With the changes made in [#47420][], `has_secure_token` declarations can be configured to execute in an `after_initialize` callback. This commit proposed a new Rails 7.1 default: generate all `has_secure_token` values when their corresponding models are initialized. To preserve pre-7.1 behavior, applications can set `config.active_record.generate_secure_token_on = :create`. By default, generate the value when the model is initialized: ```ruby class User < ApplicationRecord has_secure_token end record = User.new record.token # => "fwZcXX6SkJBJRogzMdciS7wf" ``` With `config.active_record.generate_secure_token_on = :create`, generate the value when the model is created: ```ruby # config/application.rb config.active_record.generate_secure_token_on = :create # app/models/user.rb class User < ApplicationRecord has_secure_token on: :create end record = User.new record.token # => nil record.save! record.token # => "fwZcXX6SkJBJRogzMdciS7wf" ``` [#47420]: https://github.com/rails/rails/pull/47420 Co-authored-by: Hartley McGuire <skipkayhil@gmail.com>
This commit is contained in:
parent
3bc64016af
commit
e85a3ec624
|
@ -1,3 +1,16 @@
|
|||
* Change `has_secure_token` default to `on: :initialize`
|
||||
|
||||
Change the new default value from `on: :create` to `on: :initialize`
|
||||
|
||||
Can be controlled by the `config.active_record.generate_secure_token_on`
|
||||
configuration:
|
||||
|
||||
```ruby
|
||||
config.active_record.generate_secure_token_on = :create
|
||||
```
|
||||
|
||||
*Sean Doyle*
|
||||
|
||||
* Fix `change_column` not setting `precision: 6` on `datetime` columns when
|
||||
using 7.0+ Migrations and SQLite.
|
||||
|
||||
|
|
|
@ -447,6 +447,13 @@ module ActiveRecord
|
|||
singleton_class.attr_accessor :yaml_column_permitted_classes
|
||||
self.yaml_column_permitted_classes = [Symbol]
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Controls when to generate a value for <tt>has_secure_token</tt>
|
||||
# declarations. Defaults to <tt>:create</tt>.
|
||||
singleton_class.attr_accessor :generate_secure_token_on
|
||||
self.generate_secure_token_on = :create
|
||||
|
||||
def self.marshalling_format_version
|
||||
Marshalling.format_version
|
||||
end
|
||||
|
|
|
@ -38,6 +38,7 @@ module ActiveRecord
|
|||
config.active_record.cache_query_log_tags = false
|
||||
config.active_record.raise_on_assign_to_attr_readonly = false
|
||||
config.active_record.belongs_to_required_validates_foreign_key = true
|
||||
config.active_record.generate_secure_token_on = :create
|
||||
|
||||
config.active_record.queues = ActiveSupport::InheritableOptions.new
|
||||
|
||||
|
|
|
@ -40,9 +40,10 @@ module ActiveRecord
|
|||
# The callback when the value is generated. When called with <tt>on:
|
||||
# :initialize</tt>, the value is generated in an
|
||||
# <tt>after_initialize</tt> callback, otherwise the value will be used
|
||||
# in a <tt>before_</tt> callback. It will default to <tt>:create</tt>.
|
||||
#
|
||||
def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: :create)
|
||||
# in a <tt>before_</tt> callback. When not specified, +:on+ will use the value of
|
||||
# <tt>config.active_record.generate_secure_token_on</tt>, which defaults to +:initialize+
|
||||
# starting in \Rails 7.1.
|
||||
def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: ActiveRecord.generate_secure_token_on)
|
||||
if length < MINIMUM_TOKEN_LENGTH
|
||||
raise MinimumLengthError, "Token requires a minimum length of #{MINIMUM_TOKEN_LENGTH} characters."
|
||||
end
|
||||
|
|
|
@ -16,6 +16,15 @@ class SecureTokenTest < ActiveRecord::TestCase
|
|||
assert_equal 36, @user.auth_token.size
|
||||
end
|
||||
|
||||
def test_generating_token_on_initialize_does_not_affect_reading_from_the_column
|
||||
token = "abc123"
|
||||
|
||||
@user.update! token: token
|
||||
|
||||
assert_equal token, @user.reload.token
|
||||
assert_equal token, User.find(@user.id).token
|
||||
end
|
||||
|
||||
def test_regenerating_the_secure_token
|
||||
@user.save
|
||||
old_token = @user.token
|
||||
|
|
|
@ -73,6 +73,7 @@ Below are the default values associated with each target version. In cases of co
|
|||
- [`config.active_record.default_column_serializer`](#config-active-record-default-column-serializer): `nil`
|
||||
- [`config.active_record.encryption.hash_digest_class`](#config-active-record-encryption-hash-digest-class): `OpenSSL::Digest::SHA256`
|
||||
- [`config.active_record.encryption.support_sha1_for_non_deterministic_encryption`](#config-active-record-encryption-support-sha1-for-non-deterministic-encryption): `false`
|
||||
- [`config.active_record.generate_secure_token_on`](#config-active-record-generate-secure-token-on): `:initialize`
|
||||
- [`config.active_record.marshalling_format_version`](#config-active-record-marshalling-format-version): `7.1`
|
||||
- [`config.active_record.query_log_tags_format`](#config-active-record-query-log-tags-format): `:sqlcommenter`
|
||||
- [`config.active_record.raise_on_assign_to_attr_readonly`](#config-active-record-raise-on-assign-to-attr-readonly): `true`
|
||||
|
@ -1513,6 +1514,44 @@ Defaults to `true`. Determines whether to raise an exception or not when
|
|||
the PostgreSQL adapter is provided an integer that is wider than signed
|
||||
64bit representation.
|
||||
|
||||
#### `config.active_record.generate_secure_token_on`
|
||||
|
||||
Controls when to generate a value for `has_secure_token` declarations. By
|
||||
default, generate the value when the model is initialized:
|
||||
|
||||
```ruby
|
||||
class User < ApplicationRecord
|
||||
has_secure_token
|
||||
end
|
||||
|
||||
record = User.new
|
||||
record.token # => "fwZcXX6SkJBJRogzMdciS7wf"
|
||||
```
|
||||
|
||||
With `config.active_record.generate_secure_token_on = :create`, generate the
|
||||
value when the model is created:
|
||||
|
||||
```ruby
|
||||
# config/application.rb
|
||||
|
||||
config.active_record.generate_secure_token_on = :create
|
||||
|
||||
# app/models/user.rb
|
||||
class User < ApplicationRecord
|
||||
has_secure_token on: :create
|
||||
end
|
||||
|
||||
record = User.new
|
||||
record.token # => nil
|
||||
record.save!
|
||||
record.token # => "fwZcXX6SkJBJRogzMdciS7wf"
|
||||
```
|
||||
|
||||
| Starting with version | The default value is |
|
||||
| --------------------- | -------------------- |
|
||||
| (original) | `:create` |
|
||||
| 7.1 | `:initialize` |
|
||||
|
||||
#### `ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans` and `ActiveRecord::ConnectionAdapters::TrilogyAdapter.emulate_booleans`
|
||||
|
||||
Controls whether the Active Record MySQL adapter will consider all `tinyint(1)` columns as booleans. Defaults to `true`.
|
||||
|
|
|
@ -291,6 +291,7 @@ module Rails
|
|||
active_record.encryption.support_sha1_for_non_deterministic_encryption = false
|
||||
active_record.marshalling_format_version = 7.1
|
||||
active_record.run_after_transaction_callbacks_in_order_defined = true
|
||||
active_record.generate_secure_token_on = :initialize
|
||||
end
|
||||
|
||||
if respond_to?(:action_dispatch)
|
||||
|
|
|
@ -174,6 +174,10 @@
|
|||
#
|
||||
# Rails.application.config.active_record.commit_transaction_on_non_local_return = true
|
||||
|
||||
# Controls when to generate a value for <tt>has_secure_token</tt> declarations.
|
||||
#
|
||||
# Rails.application.config.active_record.generate_secure_token_on = :initialize
|
||||
|
||||
# ** Please read carefully, this must be configured in config/application.rb **
|
||||
# Change the format of the cache entry.
|
||||
# Changing this default means that all new cache entries added to the cache
|
||||
|
|
Loading…
Reference in New Issue