Tuesday, May 23, 2006

The concept of Delegate (3)

C# use Delegate as Event. Event is one of excellent features of C#, and used for event driven programming at components.

XOOPS Cube also has the concept of Event. But, it doesn't separate Delegate and Event. I wrote that we have the plan to change the class design about Delegate. The plan is that we will make XOOPS Cube to separate these concept. Mind that the sample code of this entry will not work in the future.

OK, Let's learn Event of XOOPS Cube. Now, Event of XOOPS Cube equals Delegate of XOOPS Cube. You can register your function as Delegate to Event, and the event calls your Delegate when the event is triggered.

For example, when users are successful in login, "Module.User.Login.Success" event is triggered. The argument is XoopsUser object. In fact, one of the default delegates records current time to the last login time of the object. You can add your function as Delegate to this event.

There is popular security hack among Japanese users. That doesn't allow login as administrators except of special IP. This hack is good for company, and guards that administrators have their password stolen. In XOOPS2, the hack had to be written directly to common.php or admin.php. In XOOPS Cube Legacy 2.1, you can execute your function by using Delegate when users are successful in login. Your function may kick except of special IP.

You should register it to "Site.Login". If the attacker hijack the session, he may not get through "Module.User.Login.Success". But, "Site.Login" has to be called.

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;
}
}

Save this file as XOOPS_ROOT_PATH/preload/IPChecker.class.php.

Well, it's possible to include such function to XOOPS Cube. But, how many are minor requests? Who can include, manage and maintain these codes completely? Too fat program shall lose good maintenance. We chose the small core. It doesn't have many functions. But, Preload and Delegate give you new hacking means and sharing.

Users' idea often transcends the core. And, users can set only must of these ideas.

No comments: