I am migrating a wordpress site to another site. The users from the old site need to work with the new site. I am doing a staggered implementation, so do not want to bring all the users over at once.
Basically, when a user attempts to sign in, before the login is authenticated, if the user does not exist on the new site, I am using an api call to grab the user details from the old site, and create the user on the new site.
I am using the wp_authenticate action to do the checks before the user is authenticated.
This works, the user is created, and then the authentication should be done. The authentication fails though. If I then try to login again, it works, so I know the credentials are OK and all of the data has been written correctly.
It feels like during the same trip on the server, I cannot create a user and login.
add_action( 'wp_authenticate' , [$this,"preAuthenticate"],10,1);
public function preAuthenticate($username) {
    try {
        if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
            throw new Exception("Not an email address - carry on");
        }
        
        $usr = get_user_by("email", $username);
        
        if ($usr) {
            throw new Exception("Already a user - carry on");                
        }
        
        $this->getExternalUser($username);
        
    } catch (Exception $ex) {
        // no need to do anything
    }
}
private function getExternalUser($emailAddress) {
    try {
        $oldUser = $this->readExternalUser($emailAddress); 
        
        if (!$oldUser)) {
            throw new Exception("No user found");
        }
        $userData = [
            'user_pass' => $this->randomPassword(), //This will be updated after the user has been created using the hash passed
            'user_login' => $oldUser->login,
            'user_nicename' => $oldUser->niceName,
            'user_email' => $emailAddress,               
            'role' => "subscriber"                
        ];
        
        $result = wp_insert_user($userData);
        $usr = get_user_by("ID", $result);    
        if (!$usr) {
            throw new Exception("user not created");
        }
        global $wpdb;
              
        $wpdb->update($wpdb->users, ["user_pass" => $oldUser->hash],['ID' => $usr->ID]);
        
        return true;
    } catch (Exception $ex) {
        return false;
    }
}

