Jump to content

Recommended Posts

Posted

Hello together,

I had a deeper look into the forum but didn’t found anything, so I like to ask the following simple question. :-)

Is there a module or a simple technique to export all users from the backend into a file?

Afterwards, it should be possible to import the users again.

I have a ProcessWire installation on a dev server and I don’t like the idea to add all users again by hand on the live server   :-)

Thanks so much for your ideas.

-Thomas 

Posted

While it's certainly possible it's not as easy as you may think it is. Passwords are stored as hashes in the database. ProcessWire will never store the plain text password. The hashing is dependent on the salt value stored in the config.php. The salt is generated as part of the installation process and therefore your live installation may have another salt value as the dev one. If this is the case it means all the passwords of imported users would be invalid after moving them. What you can do is to copy the whole users database table and copy over the salt value, too. As long as all hashes of user passwords are generated with the same salt value you can exchange users as you wish. But if you have users in both installations, where the passwords where saved with different salt values, you can not move the passwords over from one installation to another. You would need to change/update the passwords by hand in this case. Everything besides the passwords shouldn't be a problem.

  • Like 6
  • 8 months later...
Posted

I am trying to find a solution for having same users with same passwords in 2 different PW installs and came across this thread.

How would I export the user table? There is no such table as users are pages. So  I would need to construct a MySQL query that gets all pages with user template and also grab required fields  name, pass, email.

Then the other tricky part would be to import that into the new PW install.

Is there a PW API side solution that also tranfers the password hashes to the new install?

Posted

I think you should be able to read the hashed password to export them, e.g. with the PageActionExportCsv which comes with listerpro. I'm just not sure if those hashed passwords would be rehashed, when importing the csv.

Posted

@LostKobraKai

Thank you. I will look into the Lister Pro Action.

Meanwhile I decided to export the users including their hashed password to csv with

// get desired users
$array = [];
$us = $users->find("roles=frontend");
foreach ($us as $key => $u) {
	$u->of(false);
	$array[$key] = ["id" => $u->id, "name" => $u->name, "email" => $u->email, "pass" => $u->pass];
}

// write to file
$fp = fopen('./inc/users.csv', 'w');
$i = 0;
foreach ($array as $fields) {
   // Add headings to the first line.
    if($i==0) fputcsv($fp, array_keys($fields), ",");
    fputcsv($fp, $fields);
 $i++;
}
fclose($fp);

Now I am looking into a way to import the users in the new PW install via API and in that process bypassing the regular $user->pass method for setting the password. So that I can store the hashed password as is during import. Then I'd only need to copy over the salt from the original PW install and the users should be able to login.

But when looking at the ___setPass($value) method in /wire/core/Password.php, I am not sure how to hook into it and make it just save the supplied value.

Also, looking at /wire/core/User.php, I don't see how this is connected to the Password class or vice versa.

  • Like 1
Posted

The user class is just an more specific page class, so it shouldn't have any correlation with the password, as 'pass' is a field with the FieldtypePassword. 

  • 2 weeks later...
Posted

Hey gebeer, I'm trying to extend your function for admin only, by adding a button to the users screen: /processwire/access/users/

Do you know where exactly I would create my hook point?
I'm a little stumped, while adding hooks to ProcessPageEdit are relativley easy, I'm yet to see an example for the users section of processwire.

Posted

ProcessUser is the module, which handles this section of the admin, and it does by itself use ProcessPageEdit for the user editing, so you'll probably don't need different hooks, but just a check if the current edited page is a user.

Posted

Thanks Lost, but I'm still Lost!

Still no idea how to hook prior to output to add the new button, this is what I have:
 

$this->addHookBefore('ProcessUser::render', $this, 'usersAddButtons');
Posted

For that page ProcessUser is inheriting the usage of a customized Lister from ProcessPageType, so you probably need to hook some of the ProcessPageType::execute… methods.

Posted

I was unable to hook to this page, so ended up creating a custom admin page to support a button to export users via CSV.
Seems overkill, and I'm sure there are other senarios which may warrant additional buttons such as: Selecting all users for another operation (copy to clipboard) or email all users etc.
It would be nice to find out the appropriate method to hook to ;)
 

  • Like 1
  • 7 years later...
Posted

Not sure if this is still a thing that people require, or this should really be posted here for security reasons, (if so, feel free to remove) but here's a solution that is tested and works.
It relies on both instances using the same user salt.

 

$usersArray = [];
foreach($users as $user) {
    if($user->isSuperuser() || $user->name == 'guest') continue; // Skip the admin and guest user

    $roles = [];

    foreach ($user->roles as $role) {
        $roles[] = $role->name;
    }

    $usersArray[] = [
        'username' => $user->name,
        'email' => $user->email,
        'roles' => $roles, 
        'pass_hash' => $user->pass->hash,
        'pass_salt' => $user->pass->salt,
    ];
}

$usersJson = json_encode($usersArray);

echo $usersJson;

Then copy the output JSON array and then drop it in $json variable in the next part on the other end.

 

$json = '';

$importUsers = json_decode($json, true);

foreach ($importUsers as $iUser) {
    $userExists = $users->get("name={$iUser['username']},email={$iUser['email']}");
    
    if ($userExists->id == 0) {

        echo "{$iUser['username']} should be added<br>";

        $u = new User();
        $u->name = $iUser['username'];
        $u->email = $iUser['email'];
        if (count($iUser['roles'])) {
            foreach ($iUser['roles'] as $role) {
                $u->addRole($role);
            }
        }
        $u->pass->hash = $iUser['pass_hash'];
        $u->pass->salt = $iUser['pass_salt'];

        $u->save();

        echo "User: $u->name added successfully<br><br>";   
    }
}

Obvs add any other field data you want to export and import.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...