# 画面設計書 93-権限エラー画面

## 概要

管理画面において、ユーザーがアクセス権限を持たないリソースにアクセスしようとした場合に表示される403エラー画面の設計書。

### 本画面の処理概要

**業務上の目的・背景**：管理画面では、ユーザーのロール（管理者、編集者、閲覧者など）に応じてアクセス可能な機能が制限されている。権限のない機能にアクセスしようとした場合、ユーザーに対して「アクセス権限がない」ことを明確に通知する必要がある。この画面により、ユーザーは自分の権限では該当機能を利用できないことを認識し、必要に応じて管理者に権限追加を依頼したり、許可された機能に戻るといった対応を取ることができる。また、HTTPステータスコード403（Forbidden）を正しく返すことで、不正アクセスの試みをログに適切に記録できる。

**画面へのアクセス方法**：この画面は直接アクセスするものではなく、以下の状況で自動的に表示される。
1. 管理画面内で、ユーザーのロールに許可されていない機能にアクセスしようとした場合
2. 各コントローラーのアクションでACL（アクセス制御リスト）チェックに失敗した場合
3. コントローラーから`_forward('privileges','error','admin')`により明示的に転送された場合

**主要な操作・処理内容**：
1. HTTPステータスコードの設定：「HTTP/1.1 403 Forbidden」をレスポンスヘッダに設定
2. エラータイトルの設定：「HTTP/1.1 403 Forbidden」をビュータイトルとして設定
3. エラーメッセージの設定：「You don't have permission to access this resource.」を表示メッセージとして設定
4. シンプルなレイアウトでの表示：管理画面のナビゲーションを含まない認証用レイアウト（admin-auth）を使用してエラー内容を表示
5. ユーザーへの案内：権限不足である旨を明確に伝達

**画面遷移**：
- 遷移元：管理画面内の権限チェックを行うすべてのアクション（記事管理、ユーザー管理、イベント管理、ページ管理、メール管理、コメント管理、ローテーター管理、アセット管理、設定など）
- 遷移先：特になし（エラー状態のため、ユーザーはブラウザの戻るボタンや直接URLアクセスで他ページに移動）

**権限による表示制御**：この画面自体はエラーハンドリング用であるため、認証状態に関係なく表示される。ただし、preDispatch内で認証状態を確認し、認証済みユーザーの場合はユーザー情報をビューに渡す。実際には、この画面に到達するユーザーは通常認証済みであり、特定のリソースへのアクセス権限のみが不足している状態である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 61 | アクセス制御 | 主機能 | アクセス権限不足エラーの表示 |

## 画面種別

エラー表示

## URL/ルーティング

- **URLパターン**: `/admin/error/privileges`
- **モジュール**: admin
- **コントローラー**: error
- **アクション**: privileges
- **転送方式**: コントローラーから`_forward('privileges','error','admin')`により転送

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| (なし) | - | - | - | このアクションは入力パラメータを必要としない |

## 表示項目

| 項目名 | データ型 | 説明 | 表示条件 |
|--------|----------|------|----------|
| title | string | エラータイトル（「HTTP/1.1 403 Forbidden」） | 常時 |
| message | string | エラーメッセージ（「You don't have permission to access this resource.」） | 常時 |

## イベント仕様

### 1-権限エラー表示

**トリガー**: 権限チェック失敗による明示的な転送

**処理フロー**:
1. コントローラーのアクション内でACLチェックを実行
2. `$this->view->acl->isAllowed($this->view->user->user_role, 'リソース名')`がfalseを返す
3. `$this->_forward('privileges','error','admin')`により権限エラーアクションに転送
4. Admin_ErrorControllerのprivilegesActionが呼び出される
5. setLayout()でレイアウトを「admin-auth」に変更
6. HTTPステータスを「HTTP/1.1 403 Forbidden」に設定
7. ビュータイトルを「HTTP/1.1 403 Forbidden」に設定
8. ビューメッセージを「You don't have permission to access this resource.」に設定
9. privileges.phtmlテンプレートでエラー内容を表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 権限エラー表示 | - | - | データベース操作なし |

この画面はエラー表示専用であり、データベースへの書き込み操作は行わない。ただし、権限チェック時およびpreDispatch内でACL構築のために以下のテーブルが参照される：

### テーブル別参照項目詳細（権限チェック時）

#### users_roles

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | role_id | 全件取得 | ACL構築時にロール一覧を取得 |
| SELECT | role_title | 全件取得 | ロール名称 |

#### users_resources

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | res_resource | 全件取得 | リソース識別子 |
| SELECT | res_module | 全件取得 | モジュール名 |
| SELECT | res_group | 全件取得 | グループ名 |
| SELECT | res_description | 全件取得 | リソース説明 |

#### users_privileges

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | prv_resource | 全件取得 | 対象リソース |
| SELECT | prv_role | 全件取得 | 許可されたロールID |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-001 | エラー | You don't have permission to access this resource. | 常時表示 |

## 例外処理

| 例外種別 | 対応 |
|---------|------|
| この画面自体がエラーハンドラ | 権限エラーページの表示に失敗した場合は、PHPの既定エラー処理に委ねられる |

## 備考

- この画面への転送は、各管理コントローラーのアクション内で明示的に行われる
- 権限チェックパターン：`if($this->view->acl->isAllowed($this->view->user->user_role, 'リソース名')) : ... else : $this->_forward('privileges','error','admin'); endif;`
- 権限チェックは複数リソースの組み合わせで行われることもある（例：`aarticles`と`aarticleedit`の両方が必要）
- HTTPステータスコード403が適切に設定されるため、セキュリティ監視ツールやログ分析で不正アクセスの試みを検知できる
- この画面は認証用の簡素なレイアウト（admin-auth）を使用するため、管理画面のナビゲーションメニューは表示されない
- ユーザーに詳細な権限情報（どのロールにどの権限があるか）は表示されない（セキュリティ上の配慮）

---

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

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

### 推奨読解順序

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

ACL（アクセス制御リスト）のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Factory.php | `library/CMS/Acl/Factory.php` | createGlobalAcl()メソッドでACLオブジェクトがどのように構築されるかを確認 |
| 1-2 | database.sql | `database.sql` | users_roles, users_resources, users_privilegesテーブルの構造を確認 |

**読解のコツ**: Zend_AclクラスはZend Frameworkの組み込みACL実装。ロール、リソース、権限の3層構造を理解することが重要。

#### Step 2: 権限チェックのパターンを理解する

各コントローラーでの権限チェック方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ArticlesController.php | `application/modules/admin/controllers/ArticlesController.php` | manageAction()等での権限チェックパターンを確認 |

**主要処理フロー**:
1. **行32**: `if($this->view->acl->isAllowed($this->view->user->user_role, 'aarticles'))`で権限チェック
2. **行47**: 権限がない場合`$this->_forward('privileges','error','admin')`で転送

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

権限エラー発生時の処理起点を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ErrorController.php | `application/modules/admin/controllers/ErrorController.php` | Admin_ErrorControllerクラスのprivilegesActionを確認 |

**主要処理フロー**:
1. **行61-68**: privilegesAction()メソッドが権限エラーハンドリングの本体
2. **行63**: setLayout()でレイアウトを「admin-auth」に切り替え
3. **行65**: HTTPステータスを「403 Forbidden」に設定
4. **行66**: タイトルを「HTTP/1.1 403 Forbidden」に設定
5. **行67**: メッセージを「You don't have permission to access this resource.」に設定

#### Step 4: 基底クラスを理解する

エラーコントローラーの共通処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Error.php | `library/CMS/Controller/Action/Error.php` | CMS_Controller_Action_Errorの継承関係とpreDispatch処理を確認 |

**主要処理フロー**:
- **行17-40**: preDispatch()で認証状態確認とACL構築
- **行23-27**: 認証済みの場合、ユーザー情報とロールをビューに渡す
- **行29-30**: ACL構築（CMS_Acl_Factory経由）

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

画面の出力内容を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | privileges.phtml | `application/modules/admin/views/scripts/error/privileges.phtml` | エラーメッセージの表示方法を確認 |

**主要処理フロー**:
- **行9-14**: ヘッダー情報（CSS、JavaScript、タイトル）の設定
- **行19-22**: メッセージが存在する場合に表示

#### Step 6: レイアウトを理解する

エラー画面のレイアウト構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | admin-auth.phtml | `application/layouts/admin-auth.phtml` | エラー表示用の簡素なレイアウト構造を確認 |

**主要処理フロー**:
- **行46-66**: シンプルなボックスレイアウトでコンテンツを表示
- **行53**: placeholder('title')でエラータイトルを表示
- **行55**: layout()->contentでエラー詳細を表示

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

```
管理コントローラーのアクション
    │
    ├─ ACL権限チェック
    │      └─ $this->view->acl->isAllowed(role, resource)
    │              └─ Zend_Acl::isAllowed()
    │
    │  （権限なしの場合）
    │
    └─ _forward('privileges','error','admin')
           │
           └─ Admin_ErrorController::privilegesAction()
                  │
                  ├─ setLayout() → 'admin-auth'レイアウト適用
                  │
                  ├─ CMS_Controller_Action_Error::preDispatch()
                  │      └─ CMS_Acl_Factory::createGlobalAcl()
                  │             └─ DB SELECT (users_roles, users_resources, users_privileges)
                  │
                  ├─ setRawHeader('HTTP/1.1 403 Forbidden')
                  │
                  └─ privileges.phtml（ビューレンダリング）
                         └─ admin-auth.phtml（レイアウト適用）
```

### データフロー図

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

権限チェック失敗     ───▶  _forward()               ───▶  privilegesAction呼び出し
                            │
                            ▼
privilegesAction     ───▶  固定値設定               ───▶  HTTPステータス: 403
                            │
                            ├─ title: "HTTP/1.1 403 Forbidden"
                            └─ message: "You don't have permission..."
                            │
                            ▼
固定値               ───▶  privileges.phtml         ───▶  HTMLレスポンス
                            │
                            ▼
HTMLコンテンツ       ───▶  admin-auth.phtml         ───▶  完成したHTML
```

### 権限チェックが行われるコントローラー一覧

| コントローラー | ファイル | チェック対象リソース |
|---------------|---------|-------------------|
| ArticlesController | `application/modules/admin/controllers/ArticlesController.php` | aarticles, aarticleedit, aarticledelete等 |
| AssetsController | `application/modules/admin/controllers/AssetsController.php` | assets関連 |
| CommentsController | `application/modules/admin/controllers/CommentsController.php` | gcomments等 |
| EventsController | `application/modules/admin/controllers/EventsController.php` | eevents, eeventedit等 |
| MailController | `application/modules/admin/controllers/MailController.php` | mmail等 |
| PagesController | `application/modules/admin/controllers/PagesController.php` | ppages, ppageedit等 |
| RotatorsController | `application/modules/admin/controllers/RotatorsController.php` | rotrotators等 |
| SettingsController | `application/modules/admin/controllers/SettingsController.php` | settings等 |
| UsersController | `application/modules/admin/controllers/UsersController.php` | uusers, uedit等 |

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ErrorController.php | `application/modules/admin/controllers/ErrorController.php` | コントローラー | 管理画面エラーハンドリングのメイン処理 |
| Error.php | `library/CMS/Controller/Action/Error.php` | 基底クラス | エラーコントローラー共通の認証・ACL処理 |
| privileges.phtml | `application/modules/admin/views/scripts/error/privileges.phtml` | ビューテンプレート | 権限エラーメッセージの表示テンプレート |
| admin-auth.phtml | `application/layouts/admin-auth.phtml` | レイアウト | 認証・エラー画面用の簡素なレイアウト |
| Factory.php | `library/CMS/Acl/Factory.php` | ユーティリティ | ACL（アクセス制御リスト）の構築 |
| template.css | `_styles/admin/template.css` | スタイルシート | 管理画面のスタイル定義 |
| common.js | `_scripts/admin/common.js` | JavaScript | 管理画面の共通スクリプト |
| database.sql | `database.sql` | DDL | users_roles, users_resources, users_privilegesテーブル定義 |
