# 画面設計書 229-アイデンティティ新規作成

## 概要

本ドキュメントは、GitLab管理者エリアにおけるユーザーアイデンティティ新規作成画面の設計について記述する。

### 本画面の処理概要

本画面は特定ユーザーに対して新しい外部認証プロバイダのアイデンティティ（LDAP、SAML、OAuth等）を追加するための管理者向け画面である。

**業務上の目的・背景**：GitLabは複数の外部認証プロバイダと連携することができる。管理者が手動でユーザーに対して外部プロバイダとの連携情報を設定する必要がある場合に本画面を使用する。例えば、LDAPサーバーとの同期が正しく機能しない場合に手動で連携を設定したり、特定のSAMLプロバイダとの連携を追加したりする際に使用される。

**画面へのアクセス方法**：管理者としてログイン後、Admin Area > Overview > Users > ユーザー詳細 > Identitiesタブ > New identityボタンをクリック、またはURLで`/admin/users/:user_id/identities/new`に直接アクセスする。

**主要な操作・処理内容**：
1. プロバイダの選択（LDAP、SAML、OAuth等）
2. 外部識別子（extern_uid）の入力
3. アイデンティティの保存

**画面遷移**：
- アイデンティティ一覧画面（No.228）からの遷移
- 保存成功時：アイデンティティ一覧画面へリダイレクト
- 保存失敗時：フォームを再表示

**権限による表示制御**：管理者権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 111 | ユーザー管理 | 主機能 | ユーザーアイデンティティの追加 |

## 画面種別

新規作成

## URL/ルーティング

| HTTP メソッド | URL | アクション | 説明 |
|--------------|-----|-----------|------|
| GET | /admin/users/:user_id/identities/new | new | アイデンティティ新規作成画面表示 |
| POST | /admin/users/:user_id/identities | create | アイデンティティ作成処理 |

## 入出力項目

| 項目名 | 入力/出力 | 型 | 必須 | 説明 |
|--------|----------|----|----|------|
| user_id | 入力（URL） | 文字列 | はい | ユーザーID（ユーザー名） |
| provider | 入力 | 選択 | はい | 認証プロバイダ |
| extern_uid | 入力 | 文字列 | はい | 外部識別子 |

## 表示項目

| セクション | 項目 | 説明 |
|-----------|------|------|
| パンくず | Users | 管理者ユーザー一覧へのリンク |
| パンくず | ユーザー名 | 対象ユーザーのアイデンティティ一覧へのリンク |
| パンくず | New identity | 現在の画面 |
| ヘッダー | タイトル | "New identity" |
| フォーム | Provider | プロバイダ選択ドロップダウン（LDAP、SAML、OAuth等） |
| フォーム | Identifier | 外部識別子入力フィールド（必須） |
| フッター | Save changesボタン | 保存実行 |

## イベント仕様

### 1-Save changesボタン押下

1. フォームをバリデーション
2. POSTリクエストを`/admin/users/:user_id/identities`に送信
3. Identity.newでインスタンス作成
4. user_idを対象ユーザーのIDに設定
5. @identity.saveを実行
6. 成功時：アイデンティティ一覧画面にリダイレクト、「User identity was successfully created.」メッセージを表示
7. 失敗時：エラーを表示してフォームを再表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | users | SELECT | ユーザー情報取得 |
| アイデンティティ作成 | identities | INSERT | アイデンティティレコード作成 |

### テーブル別更新項目詳細

#### identities

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | provider | フォーム選択値 | 認証プロバイダ名 |
| INSERT | extern_uid | フォーム入力値 | 外部識別子 |
| INSERT | user_id | @user.id | 対象ユーザーID |
| INSERT | saml_provider_id | フォーム入力値（EE版） | SAMLプロバイダID |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|---------|
| 成功 | User identity was successfully created. | 作成成功時 |
| エラー | バリデーションエラーメッセージ | 入力エラー時 |

## 例外処理

| 状態 | 処理 |
|------|------|
| 権限不足 | 403エラー画面にリダイレクト |
| ユーザー不存在 | 404エラー画面にリダイレクト |
| バリデーションエラー | フォームを再表示し、エラーメッセージを表示 |
| プロバイダ重複 | 「Provider has already been taken」エラー（同一ユーザー・プロバイダの組み合わせ） |

## 備考

- プロバイダのリストはGitlab::Auth::OAuth::Provider.providersから動的に生成される
- 各プロバイダのラベルはGitlab::Auth::OAuth::Provider.label_forで取得
- EE版ではSAMLプロバイダIDフィールドが追加される（render_if_existsで条件付き表示）
- feature_categoryは`system_access`に設定されている

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | identity.rb | `app/models/identity.rb` | Identityモデルの構造、バリデーション |

**読解のコツ**:
- provider、extern_uid、user_idの関係を理解
- validates :provider, uniqueness: { scope: :user_id }でユーザーごとのプロバイダ一意性を確認
- ldap?メソッドでLDAPプロバイダかどうかを判定

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | identities_controller.rb | `app/controllers/admin/identities_controller.rb` | newアクション、createアクション |

**主要処理フロー**:
- **行9-11**: newアクションでIdentity.new
- **行13-22**: createアクションでアイデンティティ作成
- **行14**: Identity.new(identity_params)でインスタンス作成
- **行15**: @identity.user_id = user.idでユーザーID設定
- **行17-21**: 保存成功/失敗の分岐

#### Step 3: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.haml | `app/views/admin/identities/new.html.haml` | 新規作成画面構造 |
| 3-2 | _form.html.haml | `app/views/admin/identities/_form.html.haml` | フォームフィールド定義 |

**主要処理フロー**:
- **new.html.haml 行1-3**: パンくずリスト設定
- **new.html.haml 行4**: ページタイトル「New identity」
- **new.html.haml 行6**: PageHeadingComponentでヘッダー表示
- **new.html.haml 行7**: _formパーシャルをレンダリング
- **_form.html.haml 行1**: gitlab_ui_form_forでフォーム生成
- **_form.html.haml 行8-9**: Gitlab::Auth::OAuth::Provider.providersからプロバイダリスト生成
- **_form.html.haml 行13-15**: extern_uid入力フィールド（必須）
- **_form.html.haml 行18**: Save changesボタン

#### Step 4: ルーティングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | admin.rb | `config/routes/admin.rb` | identitiesリソース定義 |

**主要処理フロー**:
- `resources :identities, except: [:show]`

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

```
Admin::IdentitiesController#new
    │
    ├─ user（ユーザー取得）
    │
    ├─ @identity = Identity.new
    │
    └─ view: new.html.haml
           │
           └─ partial: _form.html.haml
                  │
                  ├─ Gitlab::Auth::OAuth::Provider.providers
                  │
                  └─ render_if_exists: _provider_id（EE）

Admin::IdentitiesController#create
    │
    ├─ Identity.new(identity_params)
    │
    ├─ @identity.user_id = user.id
    │
    └─ @identity.save
           │
           ├─ 成功 → redirect_to identities_path + notice
           │
           └─ 失敗 → render :new
```

### データフロー図

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

URL /:user_id ───▶ IdentitiesController#new ───▶ @identity（空）
                         │
                         └─ view: new.html.haml（フォーム表示）

フォーム入力 ───────▶ IdentitiesController#create ───▶ Identity.new
                         │                               │
                         │ identity_params               │
                         │ + user_id                     ▼
                         │                        identitiesテーブル INSERT
                         │                               │
                         └───────────────────────────────┘
                                  │
                                  ▼
                         リダイレクト（一覧画面）
                              + フラッシュ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| identities_controller.rb | `app/controllers/admin/identities_controller.rb` | コントローラ | new/createアクション（行9-22） |
| new.html.haml | `app/views/admin/identities/new.html.haml` | テンプレート | 新規作成画面 |
| _form.html.haml | `app/views/admin/identities/_form.html.haml` | パーシャル | フォームフィールド |
| identity.rb | `app/models/identity.rb` | モデル | アイデンティティモデル |
| admin.rb | `config/routes/admin.rb` | ルーティング | URL定義 |
