Revision 6afd06ad
Von Moritz Bunkus vor etwa 12 Jahren hinzugefügt
SL/Controller/Base.pm | ||
---|---|---|
167 | 167 |
0; |
168 | 168 |
} |
169 | 169 |
|
170 |
sub get_auth_level { |
|
171 |
# Ignore the 'action' parameter. |
|
172 |
return 'user'; |
|
173 |
} |
|
174 |
|
|
170 | 175 |
# |
171 | 176 |
# private functions -- for use in Base only |
172 | 177 |
# |
... | ... | |
503 | 508 |
will delay all flash messages for the current request. Defaults to false for |
504 | 509 |
compatibility reasons. |
505 | 510 |
|
511 |
=item C<get_auth_level $action> |
|
512 |
|
|
513 |
May be overridden by a controller. Determines what kind of |
|
514 |
authentication is required for a particular action. Must return either |
|
515 |
C<admin> (which means that authentication as an admin is required), |
|
516 |
C<user> (authentication as a normal user suffices) with a possible |
|
517 |
future value C<none> (which would require no authentication but is not |
|
518 |
yet implemented). |
|
519 |
|
|
506 | 520 |
=back |
507 | 521 |
|
508 | 522 |
=head2 PRIVATE FUNCTIONS |
SL/Dispatcher.pm | ||
---|---|---|
17 | 17 |
use List::Util qw(first); |
18 | 18 |
use POSIX; |
19 | 19 |
use SL::Auth; |
20 |
use SL::Dispatcher::AuthHandler; |
|
20 | 21 |
use SL::LXDebug; |
21 | 22 |
use SL::LxOfficeConf; |
22 | 23 |
use SL::Locale; |
... | ... | |
37 | 38 |
|
38 | 39 |
my $self = bless {}, $class; |
39 | 40 |
$self->{interface} = lc($interface || 'cgi'); |
41 |
$self->{auth_handler} = SL::Dispatcher::AuthHandler->new; |
|
40 | 42 |
|
41 | 43 |
return $self; |
42 | 44 |
} |
... | ... | |
63 | 65 |
$::lxdebug->enter_sub; |
64 | 66 |
my $template = shift; |
65 | 67 |
my $error_type = shift || ''; |
68 |
my %params = @_; |
|
66 | 69 |
|
67 | 70 |
$::locale = Locale->new($::lx_office_conf{system}->{language}); |
68 | 71 |
$::form->{error} = $::locale->text('The session is invalid or has expired.') if ($error_type eq 'session'); |
... | ... | |
70 | 73 |
$::myconfig{countrycode} = $::lx_office_conf{system}->{language}; |
71 | 74 |
|
72 | 75 |
$::form->header; |
73 |
print $::form->parse_html_template($template); |
|
76 |
print $::form->parse_html_template($template, \%params);
|
|
74 | 77 |
$::lxdebug->leave_sub; |
75 | 78 |
|
76 | 79 |
::end_of_request(); |
... | ... | |
143 | 146 |
sub _require_controller { |
144 | 147 |
my $controller = shift; |
145 | 148 |
$controller =~ s|[^A-Za-z0-9_]||g; |
149 |
$controller = "SL/Controller/${controller}"; |
|
146 | 150 |
|
147 | 151 |
eval { |
148 | 152 |
package main; |
149 |
require "SL/Controller/${controller}.pm";
|
|
153 |
require "${controller}.pm"; |
|
150 | 154 |
} or die $EVAL_ERROR; |
151 | 155 |
} |
152 | 156 |
|
... | ... | |
163 | 167 |
|
164 | 168 |
my ($script, $path, $suffix, $script_name, $action, $routing_type); |
165 | 169 |
|
166 |
$script_name = $ENV{SCRIPT_NAME}; |
|
167 |
|
|
168 | 170 |
$self->unrequire_bin_mozilla; |
169 | 171 |
|
170 | 172 |
$::locale = Locale->new($::lx_office_conf{system}->{language}); |
... | ... | |
177 | 179 |
|
178 | 180 |
$::form->read_cgi_input; |
179 | 181 |
|
180 |
eval { ($routing_type, $script_name, $action) = _route_request($script_name); 1; } or return;
|
|
182 |
eval { ($routing_type, $script_name, $action) = _route_request($ENV{SCRIPT_NAME}); 1; } or return;
|
|
181 | 183 |
|
182 | 184 |
if ($routing_type eq 'old') { |
183 | 185 |
$::form->{action} = lc $::form->{action}; |
... | ... | |
205 | 207 |
} else { |
206 | 208 |
show_error('login/password_error', 'session') if SL::Auth::SESSION_EXPIRED == $session_result; |
207 | 209 |
|
208 |
my $login = $::auth->get_session_value('login'); |
|
209 |
show_error('login/password_error', 'password') if not defined $login; |
|
210 |
|
|
211 |
%::myconfig = $::auth->read_user(login => $login); |
|
212 |
|
|
213 |
show_error('login/password_error', 'password') unless $::myconfig{login}; |
|
214 |
|
|
215 |
$::locale = Locale->new($::myconfig{countrycode}); |
|
216 |
|
|
217 |
show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($login, undef); |
|
218 |
|
|
219 |
$::auth->create_or_refresh_session; |
|
220 |
$::auth->delete_session_value('FLASH'); |
|
221 |
delete $::form->{password}; |
|
210 |
my $auth_level = $self->{auth_handler}->handle( |
|
211 |
routing_type => $routing_type, |
|
212 |
script => $script, |
|
213 |
controller => $script_name, |
|
214 |
action => $action, |
|
215 |
); |
|
222 | 216 |
|
223 | 217 |
if ($action) { |
224 |
$::instance_conf->init; |
|
218 |
$::instance_conf->init if $auth_level eq 'user';
|
|
225 | 219 |
|
226 | 220 |
map { $::form->{$_} = $::myconfig{$_} } qw(charset) |
227 | 221 |
unless $action eq 'save' && $::form->{type} eq 'preferences'; |
SL/Dispatcher/AuthHandler.pm | ||
---|---|---|
1 |
package SL::Dispatcher::AuthHandler; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(Rose::Object); |
|
6 |
|
|
7 |
use SL::Dispatcher::AuthHandler::Admin; |
|
8 |
use SL::Dispatcher::AuthHandler::User; |
|
9 |
|
|
10 |
sub handle { |
|
11 |
my ($self, %param) = @_; |
|
12 |
|
|
13 |
my $auth_level = $self->get_auth_level(%param); |
|
14 |
my $handler_name = "SL::Dispatcher::AuthHandler::" . ucfirst($auth_level); |
|
15 |
$self->{handlers} ||= {}; |
|
16 |
$self->{handlers}->{$handler_name} ||= $handler_name->new; |
|
17 |
$self->{handlers}->{$handler_name}->handle; |
|
18 |
|
|
19 |
return $auth_level; |
|
20 |
} |
|
21 |
|
|
22 |
sub get_auth_level { |
|
23 |
my ($self, %param) = @_; |
|
24 |
|
|
25 |
my $auth_level = $param{routing_type} eq 'old' ? ($param{script} eq 'admin' ? 'admin' : 'user') |
|
26 |
: $param{routing_type} eq 'controller' ? "SL::Controller::$param{controller}"->get_auth_level($param{action}) |
|
27 |
: 'user'; |
|
28 |
|
|
29 |
return $auth_level eq 'user' ? 'user' : 'admin'; |
|
30 |
} |
|
31 |
|
|
32 |
1; |
SL/Dispatcher/AuthHandler/Admin.pm | ||
---|---|---|
1 |
package SL::Dispatcher::AuthHandler::Admin; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(Rose::Object); |
|
6 |
|
|
7 |
sub handle { |
|
8 |
%::myconfig = (); |
|
9 |
|
|
10 |
return if $::auth->authenticate_root($::auth->get_session_value('rpw')) == $::auth->OK(); |
|
11 |
|
|
12 |
$::auth->delete_session_value('rpw'); |
|
13 |
SL::Dispatcher::show_error('login/password_error', 'password', is_admin => 1); |
|
14 |
} |
|
15 |
|
|
16 |
1; |
SL/Dispatcher/AuthHandler/User.pm | ||
---|---|---|
1 |
package SL::Dispatcher::AuthHandler::User; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(Rose::Object); |
|
6 |
|
|
7 |
sub handle { |
|
8 |
my $login = $::auth->get_session_value('login'); |
|
9 |
SL::Dispatcher::show_error('login/password_error', 'password') if not defined $login; |
|
10 |
|
|
11 |
%::myconfig = $::auth->read_user(login => $login); |
|
12 |
|
|
13 |
SL::Dispatcher::show_error('login/password_error', 'password') unless $::myconfig{login}; |
|
14 |
|
|
15 |
$::locale = Locale->new($::myconfig{countrycode}); |
|
16 |
|
|
17 |
SL::Dispatcher::show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($login, undef); |
|
18 |
|
|
19 |
$::auth->create_or_refresh_session; |
|
20 |
$::auth->delete_session_value('FLASH'); |
|
21 |
delete $::form->{password}; |
|
22 |
} |
|
23 |
|
|
24 |
1; |
templates/webpages/login/password_error.html | ||
---|---|---|
5 | 5 |
|
6 | 6 |
<p>[% error %]</p> |
7 | 7 |
|
8 |
<p><a href="login.pl" target="_top">[% 'Login' | $T8 %]</a></p>
|
|
8 |
<p><a href="[% IF is_admin %]admin.pl[% ELSE %]login.pl[% END %]" target="_top">[% 'Login' | $T8 %]</a></p>
|
|
9 | 9 |
|
10 | 10 |
</body> |
11 | 11 |
</html> |
Auch abrufbar als: Unified diff
Dispatcher: Auch Controller ermöglichen, die Admin-Login benötigen
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) ],
);
sub action_proof_of_concept {
#my ($self) = @_;
sub get_auth_level {
return 'admin';
}
1;