Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 8c7e4493

Von Moritz Bunkus vor fast 17 Jahren hinzugefügt

  • ID 8c7e44938a661e035f62840e1e177353240ace5d
  • Vorgänger 3ced230b
  • Nachfolger ce45d060

Umstellung der Benutzerverwaltung von Dateien im Verzeichnis "users" auf die Verwendung einer Authentifizierungsdatenbank.
Es ist erforderlich, die Dateien doc/UPGRADE und doc/INSTALL/index.html zu lesen und die angesprochenen Punkte auszuführen, um nach einem Upgrade weiter arbeiten zu können.

Unterschiede anzeigen:

SL/AM.pm
37 37

  
38 38
package AM;
39 39

  
40
use Carp;
40 41
use Data::Dumper;
41 42
use SL::DBUtils;
42 43

  
......
1528 1529
sub save_preferences {
1529 1530
  $main::lxdebug->enter_sub();
1530 1531

  
1531
  my ($self, $myconfig, $form, $memberfile, $userspath, $webdav) = @_;
1532
  my ($self, $myconfig, $form, $webdav) = @_;
1532 1533

  
1533 1534
  my $dbh = $form->get_standard_dbh($myconfig);
1534 1535

  
......
1546 1547

  
1547 1548
  $form->{businessnumber} =  $businessnumber;
1548 1549

  
1549
  $myconfig = new User "$memberfile", "$form->{login}";
1550
  my $myconfig = new User($form->{login});
1550 1551

  
1551 1552
  foreach my $item (keys %$form) {
1552 1553
    $myconfig->{$item} = $form->{$item};
1553 1554
  }
1554 1555

  
1555
  $myconfig->save_member($memberfile, $userspath);
1556
  $myconfig->save_member($memberfile);
1557

  
1558
  my $auth = $main::auth;
1559

  
1560
  if ($auth->can_change_password()
1561
      && defined $form->{new_password}
1562
      && ($form->{new_password} ne '********')) {
1563
    $auth->change_password($form->{login}, $form->{new_password});
1564

  
1565
    $form->{password} = $form->{new_password};
1566
    $auth->set_session_value('password', $form->{password});
1567
    $auth->create_or_refresh_session();
1568
  }
1556 1569

  
1557 1570
  if ($webdav) {
1558 1571
    @webdavdirs =
......
1820 1833
  return $units;
1821 1834
}
1822 1835

  
1836
sub retrieve_all_units {
1837
  $main::lxdebug->enter_sub();
1838

  
1839
  my $self = shift;
1840

  
1841
  if (!$main::all_units) {
1842
    $main::all_units = $self->retrieve_units(\%main::myconfig, $main::form);
1843
  }
1844

  
1845
  $main::lxdebug->leave_sub();
1846

  
1847
  return $main::all_units;
1848
}
1849

  
1850

  
1823 1851
sub translate_units {
1824 1852
  $main::lxdebug->enter_sub();
1825 1853

  
......
1889 1917
  $main::lxdebug->leave_sub();
1890 1918
}
1891 1919

  
1920
sub convertible_units {
1921
  $main::lxdebug->enter_sub();
1922

  
1923
  my $self        = shift;
1924
  my $units       = shift;
1925
  my $filter_unit = shift;
1926
  my $not_smaller = shift;
1927

  
1928
  my $conv_units = [];
1929

  
1930
  $filter_unit = $units->{$filter_unit};
1931

  
1932
  foreach my $name (sort { lc $a cmp lc $b } keys %{ $units }) {
1933
    my $unit = $units->{$name};
1934

  
1935
    if (($unit->{base_unit} eq $filter_unit->{base_unit}) &&
1936
        (!$not_smaller || ($unit->{factor} >= $filter_unit->{factor}))) {
1937
      push @{$conv_units}, $unit;
1938
    }
1939
  }
1940

  
1941
  my @sorted = sort { $b->{factor} <=> $a->{factor} } @{ $conv_units };
1942

  
1943
  $main::lxdebug->leave_sub();
1944

  
1945
  return \@sorted;
1946
}
1947

  
1892 1948
# if $a is translatable to $b, return the factor between them.
1893 1949
# else return 1
1894 1950
sub convert_unit {
......
1903 1959
sub unit_select_data {
1904 1960
  $main::lxdebug->enter_sub();
1905 1961

  
1906
  my ($self, $units, $selected, $empty_entry) = @_;
1962
  my ($self, $units, $selected, $empty_entry, $convertible_into) = @_;
1907 1963

  
1908 1964
  my $select = [];
1909 1965

  
......
1912 1968
  }
1913 1969

  
1914 1970
  foreach my $unit (sort({ $units->{$a}->{"sortkey"} <=> $units->{$b}->{"sortkey"} } keys(%{$units}))) {
1915
    push(@{$select}, { "name" => $unit,
1916
                       "base_unit" => $units->{$unit}->{"base_unit"},
1917
                       "factor" => $units->{$unit}->{"factor"},
1918
                       "selected" => ($unit eq $selected) ? "selected" : "" });
1971
    if (!$convertible_into ||
1972
        ($units->{$convertible_into} &&
1973
         ($units->{$convertible_into}->{base_unit} eq $units->{$unit}->{base_unit}))) {
1974
      push @{$select}, { "name"      => $unit,
1975
                         "base_unit" => $units->{$unit}->{"base_unit"},
1976
                         "factor"    => $units->{$unit}->{"factor"},
1977
                         "selected"  => ($unit eq $selected) ? "selected" : "" };
1978
    }
1919 1979
  }
1920 1980

  
1921 1981
  $main::lxdebug->leave_sub();
......
1944 2004
  return $select;
1945 2005
}
1946 2006

  
2007
sub sum_with_unit {
2008
  $main::lxdebug->enter_sub();
2009

  
2010
  my $self  = shift;
2011

  
2012
  my $units = $self->retrieve_all_units();
2013

  
2014
  my $sum   = 0;
2015
  my $base_unit;
2016

  
2017
  while (2 <= scalar(@_)) {
2018
    my $qty  = shift(@_);
2019
    my $unit = $units->{shift(@_)};
2020

  
2021
    croak "No unit defined with name $unit" if (!defined $unit);
2022

  
2023
    if (!$base_unit) {
2024
      $base_unit = $unit->{base_unit};
2025
    } elsif ($base_unit ne $unit->{base_unit}) {
2026
      croak "Adding values with incompatible base units $base_unit/$unit->{base_unit}";
2027
    }
2028

  
2029
    $sum += $qty * $unit->{factor};
2030
  }
2031

  
2032
  $main::lxdebug->leave_sub();
2033

  
2034
  return wantarray ? ($sum, $baseunit) : $sum;
2035
}
2036

  
1947 2037
sub add_unit {
1948 2038
  $main::lxdebug->enter_sub();
1949 2039

  
SL/Auth.pm
1
package SL::Auth;
2

  
3
use constant OK           =>   0;
4
use constant ERR_PASSWORD =>   1;
5
use constant ERR_BACKEND  => 100;
6

  
7
use Digest::MD5 qw(md5_hex);
8
use IO::File;
9
use Time::HiRes qw(gettimeofday);
10

  
11
use SL::Auth::DB;
12
use SL::Auth::LDAP;
13

  
14
use SL::User;
15
use SL::DBUtils;
16

  
17
sub new {
18
  $main::lxdebug->enter_sub();
19

  
20
  my $type = shift;
21
  my $self = {};
22

  
23
  bless $self, $type;
24

  
25
  $self->{SESSION} = { };
26

  
27
  $self->_read_auth_config();
28

  
29
  $main::lxdebug->leave_sub();
30

  
31
  return $self;
32
}
33

  
34
sub DESTROY {
35
  my $self = shift;
36

  
37
  $self->{dbh}->disconnect() if ($self->{dbh});
38
}
39

  
40
sub _read_auth_config {
41
  $main::lxdebug->enter_sub();
42

  
43
  my $self   = shift;
44

  
45
  my $form   = $main::form;
46
  my $locale = $main::locale;
47

  
48
  my $code;
49
  my $in = IO::File->new('config/authentication.pl', 'r');
50

  
51
  if (!$in) {
52
    $form->error($locale->text('The config file "config/authentication.pl" was not found.'));
53
  }
54

  
55
  while (<$in>) {
56
    $code .= $_;
57
  }
58
  $in->close();
59

  
60
  eval $code;
61

  
62
  if ($@) {
63
    $form->error($locale->text('The config file "config/authentication.pl" contained invalid Perl code:') . "\n" . $@);
64
  }
65

  
66
  if ($self->{module} eq 'DB') {
67
    $self->{authenticator} = SL::Auth::DB->new($self);
68

  
69
  } elsif ($self->{module} eq 'LDAP') {
70
    $self->{authenticator} = SL::Auth::LDAP->new($self);
71
  }
72

  
73
  if (!$self->{authenticator}) {
74
    $form->error($locale->text('No or an unknown authenticantion module specified in "config/authentication.pl".'));
75
  }
76

  
77
  my $cfg = $self->{DB_config};
78

  
79
  if (!$cfg) {
80
    $form->error($locale->text('config/authentication.pl: Key "DB_config" is missing.'));
81
  }
82

  
83
  if (!$cfg->{host} || !$cfg->{db} || !$cfg->{user}) {
84
    $form->error($locale->text('config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".'));
85
  }
86

  
87
  $self->{authenticator}->verify_config();
88

  
89
  $main::lxdebug->leave_sub();
90
}
91

  
92
sub authenticate_root {
93
  $main::lxdebug->enter_sub();
94

  
95
  my $self          = shift;
96
  my $password      = shift;
97
  my $is_crypted    = shift;
98

  
99
  $password         = crypt $password, 'ro' if (!$password || !$is_crypted);
100
  $admin_password   = crypt "$self->{admin_password}", 'ro';
101

  
102
  $main::lxdebug->leave_sub();
103

  
104
  return $password eq $admin_password ? OK : ERR_PASSWORD;
105
}
106

  
107
sub authenticate {
108
  $main::lxdebug->enter_sub();
109

  
110
  my $self = shift;
111

  
112
  $main::lxdebug->leave_sub();
113

  
114
  return $self->{authenticator}->authenticate(@_);
115
}
116

  
117
sub dbconnect {
118
  $main::lxdebug->enter_sub();
119

  
120
  my $self     = shift;
121
  my $may_fail = shift;
122

  
123
  if ($self->{dbh}) {
124
    $main::lxdebug->leave_sub();
125
    return $self->{dbh};
126
  }
127

  
128
  my $cfg = $self->{DB_config};
129
  my $dsn = 'dbi:Pg:dbname=' . $cfg->{db} . ';host=' . $cfg->{host};
130

  
131
  if ($cfg->{port}) {
132
    $dsn .= ';port=' . $cfg->{port};
133
  }
134

  
135
  $main::lxdebug->message(LXDebug::DEBUG1, "Auth::dbconnect DSN: $dsn");
136

  
137
  $self->{dbh} = DBI->connect($dsn, $cfg->{user}, $cfg->{password}, { 'AutoCommit' => 0 });
138

  
139
  if (!$may_fail && !$self->{dbh}) {
140
    $main::form->error($main::locale->text('The connection to the authentication database failed:') . "\n" . $DBI::errstr);
141
  }
142

  
143
  $main::lxdebug->leave_sub();
144

  
145
  return $self->{dbh};
146
}
147

  
148
sub dbdisconnect {
149
  $main::lxdebug->enter_sub();
150

  
151
  my $self = shift;
152

  
153
  if ($self->{dbh}) {
154
    $self->{dbh}->disconnect();
155
    delete $self->{dbh};
156
  }
157

  
158
  $main::lxdebug->leave_sub();
159
}
160

  
161
sub check_tables {
162
  $main::lxdebug->enter_sub();
163

  
164
  my $self    = shift;
165

  
166
  my $dbh     = $self->dbconnect();
167
  my $query   = qq|SELECT COUNT(*) FROM pg_tables WHERE (schemaname = 'auth') AND (tablename = 'user')|;
168

  
169
  my ($count) = $dbh->selectrow_array($query);
170

  
171
  $main::lxdebug->leave_sub();
172

  
173
  return $count > 0;
174
}
175

  
176
sub check_database {
177
  $main::lxdebug->enter_sub();
178

  
179
  my $self = shift;
180

  
181
  my $dbh  = $self->dbconnect(1);
182

  
183
  $main::lxdebug->leave_sub();
184

  
185
  return $dbh ? 1 : 0;
186
}
187

  
188
sub create_database {
189
  $main::lxdebug->enter_sub();
190

  
191
  my $self   = shift;
192
  my %params = @_;
193

  
194
  my $cfg    = $self->{DB_config};
195

  
196
  if (!$params{superuser}) {
197
    $params{superuser}          = $cfg->{user};
198
    $params{superuser_password} = $cfg->{password};
199
  }
200

  
201
  $params{template} ||= 'template0';
202
  $params{template}   =~ s|[^a-zA-Z0-9_\-]||g;
203

  
204
  my $dsn = 'dbi:Pg:dbname=template1;host=' . $cfg->{host};
205

  
206
  if ($cfg->{port}) {
207
    $dsn .= ';port=' . $cfg->{port};
208
  }
209

  
210
  $main::lxdebug->message(LXDebug::DEBUG1, "Auth::create_database DSN: $dsn");
211

  
212
  my $dbh = DBI->connect($dsn, $params{superuser}, $params{superuser_password});
213

  
214
  if (!$dbh) {
215
    $main::form->error($main::locale->text('The connection to the template database failed:') . "\n" . $DBI::errstr);
216
  }
217

  
218
  my $charset    = $main::charset;
219
  $charset     ||= Common::DEFAULT_CHARSET;
220
  my $encoding   = $Common::charset_to_db_encoding{$charset};
221
  $encoding    ||= 'UNICODE';
222

  
223
  my $query = qq|CREATE DATABASE "$cfg->{db}" OWNER "$cfg->{user}" TEMPLATE "$params{template}" ENCODING '$encoding'|;
224

  
225
  $main::lxdebug->message(LXDebug::DEBUG1, "Auth::create_database query: $query");
226

  
227
  $dbh->do($query);
228

  
229
  if ($dbh->err) {
230
    $dbh->disconnect();
231

  
232
    $main::form->error($main::locale->text('The creation of the authentication database failed:') . "\n" . $DBI::errstr);
233
  }
234

  
235
  $dbh->disconnect();
236

  
237
  $main::lxdebug->leave_sub();
238
}
239

  
240
sub create_tables {
241
  $main::lxdebug->enter_sub();
242

  
243
  my $self = shift;
244
  my $dbh  = $self->dbconnect();
245

  
246
  my $charset    = $main::charset;
247
  $charset     ||= Common::DEFAULT_CHARSET;
248

  
249
  $dbh->rollback();
250
  User->process_query($main::form, $dbh, 'sql/auth_db.sql', undef, $charset);
251

  
252
  $main::lxdebug->leave_sub();
253
}
254

  
255
sub save_user {
256
  $main::lxdebug->enter_sub();
257

  
258
  my $self   = shift;
259
  my $login  = shift;
260
  my %params = @_;
261

  
262
  my $form   = $main::form;
263

  
264
  my $dbh    = $self->dbconnect();
265

  
266
  my ($sth, $query, $user_id);
267

  
268
  $query     = qq|SELECT id FROM auth."user" WHERE login = ?|;
269
  ($user_id) = selectrow_query($form, $dbh, $query, $login);
270

  
271
  if (!$user_id) {
272
    $query     = qq|SELECT nextval('auth.user_id_seq')|;
273
    ($user_id) = selectrow_query($form, $dbh, $query);
274

  
275
    $query     = qq|INSERT INTO auth."user" (id, login) VALUES (?, ?)|;
276
    do_query($form, $dbh, $query, $user_id, $login);
277
  }
278

  
279
  $query = qq|DELETE FROM auth.user_config WHERE (user_id = ?)|;
280
  do_query($form, $dbh, $query, $user_id);
281

  
282
  $query = qq|INSERT INTO auth.user_config (user_id, cfg_key, cfg_value) VALUES (?, ?, ?)|;
283
  $sth   = prepare_query($form, $dbh, $query);
284

  
285
  while (my ($cfg_key, $cfg_value) = each %params) {
286
    next if ($cfg_key eq 'password');
287

  
288
    do_statement($form, $sth, $query, $user_id, $cfg_key, $cfg_value);
289
  }
290

  
291
  $dbh->commit();
292

  
293
  $main::lxdebug->leave_sub();
294
}
295

  
296
sub can_change_password {
297
  my $self = shift;
298

  
299
  return $self->{authenticator}->can_change_password();
300
}
301

  
302
sub change_password {
303
  $main::lxdebug->enter_sub();
304

  
305
  my $self   = shift;
306
  my $result = $self->{authenticator}->change_password(@_);
307

  
308
  $main::lxdebug->leave_sub();
309

  
310
  return $result;
311
}
312

  
313
sub read_all_users {
314
  $main::lxdebug->enter_sub();
315

  
316
  my $self  = shift;
317

  
318
  my $dbh   = $self->dbconnect();
319
  my $query = qq|SELECT u.id, u.login, cfg.cfg_key, cfg.cfg_value
320
                 FROM auth.user_config cfg
321
                 LEFT JOIN auth."user" u ON (cfg.user_id = u.id)|;
322
  my $sth   = prepare_execute_query($main::form, $dbh, $query);
323

  
324
  my %users;
325

  
326
  while (my $ref = $sth->fetchrow_hashref()) {
327
    $users{$ref->{login}}                    ||= { 'login' => $ref->{login}, 'id' => $ref->{id} };
328
    $users{$ref->{login}}->{$ref->{cfg_key}}   = $ref->{cfg_value} if (($cfg_key ne 'login') && ($cfg_key ne 'id'));
329
  }
330

  
331
  $sth->finish();
332

  
333
  $main::lxdebug->leave_sub();
334

  
335
  return %users;
336
}
337

  
338
sub read_user {
339
  $main::lxdebug->enter_sub();
340

  
341
  my $self  = shift;
342
  my $login = shift;
343

  
344
  my $dbh   = $self->dbconnect();
345
  my $query = qq|SELECT cfg.cfg_key, cfg.cfg_value
346
                 FROM auth.user_config cfg
347
                 LEFT JOIN auth."user" u ON (cfg.user_id = u.id)
348
                 WHERE (u.login = ?)|;
349
  my $sth   = prepare_execute_query($main::form, $dbh, $query, $login);
350

  
351
  my %user_data;
352

  
353
  while (my $ref = $sth->fetchrow_hashref()) {
354
    $user_data{$ref->{cfg_key}} = $ref->{cfg_value};
355
    $user_data{login}           = $login;
356
  }
357

  
358
  $sth->finish();
359

  
360
  $main::lxdebug->leave_sub();
361

  
362
  return %user_data;
363
}
364

  
365
sub get_user_id {
366
  $main::lxdebug->enter_sub();
367

  
368
  my $self  = shift;
369
  my $login = shift;
370

  
371
  my $dbh   = $self->dbconnect();
372
  my ($id)  = selectrow_query($main::form, $dbh, qq|SELECT id FROM auth."user" WHERE login = ?|, $login);
373

  
374
  $main::lxdebug->leave_sub();
375

  
376
  return $id;
377
}
378

  
379
sub delete_user {
380
  $main::lxdebug->enter_sub();
381

  
382
  my $self  = shift;
383
  my $login = shift;
384

  
385
  my $form  = $main::form;
386

  
387
  my $dbh   = $self->dbconnect();
388
  my $query = qq|SELECT id FROM auth."user" WHERE login = ?|;
389

  
390
  my ($id)  = selectrow_query($form, $dbh, $query, $login);
391

  
392
  return $main::lxdebug->leave_sub() if (!$id);
393

  
394
  do_query($form, $dbh, qq|DELETE FROM auth.user_group WHERE user_id = ?|, $id);
395
  do_query($form, $dbh, qq|DELETE FROM auth.user_config WHERE user_id = ?|, $id);
396

  
397
  $dbh->commit();
398

  
399
  $main::lxdebug->leave_sub();
400
}
401

  
402
# --------------------------------------
403

  
404
my $session_id;
405

  
406
sub restore_session {
407
  $main::lxdebug->enter_sub();
408

  
409
  my $self = shift;
410

  
411
  my $cgi            =  $main::cgi;
412
  $cgi             ||=  CGI->new('');
413

  
414
  $session_id        =  $cgi->cookie($self->get_session_cookie_name());
415
  $session_id        =~ s|[^0-9a-f]||g;
416

  
417
  $self->{SESSION}   = { };
418

  
419
  return $main::lxdebug->leave_sub() if (!$session_id);
420

  
421
  my ($dbh, $query, $sth, $cookie, $ref, $form);
422

  
423
  $form   = $main::form;
424

  
425
  $dbh    = $self->dbconnect();
426
  $query  = qq|SELECT *, (mtime < (now() - '24h'::interval)) AS is_expired FROM auth.session WHERE id = ?|;
427

  
428
  $cookie = selectfirst_hashref_query($form, $dbh, $query, $session_id);
429

  
430
  if (!$cookie || $cookie->{is_expired} || ($cookie->{ip_address} ne $ENV{REMOTE_ADDR})) {
431
    $self->destroy_session();
432
    $main::lxdebug->leave_sub();
433
    return;
434
  }
435

  
436
  $query = qq|SELECT sess_key, sess_value FROM auth.session_content WHERE session_id = ?|;
437
  $sth   = prepare_execute_query($form, $dbh, $query, $session_id);
438

  
439
  while (my $ref = $sth->fetchrow_hashref()) {
440
    $self->{SESSION}->{$ref->{sess_key}} = $ref->{sess_value};
441
    $form->{$ref->{sess_key}}            = $ref->{sess_value} if (!defined $form->{$ref->{sess_key}});
442
  }
443

  
444
  $sth->finish();
445

  
446
  $main::lxdebug->leave_sub();
447
}
448

  
449
sub destroy_session {
450
  $main::lxdebug->enter_sub();
451

  
452
  my $self = shift;
453

  
454
  if ($session_id) {
455
    my $dbh = $self->dbconnect();
456

  
457
    do_query($main::form, $dbh, qq|DELETE FROM auth.session_content WHERE session_id = ?|, $session_id);
458
    do_query($main::form, $dbh, qq|DELETE FROM auth.session WHERE id = ?|, $session_id);
459

  
460
    $dbh->commit();
461

  
462
    $session_id      = undef;
463
    $self->{SESSION} = { };
464
  }
465

  
466
  $main::lxdebug->leave_sub();
467
}
468

  
469
sub expire_sessions {
470
  $main::lxdebug->enter_sub();
471

  
472
  my $self  = shift;
473

  
474
  my $dbh   = $self->dbconnect();
475
  my $query =
476
    qq|DELETE FROM auth.session_content
477
       WHERE session_id IN
478
         (SELECT id
479
          FROM auth.session
480
          WHERE (mtime < (now() - '24h'::interval)))|;
481

  
482
  do_query($main::form, $dbh, $query);
483

  
484
  $query =
485
    qq|DELETE FROM auth.session
486
       WHERE (mtime < (now() - '24h'::interval))|;
487

  
488
  do_query($main::form, $dbh, $query);
489

  
490
  $dbh->commit();
491

  
492
  $main::lxdebug->leave_sub();
493
}
494

  
495
sub _create_session_id {
496
  $main::lxdebug->enter_sub();
497

  
498
  my @secs = gettimeofday();
499
  srand $secs[1] + $$;
500

  
501
  my @data;
502
  map { push @data, int(rand() * 255); } (1..32);
503

  
504
  my $id = md5_hex(pack 'C*', @data);
505

  
506
  $main::lxdebug->leave_sub();
507

  
508
  return $id;
509
}
510

  
511
sub create_or_refresh_session {
512
  $main::lxdebug->enter_sub();
513

  
514
  my $self = shift;
515

  
516
  $session_id ||= $self->_create_session_id();
517

  
518
  my ($form, $dbh, $query, $sth, $id);
519

  
520
  $form  = $main::form;
521
  $dbh   = $self->dbconnect();
522

  
523
  $query = qq|SELECT id FROM auth.session WHERE id = ?|;
524

  
525
  ($id)  = selectrow_query($form, $dbh, $query, $session_id);
526

  
527
  if ($id) {
528
    do_query($form, $dbh, qq|UPDATE auth.session SET mtime = now() WHERE id = ?|, $session_id);
529
    do_query($form, $dbh, qq|DELETE FROM auth.session_content WHERE session_id = ?|, $session_id);
530

  
531
  } else {
532
    do_query($form, $dbh, qq|INSERT INTO auth.session (id, ip_address, mtime) VALUES (?, ?, now())|, $session_id, $ENV{REMOTE_ADDR});
533

  
534
  }
535

  
536
  $query = qq|INSERT INTO auth.session_content (session_id, sess_key, sess_value) VALUES (?, ?, ?)|;
537
  $sth   = prepare_query($form, $dbh, $query);
538

  
539
  foreach my $key (sort keys %{ $self->{SESSION} }) {
540
    do_statement($form, $sth, $query, $session_id, $key, $self->{SESSION}->{$key});
541
  }
542

  
543
  $sth->finish();
544
  $dbh->commit();
545

  
546
  $main::lxdebug->leave_sub();
547
}
548

  
549
sub set_session_value {
550
  $main::lxdebug->enter_sub();
551

  
552
  my $self  = shift;
553

  
554
  $self->{SESSION} ||= { };
555

  
556
  while (2 <= scalar @_) {
557
    my $key   = shift;
558
    my $value = shift;
559

  
560
    $self->{SESSION}->{$key} = $value;
561
  }
562

  
563
  $main::lxdebug->leave_sub();
564
}
565

  
566
sub set_cookie_environment_variable {
567
  my $self = shift;
568
  $ENV{HTTP_COOKIE} = $self->get_session_cookie_name() . "=${session_id}";
569
}
570

  
571
sub get_session_cookie_name {
572
  my $self = shift;
573

  
574
  return $self->{cookie_name} || 'lx_office_erp_session_id';
575
}
576

  
577
sub get_session_id {
578
  return $session_id;
579
}
580

  
581
sub session_tables_present {
582
  $main::lxdebug->enter_sub();
583

  
584
  my $self = shift;
585
  my $dbh  = $self->dbconnect(1);
586

  
587
  if (!$dbh) {
588
    $main::lxdebug->leave_sub();
589
    return 0;
590
  }
591

  
592
  my $query =
593
    qq|SELECT COUNT(*)
594
       FROM pg_tables
595
       WHERE (schemaname = 'auth')
596
         AND (tablename IN ('session', 'session_content'))|;
597

  
598
  my ($count) = selectrow_query($main::form, $dbh, $query);
599

  
600
  $main::lxdebug->leave_sub();
601

  
602
  return 2 == $count;
603
}
604

  
605
# --------------------------------------
606

  
607
sub all_rights_full {
608
  my $locale = $main::locale;
609

  
610
  my @all_rights = (
611
    ["--master_data",                  $locale->text("Master Data")],
612
    ["customer_vendor_edit",           $locale->text("Create and edit customers and vendors")],
613
    ["part_service_assembly_edit",     $locale->text("Create and edit parts, services, assemblies")],
614
    ["project_edit",                   $locale->text("Create and edit projects")],
615
    ["license_edit",                   $locale->text("Manage license keys")],
616
    ["--ar",                           $locale->text("AR")],
617
    ["sales_quotation_edit",           $locale->text("Create and edit sales quotations")],
618
    ["sales_order_edit",               $locale->text("Create and edit sales orders")],
619
    ["sales_delivery_order_edit",      $locale->text("Create and edit sales delivery orders")],
620
    ["invoice_edit",                   $locale->text("Create and edit invoices and credit notes")],
621
    ["dunning_edit",                   $locale->text("Create and edit dunnings")],
622
    ["--ap",                           $locale->text("AP")],
623
    ["request_quotation_edit",         $locale->text("Create and edit RFQs")],
624
    ["purchase_order_edit",            $locale->text("Create and edit purchase orders")],
625
    ["purchase_delivery_order_edit",   $locale->text("Create and edit purchase delivery orders")],
626
    ["vendor_invoice_edit",            $locale->text("Create and edit vendor invoices")],
627
    ["--general_ledger_cash",          $locale->text("General ledger and cash")],
628
    ["general_ledger",                 $locale->text("Transactions, AR transactions, AP transactions")],
629
    ["datev_export",                   $locale->text("DATEV Export")],
630
    ["cash",                           $locale->text("Receipt, payment, reconciliation")],
631
    ["--reports",                      $locale->text('Reports')],
632
    ["report",                         $locale->text('All reports')],
633
    ["advance_turnover_tax_return",    $locale->text('Advance turnover tax return')],
634
    ["--others",                       $locale->text("Others")],
635
    ["email_bcc",                      $locale->text("May set the BCC field when sending emails")],
636
    ["config",                         $locale->text("Change Lx-Office installation settings (all menu entries beneath 'System')")],
637
    );
638

  
639
  return @all_rights;
640
}
641

  
642
sub all_rights {
643
  return grep !/^--/, map { $_->[0] } all_rights_full();
644
}
645

  
646
sub read_groups {
647
  $main::lxdebug->enter_sub();
648

  
649
  my $self = shift;
650

  
651
  my $form   = $main::form;
652
  my $groups = {};
653
  my $dbh    = $self->dbconnect();
654

  
655
  my $query  = 'SELECT * FROM auth."group"';
656
  my $sth    = prepare_execute_query($form, $dbh, $query);
657

  
658
  my ($row, $group);
659

  
660
  while ($row = $sth->fetchrow_hashref()) {
661
    $groups->{$row->{id}} = $row;
662
  }
663
  $sth->finish();
664

  
665
  $query = 'SELECT * FROM auth.user_group WHERE group_id = ?';
666
  $sth   = prepare_query($form, $dbh, $query);
667

  
668
  foreach $group (values %{$groups}) {
669
    $group->{members} = [];
670

  
671
    do_statement($form, $sth, $query, $group->{id});
672

  
673
    while ($row = $sth->fetchrow_hashref()) {
674
      push @{$group->{members}}, $row->{user_id};
675
    }
676
  }
677
  $sth->finish();
678

  
679
  $query = 'SELECT * FROM auth.group_rights WHERE group_id = ?';
680
  $sth   = prepare_query($form, $dbh, $query);
681

  
682
  foreach $group (values %{$groups}) {
683
    $group->{rights} = {};
684

  
685
    do_statement($form, $sth, $query, $group->{id});
686

  
687
    while ($row = $sth->fetchrow_hashref()) {
688
      $group->{rights}->{$row->{right}} |= $row->{granted};
689
    }
690

  
691
    map { $group->{rights}->{$_} = 0 if (!defined $group->{rights}->{$_}); } all_rights();
692
  }
693
  $sth->finish();
694

  
695
  $main::lxdebug->leave_sub();
696

  
697
  return $groups;
698
}
699

  
700
sub save_group {
701
  $main::lxdebug->enter_sub();
702

  
703
  my $self  = shift;
704
  my $group = shift;
705

  
706
  my $form  = $main::form;
707
  my $dbh   = $self->dbconnect();
708

  
709
  my ($query, $sth, $row, $rights);
710

  
711
  if (!$group->{id}) {
712
    ($group->{id}) = selectrow_query($form, $dbh, qq|SELECT nextval('auth.group_id_seq')|);
713

  
714
    $query = qq|INSERT INTO auth."group" (id, name, description) VALUES (?, '', '')|;
715
    do_query($form, $dbh, $query, $group->{id});
716
  }
717

  
718
  do_query($form, $dbh, qq|UPDATE auth."group" SET name = ?, description = ? WHERE id = ?|, map { $group->{$_} } qw(name description id));
719

  
720
  do_query($form, $dbh, qq|DELETE FROM auth.user_group WHERE group_id = ?|, $group->{id});
721

  
722
  $query  = qq|INSERT INTO auth.user_group (user_id, group_id) VALUES (?, ?)|;
723
  $sth    = prepare_query($form, $dbh, $query);
724

  
725
  foreach my $user_id (@{ $group->{members} }) {
726
    do_statement($form, $sth, $query, $user_id, $group->{id});
727
  }
728
  $sth->finish();
729

  
730
  do_query($form, $dbh, qq|DELETE FROM auth.group_rights WHERE group_id = ?|, $group->{id});
731

  
732
  $query = qq|INSERT INTO auth.group_rights (group_id, "right", granted) VALUES (?, ?, ?)|;
733
  $sth   = prepare_query($form, $dbh, $query);
734

  
735
  foreach my $right (keys %{ $group->{rights} }) {
736
    do_statement($form, $sth, $query, $group->{id}, $right, $group->{rights}->{$right} ? 't' : 'f');
737
  }
738
  $sth->finish();
739

  
740
  $dbh->commit();
741

  
742
  $main::lxdebug->leave_sub();
743
}
744

  
745
sub delete_group {
746
  $main::lxdebug->enter_sub();
747

  
748
  my $self = shift;
749
  my $id   = shift;
750

  
751
  my $form = $main::from;
752

  
753
  my $dbh  = $self->dbconnect();
754

  
755
  do_query($form, $dbh, qq|DELETE FROM auth.user_group WHERE group_id = ?|, $id);
756
  do_query($form, $dbh, qq|DELETE FROM auth.group_rights WHERE group_id = ?|, $id);
757
  do_query($form, $dbh, qq|DELETE FROM auth."group" WHERE id = ?|, $id);
758

  
759
  $dbh->commit();
760

  
761
  $main::lxdebug->leave_sub();
762
}
763

  
764
sub evaluate_rights_ary {
765
  $main::lxdebug->enter_sub(2);
766

  
767
  my $ary    = shift;
768

  
769
  my $value  = 0;
770
  my $action = '|';
771

  
772
  foreach my $el (@{$ary}) {
773
    if (ref $el eq "ARRAY") {
774
      if ($action eq '|') {
775
        $value |= evaluate_rights_ary($el);
776
      } else {
777
        $value &= evaluate_rights_ary($el);
778
      }
779

  
780
    } elsif (($el eq '&') || ($el eq '|')) {
781
      $action = $el;
782

  
783
    } elsif ($action eq '|') {
784
      $value |= $el;
785

  
786
    } else {
787
      $value &= $el;
788

  
789
    }
790
  }
791

  
792
  $main::lxdebug->enter_sub(2);
793

  
794
  return $value;
795
}
796

  
797
sub _parse_rights_string {
798
  $main::lxdebug->enter_sub(2);
799

  
800
  my $self   = shift;
801

  
802
  my $login  = shift;
803
  my $access = shift;
804

  
805
  my @stack;
806
  my $cur_ary = [];
807

  
808
  push @stack, $cur_ary;
809

  
810
  while ($access =~ m/^([a-z_0-9]+|\||\&|\(|\)|\s+)/) {
811
    my $token = $1;
812
    substr($access, 0, length $1) = "";
813

  
814
    next if ($token =~ /\s/);
815

  
816
    if ($token eq "(") {
817
      my $new_cur_ary = [];
818
      push @stack, $new_cur_ary;
819
      push @{$cur_ary}, $new_cur_ary;
820
      $cur_ary = $new_cur_ary;
821

  
822
    } elsif ($token eq ")") {
823
      pop @stack;
824

  
825
      if (!@stack) {
826
        $main::lxdebug->enter_sub(2);
827
        return 0;
828
      }
829

  
830
      $cur_ary = $stack[-1];
831

  
832
    } elsif (($token eq "|") || ($token eq "&")) {
833
      push @{$cur_ary}, $token;
834

  
835
    } else {
836
      push @{$cur_ary}, $self->{RIGHTS}->{$login}->{$token} * 1;
837
    }
838
  }
839

  
840
  my $result = ($access || (1 < scalar @stack)) ? 0 : evaluate_rights_ary($stack[0]);
841

  
842
  $main::lxdebug->enter_sub(2);
843

  
844
  return $result;
845
}
846

  
847
sub check_right {
848
  $main::lxdebug->enter_sub(2);
849

  
850
  my $self    = shift;
851
  my $login   = shift;
852
  my $right   = shift;
853
  my $default = shift;
854

  
855
  $self->{FULL_RIGHTS}           ||= { };
856
  $self->{FULL_RIGHTS}->{$login} ||= { };
857

  
858
  if (!defined $self->{FULL_RIGHTS}->{$login}->{$right}) {
859
    $self->{RIGHTS}           ||= { };
860
    $self->{RIGHTS}->{$login} ||= $self->load_rights_for_user($login);
861

  
862
    $self->{FULL_RIGHTS}->{$login}->{$right} = $self->_parse_rights_string($login, $right);
863
  }
864

  
865
  my $granted = $self->{FULL_RIGHTS}->{$login}->{$right};
866
  $granted    = $default if (!defined $granted);
867

  
868
  $main::lxdebug->leave_sub(2);
869

  
870
  return $granted;
871
}
872

  
873
sub assert {
874
  $main::lxdebug->enter_sub(2);
875

  
876
  my $self       = shift;
877
  my $right      = shift;
878
  my $dont_abort = shift;
879

  
880
  my $form       = $main::form;
881

  
882
  if ($self->check_right($form->{login}, $right)) {
883
    $main::lxdebug->leave_sub(2);
884
    return 1;
885
  }
886

  
887
  if (!$dont_abort) {
888
    delete $form->{title};
889
    $form->show_generic_error($main::locale->text("You do not have the permissions to access this function."));
890
  }
891

  
892
  $main::lxdebug->leave_sub(2);
893

  
894
  return 0;
895
}
896

  
897
sub load_rights_for_user {
898
  $main::lxdebug->enter_sub();
899

  
900
  my $self  = shift;
901
  my $login = shift;
902

  
903
  my $form  = $main::form;
904
  my $dbh   = $self->dbconnect();
905

  
906
  my ($query, $sth, $row, $rights);
907

  
908
  $rights = {};
909

  
910
  $query =
911
    qq|SELECT gr."right", gr.granted
912
       FROM auth.group_rights gr
913
       WHERE group_id IN
914
         (SELECT ug.group_id
915
          FROM auth.user_group ug
916
          LEFT JOIN auth."user" u ON (ug.user_id = u.id)
917
          WHERE u.login = ?)|;
918

  
919
  $sth = prepare_execute_query($form, $dbh, $query, $login);
920

  
921
  while ($row = $sth->fetchrow_hashref()) {
922
    $rights->{$row->{right}} |= $row->{granted};
923
  }
924
  $sth->finish();
925

  
926
  map({ $rights->{$_} = 0 unless (defined $rights->{$_}); } SL::Auth::all_rights());
927

  
928
  $main::lxdebug->leave_sub();
929

  
930
  return $rights;
931
}
932

  
933
1;
SL/Auth/DB.pm
1
package SL::Auth::DB;
2

  
3
use DBI;
4

  
5
use SL::Auth;
6
use SL::DBUtils;
7

  
8
sub new {
9
  $main::lxdebug->enter_sub();
10

  
11
  my $type = shift;
12
  my $self = {};
13

  
14
  $self->{auth} = shift;
15

  
16
  bless $self, $type;
17

  
18
  $main::lxdebug->leave_sub();
19

  
20
  return $self;
21
}
22

  
23
sub authenticate {
24
  $main::lxdebug->enter_sub();
25

  
26
  my $self       = shift;
27
  my $login      = shift;
28
  my $password   = shift;
29
  my $is_crypted = shift;
30

  
31
  my $dbh        = $self->{auth}->dbconnect();
32

  
33
  if (!$dbh) {
34
    $main::lxdebug->leave_sub();
35
    return SL::Auth::ERR_BACKEND;
36
  }
37

  
38
  my $query             = qq|SELECT password FROM auth."user" WHERE login = ?|;
39
  my ($stored_password) = $dbh->selectrow_array($query, undef, $login);
40

  
41
  $password        = crypt $password, substr($login, 0, 2)        if (!$password || !$is_crypted);
42
  $stored_password = crypt $stored_password, substr($login, 0, 2) if (!$stored_password);
43

  
44
  $main::lxdebug->leave_sub();
45

  
46
  return $password eq $stored_password ? SL::Auth::OK : SL::Auth::ERR_PASSWORD;
47
}
48

  
49
sub can_change_password {
50
  return 1;
51
}
52

  
53
sub change_password {
54
  $main::lxdebug->enter_sub();
55

  
56
  my $self       = shift;
57
  my $login      = shift;
58
  my $password   = shift;
59
  my $is_crypted = shift;
60

  
61
  my $dbh        = $self->{auth}->dbconnect();
62

  
63
  if (!$dbh) {
64
    $main::lxdebug->leave_sub();
65
    return SL::Auth::ERR_BACKEND
66
  }
67

  
68
  $password = crypt $password, substr($login, 0, 2) if (!$is_crypted);
69

  
70
  do_query($main::form, $dbh, qq|UPDATE auth."user" SET password = ? WHERE login = ?|, $password, $login);
71

  
72
  $dbh->commit();
73

  
74
  $main::lxdebug->leave_sub();
75

  
76
  return 1;
77
}
78

  
79
sub verify_config {
80
  return 1;
81
}
82

  
83
1;
SL/Auth/LDAP.pm
1
package SL::Auth::LDAP;
2

  
3
use English '-no_match_vars';
4

  
5
use SL::Auth;
6

  
7
sub new {
8
  $main::lxdebug->enter_sub();
9

  
10
  if (!defined eval "require Net::LDAP;") {
11
    die 'The module "Net::LDAP" is not installed.';
12
  }
13

  
14
  my $type = shift;
15
  my $self = {};
16

  
17
  $self->{auth} = shift;
18

  
19
  bless $self, $type;
20

  
21
  $main::lxdebug->leave_sub();
22

  
23
  return $self;
24
}
25

  
26
sub _connect {
27
  $main::lxdebug->enter_sub();
28

  
29
  my $self = shift;
30
  my $cfg  = $self->{auth}->{LDAP_config};
31

  
32
  if ($self->{ldap}) {
33
    $main::lxdebug->leave_sub();
34

  
35
    return $self->{ldap};
36
  }
37

  
38
  my $port      = $cfg->{port} || 389;
39
  $self->{ldap} = Net::LDAP->new($cfg->{host}, 'port' => $port);
40

  
41
  if (!$self->{ldap}) {
42
    $main::form->error($main::locale->text('The LDAP server "#1:#2" is unreachable. Please check config/authentication.pl.', $cfg->{host}, $port));
43
  }
44

  
45
  if ($cfg->{tls}) {
46
    my $mesg = $self->{ldap}->start_tls('verify' => 'none');
47
    if ($mesg->is_error()) {
48
      $main::form->error($main::locale->text('The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/authentication.pl.'));
49
    }
50
  }
51

  
52
  if ($cfg->{bind_dn}) {
53
    my $mesg = $self->{ldap}->bind($cfg->{bind_dn}, 'password' => $cfg->{bind_password});
54
    if ($mesg->is_error()) {
55
      $main::form->error($main::locale->text('Binding to the LDAP server as "#1" failed. Please check config/authentication.pl.', $cfg->{bind_dn}));
56
    }
57
  }
58

  
59
  $main::lxdebug->leave_sub();
60

  
61
  return $self->{ldap};
62
}
63

  
64
sub _get_filter {
65
  $main::lxdebug->enter_sub();
66

  
67
  my $self   = shift;
68
  my $login  = shift;
69

  
70
  my ($cfg, $filter);
71

  
72
  $cfg    =  $self->{auth}->{LDAP_config};
73

  
74
  $filter =  "$cfg->{filter}";
75
  $filter =~ s|^\s+||;
76
  $filter =~ s|\s+$||;
77

  
78
  $login  =~ s|\\|\\\\|g;
79
  $login  =~ s|\(|\\\(|g;
80
  $login  =~ s|\)|\\\)|g;
81
  $login  =~ s|\*|\\\*|g;
82
  $login  =~ s|\x00|\\00|g;
83

  
84
  if ($filter =~ m|<\%login\%>|) {
85
    substr($filter, $LAST_MATCH_START[0], $LAST_MATCH_END[0] - $LAST_MATCH_START[0]) = $login;
86

  
87
  } elsif ($filter) {
88
    if ((substr($filter, 0, 1) ne '(') || (substr($filter, -1, 1) ne ')')) {
89
      $filter = "($filter)";
90
    }
91

  
92
    $filter = "(&${filter}($cfg->{attribute}=${login}))";
93

  
94
  } else {
95
    $filter = "$cfg->{attribute}=${login}";
96

  
97
  }
98

  
99
  $main::lxdebug->leave_sub();
100

  
101
  return $filter;
102
}
103

  
104
sub _get_user_dn {
105
  $main::lxdebug->enter_sub();
106

  
107
  my $self   = shift;
108
  my $ldap   = shift;
109
  my $login  = shift;
110

  
111
  $self->{dn_cache} ||= { };
112

  
113
  if ($self->{dn_cache}->{$login}) {
114
    $main::lxdebug->leave_sub();
115
    return $self->{dn_cache}->{$login};
116
  }
117

  
118
  my $cfg    = $self->{auth}->{LDAP_config};
119

  
120
  my $filter = $self->_get_filter($login);
121

  
122
  my $mesg   = $ldap->search('base' => $cfg->{base_dn}, 'scope' => 'sub', 'filter' => $filter);
123

  
124
  if ($mesg->is_error() || (0 == $mesg->count())) {
125
    $main::lxdebug->leave_sub();
126
    return undef;
127
  }
128

  
129
  my $entry                   = $mesg->entry(0);
130
  $self->{dn_cache}->{$login} = $entry->dn();
131

  
132
  $main::lxdebug->leave_sub();
133

  
134
  return $self->{dn_cache}->{$login};
135
}
136

  
137
sub authenticate {
138
  $main::lxdebug->enter_sub();
139

  
140
  my $self       = shift;
141
  my $login      = shift;
142
  my $password   = shift;
143
  my $is_crypted = shift;
144

  
145
  if ($is_crypted) {
146
    $main::lxdebug->leave_sub();
147
    return SL::Auth::ERR_BACKEND;
148
  }
149

  
150
  my $ldap = $self->_connect();
151

  
152
  if (!$ldap) {
153
    $main::lxdebug->leave_sub();
154
    return SL::Auth::ERR_BACKEND;
155
  }
156

  
157
  my $dn = $self->_get_user_dn($ldap, $login);
158

  
159
  $main::lxdebug->message(LXDebug::DEBUG2, "LDAP authenticate: dn $dn");
160

  
161
  if (!$dn) {
162
    $main::lxdebug->leave_sub();
163
    return SL::Auth::ERR_BACKEND;
164
  }
165

  
166
  my $mesg = $ldap->bind($dn, 'password' => $password);
167

  
168
  $main::lxdebug->message(LXDebug::DEBUG2, "LDAP authenticate: bind mesg " . $mesg->error());
169

  
170
  $main::lxdebug->leave_sub();
171

  
172
  return $mesg->is_error() ? SL::Auth::ERR_PASSWORD : SL::Auth::OK;
173
}
174

  
175
sub can_change_password {
176
  return 0;
177
}
178

  
179
sub change_password {
180
  return SL::Auth::ERR_BACKEND;
181
}
182

  
183
sub verify_config {
184
  $main::lxdebug->enter_sub();
185

  
186
  my $self = shift;
187
  my $cfg  = $self->{auth}->{LDAP_config};
188

  
189
  if (!$cfg) {
190
    $form->error($locale->text('config/authentication.pl: Key "LDAP_config" is missing.'));
191
  }
192

  
193
  if (!$cfg->{host} || !$cfg->{attribute} || !$cfg->{base_dn}) {
194
    $form->error($locale->text('config/authentication.pl: Missing parameters in "LDAP_config". Required parameters are "host", "attribute" and "base_dn".'));
195
  }
196

  
197
  $main::lxdebug->leave_sub();
198
}
199

  
200
1;
SL/Common.pm
29 29
);
30 30

  
31 31
%db_encoding_to_charset = map { $_->{dbencoding}, $_->{charset} } @db_encodings;
32
%charset_to_db_encoding = map { $_->{charset}, $_->{dbencoding} } @db_encodings;
32 33

  
33 34
use constant DEFAULT_CHARSET => 'ISO-8859-15';
34 35

  
......
49 50
  my $dbh = $form->dbconnect($myconfig);
50 51

  
51 52
  my (@filter_values, $filter);
52
  if ($form->{"partnumber"}) {
53
    $filter .= qq| AND (partnumber ILIKE ?)|;
54
    push(@filter_values, '%' . $form->{"partnumber"} . '%');
53

  
54
  foreach (qw(partnumber description)) {
55
    next unless $form->{$_};
56

  
57
    $filter .= qq| AND ($_ ILIKE ?)|;
58
    push @filter_values, '%' . $form->{$_} . '%';
55 59
  }
56
  if ($form->{"description"}) {
57
    $filter .= qq| AND (description ILIKE ?)|;
58
    push(@filter_values, '%' . $form->{"description"} . '%');
60

  
61
  if ($form->{no_assemblies}) {
62
    $filter .= qq| AND (NOT COALESCE(assembly, 'f'))|;
63
  }
64

  
65
  if ($form->{no_services}) {
66
    $filter .= qq| AND (COALESCE(inventory_accno_id, 0) > 0)|;
59 67
  }
68

  
60 69
  substr($filter, 1, 3) = "WHERE" if ($filter);
61 70

  
62 71
  $order_by =~ s/[^a-zA-Z_]//g;
SL/DBUtils.pm
7 7
             dump_query quote_db_date
8 8
             selectfirst_hashref_query selectfirst_array_query
9 9
             selectall_hashref_query selectall_array_query
10
             selectall_as_map
10 11
             prepare_execute_query prepare_query);
11 12

  
12 13
sub conv_i {
......
194 195
  return @ret;
195 196
}
196 197

  
198
sub selectall_as_map {
199
  $main::lxdebug->enter_sub(2);
200

  
201
  my ($form, $dbh, $query, $key_col, $value_col) = splice(@_, 0, 5);
202

  
203
  my $sth = prepare_execute_query($form, $dbh, $query, @_);
204

  
205
  my %hash;
206
  if ('' eq ref $value_col) {
207
    while (my $ref = $sth->fetchrow_hashref()) {
208
      $hash{$ref->{$key_col}} = $ref->{$value_col};
209
    }
210
  } else {
211
    while (my $ref = $sth->fetchrow_hashref()) {
212
      $hash{$ref->{$key_col}} = { map { $_ => $ref->{$_} } @{ $value_col } };
213
    }
214
  }
215

  
216
  $sth->finish();
217

  
218
  $main::lxdebug->leave_sub(2);
219

  
220
  return %hash;
221
}
222

  
197 223
1;
198 224

  
199 225

  
......
304 330

  
305 331
Prepares and executes a query using DBUtils functions, retireves all data from the database, and returns it in hashref mode. This is slightly confusing, as the data structure will actually be a reference to an array, containing hashrefs for each row.
306 332

  
... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen überschreitet.

Auch abrufbar als: Unified diff