<?php

function GenerateUsername($BaseName)
{
    global $DB;

    $DB->Query("SELECT UserName FROM APUsers");

    $Names = array();
    while ($Row = $DB->FetchRow())
    {
        $Names []= $Row["UserName"];
    }

    $Str="";
    while (in_array($BaseName.$Str, $Names) )
    {
        $Str = ($Str==="")? 1 : $Str+1;
    }

    return $BaseName.$Str;
}

global $DB, $AF, $SysConfig;
global $SPT_DBUserName, $SPT_DBPassword, $SPT_DBHost;

if (isset($_GET["D"]) && isset($_GET["C"]) &&
    md5($_GET["D"].$SPT_DBUserName.$SPT_DBPassword.$SPT_DBHost) == $_GET["C"])
{
    $Response = unserialize( gzinflate( base64_decode( $_GET["D"] )));

    if ($Response["Status"] == "success" && time() - $Response["Timestamp"] < 600 )
    {
        $UserName = $DB->Query(
            "SELECT UserName FROM OpenId_UserMap "
            ."WHERE DisplayId='".addslashes($Response["DisplayId"])."'",
            "UserName");
        $ExtInfo = $Response["ExtendedInfo"];

        if ($UserName === NULL && isset($ExtInfo["email"]) )
        {
            $UserFactory = new UserFactory();

            // Now the most exciting part: trying to map the OpenID into a username:

            // If the user gave us a nickname, try to use that plus an
            // optional sequence number
            if (isset($ExtInfo["nickname"]))
            {
                $UserName = GenerateUsername($ExtInfo["nickname"]);
            }
            // If we have no nickname, but we have a full name, smash all the
            // alphabetic characters in it goether, and try to use that plus
            // an optional sequence number.
            elseif (isset($ExtInfo["fullname"]))
            {
                $FnMunge = preg_replace("/[^A-Za-z]/", "", $ExtInfo["fullname"]);
                $UserName = GenerateUsername($FnMunge);
            }
            // If all that fails, use the local part on someone's email
            else
            {
                $EmailParts = explode('@', $ExtInfo["email"]);
                $TmpName = array_shift($EmailParts);

                $UserName = GenerateUsername($TmpName);
            }

            $UserPassword = md5(time());

            $TmpUser = $UserFactory->CreateNewUser(
                $UserName,
                $UserPassword, $UserPassword,
                $ExtInfo["email"], $ExtInfo["email"],
                array(U_ILLEGALPASSWORD, U_ILLEGALPASSWORDAGAIN,
                      U_ILLEGALEMAIL, U_ILLEGALEMAILAGAIN,
                      U_ILLEGALUSERNAME));

            if (!is_object($TmpUser) )
            {
                global $G_ErrorMessages;

                if (in_array(U_DUPLICATEEMAIL, $TmpUser)){
                    $G_ErrorMessages []= "The email address associated with your OpenId "
                        ."is already associated with an account. "
                        ."If you have forgotten the account user name or"
                        ." password you can click"
                        ." <a href=\"index.php?P=ForgottenPasswordComplete&UN="
                        .$ExtInfo["email"]
                        ."\">here</a>"
                        ." to send a reminder via e-mail.";
                } else {
                    # Shouldn't ever happen, but add a general error message just in case:
                    $G_ErrorMessages []= "Could not create user.";
                }
            }
            else
            {
                # No other errors should be possible, so proceed with
                # setting up the user:

                $TmpUser->Set("ActiveUI", $SysConfig->DefaultActiveUI());
                foreach ($SysConfig->DefaultUserPrivs() as $Privilege)
                {
                    $TmpUser->GivePriv($Privilege);
                }

                # Mark the user as active:
                $TmpUser->IsActivated(TRUE);

                # signal that user has been added and verified
                $AF->SignalEvent("EVENT_USER_ADDED", array(
                                     "UserId" => $TmpUser->Id(),
                                     "Password" => $UserPassword));
                $AF->SignalEvent("EVENT_USER_VERIFIED",
                                 array("UserId" => $TmpUser->Id()));

                $DB->Query(
                    "INSERT INTO OpenId_UserMap (DisplayId, UserName) "
                    ."VALUES ('".addslashes($Response["DisplayId"])."',"
                    ."'".addslashes($TmpUser->Name())."')");

                $AF->SetJumpToPage("P_OpenId_FinishAuth&D=".urlencode($_GET["D"])."&C=".$_GET["C"]);
            }
        }
    }
}
