Dispatcher: Requests auf controller.pl ohne action auf Loginseite redirecten
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 12 Jun 2014 07:07:31 +0000 (09:07 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 12 Jun 2014 07:18:16 +0000 (09:18 +0200)
Ist hilfreich, wenn man aus der Browserhistory einen Link wie
http://…/kivitendo/controller.pl aufruft. Bisher wurde nur eine böse
Fehlerseite angezeigt.

SL/Controller/LoginScreen.pm
SL/Dispatcher.pm
locale/de/all

index adf8b47..d38736b 100644 (file)
@@ -155,6 +155,7 @@ sub error_state {
   my %states = (
     session  => { warning => t8('The session has expired. Please log in again.')                   },
     password => { error   => t8('Incorrect username or password or no access to selected client!') },
+    action   => { warning => t8('The action is missing or invalid.')                               },
   );
 
   return %{ $states{$_[0]} || {} };
index 854b863..56791ed 100644 (file)
@@ -131,6 +131,7 @@ sub show_error {
   $::locale                = Locale->new($::myconfig{countrycode});
   $::form->{error}         = $::locale->text('The session is invalid or has expired.') if ($error_type eq 'session');
   $::form->{error}         = $::locale->text('Incorrect password!')                    if ($error_type eq 'password');
+  $::form->{error}         = $::locale->text('The action is missing or invalid.')      if ($error_type eq 'action');
 
   return render_error_ajax($::form->{error}) if $::request->is_ajax;
 
@@ -236,7 +237,7 @@ sub handle_request {
   $::form->read_cgi_input;
 
   my %routing;
-  eval { %routing = _route_request($ENV{SCRIPT_NAME}); 1; } or return;
+  eval { %routing = $self->_route_request($ENV{SCRIPT_NAME}); 1; } or return;
   ($routing_type, $script_name, $action) = @routing{qw(type controller action)};
   $::lxdebug->log_request($routing_type, $script_name, $action);
 
@@ -275,7 +276,7 @@ sub handle_request {
     if (   (($script eq 'login') && !$action)
         || ($script eq 'admin')
         || (SL::Auth::SESSION_EXPIRED() == $session_result)) {
-      $self->redirect_to_login($script);
+      $self->redirect_to_login(script => $script, error => 'session');
 
     }
 
@@ -338,8 +339,10 @@ sub handle_request {
 }
 
 sub redirect_to_login {
-  my ($self, $script) = @_;
-  my $action          = $script =~ m/^admin/i ? 'Admin/login' : 'LoginScreen/user_login&error=session';
+  my ($self, %params) = @_;
+  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}");
   ::end_of_request();
 }
@@ -362,14 +365,15 @@ sub _interface_is_fcgi {
 }
 
 sub _route_request {
-  my $script_name = shift;
+  my ($self, $script_name) = @_;
 
-  return $script_name =~ m/dispatcher\.pl$/ ? (type => 'old',        _route_dispatcher_request())
-       : $script_name =~ m/controller\.pl/  ? (type => 'controller', _route_controller_request())
+  return $script_name =~ m/dispatcher\.pl$/ ? (type => 'old',        $self->_route_dispatcher_request)
+       : $script_name =~ m/controller\.pl/  ? (type => 'controller', $self->_route_controller_request)
        :                                      (type => 'old',        controller => $script_name, action => $::form->{action});
 }
 
 sub _route_dispatcher_request {
+  my ($self)  = @_;
   my $name_re = qr{[a-z]\w*};
   my ($script_name, $action);
 
@@ -400,9 +404,16 @@ sub _route_dispatcher_request {
 }
 
 sub _route_controller_request {
+  my ($self) = @_;
   my ($controller, $action, $request_type);
 
   eval {
+    # Redirect simple requests to controller.pl without any GET/POST
+    # param to the login page.
+    $self->redirect_to_login(error => 'action') if !$::form->{action};
+
+    # Show an error if the »action« parameter doesn't match the
+    # pattern »Controller/action«.
     $::form->{action}      =~ m|^ ( [A-Z] [A-Za-z0-9_]* ) / ( [a-z] [a-z0-9_]* ) ( \. [a-zA-Z]+ )? $|x || die "Unroutable request -- invalid controller/action.\n";
     ($controller, $action) =  ($1, $2);
     delete $::form->{action};
index 56d5255..8415ec7 100755 (executable)
@@ -2305,6 +2305,7 @@ $self->{texts} = {
   'The access rights have been saved.' => 'Die Zugriffsrechte wurden gespeichert.',
   'The account 3804 already exists, the update will be skipped.' => 'Das Konto 3804 existiert schon, das Update wird übersprungen.',
   'The account 3804 will not be added automatically.' => 'Das Konto 3804 wird nicht automatisch hinzugefügt.',
+  'The action is missing or invalid.' => 'Die action fehlt, oder sie ist ungültig.',
   'The action you\'ve chosen has not been executed because the document does not contain any item yet.' => 'Die von Ihnen ausgewählte Aktion wurde nicht ausgeführt, weil der Beleg noch keine Positionen enthält.',
   'The administration area is always accessible.' => 'Der Administrationsbereich ist immer zugänglich.',
   'The application "#1" was not found on the system.' => 'Die Anwendung "#1" wurde auf dem System nicht gefunden.',