From 6afd06adfeb66b481b7240637351a34a41e702d1 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 17 Aug 2012 12:24:58 +0200 Subject: [PATCH] =?utf8?q?Dispatcher:=20Auch=20Controller=20erm=C3=B6glich?= =?utf8?q?en,=20die=20Admin-Login=20ben=C3=B6tigen?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Default ist für Controller, dass all ihre Funktionen User-Logins benötigen. Kann ein Controller ändern, indem er die Sub "get_auth_level" überschreibt (siehe Doku in SL::Contrller::Base). Dies schafft die Basis dafür, auch Admin-Dinge in der neuen Controller-Architektur zu implementieren. Für die Zukunft kann man leicht ein weiteres Level neben 'user' und 'admin' einbauen, z.B. 'none' für Actions, die definitiv kein Login benötigen. Funktionierendes Beispiel für einen solchen Controller (Aufruf dann über URL ".../controller.pl?action=AdminTest/proof_of_concept"): package SL::Controller::AdminTest; use strict; use parent qw(SL::Controller::Base); use Rose::Object::MakeMethods::Generic ( scalar => [ qw(business) ], ); # # actions # sub action_proof_of_concept { my ($self) = @_; $::form->header; print $self->render(< 1 });

I've been called with an ADMIN login only!

EOHTML } # # overrides # sub get_auth_level { return 'admin'; } 1; --- SL/Controller/Base.pm | 14 ++++++++ SL/Dispatcher.pm | 34 ++++++++------------ SL/Dispatcher/AuthHandler.pm | 32 ++++++++++++++++++ SL/Dispatcher/AuthHandler/Admin.pm | 16 +++++++++ SL/Dispatcher/AuthHandler/User.pm | 24 ++++++++++++++ templates/webpages/login/password_error.html | 2 +- 6 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 SL/Dispatcher/AuthHandler.pm create mode 100644 SL/Dispatcher/AuthHandler/Admin.pm create mode 100644 SL/Dispatcher/AuthHandler/User.pm diff --git a/SL/Controller/Base.pm b/SL/Controller/Base.pm index ac09057af..c8713950c 100644 --- a/SL/Controller/Base.pm +++ b/SL/Controller/Base.pm @@ -167,6 +167,11 @@ sub delay_flash_on_redirect { 0; } +sub get_auth_level { + # Ignore the 'action' parameter. + return 'user'; +} + # # private functions -- for use in Base only # @@ -503,6 +508,15 @@ May be overridden by a controller. If this method returns true, redirect_to will delay all flash messages for the current request. Defaults to false for compatibility reasons. +=item C + +May be overridden by a controller. Determines what kind of +authentication is required for a particular action. Must return either +C (which means that authentication as an admin is required), +C (authentication as a normal user suffices) with a possible +future value C (which would require no authentication but is not +yet implemented). + =back =head2 PRIVATE FUNCTIONS diff --git a/SL/Dispatcher.pm b/SL/Dispatcher.pm index 21398ccca..8301e5602 100644 --- a/SL/Dispatcher.pm +++ b/SL/Dispatcher.pm @@ -17,6 +17,7 @@ use List::MoreUtils qw(all); use List::Util qw(first); use POSIX; use SL::Auth; +use SL::Dispatcher::AuthHandler; use SL::LXDebug; use SL::LxOfficeConf; use SL::Locale; @@ -37,6 +38,7 @@ sub new { my $self = bless {}, $class; $self->{interface} = lc($interface || 'cgi'); + $self->{auth_handler} = SL::Dispatcher::AuthHandler->new; return $self; } @@ -63,6 +65,7 @@ sub show_error { $::lxdebug->enter_sub; my $template = shift; my $error_type = shift || ''; + my %params = @_; $::locale = Locale->new($::lx_office_conf{system}->{language}); $::form->{error} = $::locale->text('The session is invalid or has expired.') if ($error_type eq 'session'); @@ -70,7 +73,7 @@ sub show_error { $::myconfig{countrycode} = $::lx_office_conf{system}->{language}; $::form->header; - print $::form->parse_html_template($template); + print $::form->parse_html_template($template, \%params); $::lxdebug->leave_sub; ::end_of_request(); @@ -143,10 +146,11 @@ sub require_main_code { sub _require_controller { my $controller = shift; $controller =~ s|[^A-Za-z0-9_]||g; + $controller = "SL/Controller/${controller}"; eval { package main; - require "SL/Controller/${controller}.pm"; + require "${controller}.pm"; } or die $EVAL_ERROR; } @@ -163,8 +167,6 @@ sub handle_request { my ($script, $path, $suffix, $script_name, $action, $routing_type); - $script_name = $ENV{SCRIPT_NAME}; - $self->unrequire_bin_mozilla; $::locale = Locale->new($::lx_office_conf{system}->{language}); @@ -177,7 +179,7 @@ sub handle_request { $::form->read_cgi_input; - eval { ($routing_type, $script_name, $action) = _route_request($script_name); 1; } or return; + eval { ($routing_type, $script_name, $action) = _route_request($ENV{SCRIPT_NAME}); 1; } or return; if ($routing_type eq 'old') { $::form->{action} = lc $::form->{action}; @@ -205,23 +207,15 @@ sub handle_request { } else { show_error('login/password_error', 'session') if SL::Auth::SESSION_EXPIRED == $session_result; - my $login = $::auth->get_session_value('login'); - show_error('login/password_error', 'password') if not defined $login; - - %::myconfig = $::auth->read_user(login => $login); - - show_error('login/password_error', 'password') unless $::myconfig{login}; - - $::locale = Locale->new($::myconfig{countrycode}); - - show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($login, undef); - - $::auth->create_or_refresh_session; - $::auth->delete_session_value('FLASH'); - delete $::form->{password}; + my $auth_level = $self->{auth_handler}->handle( + routing_type => $routing_type, + script => $script, + controller => $script_name, + action => $action, + ); if ($action) { - $::instance_conf->init; + $::instance_conf->init if $auth_level eq 'user'; map { $::form->{$_} = $::myconfig{$_} } qw(charset) unless $action eq 'save' && $::form->{type} eq 'preferences'; diff --git a/SL/Dispatcher/AuthHandler.pm b/SL/Dispatcher/AuthHandler.pm new file mode 100644 index 000000000..60dc63720 --- /dev/null +++ b/SL/Dispatcher/AuthHandler.pm @@ -0,0 +1,32 @@ +package SL::Dispatcher::AuthHandler; + +use strict; + +use parent qw(Rose::Object); + +use SL::Dispatcher::AuthHandler::Admin; +use SL::Dispatcher::AuthHandler::User; + +sub handle { + my ($self, %param) = @_; + + my $auth_level = $self->get_auth_level(%param); + my $handler_name = "SL::Dispatcher::AuthHandler::" . ucfirst($auth_level); + $self->{handlers} ||= {}; + $self->{handlers}->{$handler_name} ||= $handler_name->new; + $self->{handlers}->{$handler_name}->handle; + + return $auth_level; +} + +sub get_auth_level { + my ($self, %param) = @_; + + my $auth_level = $param{routing_type} eq 'old' ? ($param{script} eq 'admin' ? 'admin' : 'user') + : $param{routing_type} eq 'controller' ? "SL::Controller::$param{controller}"->get_auth_level($param{action}) + : 'user'; + + return $auth_level eq 'user' ? 'user' : 'admin'; +} + +1; diff --git a/SL/Dispatcher/AuthHandler/Admin.pm b/SL/Dispatcher/AuthHandler/Admin.pm new file mode 100644 index 000000000..5a92015f5 --- /dev/null +++ b/SL/Dispatcher/AuthHandler/Admin.pm @@ -0,0 +1,16 @@ +package SL::Dispatcher::AuthHandler::Admin; + +use strict; + +use parent qw(Rose::Object); + +sub handle { + %::myconfig = (); + + return if $::auth->authenticate_root($::auth->get_session_value('rpw')) == $::auth->OK(); + + $::auth->delete_session_value('rpw'); + SL::Dispatcher::show_error('login/password_error', 'password', is_admin => 1); +} + +1; diff --git a/SL/Dispatcher/AuthHandler/User.pm b/SL/Dispatcher/AuthHandler/User.pm new file mode 100644 index 000000000..13d644863 --- /dev/null +++ b/SL/Dispatcher/AuthHandler/User.pm @@ -0,0 +1,24 @@ +package SL::Dispatcher::AuthHandler::User; + +use strict; + +use parent qw(Rose::Object); + +sub handle { + my $login = $::auth->get_session_value('login'); + SL::Dispatcher::show_error('login/password_error', 'password') if not defined $login; + + %::myconfig = $::auth->read_user(login => $login); + + SL::Dispatcher::show_error('login/password_error', 'password') unless $::myconfig{login}; + + $::locale = Locale->new($::myconfig{countrycode}); + + SL::Dispatcher::show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($login, undef); + + $::auth->create_or_refresh_session; + $::auth->delete_session_value('FLASH'); + delete $::form->{password}; +} + +1; diff --git a/templates/webpages/login/password_error.html b/templates/webpages/login/password_error.html index e1060a015..1ee8ec830 100644 --- a/templates/webpages/login/password_error.html +++ b/templates/webpages/login/password_error.html @@ -5,7 +5,7 @@

[% error %]

-

[% 'Login' | $T8 %]

+

[% 'Login' | $T8 %]

-- 2.20.1