<?PHP
#
#   FILE:  phpBBSync.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2011 Edward Almasy and Internet Scout
#   http://scout.wisc.edu
#

/**
* Plugin to synchronize logins with a phpBB site.
*/
class phpBBSync extends Plugin
{
    /**
    * Register the phpBBSync plugin.
    * @see Plugin::Register
    */
    function Register()
    {
        $this->Name = "phpBB Login Synchronization";
        $this->Version = "1.0.2";
        $this->Description = "Allows users to sign in to an associated "
            ."phpBB installation using their CWIS login.  An included companion "
            ."module (<i>auth_cwis.php</i>) must be loaded into phpBB "
            ."for this plugin to work.";
        $this->Author = "Internet Scout";
        $this->Url = "http:#scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array(
            "CWISCore" => "2.0.0"
            );
    }

    /**
    * Install the phpBBSync plugin.
    * @see Plugin::Install
    */
    function Install()
    {
        $DB = new Database();
        $DB->Query("CREATE TABLE phpBBSync_LoginData ( "
                   ."UserName TEXT, "
                   ."RemIp TEXT,"
                   ."Token INT );");
    }

    /**
    * Hook the phpBBSync plugin into the event system.
    * @see Plugin::HookEvents
    */
    function HookEvents()
    {
        return array(
            "EVENT_USER_LOGIN"            => "MirrorUserLogin",
            "EVENT_USER_LOGOUT"           => "MirrorUserLogout",
            "EVENT_USER_DELETED"          => "MirrorUserDel"
            );
    }

    /**
    * Upgrade the phpBBSync plugin.
    * @see Plugin::Upgrade
    */
    function Upgrade($PreviousVersion)
    {
        $DB = new Database();

        if (version_compare($PreviousVersion, "1.0.1", "<"))
        {
            $DB->Query("ALTER TABLE phpBBLoginData "
                       ."RENAME TO phpBBSync_LoginData");
        }
    }


    /**
    * Synchronize a login with the phpBB site.
    * @param UserId giving the UID to log in
    * @param Password giving the plain text password
    */
    function MirrorUserLogin($UserId, $Password)
    {
        # The phpBB auth_cwis module looks for a login token set by CWIS
        # to determine if a user should be logged in or out. To guard
        # against cookie forgery, there's a random number embedded in the
        # cookie and stored in the CWIS database which phpBB will validate
        # before completing a login/logout.
        #
        # Logging a user in to phpBB means setting the cookie and DB
        # token.
        #
        # A user is logged out of phpBB when that cookie/token is deleted.
        $DB = new Database();
        $User = new SPTUser($UserId);

        # Generate a login token
        mt_srand((double)microtime() * 1000000);
        $Token = mt_rand(0, 2147483647);

        # Insert data into the database
        $DB->Query("INSERT INTO phpBBSync_LoginData "
                   ."(UserName, RemIP, Token) VALUES ("
                   ."'".addslashes($User->Name())."', "
                   ."'".$_SERVER["REMOTE_ADDR"]."', "
                   .$Token.")");

        # And set a cookie for phpBB to find
        $CookieName = "phpBBLoginToken";
        $CookieData = array(
            "Version" => 1,
            "UserName" => $User->Name(),
            "Token"    => $Token);
        $EncData = urlencode(
            base64_encode(gzcompress(serialize($CookieData))));
        setcookie($CookieName, $EncData, time()+3600*24, "/");

    }

    /**
    * Synchronize logouts with the phpBB site.
    * @param UserId giving the UID to log out.
    */
    function MirrorUserLogout($UserId)
    {
        $DB = new Database();
        $User = new SPTUser($UserId);

        # Nuke the DB entry
        $DB->Query("DELETE FROM phpBBSync_LoginData WHERE "
                   ."UserName='".addslashes($User->Name())."'");

        # Nuke the cookie
        $CookieName = "phpBBLoginToken";
        setcookie($CookieName, "", time() - 3600, "/");
    }

    /**
    * Synchronize user deletion.
    * @param UserId giving the UID to delete.
    */
    function MirrorUserDel($UserId)
    {
        $DB = new Database();
        $User = new SPTUser($UserId);

        $DB->Query("INSERT INTO phpBBSync_LoginData (UserName,RemIp) "
                   ."VALUES ('".$User->Name()."','GoAwayMrUser')");
    }

};
?>
