Merge branch 'master' of git@lx-office.linet-services.de:lx-office-erp
[kivitendo-erp.git] / SL / Auth.pm
index eb5a780..f2d15a8 100644 (file)
@@ -6,12 +6,14 @@ use Digest::MD5 qw(md5_hex);
 use IO::File;
 use Time::HiRes qw(gettimeofday);
 use List::MoreUtils qw(uniq);
+use YAML;
 
 use SL::Auth::Constants qw(:all);
 use SL::Auth::DB;
 use SL::Auth::LDAP;
 
 use SL::User;
+use SL::DBUpgrade2;
 use SL::DBUtils;
 
 use strict;
@@ -59,19 +61,31 @@ sub DESTROY {
   $self->{dbh}->disconnect() if ($self->{dbh});
 }
 
+# form isn't loaded yet, so auth needs it's own error.
+sub mini_error {
+  $::lxdebug->show_backtrace();
+
+  my ($self, @msg) = @_;
+  if ($ENV{HTTP_USER_AGENT}) {
+    print Form->create_http_response(content_type => 'text/html');
+    print "<pre>", join ('<br>', @msg), "</pre>";
+  } else {
+    print STDERR "Error: @msg\n";
+  }
+  ::end_of_request();
+}
+
 sub _read_auth_config {
   $main::lxdebug->enter_sub();
 
   my $self   = shift;
 
-  my $form   = $main::form;
-  my $locale = $main::locale;
-
   my $code;
   my $in = IO::File->new('config/authentication.pl', 'r');
 
   if (!$in) {
-    $form->error($locale->text('The config file "config/authentication.pl" was not found.'));
+    my $locale = Locale->new('en');
+    $self->mini_error($locale->text('The config file "config/authentication.pl" was not found.'));
   }
 
   while (<$in>) {
@@ -82,7 +96,8 @@ sub _read_auth_config {
   eval $code;
 
   if ($@) {
-    $form->error($locale->text('The config file "config/authentication.pl" contained invalid Perl code:') . "\n" . $@);
+    my $locale = Locale->new('en');
+    $self->mini_error($locale->text('The config file "config/authentication.pl" contained invalid Perl code:'), $@);
   }
 
   if ($self->{module} eq 'DB') {
@@ -93,17 +108,20 @@ sub _read_auth_config {
   }
 
   if (!$self->{authenticator}) {
-    $form->error($locale->text('No or an unknown authenticantion module specified in "config/authentication.pl".'));
+    my $locale = Locale->new('en');
+    $self->mini_error($locale->text('No or an unknown authenticantion module specified in "config/authentication.pl".'));
   }
 
   my $cfg = $self->{DB_config};
 
   if (!$cfg) {
-    $form->error($locale->text('config/authentication.pl: Key "DB_config" is missing.'));
+    my $locale = Locale->new('en');
+    $self->mini_error($locale->text('config/authentication.pl: Key "DB_config" is missing.'));
   }
 
   if (!$cfg->{host} || !$cfg->{db} || !$cfg->{user}) {
-    $form->error($locale->text('config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".'));
+    my $locale = Locale->new('en');
+    $self->mini_error($locale->text('config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".'));
   }
 
   $self->{authenticator}->verify_config();
@@ -126,7 +144,9 @@ sub authenticate_root {
 
   $main::lxdebug->leave_sub();
 
-  return $password eq $admin_password ? OK : ERR_PASSWORD;
+  return OK if $password eq $admin_password;
+  sleep 5;
+  return ERR_PASSWORD;
 }
 
 sub authenticate {
@@ -136,7 +156,10 @@ sub authenticate {
 
   $main::lxdebug->leave_sub();
 
-  return $self->{authenticator}->authenticate(@_);
+  my $result = $self->{authenticator}->authenticate(@_);
+  return OK if $result eq OK;
+  sleep 5;
+  return $result;
 }
 
 sub dbconnect {
@@ -165,7 +188,7 @@ sub dbconnect {
     $main::form->error($main::locale->text('The connection to the authentication database failed:') . "\n" . $DBI::errstr);
   }
 
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return $self->{dbh};
 }
@@ -234,7 +257,7 @@ sub create_database {
 
   $main::lxdebug->message(LXDebug->DEBUG1(), "Auth::create_database DSN: $dsn");
 
-  my $charset    = $main::dbcharset;
+  my $charset    = $::lx_office_conf{system}->{dbcharset};
   $charset     ||= Common::DEFAULT_CHARSET;
   my $encoding   = $Common::charset_to_db_encoding{$charset};
   $encoding    ||= 'UNICODE';
@@ -277,11 +300,11 @@ sub create_tables {
   my $self = shift;
   my $dbh  = $self->dbconnect();
 
-  my $charset    = $main::dbcharset;
+  my $charset    = $::lx_office_conf{system}->{dbcharset};
   $charset     ||= Common::DEFAULT_CHARSET;
 
   $dbh->rollback();
-  User->process_query($main::form, $dbh, 'sql/auth_db.sql', undef, $charset);
+  SL::DBUpgrade2->new(form => $::form)->process_query($dbh, 'sql/auth_db.sql', undef, $charset);
 
   $main::lxdebug->leave_sub();
 }
@@ -467,7 +490,7 @@ sub restore_session {
   if (!$cookie || $cookie->{is_expired} || ($cookie->{ip_address} ne $ENV{REMOTE_ADDR})) {
     $self->destroy_session();
     $main::lxdebug->leave_sub();
-    return SESSION_EXPIRED;
+    return $cookie ? SESSION_EXPIRED : SESSION_NONE;
   }
 
   $query = qq|SELECT sess_key, sess_value FROM auth.session_content WHERE session_id = ?|;
@@ -475,7 +498,7 @@ sub restore_session {
 
   while (my $ref = $sth->fetchrow_hashref()) {
     $self->{SESSION}->{$ref->{sess_key}} = $ref->{sess_value};
-    $form->{$ref->{sess_key}}            = $ref->{sess_value} if (!defined $form->{$ref->{sess_key}});
+    $form->{$ref->{sess_key}}            = $self->_load_value($ref->{sess_value}) if (!defined $form->{$ref->{sess_key}});
   }
 
   $sth->finish();
@@ -485,6 +508,18 @@ sub restore_session {
   return SESSION_OK;
 }
 
+sub _load_value {
+  return $_[1] if $_[1] !~ m/^---/;
+
+  my $value;
+  eval {
+    $value = YAML::Load($_[1]);
+    1;
+  } or return $_[1];
+
+  return $value;
+}
+
 sub destroy_session {
   $main::lxdebug->enter_sub();
 
@@ -562,41 +597,80 @@ sub create_or_refresh_session {
 
   if ($id) {
     do_query($form, $dbh, qq|UPDATE auth.session SET mtime = now() WHERE id = ?|, $session_id);
-    do_query($form, $dbh, qq|DELETE FROM auth.session_content WHERE session_id = ?|, $session_id);
 
   } else {
     do_query($form, $dbh, qq|INSERT INTO auth.session (id, ip_address, mtime) VALUES (?, ?, now())|, $session_id, $ENV{REMOTE_ADDR});
 
   }
 
-  $query = qq|INSERT INTO auth.session_content (session_id, sess_key, sess_value) VALUES (?, ?, ?)|;
-  $sth   = prepare_query($form, $dbh, $query);
+  $self->save_session($dbh);
 
-  foreach my $key (sort keys %{ $self->{SESSION} }) {
-    do_statement($form, $sth, $query, $session_id, $key, $self->{SESSION}->{$key});
-  }
-
-  $sth->finish();
   $dbh->commit();
 
   $main::lxdebug->leave_sub();
 }
 
+sub save_session {
+  my $self         = shift;
+  my $provided_dbh = shift;
+
+  my $dbh          = $provided_dbh || $self->dbconnect();
+
+  do_query($::form, $dbh, qq|DELETE FROM auth.session_content WHERE session_id = ?|, $session_id);
+
+  if (%{ $self->{SESSION} }) {
+    my $query = qq|INSERT INTO auth.session_content (session_id, sess_key, sess_value) VALUES (?, ?, ?)|;
+    my $sth   = prepare_query($::form, $dbh, $query);
+
+    foreach my $key (sort keys %{ $self->{SESSION} }) {
+      do_statement($::form, $sth, $query, $session_id, $key, $self->{SESSION}->{$key});
+    }
+
+    $sth->finish();
+  }
+
+  $dbh->commit() unless $provided_dbh;
+}
+
 sub set_session_value {
   $main::lxdebug->enter_sub();
 
-  my $self  = shift;
+  my $self   = shift;
+  my %params = @_;
 
   $self->{SESSION} ||= { };
 
-  while (2 <= scalar @_) {
-    my $key   = shift;
-    my $value = shift;
-
-    $self->{SESSION}->{$key} = $value;
+  while (my ($key, $value) = each %params) {
+    $self->{SESSION}->{ $key } = YAML::Dump($value);
   }
 
   $main::lxdebug->leave_sub();
+
+  return $self;
+}
+
+sub delete_session_value {
+  $main::lxdebug->enter_sub();
+
+  my $self = shift;
+
+  $self->{SESSION} ||= { };
+  delete @{ $self->{SESSION} }{ @_ };
+
+  $main::lxdebug->leave_sub();
+
+  return $self;
+}
+
+sub get_session_value {
+  $main::lxdebug->enter_sub();
+
+  my $self  = shift;
+  my $value = $self->{SESSION} ? $self->_load_value($self->{SESSION}->{ $_[0] }) : undef;
+
+  $main::lxdebug->leave_sub();
+
+  return $value;
 }
 
 sub set_cookie_environment_variable {
@@ -685,6 +759,8 @@ sub all_rights_full {
     ["--reports",                      $locale->text('Reports')],
     ["report",                         $locale->text('All reports')],
     ["advance_turnover_tax_return",    $locale->text('Advance turnover tax return')],
+    ["--batch_printing",               $locale->text("Batch Printing")],
+    ["batch_printing",                 $locale->text("Batch Printing")],
     ["--others",                       $locale->text("Others")],
     ["email_bcc",                      $locale->text("May set the BCC field when sending emails")],
     ["config",                         $locale->text("Change Lx-Office installation settings (all menu entries beneath 'System')")],