# 機能設計書 50-同意処理

## 概要

本ドキュメントは、Etherpadにおける同意処理機能の詳細設計を記載したものである。この機能は、OAuth2フローにおけるユーザー同意（Consent）を処理し、クライアントアプリケーションへのスコープ権限付与を管理する。

### 本機能の処理概要

**業務上の目的・背景**：
OAuth2/OpenID Connect認証フローにおいて、ユーザーがクライアントアプリケーションに対してどのような権限（スコープ）を許可するかを明示的に同意させることは、プライバシー保護とセキュリティの観点から重要である。この機能は、同意画面の表示と同意処理を行い、Grant（認可付与）オブジェクトを管理する。

**機能の利用シーン**：
- 初回認可時のスコープ同意
- 追加スコープ要求時の同意
- クライアントアプリケーションへの権限付与確認

**主要な処理内容**：
1. 同意画面の表示
2. 同意フォームからの同意情報受信
3. Grant（認可付与）オブジェクトの作成または更新
4. 不足スコープ・クレームの追加
5. OAuth2フローの継続（認可コード発行）

**関連システム・外部連携**：
- oidc-providerライブラリとの連携
- Grantオブジェクト管理
- OIDCセッション管理

**権限による制御**：
- ユーザーが同意したスコープのみがアクセストークンに含まれる

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | 同意画面 | 主機能 | OAuth2フローにおけるユーザー同意を処理 |

## 機能種別

認可処理

## 入力仕様

### 入力パラメータ

同意画面からのPOSTリクエスト（フォームデータ）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 同意フォームからの送信（パラメータなし） | - |

### 入力データソース

- REST API: `POST /interaction/:uid`
- OIDCインタラクション詳細から同意情報を取得

## 出力仕様

### 出力データ

OAuth2認可フローのリダイレクト（認可コード付き）

### 出力先

- 成功時: リダイレクト（redirect_uriへ認可コード付き）

## 処理フロー

### 処理シーケンス

```
1. 同意画面表示
   └─ GET /interaction/:uid → /views/consent.html にリダイレクト

2. 同意フォーム送信
   └─ POST /interaction/:uid

3. インタラクション詳細取得
   └─ oidc.interactionDetails でセッション情報取得

4. プロンプト種別確認
   └─ prompt.name === 'consent' を確認

5. Grant処理
   ├─ grantIdがある場合: 既存Grantを取得
   └─ grantIdがない場合: 新規Grantを作成

6. スコープ・クレーム追加
   ├─ missingOIDCScope があれば追加
   ├─ missingOIDCClaims があれば追加
   └─ missingResourceScopes があれば追加

7. Grant保存
   └─ grant.save() でGrantを永続化

8. インタラクション完了
   └─ interactionFinished で同意完了を通知

9. 認可フロー継続
   └─ 認可コード発行、redirect_uriへリダイレクト
```

### フローチャート

```mermaid
flowchart TD
    A[同意画面表示] --> B[同意フォーム送信]
    B --> C[インタラクション詳細取得]
    C --> D{prompt.name === 'consent'?}
    D -->|No| E[他のプロンプト処理]
    D -->|Yes| F{grantId存在?}
    F -->|Yes| G[既存Grant取得]
    F -->|No| H[新規Grant作成]
    G --> I[不足スコープ追加]
    H --> I
    I --> J[不足クレーム追加]
    J --> K[リソーススコープ追加]
    K --> L[Grant保存]
    L --> M[interactionFinished]
    M --> N[認可コード発行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | Grant継続 | 既存セッションにgrantIdがあれば既存Grantを更新 | 再同意時 |
| BR-50-02 | 新規Grant | grantIdがなければ新規Grantを作成 | 初回同意時 |
| BR-50-03 | スコープ追加 | missingOIDCScopeをスペース区切りで追加 | スコープ不足時 |
| BR-50-04 | クレーム追加 | missingOIDCClaimsを配列で追加 | クレーム不足時 |
| BR-50-05 | リソース追加 | missingResourceScopesをリソースごとに追加 | リソーススコープ不足時 |
| BR-50-06 | マージ有効 | mergeWithLastSubmission: trueで既存状態と統合 | 同意完了時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Grant取得 | LRUCache（メモリ） | SELECT | 既存Grant取得 |
| Grant作成 | LRUCache（メモリ） | INSERT | 新規Grant作成 |
| Grant保存 | LRUCache（メモリ） | UPDATE | Grant情報更新 |

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

Grantオブジェクトはoidc-providerによりLRUCacheに保存される

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 500 | サーバーエラー | 内部処理エラー | サーバーログを確認 |
| access_denied | OAuth2エラー | ユーザーが同意を拒否（未実装） | クライアントで対処 |

### リトライ仕様

同意フロー全体を再実行すること

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

LRUCacheベースのメモリストレージのため、明示的なトランザクション管理なし

## パフォーマンス要件

- 同意処理: 100ms以内
- Grant保存: 50ms以内

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

- 同意画面でユーザーに明確にスコープを表示すること
- 過剰なスコープ要求を避けること
- 同意は明示的なユーザーアクションによってのみ付与されること

## 備考

- 現在の実装では同意拒否のハンドリングが明示的に実装されていない
- 同意画面のUIはカスタマイズ可能（/views/consent.html）
- 同意は永続化されないため、サーバー再起動で失われる

---

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

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

### 推奨読解順序

#### Step 1: 同意画面表示を理解する

GET /interaction/:uid の同意画面リダイレクトを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OAuth2Provider.ts | `src/node/security/OAuth2Provider.ts` | 同意画面リダイレクト |

**読解のコツ**:
- **230-259行目**: GET /interaction/:uid 全体
- **246-250行目**: prompt.name === 'consent' で同意画面にリダイレクト

#### Step 2: 同意処理を理解する

POST /interaction/:uid の同意処理ブロックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OAuth2Provider.ts | `src/node/security/OAuth2Provider.ts` | 同意処理ブロック |

**主要処理フロー**:
- **191-221行目**: 同意処理ブロック全体
- **192-202行目**: Grant取得または作成
- **204-207行目**: missingOIDCScope追加
- **208-210行目**: missingOIDCClaims追加
- **211-214行目**: missingResourceScopes追加
- **216行目**: Grant保存
- **217-220行目**: interactionFinished呼び出し

#### Step 3: Grantオブジェクトを理解する

oidc-providerのGrantクラスの使用方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OAuth2Provider.ts | `src/node/security/OAuth2Provider.ts` | Grant操作 |

**主要処理フロー**:
- **195行目**: oidc.Grant.find(grantId) で既存Grant取得
- **197-201行目**: new oidc.Grant() で新規Grant作成
- **206行目**: grant.addOIDCScope() でスコープ追加
- **209行目**: grant.addOIDCClaims() でクレーム追加
- **213行目**: grant.addResourceScope() でリソーススコープ追加
- **216行目**: grant.save() で保存

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

```
GET /interaction/:uid (同意画面表示)
    │
    ├─ oidc.interactionDetails(req, res)
    │      └─ prompt.name === 'consent' 判定
    │
    └─ res.redirect('/views/consent.html')

POST /interaction/:uid (同意処理)
    │
    ├─ oidc.interactionDetails(req, res)
    │      └─ prompt, grantId, session, params 取得
    │
    ├─ Grant処理
    │      ├─ oidc.Grant.find(grantId)  // 既存Grant
    │      └─ new oidc.Grant()          // 新規Grant
    │
    ├─ スコープ・クレーム追加
    │      ├─ grant.addOIDCScope()
    │      ├─ grant.addOIDCClaims()
    │      └─ grant.addResourceScope()
    │
    ├─ grant.save()
    │
    └─ oidc.interactionFinished(req, res, {consent: {grantId}})
```

### データフロー図

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

同意フォーム送信 ───▶  POST /interaction/:uid  ───▶  リダイレクト
                              │                      (認可コード付き)
                              ▼
                      interactionDetails取得
                              │
                              ▼
                      Grant取得/作成
                              │
                              ▼
                      スコープ・クレーム追加
                              │
                              ▼
                      Grant保存
                              │
                              ▼
                      interactionFinished
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OAuth2Provider.ts | `src/node/security/OAuth2Provider.ts` | ソース | 同意処理の実装 |
| consent.html | `src/static/oidc/consent.html` | 静的ファイル | 同意画面 |
| OIDCAdapter.ts | `src/node/security/OIDCAdapter.ts` | ソース | Grant保存 |
