summaryrefslogtreecommitdiff
path: root/LedgerSMB/User.pm
blob: c24eb98f0334b8d81d656967064ead16e58fa85e (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. #
  6. # Copyright (C) 2006
  7. # This work contains copyrighted information from a number of sources all used
  8. # with permission.
  9. #
  10. # This file contains source code included with or based on SQL-Ledger which
  11. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  12. # under the GNU General Public License version 2 or, at your option, any later
  13. # version. For a full list including contact information of contributors,
  14. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  15. #
  16. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  17. # Copyright (C) 2000
  18. #
  19. # Author: DWS Systems Inc.
  20. # Web: http://www.sql-ledger.org
  21. #
  22. # Contributors: Jim Rawlings <jim@your-dba.com>
  23. #
  24. #======================================================================
  25. #
  26. # This file has undergone whitespace cleanup.
  27. #
  28. #======================================================================
  29. #
  30. # user related functions
  31. #
  32. #=====================================================================
  33. package LedgerSMB::User;
  34. use LedgerSMB::Sysconfig;
  35. use LedgerSMB::Session;
  36. use Data::Dumper;
  37. sub new {
  38. my ( $type, $login ) = @_;
  39. my $self = {};
  40. if ( $login ne "" ) {
  41. # use central db
  42. my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
  43. # for now, this is querying the table directly... ugly
  44. my $fetchUserPrefs = $dbh->prepare(
  45. "SELECT acs, address, businessnumber,
  46. company, countrycode, currency,
  47. dateformat, dbdriver, dbhost, dbname,
  48. dboptions, dbpasswd, dbport, dbuser,
  49. email, fax, menuwidth, name, numberformat,
  50. password, print, printer, role, sid,
  51. signature, stylesheet, tel, templates,
  52. timeout, vclimit, u.username
  53. FROM users_conf as uc, users as u
  54. WHERE u.username = ?
  55. AND u.id = uc.id;"
  56. );
  57. $fetchUserPrefs->execute($login);
  58. my $userHashRef = $fetchUserPrefs->fetchrow_hashref;
  59. while ( my ( $key, $value ) = each( %{$userHashRef} ) ) {
  60. $self->{$key} = $value;
  61. }
  62. chomp( $self->{dbport} );
  63. chomp( $self->{dbname} );
  64. chomp( $self->{dbhost} );
  65. $self->{dbconnect} =
  66. 'dbi:Pg:dbname='
  67. . $self->{dbname}
  68. . ';host='
  69. . $self->{dbhost}
  70. . ';port='
  71. . $self->{dbport};
  72. if ( $self->{username} ) {
  73. $self->{login} = $login;
  74. }
  75. }
  76. bless $self, $type;
  77. }
  78. sub country_codes {
  79. use Locale::Country;
  80. use Locale::Language;
  81. my %cc = ();
  82. # scan the locale directory and read in the LANGUAGE files
  83. opendir DIR, "${LedgerSMB::Sysconfig::localepath}";
  84. my @dir = grep !/^\..*$/, readdir DIR;
  85. foreach my $dir (@dir) {
  86. $dir = substr( $dir, 0, -3 );
  87. $cc{$dir} = code2language( substr( $dir, 0, 2 ) );
  88. $cc{$dir} .= ( "/" . code2country( substr( $dir, 3, 2 ) ) )
  89. if length($dir) > 2;
  90. $cc{$dir} .= ( " " . substr( $dir, 6 ) ) if length($dir) > 5;
  91. }
  92. closedir(DIR);
  93. %cc;
  94. }
  95. sub fetch_config {
  96. #I'm hoping that this function will go and is a temporary bridge
  97. #until we get rid of %myconfig elsewhere in the code
  98. my ( $self, $login ) = @_;
  99. if ( !$login ) {
  100. &error( $self, "Access Denied" );
  101. }
  102. # use central db
  103. my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
  104. # for now, this is querying the table directly... ugly
  105. my $fetchUserPrefs = $dbh->prepare(
  106. "SELECT acs, address, businessnumber,
  107. company, countrycode, currency,
  108. dateformat, dbdriver, dbhost, dbname,
  109. dboptions, dbpasswd, dbport, dbuser,
  110. email, fax, menuwidth, name, numberformat,
  111. password, print, printer, role, sid,
  112. signature, stylesheet, tel, templates,
  113. timeout, vclimit, u.username
  114. FROM users_conf as uc, users as u
  115. WHERE u.username = ?
  116. AND u.id = uc.id;"
  117. );
  118. $fetchUserPrefs->execute($login);
  119. my $userHashRef = $fetchUserPrefs->fetchrow_hashref;
  120. if ( !$userHashRef ) {
  121. &error( $self, "Access Denied" );
  122. }
  123. while ( my ( $key, $value ) = each( %{$userHashRef} ) ) {
  124. $myconfig{$key} = $value;
  125. }
  126. chomp( $myconfig{'dbport'} );
  127. chomp( $myconfig{'dbname'} );
  128. chomp( $myconfig{'dbhost'} );
  129. $myconfig{'login'} = $login;
  130. $myconfig{'dbconnect'} =
  131. 'dbi:Pg:dbname='
  132. . $myconfig{'dbname'}
  133. . ';host='
  134. . $myconfig{'dbhost'}
  135. . ';port='
  136. . $myconfig{'dbport'};
  137. return \%myconfig;
  138. }
  139. sub login {
  140. my ( $self, $form ) = @_;
  141. my $rc = -1;
  142. if ( $self->{login} ne "" ) {
  143. if (
  144. !Session::password_check(
  145. $form, $form->{login}, $form->{password}
  146. )
  147. )
  148. {
  149. return -1;
  150. }
  151. #this is really dumb, but %myconfig will have to stay until 1.3
  152. while ( my ( $key, $value ) = each( %{$self} ) ) {
  153. $myconfig{$key} = $value;
  154. }
  155. # check if database is down
  156. my $dbh =
  157. DBI->connect( $myconfig{dbconnect}, $myconfig{dbuser},
  158. $myconfig{dbpasswd} )
  159. or $self->error( __FILE__ . ':' . __LINE__ . ': ' . $DBI::errstr );
  160. # we got a connection, check the version
  161. my $query = qq|
  162. SELECT value FROM defaults
  163. WHERE setting_key = 'version'|;
  164. my $sth = $dbh->prepare($query);
  165. $sth->execute || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  166. my ($dbversion) = $sth->fetchrow_array;
  167. $sth->finish;
  168. # add login to employee table if it does not exist
  169. # no error check for employee table, ignore if it does not exist
  170. my $login = $self->{login};
  171. $login =~ s/@.*//;
  172. $query = qq|SELECT id FROM employees WHERE login = ?|;
  173. $sth = $dbh->prepare($query);
  174. $sth->execute($login);
  175. my ($id) = $sth->fetchrow_array;
  176. $sth->finish;
  177. if ( !$id ) {
  178. my ($employeenumber) =
  179. $form->update_defaults( \%myconfig, "employeenumber", $dbh );
  180. $query = qq|
  181. INSERT INTO employees
  182. (login, employeenumber, name,
  183. workphone, role)
  184. VALUES (?, ?, ?, ?, ?)|;
  185. $sth = $dbh->prepare($query);
  186. $sth->execute(
  187. $login, $employeenumber, $myconfig{name},
  188. $myconfig{tel}, $myconfig{role}
  189. );
  190. }
  191. $dbh->disconnect;
  192. $rc = 0;
  193. if ( $form->{dbversion} ne $dbversion ) {
  194. $rc = -3;
  195. $dbupdate =
  196. ( calc_version($dbversion) < calc_version( $form->{dbversion} ) );
  197. }
  198. if ($dbupdate) {
  199. $rc = -4;
  200. # if DB2 bale out
  201. if ( $myconfig{dbdriver} eq 'DB2' ) {
  202. $rc = -2;
  203. }
  204. }
  205. }
  206. $rc;
  207. }
  208. sub check_recurring {
  209. my ( $self, $form ) = @_;
  210. my $dbh =
  211. DBI->connect( $self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd} )
  212. or $form->dberror( __FILE__ . ':' . __LINE__ );
  213. my $query = qq|
  214. SELECT count(*) FROM recurring
  215. WHERE enddate >= current_date AND nextdate <= current_date|;
  216. ($_) = $dbh->selectrow_array($query);
  217. $dbh->disconnect;
  218. $_;
  219. }
  220. sub dbconnect_vars {
  221. my ( $form, $db ) = @_;
  222. my %dboptions = (
  223. 'Pg' => {
  224. 'yy-mm-dd' => 'set DateStyle to \'ISO\'',
  225. 'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
  226. 'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
  227. 'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
  228. 'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
  229. 'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
  230. }
  231. );
  232. $form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };
  233. $form->{dbconnect} = "dbi:$form->{dbdriver}:dbname=$db";
  234. $form->{dbconnect} .= ";host=$form->{dbhost}";
  235. $form->{dbconnect} .= ";port=$form->{dbport}";
  236. }
  237. sub dbdrivers {
  238. my @drivers = DBI->available_drivers();
  239. # return (grep { /(Pg|Oracle|DB2)/ } @drivers);
  240. return ( grep { /Pg$/ } @drivers );
  241. }
  242. sub dbsources {
  243. my ( $self, $form ) = @_;
  244. my @dbsources = ();
  245. my ( $sth, $query );
  246. $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
  247. $form->{sid} = $form->{dbdefault};
  248. &dbconnect_vars( $form, $form->{dbdefault} );
  249. my $dbh =
  250. DBI->connect( $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd} )
  251. or $form->dberror( __FILE__ . ':' . __LINE__ );
  252. if ( $form->{dbdriver} eq 'Pg' ) {
  253. $query = qq|SELECT datname FROM pg_database|;
  254. $sth = $dbh->prepare($query);
  255. $sth->execute || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  256. while ( my ($db) = $sth->fetchrow_array ) {
  257. if ( $form->{only_acc_db} ) {
  258. next if ( $db =~ /^template/ );
  259. &dbconnect_vars( $form, $db );
  260. my $dbh =
  261. DBI->connect( $form->{dbconnect}, $form->{dbuser},
  262. $form->{dbpasswd} )
  263. or $form->dberror( __FILE__ . ':' . __LINE__ );
  264. $query = qq|
  265. SELECT tablename FROM pg_tables
  266. WHERE tablename = 'defaults'
  267. AND tableowner = ?|;
  268. my $sth = $dbh->prepare($query);
  269. $sth->execute( $form->{dbuser} )
  270. || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  271. if ( $sth->fetchrow_array ) {
  272. push @dbsources, $db;
  273. }
  274. $sth->finish;
  275. $dbh->disconnect;
  276. next;
  277. }
  278. push @dbsources, $db;
  279. }
  280. }
  281. $sth->finish;
  282. $dbh->disconnect;
  283. return @dbsources;
  284. }
  285. sub dbcreate {
  286. my ( $self, $form ) = @_;
  287. my %dbcreate =
  288. ( 'Pg' => qq|CREATE DATABASE "$form->{db}" WITH ENCODING = 'UNICODE'| );
  289. $form->{sid} = $form->{dbdefault};
  290. &dbconnect_vars( $form, $form->{dbdefault} );
  291. # The below line connects to Template1 or another template file in order
  292. # to create the db. One must disconnect and reconnect later.
  293. if ( $form->{dbsuperuser} ) {
  294. my $superdbh =
  295. DBI->connect( $form->{dbconnect}, $form->{dbsuperuser},
  296. $form->{dbsuperpasswd} )
  297. or $form->dberror( __FILE__ . ':' . __LINE__ );
  298. my $query = qq|$dbcreate{$form->{dbdriver}}|;
  299. $superdbh->do($query)
  300. || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  301. $superdbh->disconnect;
  302. }
  303. #Reassign for the work below
  304. &dbconnect_vars( $form, $form->{db} );
  305. my $dbh =
  306. DBI->connect( $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd} )
  307. or $form->dberror( __FILE__ . ':' . __LINE__ );
  308. if ( $form->{dbsuperuser} ) {
  309. my $superdbh =
  310. DBI->connect( $form->{dbconnect}, $form->{dbsuperuser},
  311. $form->{dbsuperpasswd} )
  312. or $form->dberror( __FILE__ . ':' . __LINE__ );
  313. # JD: We need to check for plpgsql,
  314. # if it isn't there create it, if we can't error
  315. # Good chance I will have to do this twice as I get
  316. # used to the way the code is structured
  317. my %langcreate = ( 'Pg' => qq|CREATE LANGUAGE plpgsql| );
  318. my $query = qq|$langcreate{$form->{dbdriver}}|;
  319. $superdbh->do($query);
  320. $superdbh->disconnect;
  321. }
  322. # create the tables
  323. my $dbdriver =
  324. ( $form->{dbdriver} =~ /Pg/ )
  325. ? 'Pg'
  326. : $form->{dbdriver};
  327. my $filename = qq|sql/Pg-database.sql|;
  328. $self->process_query( $form, $dbh, $filename );
  329. # load gifi
  330. ($filename) = split /_/, $form->{chart};
  331. $filename =~ s/_//;
  332. $self->process_query( $form, $dbh, "sql/${filename}-gifi.sql" );
  333. # load chart of accounts
  334. $filename = qq|sql/$form->{chart}-chart.sql|;
  335. $self->process_query( $form, $dbh, $filename );
  336. # create custom tables and functions
  337. my $item;
  338. foreach $item (qw(tables functions)) {
  339. $filename = "sql/${dbdriver}-custom_${item}.sql";
  340. if ( -f "$filename" ) {
  341. $self->process_query( $form, $dbh, $filename );
  342. }
  343. }
  344. $dbh->disconnect;
  345. }
  346. sub process_query {
  347. my ( $self, $form, $dbh, $filename ) = @_;
  348. return unless ( -f $filename );
  349. $ENV{PGPASSWORD} = $form->{dbpasswd};
  350. $ENV{PGUSER} = $form->{dbuser};
  351. $ENV{PGDATABASE} = $form->{db};
  352. $ENV{PGHOST} = $form->{dbhost};
  353. $ENV{PGPORT} = $form->{dbport};
  354. $results = `psql -f $filename 2>&1`;
  355. if ($?) {
  356. $form->error($!);
  357. }
  358. elsif ( $results =~ /error/i ) {
  359. $form->error($results);
  360. }
  361. }
  362. sub dbdelete {
  363. my ( $self, $form ) = @_;
  364. $form->{sid} = $form->{dbdefault};
  365. &dbconnect_vars( $form, $form->{dbdefault} );
  366. my $dbh =
  367. DBI->connect( $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd} )
  368. or $form->dberror( __FILE__ . ':' . __LINE__ );
  369. my $query = qq|DROP DATABASE "$form->{db}"|;
  370. $dbh->do($query) || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  371. $dbh->disconnect;
  372. }
  373. sub dbsources_unused {
  374. my ( $self, $form, $memfile ) = @_;
  375. my @dbexcl = ();
  376. my @dbsources = ();
  377. $form->error( __FILE__ . ':' . __LINE__ . ": $memfile locked!" )
  378. if ( -f "${memfile}.LCK" );
  379. # open members file
  380. open( FH, '<', "$memfile" )
  381. or $form->error( __FILE__ . ':' . __LINE__ . ": $memfile : $!" );
  382. while (<FH>) {
  383. if (/^dbname=/) {
  384. my ( $null, $item ) = split /=/;
  385. push @dbexcl, $item;
  386. }
  387. }
  388. close FH;
  389. $form->{only_acc_db} = 1;
  390. my @db = &dbsources( "", $form );
  391. push @dbexcl, $form->{dbdefault};
  392. foreach $item (@db) {
  393. unless ( grep /$item$/, @dbexcl ) {
  394. push @dbsources, $item;
  395. }
  396. }
  397. return @dbsources;
  398. }
  399. sub dbneedsupdate {
  400. my ( $self, $form ) = @_;
  401. my %dbsources = ();
  402. my $query;
  403. $form->{sid} = $form->{dbdefault};
  404. &dbconnect_vars( $form, $form->{dbdefault} );
  405. my $dbh =
  406. DBI->connect( $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd} )
  407. or $form->dberror( __FILE__ . ':' . __LINE__ );
  408. if ( $form->{dbdriver} =~ /Pg/ ) {
  409. $query = qq|
  410. SELECT d.datname
  411. FROM pg_database d, pg_user u
  412. WHERE d.datdba = u.usesysid
  413. AND u.usename = ?|;
  414. my $sth = $dbh->prepare($query);
  415. $sth->execute( $form->{dbuser} )
  416. || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  417. while ( my ($db) = $sth->fetchrow_array ) {
  418. next if ( $db =~ /^template/ );
  419. &dbconnect_vars( $form, $db );
  420. my $dbh =
  421. DBI->connect( $form->{dbconnect}, $form->{dbuser},
  422. $form->{dbpasswd} )
  423. or $form->dberror( __FILE__ . ':' . __LINE__ );
  424. $query = qq|
  425. SELECT tablename
  426. FROM pg_tables
  427. WHERE tablename = 'defaults'|;
  428. my $sth = $dbh->prepare($query);
  429. $sth->execute
  430. || $form->dberror( __FILE__ . ':' . __LINE__ . $query );
  431. if ( $sth->fetchrow_array ) {
  432. $query = qq|
  433. SELECT value FROM defaults
  434. WHERE setting_key = 'version'|;
  435. my $sth = $dbh->prepare($query);
  436. $sth->execute;
  437. if ( my ($version) = $sth->fetchrow_array ) {
  438. $dbsources{$db} = $version;
  439. }
  440. $sth->finish;
  441. }
  442. $sth->finish;
  443. $dbh->disconnect;
  444. }
  445. $sth->finish;
  446. }
  447. $dbh->disconnect;
  448. %dbsources;
  449. }
  450. sub dbupdate {
  451. my ( $self, $form ) = @_;
  452. $form->{sid} = $form->{dbdefault};
  453. my @upgradescripts = ();
  454. my $query;
  455. my $rc = -2;
  456. if ( $form->{dbupdate} ) {
  457. # read update scripts into memory
  458. opendir SQLDIR, "sql/."
  459. or $form->error( __FILE__ . ':' . __LINE__ . ': ' . $! );
  460. @upgradescripts =
  461. sort script_version grep /$form->{dbdriver}-upgrade-.*?\.sql$/,
  462. readdir SQLDIR;
  463. closedir SQLDIR;
  464. }
  465. foreach my $db ( split / /, $form->{dbupdate} ) {
  466. next unless $form->{$db};
  467. # strip db from dataset
  468. $db =~ s/^db//;
  469. &dbconnect_vars( $form, $db );
  470. my $dbh = DBI->connect(
  471. $form->{dbconnect}, $form->{dbuser},
  472. $form->{dbpasswd}, { AutoCommit => 0 }
  473. ) or $form->dberror( __FILE__ . ':' . __LINE__ );
  474. # check version
  475. $query = qq|
  476. SELECT value FROM defaults
  477. WHERE setting_key = 'version'|;
  478. my $sth = $dbh->prepare($query);
  479. # no error check, let it fall through
  480. $sth->execute;
  481. my $version = $sth->fetchrow_array;
  482. $sth->finish;
  483. next unless $version;
  484. $version = calc_version($version);
  485. my $dbversion = calc_version( $form->{dbversion} );
  486. foreach my $upgradescript (@upgradescripts) {
  487. my $a = $upgradescript;
  488. $a =~ s/(^$form->{dbdriver}-upgrade-|\.sql$)//g;
  489. my ( $mindb, $maxdb ) = split /-/, $a;
  490. $mindb = calc_version($mindb);
  491. $maxdb = calc_version($maxdb);
  492. next if ( $version >= $maxdb );
  493. # exit if there is no upgrade script or version == mindb
  494. last if ( $version < $mindb || $version >= $dbversion );
  495. # apply upgrade
  496. $self->process_query( $form, $dbh, "sql/$upgradescript" );
  497. $dbh->commit;
  498. $version = $maxdb;
  499. }
  500. $rc = 0;
  501. $dbh->disconnect;
  502. }
  503. $rc;
  504. }
  505. sub calc_version {
  506. my @v = split /\./, $_[0];
  507. my $version = 0;
  508. my $i;
  509. for ( $i = 0 ; $i <= $#v ; $i++ ) {
  510. $version *= 1000;
  511. $version += $v[$i];
  512. }
  513. return $version;
  514. }
  515. sub script_version {
  516. my ( $my_a, $my_b ) = ( $a, $b );
  517. my ( $a_from, $a_to, $b_from, $b_to );
  518. my ( $res_a, $res_b, $i );
  519. $my_a =~ s/.*-upgrade-//;
  520. $my_a =~ s/.sql$//;
  521. $my_b =~ s/.*-upgrade-//;
  522. $my_b =~ s/.sql$//;
  523. ( $a_from, $a_to ) = split( /-/, $my_a );
  524. ( $b_from, $b_to ) = split( /-/, $my_b );
  525. $res_a = calc_version($a_from);
  526. $res_b = calc_version($b_from);
  527. if ( $res_a == $res_b ) {
  528. $res_a = calc_version($a_to);
  529. $res_b = calc_version($b_to);
  530. }
  531. return $res_a <=> $res_b;
  532. }
  533. sub save_member {
  534. my ($self) = @_;
  535. # replace \r\n with \n
  536. for (qw(address signature)) { $self->{$_} =~ s/\r?\n/\\n/g }
  537. # use central db
  538. my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
  539. #check to see if the user exists already
  540. my $userCheck = $dbh->prepare("SELECT id FROM users WHERE username = ?");
  541. $userCheck->execute( $self->{login} );
  542. my ($userID) = $userCheck->fetchrow_array;
  543. if ( !$self->{dbhost} ) {
  544. $self->{dbhost} = 'localhost';
  545. }
  546. if ( !$self->{dbport} ) {
  547. $self->{dbport} = '5432';
  548. }
  549. my $userConfExists = 0;
  550. if ($userID) {
  551. #got an id, check to see if it's in the users_conf table
  552. my $userConfCheck =
  553. $dbh->prepare("SELECT password, 1 FROM users_conf WHERE id = ?");
  554. $userConfCheck->execute($userID);
  555. ( $oldPassword, $userConfExists ) = $userConfCheck->fetchrow_array;
  556. }
  557. else {
  558. my $userConfAdd = $dbh->prepare("SELECT create_user(?);");
  559. $userConfAdd->execute( $self->{login} );
  560. ($userID) = $userConfAdd->fetchrow_array;
  561. }
  562. if ($userConfExists) {
  563. # for now, this is updating the table directly... ugly
  564. my $userConfUpdate = $dbh->prepare(
  565. "UPDATE users_conf
  566. SET acs = ?, address = ?, businessnumber = ?,
  567. company = ?, countrycode = ?, currency = ?,
  568. dateformat = ?, dbdriver = ?,
  569. dbhost = ?, dbname = ?, dboptions = ?,
  570. dbpasswd = ?, dbport = ?, dbuser = ?,
  571. email = ?, fax = ?, menuwidth = ?,
  572. name = ?, numberformat = ?,
  573. print = ?, printer = ?, role = ?,
  574. sid = ?, signature = ?, stylesheet = ?,
  575. tel = ?, templates = ?, timeout = ?,
  576. vclimit = ?
  577. WHERE id = ?;"
  578. );
  579. $userConfUpdate->execute(
  580. $self->{acs}, $self->{address},
  581. $self->{businessnumber}, $self->{company},
  582. $self->{countrycode}, $self->{currency},
  583. $self->{dateformat}, $self->{dbdriver},
  584. $self->{dbhost}, $self->{dbname},
  585. $self->{dboptions}, $self->{dbpasswd},
  586. $self->{dbport}, $self->{dbuser},
  587. $self->{email}, $self->{fax},
  588. $self->{menuwidth}, $self->{name},
  589. $self->{numberformat}, $self->{print},
  590. $self->{printer}, $self->{role},
  591. $self->{sid}, $self->{signature},
  592. $self->{stylesheet}, $self->{tel},
  593. $self->{templates}, $self->{timeout},
  594. $self->{vclimit}, $userID
  595. );
  596. if ( $oldPassword ne $self->{password} ) {
  597. # if they're supplying a 32 char password that matches their old password
  598. # assume they don't want to change passwords
  599. $userConfUpdate = $dbh->prepare(
  600. "UPDATE users_conf
  601. SET password = md5(?)
  602. WHERE id = ?"
  603. );
  604. $userConfUpdate->execute( $self->{password}, $userID );
  605. }
  606. }
  607. else {
  608. my $userConfInsert = $dbh->prepare(
  609. "INSERT INTO users_conf(acs, address, businessnumber,
  610. company, countrycode, currency,
  611. dateformat, dbdriver,
  612. dbhost, dbname, dboptions, dbpasswd,
  613. dbport, dbuser, email, fax, menuwidth,
  614. name, numberformat, print, printer, role,
  615. sid, signature, stylesheet, tel, templates,
  616. timeout, vclimit, id, password)
  617. VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
  618. ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
  619. ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, md5(?));"
  620. );
  621. $userConfInsert->execute(
  622. $self->{acs}, $self->{address},
  623. $self->{businessnumber}, $self->{company},
  624. $self->{countrycode}, $self->{currency},
  625. $self->{dateformat}, $self->{dbdriver},
  626. $self->{dbhost}, $self->{dbname},
  627. $self->{dboptions}, $self->{dbpasswd},
  628. $self->{dbport}, $self->{dbuser},
  629. $self->{email}, $self->{fax},
  630. $self->{menuwidth}, $self->{name},
  631. $self->{numberformat}, $self->{print},
  632. $self->{printer}, $self->{role},
  633. $self->{sid}, $self->{signature},
  634. $self->{stylesheet}, $self->{tel},
  635. $self->{templates}, $self->{timeout},
  636. $self->{vclimit}, $userID,
  637. $self->{password}
  638. );
  639. }
  640. if ( !$self->{'admin'} ) {
  641. $self->{dbpasswd} =~ s/\\'/'/g;
  642. $self->{dbpasswd} =~ s/\\\\/\\/g;
  643. # format dbconnect and dboptions string
  644. &dbconnect_vars( $self, $self->{dbname} );
  645. # check if login is in database
  646. my $dbh = DBI->connect(
  647. $self->{dbconnect}, $self->{dbuser},
  648. $self->{dbpasswd}, { AutoCommit => 0 }
  649. ) or $self->error($DBI::errstr);
  650. # add login to employees table if it does not exist
  651. my $login = $self->{login};
  652. $login =~ s/@.*//;
  653. my $sth = $dbh->prepare("SELECT id FROM employees WHERE login = ?;");
  654. $sth->execute($login);
  655. my ($id) = $sth->fetchrow_array;
  656. $sth->finish;
  657. my $employeenumber;
  658. my @values;
  659. if ($id) {
  660. $query = qq|UPDATE employees SET
  661. role = ?,
  662. email = ?,
  663. name = ?
  664. WHERE login = ?|;
  665. @values = ( $self->{role}, $self->{email}, $self->{name}, $login );
  666. }
  667. else {
  668. my ($employeenumber) =
  669. Form::update_defaults( "", \%$self, "employeenumber", $dbh );
  670. $query = qq|
  671. INSERT INTO employees
  672. (login, employeenumber, name,
  673. workphone, role, email, sales)
  674. VALUES (?, ?, ?, ?, ?, ?, '1')|;
  675. @values = (
  676. $login, $employeenumber, $self->{name},
  677. $self->{tel}, $self->{role}, $self->{email}
  678. );
  679. }
  680. $sth = $dbh->prepare($query);
  681. $sth->execute(@values);
  682. $dbh->commit;
  683. $dbh->disconnect;
  684. }
  685. }
  686. sub delete_login {
  687. my ( $self, $form ) = @_;
  688. my $dbh = DBI->connect(
  689. $form->{dbconnect}, $form->{dbuser},
  690. $form->{dbpasswd}, { AutoCommit => 0 }
  691. ) or $form->dberror( __FILE__ . ':' . __LINE__ );
  692. my $login = $form->{login};
  693. $login =~ s/@.*//;
  694. my $query = qq|SELECT id FROM employees WHERE login = ?|;
  695. my $sth = $dbh->prepare($query);
  696. $sth->execute($login)
  697. || $form->dberror( __FILE__ . ':' . __LINE__ . ': ' . $query );
  698. my ($id) = $sth->fetchrow_array;
  699. $sth->finish;
  700. my $query = qq|
  701. UPDATE employees
  702. SET login = NULL,
  703. enddate = current_date
  704. WHERE login = ?|;
  705. $sth = $dbh->prepare($query);
  706. $sth->execute($login);
  707. $dbh->commit;
  708. $dbh->disconnect;
  709. }
  710. sub config_vars {
  711. my @conf = qw(acs address businessnumber company countrycode
  712. currency dateformat dbconnect dbdriver dbhost dbname dboptions
  713. dbpasswd dbport dbuser email fax menuwidth name numberformat
  714. password printer role sid signature stylesheet tel templates
  715. timeout vclimit);
  716. @conf;
  717. }
  718. sub error {
  719. my ( $self, $msg ) = @_;
  720. if ( $ENV{GATEWAY_INTERFACE} ) {
  721. print qq|Content-Type: text/html\n\n|
  722. . qq|<body bgcolor=ffffff>\n\n|
  723. . qq|<h2><font color=red>Error!</font></h2>\n|
  724. . qq|<p><b>$msg</b>|;
  725. }
  726. die "Error: $msg\n";
  727. }
  728. 1;