モデルごとにパスワード変更後の自動サインイン設定を可能に

heartcombo/devise

Deviseでは、パスワード変更後の自動サインイン動作をモデル単位で制御できるようになりました。これにより、アプリケーション内の複数のユーザーモデルで異なるセキュリティポリシーを適用できます。

背景

Deviseには sign_in_after_change_password という設定があり、パスワード変更後にユーザーを自動的にサインインさせるかを制御します。しかし、この設定はグローバル設定としてのみ機能しており、モデルごとに定義された設定値が無視されていました。RegistrationsControllersign_in_after_change_password? メソッドは、常に Devise.sign_in_after_change_password を参照していたためです。

#5429sign_in_after_reset_password に対して同様の修正が行われており、本PRはその一貫性を保つための変更です。

技術的な変更

app/controllers/devise/registrations_controller.rbsign_in_after_change_password? メソッドが、グローバル設定ではなくリソースクラスの設定を参照するように変更されました。

変更前:

def sign_in_after_change_password?
  return true if account_update_params[:password].blank?

  Devise.sign_in_after_change_password
end

変更後:

def sign_in_after_change_password?
  return true if account_update_params[:password].blank?

  resource_class.sign_in_after_change_password
end

Devise.sign_in_after_change_password から resource_class.sign_in_after_change_password への変更により、モデルクラスで定義された設定値が優先されるようになります。パスワードが空の場合(メールアドレスのみの更新など)は、従来通り true を返して自動サインインを許可します。

モデルごとの設定は以下のように記述します:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable

  self.sign_in_after_change_password = false
end

テストカバレッジの追加

test/integration/registerable_test.rb に、モデル設定が正しく反映されることを検証するテストケースが追加されました。

test 'a signed in user should not be able to use the website after changing their password if resource_class.sign_in_after_change_password is false' do
  swap_model_config User, sign_in_after_change_password: false do
    sign_in_as_user
    get edit_user_registration_path

    fill_in 'password', with: '1234567890'
    fill_in 'password confirmation', with: '1234567890'
    fill_in 'current password', with: '12345678'
    click_button 'Update'

    assert_contain 'Your account has been updated successfully, but since your password was changed, you need to sign in again.'
    assert_equal new_user_session_path, @request.path
    assert_not warden.authenticated?(:user)
  end
end

このテストは、User モデルで sign_in_after_change_passwordfalse に設定した場合、パスワード変更後にサインアウトされることを確認します。

設計判断

リソースクラスへの委譲方式 が採用されました。グローバル設定を完全に置き換えるのではなく、モデルクラスの設定を優先する形で後方互換性を維持しています。

この実装により、既存のグローバル設定 Devise.sign_in_after_change_password をデフォルト値として使いつつ、モデル単位でオーバーライドできる柔軟性が確保されます。#5429sign_in_after_reset_password と同じパターンを踏襲することで、API全体の一貫性も保たれています。

まとめ

本PRは、sign_in_after_change_password の設定スコープをグローバルからモデル単位に拡張した変更です。1行の変更とテストの追加により、マルチテナントアプリケーションや異なるユーザータイプを持つシステムで、モデルごとに異なるセキュリティポリシーを適用できるようになりました。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細(各論)→まとめ(結論)という構成が明確で、読者が変更の全体像を理解しやすい。設計判断のセクションも設けられており、網羅性が高い。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライトやGitHubのPR番号へのリンク記法が正しく使用されており、技術記事としての体裁が整っている。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

DeviseやRailsの知識を持つエンジニアを対象としており、専門用語を適切に使いつつ、冗長な説明を省いているため、ターゲット読者に最適化されている。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られている。非常に読みやすい。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

Diffで示されたコード変更(registrations_controller.rb, registerable_test.rb)を正確に引用している。モデルの使用例はDiff外だが、変更の利用方法を示すための有益な補足であり、技術的に妥当。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`resource_class`, `RegistrationsController` など、Deviseのコンテキストにおける技術用語が正確に使用されている。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「グローバル設定からモデルごとの設定(resource_class)を参照するように変更された」という説明は、コード変更の意図と影響を技術的に正しく捉えている。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張はすべてPRのDescriptionやDiff内容に基づいており、ハルシネーションは見られない。特に、類似の修正(#5429)への言及はPR Descriptionと一致している。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#5825, #5429)やファイルパスなどの固有名詞はすべて正確に記載されている。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「モデルごとにパスワード変更後の自動サインイン設定を可能に」は、PRのタイトル「Allow model config to override `sign_in_after_change_password`」の内容を的確に表現している。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容は提供されたPR情報に限定されており、バージョンサポート状況やリリース日程など、PR外の外部知識の追記は見られない。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

PR情報と矛盾するような時間表現(「既に」「まもなく」など)は使用されておらず、事実を客観的に記述している。