HTML::FormFuや、現在開発中のアプリケーションで使わせていただいているHTML:Shakanなどのフォームクリエーター&バリデーターモジュールはとても有用です。もっと早く使えば良かったです。
有用ついでに感心したのが、アプリケーションをよりセキュアに出来るというおまけです。おまけというよりも仕様なのですが、$c->req->paramsを生で使わずに$form->paramsを使うことによって、フォームで定義していないパラメーターを食べなくて済むことが、細かいことですが嬉しい点です。
何にそんなに感激したかという具体的な話は以下の通りです。まあ上記の話を一歩も出るものではありませんが。
入力されたら困る値
一度DBに登録されたら以後その値を使い回すもの、例えば$row->idやら$row->registered_onやらといった値は、勝手な値を入れられると困ります。CLIでのみ入力したい値(例えば$user->levelで管理者権限ユーザーの色を付けるなど)に至っては致命的なセキュリティホールになります。そうした穴は絶対に塞がなければなりません。
ソースを公開するということは内部でどんな属性(アトリビュート)名すなわちDBの列名を使っているのかが丸わかりであること意味していて、穴のありかをオーロラビジョンで喧伝しているようなものなので、深刻度はさらに増します(穴を塞がない時点で深刻度の多寡は変わらないようなものですが......)。
穴なんていちいち塞げない
そんなときに、CLIとWeb GUIとWeb APIとテストと......というように、インターフェース毎に穴を塞いでいてはきりがありません。
今回のアプリケーションの場合、行オブジェクト(Data::ModelなのでData::Model::Row)をそのまま使っておらず、間に一枚Moose/Mouseクラスを挟んでいる(リレーションを簡便に実現するなどの意図があります)ので、当該クラスのアトリビュートをis => 'ro'指定しつつ別個定義したセッターでアクセスしにいく......という手もあります。ただ、似非画面遷移図に付記したDBの項目の数を見ると、その試みが現実的でないことはよく分かります。当の遷移図もどきは、数日経って、現状はさらにカオスになっています。もう目も当てられないほどに。
こういうのは面倒臭いと思った時点で負けです。その嗅覚は実装漏れやらテスト漏れやらを惹起する地雷原を察知しているようなもので、何か考えなくてはいけないなと思ってはいました。
ところが、何のことはない、ちょっとテストしてみたらどんなことかよく分かりました。
use strict;
use warnings;
use WWW::Mechanize;
WWW::Mechanize->new->post(
'http://localhost:4423/player/',
[
name => 'foo',
mail_address => 'foo@bar.example',
disclosure_range => 'everybody',
locale => 'ja',
time_zone => 'Asia/Tokyo',
password => 'aaaa1111',
password_for_verification => 'aaaa1111',
level => 'administrator', # ちゃんと無視する
],
);
上記のようなインプットを食らった場合に、$c->req->paramsには勿論levelが鎮座していますが、一旦HTML::Shakan->new(request => $c->req)してしまえば(実際にはHTML::Shakanを継承したクラスを使っています)、$form->paramsから忌まわしいlevelを霧消してくれます。
今すぐ使おうさあ使おう
「欲しいと思った値だけをくれ、他は要らん」ということを、何ら特別なことをせずに実現出来るのは、とても嬉しいことです。
フォーム作成・検証器というのは単に画面上のユーザーインターフェースを規定するだけではなくて、フォームの値を検証(バリデート)してくれるだけでもなくて、内部のロジックとの入出力についても(入力は$form->paramsで、出力は$form->model->fill($row)やら$form->fillin_paramsやらで)仲立ちしてくれる、とても強力なモジュールであることを、さらに思い知らされました。
実際のサンプルコードは......構成部品を一通り挙げると長くなるので、近い将来に公開する予定の、アプリケーション丸ごと一式をご覧いただこうと思います。
コメントする