External Registration

khurt

Member
I have a program that has a database full of users (not a forum). I'd like to build something that will take this existing data and create forum accounts by creating records directly in the xf database. By doing it this way, as opposed to just having the users register as normal, I'll be able to establish a link between their forum account and the external database. This seems doable, but I'm running into an issue with correctly formatting the (plain text) password to store it in the xf database.

So, basically, the process is this:
  • Person looks up somebody in the external program
  • They type in a username/password and click submit
  • My script will execute to insert all the relevant information in the xf database
  • However, password isn't properly hashed
The answer for this is probably something I can dig out of the xf code (and if all else fails I could probably have them use of the lost password feature), but if anyone has a quick answer on how to hash the password, it would be much appreciated. :)
 
I have imported some of my users using the following script.


You have to change the database fields to fit to your own and create.
PHP:
<?php
include '../library/config.php';
$link = mysql_connect('localhost', $config['db']['username'], $config['db']['password']);
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
$db_selected = mysql_select_db($config['db']['dbname'], $link);
if (!$db_selected) {
    die ('Can\'t use foo : ' . mysql_error());
}
 
addusers();

function addusers(){
//Retrieve the users from your database
    $getuser= mysql_query("SELECT * FROM perdorues");
    while ($user =mysql_fetch_array($getuser)){
        $username=$user["username"];
        $email=$user["email"];
        $gjinia=$user["sex"];
        $dt=$user["birthday"];

        $dtarr = explode("-", $dt);

        if ($gjinia=='m')
            $gjinia='male';
        else
            $gjinia='female';

        $data=serialize(array('password'=>$user["perdoruesFjala"],'username'=>$username));
        $krk="INSERT INTO xf_user (username,email,gender,language_id,timezone,visible,user_group_id,display_style_group_id,permission_combination_id,user_state,register_date) VALUES
                            ('$username','$email','$gjinia',1,'Europe/Berlin',1,2,2,2,'valid','1289127598')";

    if (mysql_query($krk)){
        $userid=mysql_insert_id();
        $krkauth="INSERT INTO `xf_user_authenticate` (user_id,scheme_class,data,remember_key) VALUES ($userid,'XenForo_Authentication_shqiperia','$data','')";
        if (!mysql_query($krkauth)){
            echo mysql_error();
        }else{
            $krkprofile="INSERT INTO xf_user_profile (user_id,dob_day,dob_month,dob_year) VALUES ('$userid','$dtarr[2]','$dtarr[1]','$dtarr[0]')";
            mysql_query($krkprofile);

            $krkoptions="INSERT INTO xf_user_option (user_id,show_dob_year,show_dob_date,email_on_conversation) VALUES ('$userid',1,1,1)";
            mysql_query($krkoptions);

            $krkprivacy="INSERT INTO xf_user_privacy (user_id,allow_view_profile,allow_post_profile,allow_send_personal_conversation,allow_view_identities,allow_receive_news_feed) VALUES ('$userid','everyone','everyone','everyone','everyone','everyone')";
            mysql_query($krkprivacy);
        }
    }else{
        $error=addslashes(mysql_error());
        echo $error;
        $krk2="INSERT INTO `errors` (`id` ,`errori`) VALUES (NULL , '$error')";
        mysql_query($krk2);
    }

    //printf("Last inserted record has id %d\n", mysql_insert_id());

}

}
mysql_close($link);
 
That wouldn be enought;)
You're using in your script a own auth class, this has also to be done^^
PHP:
        $krkauth="INSERT INTO `xf_user_authenticate` (user_id,scheme_class,data,remember_key) VALUES ($userid,'XenForo_Authentication_shqiperia','$data','')";
 
I appreciate the responses.

I dug around a bit and came up with a password solution that seems to work using the default xenforo auth scheme. I based it off lines 65-69 of core.php in the authentication folder.

I'd like to get a better idea of what's going on with the csrf_token column in the xf_user_profile table and the remember_key column in xf_user_authenticate. At the moment, these are being left blank by my insert script but populated when a user registers normally. It seems to be ok that these are left blank, but we'll see...
 
That wouldn be enought;)
You're using in your script a own auth class, this has also to be done^^
PHP:
        $krkauth="INSERT INTO `xf_user_authenticate` (user_id,scheme_class,data,remember_key) VALUES ($userid,'XenForo_Authentication_shqiperia','$data','')";
Oh yeah, I forgot about the xf_user_authenticate, you have to create e class file for your XenForo_Authentication_METHOD
 
I appreciate the responses.

I dug around a bit and came up with a password solution that seems to work using the default xenforo auth scheme. I based it off lines 65-69 of core.php in the authentication folder.

I'd like to get a better idea of what's going on with the csrf_token column in the xf_user_profile table and the remember_key column in xf_user_authenticate. At the moment, these are being left blank by my insert script but populated when a user registers normally. It seems to be ok that these are left blank, but we'll see...

Could you describe to us your solution using lines 65-69?
 
Could you describe to us your solution using lines 65-69?
Those lines showed me how the password is hashed in the default authentication scheme. Based on that, I was able to write something that hashed my plain text passwords in a similar way. This allowed me to create a new user in the forum, based on data from a 3rd source, with a few sql insert statements. Because I'll still have users that are created through the normal registration process, using the same authentication scheme for everyone seemed best.

If you look at one of the other files in that folder (abstract.php, I believe), you can see how the salt is generated. For that, you'll want to randomly generate a 10 character string and apply the appropriate hash.

PHP:
$salt = hash('sha256', $randomTenCharacters);

$hash = hash('sha256', hash('sha256', $password) . $salt);

$data = serialize(array('hash' => $hash, 'salt' => $salt, 'hashFunc' => 'sha256'));
 
I want to login the user straight after registering. So I'm exploring posting to /forum/login/login with my redirect set but how would I do that without the user triggering the submit.

I can't do a PHP header because of the way xenforo works with urls? Even then thats not POST its GET isn't it?

/////////////// GET FORM DATA
$username=$_POST["username"];
$password=$_POST["password"];
$email=$_POST["user_email"];



/////////////// PASSWORD HASH
$str = "012345678923456789";
for($i=0; $i < 10; $i++){ $randomTenCharacters .= $str{rand() % strlen($str)}; }

$salt = hash('sha256', $randomTenCharacters);
$hash = hash('sha256', hash('sha256', $password) . $salt);
$data = serialize(array('hash' => $hash, 'salt' => $salt, 'hashFunc' => 'sha256'));


/////////////// ADD USER
$krk="INSERT INTO freetplclassified_members (username,user_email,gender,language_id,timezone,visible,user_group_id,display_style_group_id,permission_combination_id,user_state,register_date) VALUES
('$username','$email','$gjinia',1,'Europe/London',1,2,2,2,'valid','1289127598')";



if (mysql_query($krk)){
$userid=mysql_insert_id();
$krkauth="INSERT INTO `xf_user_authenticate` (user_id,scheme_class,data,remember_key) VALUES ($userid,'XenForo_Authentication_shqiperia','$data','')";

if (!mysql_query($krkauth)){
echo mysql_error();
}else{


$krkprofile="INSERT INTO xf_user_profile (user_id,dob_day,dob_month,dob_year) VALUES ('$userid','01','01','1980')";mysql_query($krkprofile) or die('Query failed: ' . mysql_error());


$krkoptions="INSERT INTO xf_user_option (user_id,show_dob_year,show_dob_date,email_on_conversation) VALUES ('$userid',1,1,1)";mysql_query($krkoptions) or die('Query failed: ' . mysql_error());

$krkprivacy="INSERT INTO xf_user_privacy (user_id,allow_view_profile,allow_post_profile,allow_send_personal_conversation,allow_view_identities,allow_receive_news_feed) VALUES ('$userid','everyone','everyone','everyone','everyone','everyone')";
mysql_query($krkprivacy)or die('Query failed: ' . mysql_error());
}
}else{
$error=addslashes(mysql_error());
echo $error;



}
 
Ive added this to the bottom of the PHP

<html><body>

<form action="/forum/login/login" method="post" class="xenForm formOverlay" name="MyForm">
<input type="hidden" name="login" value="<? echo $email; ?>">
<input type="hidden" name="password" value="<? echo $password; ?>">
<input type="hidden" name="cookie_check" value="1" />
<input type="hidden" name="redirect" value="http://www.MYDOMAIN/somepage.php" />
<input type="hidden" name="_xfToken" value="" />
</form>

<script language="javascript" type="text/javascript">
document.MyForm.submit();
</script>
<noscript><input type="submit" value="verify submit"></noscript>

</body></html>
It works perfectly however Im not comfortable with using Javascript incase the user doesn't support it etc then the script will fail.
 
Top Bottom