# バッチ設計書 36-remove_mfa

## 概要

本ドキュメントは、InvenTreeシステムにおけるMFA削除バッチ（remove_mfa）の設計仕様を定義する。

### 本バッチの処理概要

remove_mfaは、指定されたユーザーの多要素認証（MFA: Multi-Factor Authentication）設定を削除するDjango管理コマンドである。

**業務上の目的・背景**：InvenTreeはセキュリティ強化のためにMFA（多要素認証）機能を提供している。ユーザーがMFAデバイス（スマートフォンのTOTPアプリなど）を紛失した場合や、MFA設定に問題が発生した場合、ユーザーはシステムにログインできなくなる可能性がある。本バッチは、システム管理者が緊急時にユーザーのMFA設定を削除し、ユーザーがパスワードのみでログインできるようにするための管理ツールである。これにより、ユーザーは再度ログインしてMFAを再設定することができる。

**バッチの実行タイミング**：手動実行（CLIコマンド）。以下の場面で実行される：
- ユーザーがMFAデバイスを紛失した場合
- MFA設定に問題が発生し、ユーザーがログインできない場合
- ユーザーアカウントのトラブルシューティング時

**主要な処理内容**：
1. メールアドレスまたはユーザー名でユーザーを検索
2. 該当ユーザーの一意性を確認
3. ユーザーに紐付いている全てのMFA認証メソッドを削除
4. 削除結果をログ出力

**前後の処理との関連**：
- 前提：対象ユーザーがシステムに存在すること
- 後続：ユーザーがパスワードのみでログイン可能になる

**影響範囲**：
- 指定ユーザーのauthenticator_setテーブルのレコード
- ユーザーのログイン認証フロー

## バッチ種別

ユーザー管理 / セキュリティ設定変更

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（手動） |
| 実行時刻 | 任意 |
| 実行曜日 | 任意 |
| 実行日 | 任意 |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Django環境 | Django環境が正しく設定されていること |
| ユーザー存在 | 指定されたメールアドレスまたはユーザー名のユーザーが存在すること |
| 管理者権限 | コマンド実行者がシステム管理者であること |

### 実行可否判定

- メールアドレスまたはユーザー名のいずれかが指定されていること
- 指定された条件で一意のユーザーが特定できること（複数ユーザーが該当する場合はエラー）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --mail | str | No* | None | MFAを削除するユーザーのメールアドレス |
| --username | str | No* | None | MFAを削除するユーザーのユーザー名 |

*注: --mailまたは--usernameのいずれか一方は必須

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| User (auth.User) | DBテーブル | ユーザー情報 |
| EmailAddress (allauth) | DBテーブル | ユーザーのメールアドレス情報 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 処理結果メッセージ |
| ログ | structlog | 処理結果のログ |

### 出力ファイル仕様

ファイル出力なし（コンソール出力のみ）

## 処理フロー

### 処理シーケンス

```
1. コマンド引数の検証
   └─ mailとusernameの両方が未指定の場合はエラー
2. ユーザー検索
   └─ mailが指定された場合：
      └─ User.emailまたはEmailAddress.emailでユーザーを検索
   └─ usernameが指定された場合：
      └─ User.usernameでユーザーを検索
3. ユーザー一意性の確認
   └─ 該当ユーザーが0人の場合：警告ログ出力
   └─ 該当ユーザーが複数の場合：エラーログ出力
   └─ 該当ユーザーが1人の場合：処理続行
4. MFA削除処理
   └─ user.authenticator_set.all()で全MFAメソッドを取得
   └─ 取得したレコードを削除
5. 結果出力
   └─ 削除件数をログ出力
   └─ 'done'を返却
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{mail/username指定?}
    B -->|両方未指定| C[ValueError発生]
    B -->|mail指定| D[メールでユーザー検索]
    B -->|username指定| E[ユーザー名で検索]
    D --> F{ユーザー数?}
    E --> F
    F -->|0人| G[警告ログ出力]
    F -->|複数| H[エラーログ出力]
    F -->|1人| I[MFA設定を取得]
    G --> J[False返却]
    H --> J
    I --> K[全MFAメソッドを削除]
    K --> L[削除件数をログ出力]
    L --> M['done'返却]
    J --> N[バッチ終了]
    M --> N
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー検索 | auth_user | SELECT | メール/ユーザー名でユーザーを検索 |
| メール検索 | account_emailaddress | SELECT | メールアドレスでユーザーを検索 |
| MFA削除 | mfa_authenticator | DELETE | ユーザーの全MFA設定を削除 |

### テーブル別操作詳細

#### auth_user

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | email, username | email=指定値 OR username=指定値 | ユーザー特定用 |

#### account_emailaddress

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | email, user_id | email=指定値 | allauthのメールアドレステーブル |

#### mfa_authenticator

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | * | user_id=対象ユーザーID | 全MFA設定を削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ValueError | mail/usernameが両方未指定 | いずれかの引数を指定 |
| - | Warning | 指定条件に該当するユーザーがいない | メールアドレス/ユーザー名を確認 |
| - | Error | 複数ユーザーが該当 | より限定的な条件を使用 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（手動再実行） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. エラーメッセージを確認
2. 指定したメールアドレス/ユーザー名が正しいか確認
3. 複数ユーザーが該当する場合は、より限定的な条件（username）を使用

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | delete()操作単位 |
| コミットタイミング | delete()完了時に自動コミット |
| ロールバック条件 | delete()操作中のエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1ユーザーあたり1〜数件のMFA設定 |
| 目標処理時間 | 1秒未満 |
| メモリ使用量上限 | 最小限 |

## 排他制御

同時実行の制御は行わない。同一ユーザーに対する同時実行は避けることを推奨。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | ユーザー未発見時 | "No user with this mail/username associated" |
| エラーログ | 複数ユーザー該当時 | "Multiple users found with the provided email/username; Usernames: '...', Emails: '...'" |
| 情報ログ | 削除成功時 | "Removed all ({n}) MFA methods for user {username}" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | - |

## 備考

- 本コマンドは `invoke remove_mfa` からも呼び出し可能
- MFA削除後、ユーザーはパスワードのみでログインできるようになる
- ユーザーには再度MFAを設定することを推奨
- メールアドレス検索はUser.emailとallauth.EmailAddressの両方を検索する
- セキュリティ上の理由から、このコマンドの実行はログに記録される
