# 通知設計書 6-リバースプロキシ設定警告（ReverseProxySetupMonitor）

## 概要

本ドキュメントは、リバースプロキシの設定が不正な場合に管理者へ警告を表示するReverseProxySetupMonitor（リバースプロキシ設定警告）の通知設計について記述する。

### 本通知の処理概要

ReverseProxySetupMonitorは、リバースプロキシ環境においてLocationヘッダーの書き換えが正しく行われていない場合を検出し、管理者に対して設定確認を促す警告メッセージを表示する通知機能である。

**業務上の目的・背景**：JenkinsをNginxやApacheなどのリバースプロキシ背後で運用する場合、プロキシはLocationヘッダーを適切に書き換える必要がある。設定が不正な場合、リダイレクトが正しく機能せず、ユーザーが内部URLにアクセスしようとしてエラーになる。本通知は、JavaScript経由でAJAXリクエストを行い、302リダイレクトの処理結果を検証することで、リバースプロキシの設定問題を検出する。

**通知の送信タイミング**：`isActivated()`は常にtrueを返すが、`isActivationFake()`もtrueを返すため、実際の警告表示はJavaScriptによるクライアントサイドテストの結果に依存する。管理画面読み込み時にJavaScriptがAJAXリクエストを発行し、リダイレクト処理の正常性を検証する。

**通知の受信者**：Jenkins.SYSTEM_READ権限を持つユーザーが対象となる。ただし、Dismissボタンは管理者のみに表示される。

**通知内容の概要**：リバースプロキシの設定に問題がある可能性を示すメッセージが表示される。「More Info」ボタンでJenkins公式ドキュメントへの誘導、「Dismiss」ボタンで警告の非表示化が可能。

**期待されるアクション**：管理者は「More Info」をクリックしてJenkins公式のリバースプロキシトラブルシューティングガイドを参照し、プロキシサーバーの設定を確認・修正することが期待される。

## 通知種別

アプリ内通知（管理画面バナー表示）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | クライアントサイド（JavaScript） |
| 優先度 | 中 |
| リトライ | 無（画面表示のため不要） |

### 送信先決定ロジック

Jenkins.SYSTEM_READ権限を持つユーザーに対して表示される。実際の表示はクライアントサイドのJavaScriptテスト結果に依存。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 表示位置 | 管理画面上部 |
| アラートタイプ | jenkins-alert-danger（危険） |
| 形式 | HTML + JavaScript |

### 本文テンプレート

```html
<div id="redirect-error" class="jenkins-alert jenkins-alert-danger reverse-proxy__hidden"
     data-url="${rootURL}/${it.url}/test" data-context="${rootURL}">
  <form method="post" action="${rootURL}/${it.url}/act" name="${it.id}">
    <f:submit name="yes" value="More Info"/>
    <l:isAdmin>
      <f:submit name="no" value="Dismiss"/>
    </l:isAdmin>
  </form>
  <div>${%blurb}</div>
  <div class="js-context-message reverse-proxy__hidden">${%missingContextMessage(rootURL)}</div>
</div>
<st:adjunct includes="hudson.diagnosis.ReverseProxySetupMonitor.resources"/>
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| rootURL | JenkinsのルートURL | Jenkins.get().getRootUrl() | Yes |
| it.url | モニターのURL | AdministrativeMonitor.getUrl() | Yes |
| it.id | モニターのID | AdministrativeMonitor.id | Yes |
| blurb | 警告メッセージ本文 | Messages.properties | Yes |
| missingContextMessage | コンテキストパス不正時のメッセージ | Messages.properties | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | 管理画面読み込み | JavaScriptテスト失敗 | リダイレクトテストの結果に基づく |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| disable(true)が呼び出された場合 | 管理者が「Dismiss」をクリックした場合 |
| JavaScriptテスト成功 | リダイレクト処理が正常な場合、hidden状態のまま |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[管理画面読み込み] --> B[JavaScript実行]
    B --> C[doTest AJAXリクエスト]
    C --> D[サーバー側302リダイレクト]
    D --> E[getTestForReverseProxySetup]
    E --> F{リダイレクト先URL検証}
    F -->|一致| G[200 OK返却]
    F -->|不一致| H[404 Error返却]
    G --> I[警告非表示維持]
    H --> J[警告バナー表示]
    J --> K{ユーザーアクション}
    K -->|More Info| L[Jenkins公式ドキュメントへ]
    K -->|Dismiss| M[disable true]
    I --> N[終了]
    L --> N
    M --> N
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（リクエスト情報を参照）

### 参照情報

| 情報 | 用途 | 備考 |
|------|------|------|
| request.getReferer() | リファラーURL | テストリクエストの検証に使用 |
| Jenkins.getRootUrl() | ルートURL | リダイレクト先の構築に使用 |
| Jenkins.getRootUrlFromRequest() | リクエストからのルートURL | 検証用の推測URL構築に使用 |

### 更新ファイル

| ファイル | 操作 | 概要 |
|---------|------|------|
| $JENKINS_HOME/config.xml | UPDATE | disable()呼び出し時にdisabledAdministrativeMonitorsを更新 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リダイレクトテスト失敗 | URLの不一致 | 404エラー返却、警告表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

該当なし（画面表示のため）

### 配信時間帯

制限なし（常時有効）

## セキュリティ考慮事項

- getRequiredPermission()でJenkins.SYSTEM_READを返し、読み取り専用アクセスを許可
- doAct()は`@RequirePOST`で保護
- Dismissボタンは管理者のみに表示（`<l:isAdmin>`）
- doTest(), getTestForReverseProxySetup()は`@Restricted(DoNotUse.class)`で直接呼び出し制限

## 備考

- Symbol: `reverseProxy`
- パッケージ: hudson.diagnosis
- 特殊性: isActivated()は常にtrue、isActivationFake()もtrue（実際の表示はJavaScript制御）
- 外部リンク: https://www.jenkins.io/redirect/troubleshooting/broken-reverse-proxy
- メッセージリソース: hudson/diagnosis/Messages.properties

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: 特殊な有効化ロジックを理解する

isActivated()とisActivationFake()の関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ReverseProxySetupMonitor.java | `core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java` | 常にtrueを返すisActivated()、isActivationFake() |

**読解のコツ**: isActivationFake()がtrueを返すことで、管理者モニター件数カウントから除外される点に注目。

#### Step 2: テスト処理を理解する

doTest()とgetTestForReverseProxySetup()。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ReverseProxySetupMonitor.java | `core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java` | テストリクエスト処理、リダイレクト検証 |

**主要処理フロー**:
1. **74-95行目**: `doTest()` - テストリクエストのハンドリング
   - **77行目**: リファラー取得
   - **81-89行目**: testWithContextパラメータでコンテキストパス付きURLを構築
   - **94行目**: HttpRedirectでテストURLへリダイレクト
2. **97-110行目**: `getTestForReverseProxySetup()` - リダイレクト先での検証
   - **102行目**: getRootUrlFromRequest()で推測URL取得
   - **104-108行目**: URL比較、一致なら200 OK、不一致なら404

#### Step 3: ビューとJavaScriptを理解する

message.jellyとクライアントサイドのテスト実行。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | message.jelly | `core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message.jelly` | 初期非表示状態、data属性でテストURL指定 |

**主要処理フロー**:
- **26-27行目**: `reverse-proxy__hidden`クラスで初期非表示
- **27行目**: `data-url`と`data-context`でテスト用情報提供
- **37行目**: st:adjunctでJavaScriptリソース読み込み

### プログラム呼び出し階層図

```
[クライアントサイド]
管理画面読み込み
    │
    └─ JavaScript実行
           │
           └─ AJAX: doTest(testWithContext)
                  │
                  └─ HttpRedirect → getTestForReverseProxySetup(rest)
                         │
                         ├─ getRootUrlFromRequest() + "manage"
                         │
                         └─ rest.startsWith(inferred)?
                                │
                                ├─ Yes → 200 OK
                                │
                                └─ No → 404 Error → 警告表示

[サーバーサイド]
Jenkins.getAdministrativeMonitors()
    │
    ├─ ReverseProxySetupMonitor.isActivated()
    │      └─ return true
    │
    ├─ ReverseProxySetupMonitor.isActivationFake()
    │      └─ return true
    │
    └─ ReverseProxySetupMonitor.doAct(no)
           ├─ "no" → disable(true), redirect /manage
           └─ "yes" → redirect Jenkins公式ドキュメント
```

### データフロー図

```
[入力]                    [処理]                         [出力]

管理画面読み込み ───▶ JavaScript実行 ───▶ AJAXリクエスト
                                                │
                                                ▼
                                         doTest()
                                                │
                                                ▼
                                       302 Redirect
                                                │
                                                ▼
                              getTestForReverseProxySetup()
                                                │
                                    ┌───────────┴───────────┐
                                    ▼                       ▼
                              URL一致                    URL不一致
                                    │                       │
                                    ▼                       ▼
                              200 OK                   404 Error
                                    │                       │
                                    ▼                       ▼
                              警告非表示               警告表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ReverseProxySetupMonitor.java | `core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java` | ソース | メインクラス |
| AdministrativeMonitor.java | `core/src/main/java/hudson/model/AdministrativeMonitor.java` | ソース | 基底クラス |
| message.jelly | `core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message.jelly` | テンプレート | 警告バナーUI |
| description.jelly | `core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/description.jelly` | テンプレート | 説明文 |
| Messages.properties | `core/src/main/resources/hudson/diagnosis/Messages.properties` | リソース | メッセージ定義 |
| ReverseProxySetupMonitorTest.java | `test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java` | テスト | 単体テスト |
