なるようになるブログ

読書感想文かrailsについてかrubyについてか

rails commit log流し読み(2017/09/25)

2017/09/25分のコミットです。

CHANGELOGにのったコミットは以下の通りです。

actionpack/CHANGELOG.md

activesupport/CHANGELOG.md


Merge pull request #29716 from mikeycgto/active-support-key-rotator

Action Pack及びActive Supportの修正です。

MessageEncryptorクラス及びMessageVerifierクラスにkey rotationのサポートを追加しています。

それぞれrotateメソッドが提供されおり(実際の処理はActiveSupport::Messages moduleに定義されており共通で使用されている)、左記メソッドを使用する事でkeyのrotationが出来るようになっています。

old_secret  = SecureRandom.random_bytes(32)
old_message = ActiveSupport::MessageEncryptor.new(old_secret, cipher: "aes-256-gcm").encrypt_and_sign("old")

new_secret  = SecureRandom.random_bytes(32)
encryptor = ActiveSupport::MessageEncryptor.new(new_secret, cipher: "aes-256-gcm")
encryptor.rotate(old_secret)

encryptor.decrypt_and_verify(old_message) # => "old"

また、これを利用してEncrypted Cookies及びSigned Cookiesのkeyのrotationも出来るようになっています。

Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
  cookies.rotate :encrypted, secret: Rails.application.credentials.old_secret_key_base
  cookies.rotate :signed,    secret: Rails.application.credentials.old_secret_key_base
end

APIはまだ少し変わりそうな気配があるので、5.2がリリースされる頃には少し変わっているかもしれません。


[ci skip] RotationConfiguration is an implementation detail, not public API.

activesupport/lib/active_support/messages/rotation_configuration.rbのdoc、及び、rails guideのRuby on Rails Security Guideの修正です。

ActiveSupport::Messages::RotationConfigurationクラスに:nodoc:を指定、及び、左記クラスのdocへリンクしている箇所を削除しています。ActiveSupport::Messages::RotationConfigurationはpublic APIではない(ユーザが直接参照するクラスではない)為。


Refactor Css::Generators::ScaffoldGenerator

railties/lib/rails/generators/css/scaffold/scaffold_generator.rbの修正です。

`Css::Generators::ScaffoldGeneratorクラスのリファクタリングとして、source_rootメソッドを使用してrootの定義、及び、ファイルをコピーするのにcreate_fileメソッドを使用していたのを、copy_fileメソッドを使用するよう修正しています。


Infer options from the primary verifier.

activesupport/lib/active_support/messages/rotator.rbの修正です。

cipher、digest、serializerについて、rotateメソッドに値の指定がない場合primary verifierの値をそのまま使用するよう修正しています。


Remove advanced key generator rotations from verifier/encryptor.

activesupport/lib/active_support/messages/rotator.rbの修正です。

rotationを生成する際に、keyの生成処理等を独自に行っていたのを、Messages::Rotatorをincludeしているクラスに処理を移譲するよう修正しています。


Use new rotation signature in cookies.

actionpack/lib/action_dispatch/middleware/cookies.rbの修正です。

cookiesのsignatureのrotation処理で、rotate後新しいsignatureを使用するよう修正しています。


[ci skip] Attempt a new explanation for rotations.

各docの修正です。

key rotationについての説明及びexampleコードを修正しています。


Fix “warning: `*‘ interpreted as argument prefix” https://github.com/rails/rails/commit/8b1fe28017b264de770e15f2417e84ef57ae0571

actionpack/lib/action_dispatch/middleware/cookies.rbの修正です。

SignedKeyRotatingCookieJar#initialize及びEncryptedKeyRotatingCookieJar#initializeRubyのwarning(“warning: `*‘ interpreted as argument prefix”)が出ていたのを、中括弧を追加し修正しています。


Fix RotationConfiguration test and remove nil-kind rotates.

activesupport/lib/active_support/messages/rotation_configuration.rbの修正です。

Messages::RotationConfiguration#rotateの第一引数(kind)のデフォルト値を削除しています。必ず設定される値の為。


Skip complex cookie tests for now; I’ll deal with them tomorrow.

railties/test/application/middleware/cookies_test.rbrailties/test/application/middleware/session_test.rbの修正です。

cookiesのtestがコケてしまっているので、一時的にskipしています。I'll deal with them tomorrow.とのこと。


Fix test_should_sanitize_illegal_style_properties failure

actionview/test/template/sanitize_helper_test.rbの修正です。

test_should_sanitize_illegal_style_propertiesで生成されるcssのフォーマットを修正しています。

-    expected = %(display: block; width: 100%; height: 100%; background-color: black; background-x: center; background-y: center;)
-    assert_equal expected, sanitize_css(raw)
+    expected = %r(\Adisplay:\s?block;\s?width:\s?100%;\s?height:\s?100%;\s?background-color:\s?black;\s?background-x:\s?center;\s?background-y:\s?center;\z)
+    assert_match expected, sanitize_css(raw)

loofah側で生成するcssが変更になった為。

参考:Replace CSS regexes with Crass.


Merge pull request #30698 from bogdanvlviv/remove-unused-variables-from-release_rb

tasks/release.rbの修正です。

使用していないgem_version変数を削除しています。


Merge pull request #30615 from yhirano55/update_form_helpers_guide

rails guideのForm Helpersの修正です。

form_forメソッドの実行例のhtmlが実際生成されるhtmlと異なっていたのを修正しています。


Extract integer_like_primary_key_type to ease to handle it for adapters

Active Recordの修正です。

primary_key typeを扱う処理をメソッド(integer_like_primary_key_type)に切り出しています。各adapter毎にカスタマイズしやすいようにする為。


Unneeded Mocha stubs for Kernel#system

activerecord/test/cases/tasks/postgresql_rake_test.rbの修正です。

不要なKernel#systemのstub処理を削除しています。違うメソッド呼び出し(assert_called_with又はKernel.expects)でもうstubされている為。


mocha 1.3.0

Gemfileの修正です。

mocha gemのバージョンを1.3.0に更新しています。


Respect quiet option in all process of rails new command

railties/lib/rails/generators/rails/app/app_generator.rbrailties/lib/rails/generators/rails/master_key/master_key_generator.rbの修正です。

rails newコマンドにquietオプションを指定した場合に、statusが表示されしまっている処理があったのを、statusが表示されないよう修正しています。


Fix minor CodeClimate issue

activesupport/test/message_encryptor_test.rbの修正です。

テスト内でrubocopの規約に違反している箇所があったのを修正しています。


new missing backquotes [ci skip]

rails guideのGetting Started with EnginesThe Basics of Creating Rails Pluginsの修正です。

ディレクトリ名やメソッド名をバッククォートで囲むよう修正しています。


PERF: Restore memoization when preloading associations.

activerecord/lib/active_record/reflection.rbの修正です。

Reflection::AssociationReflection#inverse_nameメソッドで、inverse_nameの値をメモ化するよう修正しています。associations preloading処理の性能改善の為。

ベンチマークの結果は下記の通り。

require 'active_record'
require 'benchmark/ips'
require 'ruby-prof'
require 'memory_profiler'
require 'byebug'

ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
ActiveRecord::Migration.verbose = false

ActiveRecord::Schema.define do
  create_table :users, force: true do |t|
    t.string :name, :email
    t.integer :topic_id
    t.timestamps null: false
  end

  create_table :topics, force: true do |t|
    t.string :title
    t.timestamps null: false
  end
end

attributes = {
  name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  email: 'foobar@email.com'
}

class Topic < ActiveRecord::Base
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :topic
end

100.times do
  User.create!(attributes)
end

users = User.first(50)

Topic.create!(title: 'This is a topic', users: users)

Benchmark.ips do |x|
  x.config(time: 10, warmup: 5)

  x.report("preload") do
    User.includes(:topic).all.to_a
  end
end
Before

Calculating -------------------------------------
             preload    26.000  i/100ms
-------------------------------------------------
             preload    265.347  (± 3.0%) i/s -      2.652k
After

Calculating -------------------------------------
             preload    39.000  i/100ms
-------------------------------------------------
             preload    406.053  (± 1.7%) i/s -      4.095k

割とはやくなってますねえ。