The concept of Delegate (3)
C# は、デリゲートをイベントとして用います。イベントは、 C# の優れたフィーチャーのひとつであり、コンポーネントにおいてイベント・ドリブンなプログラミングのために使われています。

XOOPS Cubeも、イベントの概念を持っています。しかし、それはデリゲートとイベントを区別しません。私は、コアチームはデリゲートについてクラス設計を変更する計画を持っていると書きました。その計画は、XOOPS Cubeにこれらの概念を分離させるということです。将来、このエントリのサンプル・コードが動作しないであろうことに注意してください。

さて、 XOOPS Cube のイベントを学びましょう。現在、XOOPS Cube のイベントは、デリゲートと同じものです。あなたは、デリゲートとしてあなたの関数をイベントに登録することができ、そして、そのイベントが発生したとき、イベントはあなたのデリゲートを呼びます。

例えば、ユーザーがログインに成功すると、Module.User.Login.Successイベントが発生します。その引数は、 XoopsUser オブジェクトです。実際、デフォルトのデリゲートのうちのひとつは、オブジェクトの最終ログイン時刻に現在の時間を記録します。あなたは、デリゲートとしてのあなたの関数をこのイベントに追加できます。

日本のユーザーの間でポピュラーなセキュリティ・ハックがあります。それは、特定の IP を除いて、管理者としてのログインを許可しないという機能を持っています。このハックは、会社や、管理者のパスワードが盗まれたケースへのガードに有効です。XOOPS2 においては、そのハックは、直接 common.php 、または、 admin.php に書かれなければなりませんでした。XOOPS Cube Legacy 2.1 においては、ユーザーがログインに成功したときに、デリゲートを使うことで自前の関数を実行できます。あとは、あなたの関数が、特定のIP以外を跳ね返せばよいのです。

あなたは、それを Site.Login に登録すべきです。もしアタッカーがセッションハイジャックを行えば、彼は Module.User.Login.Success を通過しないかも知れません。しかし、 "Site.Login" は、常に呼ばれます。

if (!defined('XOOPS_ROOT_PATH')) exit();

define("ALLOW_AS_ADMIN_IP", "127.0.0.1");

class
IPChecker extends XCube_ActionFilter
{
    function
preBlockFilter()
    {
        
$delegate =& new XCube_Delegate("IPChecker", "siteLogin");
        
$this->mController->mRoot->mEventManager->add("Site.Login", $delegate);
    }

    function
siteLoginSuccess(&$sender, &$eventArgs)
    {
        
//
        // Delegate doesn't know own turn. Call static function
        // of the user module to login.
        //
        
if (!is_object($eventArgs->mXoopsUser)) {
            
UserCommonEventFunction::Login($sender, $eventArgs);
        }
        
        
//
        // If the current user is guest, return.
        //
        
if (!is_object($eventArgs->mXoopsUser)) {
            return
$eventArgs;
        }
        
        
//
        // If the current user is a administrator, check IP.
        //
        
if ($eventArgs->mXoopsUser->isAdmin()
            &&
$_SERVER['SERVER_ADDR'] != ALLOW_AS_ADMIN_IP) {
            
$_SESSION = array();
            
$sender->executeForward(XOOPS_URL . "/");
            die();
        }
        
        return
$eventArgs;
    }
}

このファイルを XOOPS_ROOT_PATH/preload/IPChecker.class.php に保存してください。

さて……このような機能は XOOPS Cube の本体に含めることが可能です。しかし、一部の人のみが必要とするリクエストが、どれくらいあるでしょうか? 一体だれが、これらのコードを取り込んで、管理して、メンテナンスできるでしょうか? 肥満プログラムは、えてして良好なメンテナンスを失いがちです。私達は、小さなコアを選択しました。それはそれほど多くの機能を内蔵していません。しかし、プリロードとデリゲートは新しいハック手段と共有をもたらすでしょう。

ユーザーのアイデアは、しばしばコアを超越します。そして、ユーザーは、これらのアイデアのうち必要なものだけをセットすることができるのです。
|