#!/usr/bin/perl ##################################################################### # Data import script to migrate from version 1.1's flat file based # users to version 1.2's central database. # # NOTE: This script will die if the user it tries to import is # tied to a bogus or non-existing dataset/database. The fix # is to edit the members file and either manually set the right # database configuration for that user, or delete the user entirely. # # If the script makes it through all users it will print: # # 'SUCCESS! It seems that every user in the members file was imported!' # # If you don't get that output at the end of the script, something # went wrong in the import. # # For help/troubleshooting please join the LedgerSMB users mailing # list. Info on how to subscribe can be found here: # # http://lists.sourceforge.net/mailman/listinfo/ledger-smb-users # # Other info on how to get help, including commercial support # can be found at: # # http://www.ledgersmb.org/help/ # use LedgerSMB::User; use LedgerSMB::Form; use LedgerSMB::Sysconfig; if ( $ENV{HTTP_HOST} ) { print "Content-type: text/html\n\n"; print "\n"; print "This script cannot be executed via http. You must run it via the command line.\n"; print "\n"; exit; } my $membersfile = $ARGV[0]; if ( length($membersfile) < 2 ) { print "\nUsage: import_members.pl path/to/members\n\n"; print "You must supply the path to the members file. Default location\n"; print "is users/members. In this case do this:\n\n"; print " ./import_members.pl users/members\n\n"; exit; } my @users = (); open( FH, '<', "$membersfile" ) || die("Couldn't open members file!"); while () { chop; if (/^\[.*\]/) { $login = $_; $login =~ s/(\[|\])//g; if ( $login eq 'admin' ) { print "\nIMPORT FAILED: User 'admin' was found.\n\n"; print "Please change this user's name to something else. In LedgerSMB version 1.2, \n"; print "'admin' is a reserved user for the administration of the entire system.\n"; print "To change the user's name, find the line in the members file that looks \n"; print "like [admin] and change 'admin' to something else (keep the '[' and ']').\n"; print "Save the file and run this script again.\n\n"; exit; } elsif ( $login ne 'root login' ) { push @users, $login; $member{$login}{'login'} = $login; } next; } if ( $login ne 'root login' ) { if ( ( $key, $value ) = split /=/, $_, 2 ) { if ( $key eq 'dbpasswd' ) { $member{$login}{$key} = unpack 'u', $value; } elsif ( $key eq 'password' ) { $member{$login}{'crypted_password'} = $value; } else { $member{$login}{$key} = $value; } } } } close(FH); print "\n\nParsing members file completed. Now trying to import user data.\n\n"; foreach (@users) { $myUser = $member{$_}; &save_member($myUser); print "Import of user '$_' seems to have succeeded.\n"; } print "\nSUCCESS! It seems that every user in the members file was imported!\n\n"; sub save_member { # a slightly modified version of LegerSBM::User::save_member # with special handling of the password -> crypted_password my ($self) = @_; # replace \r\n with \n for (qw(address signature)) { $self->{$_} =~ s/\r?\n/\\n/g } # use central db my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH}; #check to see if the user exists already my $userCheck = $dbh->prepare("SELECT id FROM users WHERE username = ?"); $userCheck->execute( $self->{login} ); my ($userID) = $userCheck->fetchrow_array; if ($userID) { #got an id, check to see if it's in the users_conf table my $userConfCheck = $dbh->prepare("SELECT count(*) FROM users_conf WHERE id = ?"); $userConfCheck->execute($userID); ($userConfExists) = $userConfCheck->fetchrow_array; } else { my $userConfAdd = $dbh->prepare("SELECT create_user(?);"); $userConfAdd->execute( $self->{login} ); ($userID) = $userConfAdd->fetchrow_array; } if ($userConfExists) { my $userConfUpdate = $dbh->prepare( "UPDATE users_conf SET acs = ?, address = ?, businessnumber = ?, company = ?, countrycode = ?, currency = ?, dateformat = ?, dbdriver = ?, dbhost = ?, dbname = ?, dboptions = ?, dbpasswd = ?, dbport = ?, dbuser = ?, email = ?, fax = ?, menuwidth = ?, name = ?, numberformat = ?, crypted_password = ?, print = ?, printer = ?, role = ?, sid = ?, signature = ?, stylesheet = ?, tel = ?, templates = ?, timeout = ?, vclimit = ? WHERE id = ?;" ); $userConfUpdate->execute( $self->{acs}, $self->{address}, $self->{businessnumber}, $self->{company}, $self->{countrycode}, $self->{currency}, $self->{dateformat}, $self->{dbdriver}, $self->{dbhost}, $self->{dbname}, $self->{dboptions}, $self->{dbpasswd}, $self->{dbport}, $self->{dbuser}, $self->{email}, $self->{fax}, $self->{menuwidth}, $self->{name}, $self->{numberformat}, $self->{crypted_password}, $self->{print}, $self->{printer}, $self->{role}, $self->{sid}, $self->{signature}, $self->{stylesheet}, $self->{tel}, $self->{templates}, $self->{timeout}, $self->{vclimit}, $userID ); } else { my $userConfInsert = $dbh->prepare( "INSERT INTO users_conf(acs, address, businessnumber, company, countrycode, currency, dateformat, dbdriver, dbhost, dbname, dboptions, dbpasswd, dbport, dbuser, email, fax, menuwidth, name, numberformat, print, printer, role, sid, signature, stylesheet, tel, templates, timeout, vclimit, id, crypted_password) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" ); $userConfInsert->execute( $self->{acs}, $self->{address}, $self->{businessnumber}, $self->{company}, $self->{countrycode}, $self->{currency}, $self->{dateformat}, $self->{dbdriver}, $self->{dbhost}, $self->{dbname}, $self->{dboptions}, $self->{dbpasswd}, $self->{dbport}, $self->{dbuser}, $self->{email}, $self->{fax}, $self->{menuwidth}, $self->{name}, $self->{numberformat}, $self->{print}, $self->{printer}, $self->{role}, $self->{sid}, $self->{signature}, $self->{stylesheet}, $self->{tel}, $self->{templates}, $self->{timeout}, $self->{vclimit}, $userID, $self->{crypted_password} ); } if ( !$self->{'admin'} ) { $self->{dbpasswd} =~ s/\\'/'/g; $self->{dbpasswd} =~ s/\\\\/\\/g; # format dbconnect and dboptions string LedgerSMB::User::dbconnect_vars( $self, $self->{dbname} ); # check if login is in database my $dbh = DBI->connect( $self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd}, { AutoCommit => 0 } ) or $self->error($DBI::errstr); $dbh->{pg_enable_utf8} = 1; # add login to employee table if it does not exist my $login = $self->{login}; $login =~ s/@.*//; my $sth = $dbh->prepare("SELECT entity_id FROM employee WHERE login = ?;"); $sth->execute($login); my ($id) = $sth->fetchrow_array; $sth->finish; my $employeenumber; my @values; if ($id) { $query = qq|UPDATE employee SET role = ?, email = ?, name = ? WHERE login = ?|; @values = ( $self->{role}, $self->{email}, $self->{name}, $login ); } else { my ($employeenumber) = Form::update_defaults( "", \%$self, "employeenumber", $dbh ); $query = qq| INSERT INTO employee (login, employeenumber, name, workphone, role, email, sales) VALUES (?, ?, ?, ?, ?, ?, '1')|; @values = ( $login, $employeenumber, $self->{name}, $self->{tel}, $self->{role}, $self->{email} ); } $sth = $dbh->prepare($query); $sth->execute(@values); $dbh->commit; $dbh->disconnect; } }