FailedRowsToken
in package
CSVインポートの失敗行CSVダウンロードを認可するためのメタデータを token テーブル(鍵付き・型付き・期限管理の汎用ストア)へ保存・検証する
run ID(推測困難なランダム文字列。呼び出し側が実行単位ごとに発行する)をハッシュ化した 上で token_value として保存し、SQL側でハッシュ一致に絞り込んだ後さらに PHP側で hash_equals() により再確認する(Acms\Services\Login\Traits\ValidateAuthUrl と同じ二段構え)。 token_key にはブログIDを入れ、同一ブログ内の発行済みメタデータをスコープする。
「誰が」「どのブログの」失敗行CSVを、PrivateStorage上のどこに保存したかだけを記録する。 実際の認可判定(作成者本人か、当該ブログの編集権限を今なお持つか)はダウンロード ハンドラ側が Auth ファサード等と組み合わせて行う(このクラスの責務は保存・検証のみ)。
Why not 独自テーブルを新設しないか: token テーブルは a-blog cms 既存の「鍵付き・型付き・ 期限管理」ストアとして Acms\Services\Login\Traits\CreateAuthUrl 等で確立済みのパターンで、 token_type を専用の値で名前空間分けするだけで要件を満たせる。
Table of Contents
Constants
- TOKEN_TYPE = 'csv-import-failed-rows'
Methods
- find() : array{creatorUserId: int, storagePath: string}|null
- run ID に対応するメタデータを取得する(有効期限切れ・不一致の場合は null)
- findExpired() : array<int, array{blogId: int, tokenValue: string, storagePath: string}>
- 期限切れのメタデータ一覧を返す(削除はしない)
- issue() : void
- 失敗行CSVのダウンロード認可メタデータを発行する
- isValidStoragePath() : bool
- token_data 由来の保存パスが、失敗行CSV専用ディレクトリ配下に収まっているか検証する
- revoke() : void
- 発行済みメタデータを削除する(インポート完了処理の後始末で呼ぶ)
- revokeByTokenValue() : void
- findExpired() が返した1件を、その token_value を鍵に直接削除する
- storageDirectoryPrefix() : string
- 失敗行CSVの保存先として許可するPrivateStorage上のディレクトリ(前方一致で検証する)
Constants
TOKEN_TYPE
public
mixed
TOKEN_TYPE
= 'csv-import-failed-rows'
Methods
find()
run ID に対応するメタデータを取得する(有効期限切れ・不一致の場合は null)
public
find(int $blogId, string $runId) : array{creatorUserId: int, storagePath: string}|null
Parameters
- $blogId : int
- $runId : string
Return values
array{creatorUserId: int, storagePath: string}|nullfindExpired()
期限切れのメタデータ一覧を返す(削除はしない)
public
findExpired() : array<int, array{blogId: int, tokenValue: string, storagePath: string}>
呼び出し側は、まずこの戻り値の storagePath を使って PrivateStorage 上の実ファイルを 削除し、それが成功した場合に限って revokeByTokenValue() でDB行を消すこと。 このクラス自身はDB行とファイルの削除を同時に行わない(ファイル削除が失敗した場合に DB側のメタデータだけ先に失われると、次回以降ファイルを再試行削除する手段がなくなり 孤児化するため)。
Return values
array<int, array{blogId: int, tokenValue: string, storagePath: string}>issue()
失敗行CSVのダウンロード認可メタデータを発行する
public
issue(int $blogId, string $runId, int $creatorUserId, string $storagePath, int $lifetimeSeconds) : void
Parameters
- $blogId : int
- $runId : string
- $creatorUserId : int
- $storagePath : string
- $lifetimeSeconds : int
isValidStoragePath()
token_data 由来の保存パスが、失敗行CSV専用ディレクトリ配下に収まっているか検証する
public
static isValidStoragePath(string $path) : bool
token_data はDB上の値であり本来は自分自身が発行した値しか入らないはずだが、 万一DBが改ざん・破損した場合でも、ダウンロード配信・期限切れ削除の対象を このディレクトリ配下に限定する防御層として機能させる。
Parameters
- $path : string
Return values
boolrevoke()
発行済みメタデータを削除する(インポート完了処理の後始末で呼ぶ)
public
revoke(int $blogId, string $runId) : void
Parameters
- $blogId : int
- $runId : string
revokeByTokenValue()
findExpired() が返した1件を、その token_value を鍵に直接削除する
public
revokeByTokenValue(int $blogId, string $tokenValue) : void
run ID の元値は token_value(SHA-256ハッシュ)から復元できないため、revoke() の ように run ID からハッシュ化して絞り込むことができない。findExpired() が返した ハッシュ値そのものを条件に使う。
Parameters
- $blogId : int
- $tokenValue : string
storageDirectoryPrefix()
失敗行CSVの保存先として許可するPrivateStorage上のディレクトリ(前方一致で検証する)
public
static storageDirectoryPrefix() : string
PrivateStorageはS3未設定時、PublicStorageと同一のFilesystem実装(ドキュメントルート 相対のプレーンなファイル書き込み)に解決される(StorageServiceProvider参照)ため、 保存先ディレクトリ自体がWebから直接参照不可能であることに依存する必要がある。 MEDIA_STORAGE_DIR(既定 'storage/')は Backup/Export/Media 系の既存機能が同じ理由で 使っている場所で、配布物同梱の storage/htaccess.txt が初回インストール時に .htaccess として設置され、以後の update パッケージは storage/ 配下を一切上書き・削除 しない(tools/build-cms.js の除外リスト参照)ため、既存サイトのアップグレードでも 追加のデプロイ作業なしに deny-all が効き続ける。ルート直下の htaccess.txt は逆に update パッケージから除外される(サイト側のカスタマイズを保持するため)運用のため、 ルートの新規Rewriteルールに保護を頼ると既存サイトには一切届かない。