<?PHP
  /**
     The DrupalSync plugin provides login integration between a CWIS
     and a Drupal site.  There is a companion cwis_user plugin which
     must be installed on the Drupal site for any of this to work.
     The Drupal side of the plugin will need to be configured with the
     database information for the CWIS installation.  The CWIS side
     needs no additional configuration once the plugin is installed.

     User creation, deletion, modifiction, login, and logout are
     mirrored from one site to the other.

     CWIS has more stringent username requirements than Drupal does,
     so usernames created on Drupal are normalzed to meet CWIS'
     standards before creating a companion CWIS user.
   */

require_once("sync_common.php");

final class DrupalSync extends Plugin
{
    function Register()
    {
        $this->Name = "Drupal Login Synchronization";
        $this->Version = "1.0.1";
        $this->Description = "Allows users to register or log in"
            ." on CWIS or an associated Drupal installation "
            ." and be registered or logged in on the other package as well.  "
            ." An included companion module (<i>cwis_user</i>) must"
            ." be loaded on the Drupal site 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"
            );
    }

    function Install()
    {
        $DB = new Database();
        $DB->Query("CREATE TABLE DrupalToCwisUserSync ( "
                   ."UserName TEXT, "
                   ."Command TEXT,"
                   ."Password TEXT, "
                   ."Email TEXT, "
                   ."Token INT );");
        $DB->Query("CREATE TABLE CwisToDrupalUserSync ( "
                   ."UserName TEXT, "
                   ."Command TEXT,"
                   ."Password TEXT, "
                   ."Email TEXT, "
                   ."Token INT );");
        $DB->Query("CREATE TABLE UserNameMap ( "
                   ."CwisName TEXT, "
                   ."DrupalName TEXT)");
    }

    function HookEvents()
    {
        return array(
            "EVENT_PAGE_LOAD"             => "CheckLoginCookie",
            "EVENT_USER_ADDED"            => "DrupalMirrorUserAdd",
            "EVENT_USER_DELETED"          => "DrupalMirrorUserDel",
            "EVENT_USER_PASSWORD_CHANGED" => "DrupalMirrorUserUpdate",
            "EVENT_USER_LOGIN"            => "DrupalMirrorUserLogin",
            "EVENT_USER_LOGOUT"           => "DrupalMirrorUserLogout"
            );
    }
    
    function CheckLoginCookie($PageName)
    {
        global $G_User, $Session;

        $Helper = new SyncHelper();

        $UserFactory = new UserFactory($Session);

        // Handle pending user creation requested by Drupal
        $UsersToCreate = $Helper->UsersToCreate();
        foreach ($UsersToCreate as $UserData)
        {
            $TmpUser = new SPTUser($UserData["UserName"]);
            if ($TmpUser->Status() == U_NOSUCHUSER)
            {
                // If we've gotten this far, then the user has already
                // passed Drupal's password strength and email format
                // requirements. We don't want to fail to mirrow a
                // user that's valid on the Drupal side because they
                // have different PW/Email format requirements than we
                // do. Therefore, ignore format errors.
                $TmpUser = $UserFactory->CreateNewUser(
                    $UserData["UserName"],
                    $UserData["Password"], $UserData["Password"],
                    $UserData["Email"], $UserData["Email"],
                    array(U_ILLEGALPASSWORD, U_ILLEGALPASSWORDAGAIN,
                          U_ILLEGALEMAIL, U_ILLEGALEMAILAGAIN));
                $TmpUser->GivePriv(PRIV_POSTTOFORUMS);
                $TmpUser->GivePriv(PRIV_POSTCOMMENTS);
            }

            if ($TmpUser->Status() == U_OKAY)
            {
                $Helper->UserCreated($UserData["UserName"]);
            }
        }

        // Handle pending user deletions requested by Drupal
        $UsersToDelete = $Helper->UsersToDelete();
        foreach ($UsersToDelete as $UserData)
        {
            $TmpUser = new SPTUser($UserData["UserName"]);
            $TmpUser->Delete();
            $Helper->UserDeleted($UserData["UserName"]);
        }

        // Handle pending user update requests by Drupal
        $UsersToUpdate = $Helper->UsersToUpdate();
        foreach ($UsersToUpdate as $UserData)
        {
            $TmpUser = new SPTUser($UserData["UserName"]);
            if (is_object($TmpUser) && $TmpUser->Status() == U_OKAY )
            {
                if (strlen($UserData["Password"]))
                {
                    $TmpUser->SetPassword($UserData["Password"]);
                }

                if (strlen($UserData["Email"]))
                {
                    $TmpUser->Set("EMail",$UserData["Email"]);
                }

                $Helper->UserUpdated($UserData["UserName"]);
            }
        }

        // Check for requests dealing with this user
        $Cmd = $Helper->CheckForCommand( $G_User->Name() );

        if ($Cmd["Command"]==="Login")
        {
            if ($G_User->Login($Cmd["UserName"],$Cmd["Password"])==U_OKAY)
            {
                $Helper->UserLoggedIn($Cmd["UserName"]);
            }
        }
        else if ($Cmd["Command"]==="Logout")
        {
            $G_User->Logout();
            $Helper->UserLoggedOut($Cmd["UserName"]);
        }
    }

    function DrupalMirrorUserAdd($UserId, $Password)
    {
        $Helper = new SyncHelper();
        $User = new SPTUser($UserId);
        $Helper->SignalCommand(
            "Create", $User->Name(), $Password, $User->Get("EMail"));
    }
    
    function DrupalMirrorUserDel($UserId)
    {
        $Helper = new SyncHelper();
        $User = new SPTUser($UserId);
        $Helper->SignalCommand("Delete", $User->Name());
    }
    
    function DrupalMirrorUserUpdate($UserId,$OldPass,$NewPass)
    {
        $Helper = new SyncHelper();
        $User = new SPTUser($UserId);
        $Helper->SignalCommand(
            "Update",$User->Name(), $NewPass, $User->Get("EMail"));
    }
    
    function DrupalMirrorUserLogin($UserId, $Password)
    {
        $Helper = new SyncHelper();
        $User = new SPTUser($UserId);
        $Helper->SignalCommand(
            "Login", $User->Name(), $Password, $User->Get("EMail"));
    }
    
    function DrupalMirrorUserLogout($UserId)
    {
        $Helper = new SyncHelper();
        $User = new SPTUser($UserId);
        $Helper->SignalCommand("Logout", $User->Name());
    }
};
?>
