commit a4c8924a3a105f8b4ba750a5911ed0099f9bb4bc
Author: Bernd Bleßmann <bernd@kivitendo-premium.de>
Date:   Mon Oct 7 15:30:11 2019 +0200

    Login: Callback setzen und berücksichtigen, wenn abgemeldet
    
    Wenn ein Ziel innerhalb des Programms aufgerufen wird (z.B. aus einem
    Link, den man zugschickt bekommt) und man nicht eingeloggt ist, so
    wird man zu dem Ziel weitergeleitet, nachdem man sich eingeloggt hat.

diff --git a/SL/Controller/LoginScreen.pm b/SL/Controller/LoginScreen.pm
index 6d59a9933..59fabb245 100644
--- a/SL/Controller/LoginScreen.pm
+++ b/SL/Controller/LoginScreen.pm
@@ -58,7 +58,7 @@ sub action_login {
 
   %::myconfig      = $login ? $::auth->read_user(login => $login) : ();
   $::locale        = Locale->new($::myconfig{countrycode}) if $::myconfig{countrycode};
-  my $auth_result  = SL::Dispatcher::AuthHandler::User->new->handle;
+  my $auth_result  = SL::Dispatcher::AuthHandler::User->new->handle(callback => $::form->{callback});
 
   $::dispatcher->end_request unless $auth_result;
 
@@ -181,7 +181,7 @@ sub init_default_client_id {
 sub show_login_form {
   my ($self, %params) = @_;
 
-  $self->render('login_screen/user_login', %params, version => SL::Version->get_version );
+  $self->render('login_screen/user_login', %params, version => SL::Version->get_version, callback => $::form->{callback});
 }
 
 1;
diff --git a/SL/Dispatcher.pm b/SL/Dispatcher.pm
index 4efcdf692..af9bdc052 100644
--- a/SL/Dispatcher.pm
+++ b/SL/Dispatcher.pm
@@ -30,6 +30,7 @@ use SL::Common;
 use SL::Form;
 use SL::Helper::DateTime;
 use SL::InstanceConfiguration;
+use SL::MoreCommon qw(uri_encode);
 use SL::Template::Plugin::HTMLFixes;
 use SL::User;
 
@@ -291,8 +292,11 @@ sub handle_request {
     if (   (($script eq 'login') && !$action)
         || ($script eq 'admin')
         || (SL::Auth::SESSION_EXPIRED() == $session_result)) {
-      $self->handle_login_error(script => $script, error => 'session');
-
+      $self->handle_login_error(routing_type => $routing_type,
+                                script       => $script,
+                                controller   => $script_name,
+                                action       => $action,
+                                error        => 'session');
     }
 
     my %auth_result = $self->{auth_handler}->handle(
@@ -393,7 +397,19 @@ sub handle_login_error {
   my $action          = ($params{script} // '') =~ m/^admin/i ? 'Admin/login' : 'LoginScreen/user_login';
   $action            .= '&error=' . $params{error} if $params{error};
 
-  print $::request->cgi->redirect("controller.pl?action=${action}");
+  my $redirect_url = "controller.pl?action=${action}";
+
+  if ($action =~ m/LoginScreen\/user_login/) {
+    require SL::Controller::Base;
+    my $controller = SL::Controller::Base->new;
+
+    delete $params{error};
+    delete @{ $::form }{ grep { m/^\{AUTH\}/ } keys %{ $::form } };
+    my $callback   = $controller->url_for(%params, %{$::form});
+    $redirect_url .= '&callback=' . uri_encode($callback);
+  }
+
+  print $::request->cgi->redirect($redirect_url);
   $self->end_request;
 }
 
diff --git a/SL/Dispatcher/AuthHandler/User.pm b/SL/Dispatcher/AuthHandler/User.pm
index 3748dc110..bd3d29e21 100644
--- a/SL/Dispatcher/AuthHandler/User.pm
+++ b/SL/Dispatcher/AuthHandler/User.pm
@@ -43,10 +43,10 @@ sub handle {
 }
 
 sub _error {
-  my $self = shift;
+  my ($self, %param) = @_;
 
   $::auth->punish_wrong_login;
-  $::dispatcher->handle_login_error(error => 'password');
+  $::dispatcher->handle_login_error(%param, error => 'password');
 
   return 0;
 }
diff --git a/templates/webpages/login_screen/user_login.html b/templates/webpages/login_screen/user_login.html
index 7ae4c2b7b..20c63f1e7 100644
--- a/templates/webpages/login_screen/user_login.html
+++ b/templates/webpages/login_screen/user_login.html
@@ -24,6 +24,7 @@
       <form method="post" name="loginscreen" action="controller.pl" target="_top">
 
        <input type="hidden" name="show_dbupdate_warning" value="1">
+       [% L.hidden_tag("callback", callback) %]
 
        <table width="100%">
         <tr>
