X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/9f522077cdc739cbb17564f76e31e9b7ce7ab4f1..c781544686f9faf39259f1076297b0ec69aff6fc:/SL/Auth.pm diff --git a/SL/Auth.pm b/SL/Auth.pm index 77ea226ae..365ee2323 100644 --- a/SL/Auth.pm +++ b/SL/Auth.pm @@ -11,7 +11,9 @@ use YAML; use SL::Auth::Constants qw(:all); use SL::Auth::DB; use SL::Auth::LDAP; +use SL::Auth::Password; +use SL::SessionFile; use SL::User; use SL::DBConnect; use SL::DBUpgrade2; @@ -135,12 +137,10 @@ sub _read_auth_config { sub authenticate_root { $main::lxdebug->enter_sub(); - my $self = shift; - my $password = shift; - my $is_crypted = shift; + my ($self, $password) = @_; - $password = crypt $password, 'ro' if (!$password || !$is_crypted); - my $admin_password = crypt "$self->{admin_password}", 'ro'; + $password = SL::Auth::Password->hash_if_unhashed(login => 'root', password => $password); + my $admin_password = SL::Auth::Password->hash_if_unhashed(login => 'root', password => $self->{admin_password}); $main::lxdebug->leave_sub(); @@ -162,6 +162,38 @@ sub authenticate { return $result; } +sub store_credentials_in_session { + my ($self, %params) = @_; + + if (!$self->{authenticator}->requires_cleartext_password) { + $params{password} = SL::Auth::Password->hash_if_unhashed(login => $params{login}, + password => $params{password}, + look_up_algorithm => 1, + auth => $self); + } + + $self->set_session_value(login => $params{login}, password => $params{password}); +} + +sub store_root_credentials_in_session { + my ($self, $rpw) = @_; + + $self->set_session_value(rpw => SL::Auth::Password->hash_if_unhashed(login => 'root', password => $rpw)); +} + +sub get_stored_password { + my ($self, $login) = @_; + + my $dbh = $self->dbconnect; + + return undef unless $dbh; + + my $query = qq|SELECT password FROM auth."user" WHERE login = ?|; + my ($stored_password) = $dbh->selectrow_array($query, undef, $login); + + return $stored_password; +} + sub dbconnect { $main::lxdebug->enter_sub(2); @@ -361,8 +393,14 @@ sub can_change_password { sub change_password { $main::lxdebug->enter_sub(); - my $self = shift; - my $result = $self->{authenticator}->change_password(@_); + my ($self, $login, $new_password) = @_; + + my $result = $self->{authenticator}->change_password($login, $new_password); + + $self->store_credentials_in_session(login => $login, + password => $new_password, + look_up_algorithm => 1, + auth => $self); $main::lxdebug->leave_sub(); @@ -555,6 +593,8 @@ sub destroy_session { $dbh->commit(); + SL::SessionFile->destroy_session($session_id); + $session_id = undef; $self->{SESSION} = { }; } @@ -567,26 +607,31 @@ sub expire_sessions { my $self = shift; + $main::lxdebug->leave_sub and return if !$self->session_tables_present; + my $dbh = $self->dbconnect(); - $dbh->begin_work; + my $query = qq|SELECT id + FROM auth.session + WHERE (mtime < (now() - '$self->{session_timeout}m'::interval))|; - my $query = - qq|DELETE FROM auth.session_content - WHERE session_id IN - (SELECT id - FROM auth.session - WHERE (mtime < (now() - '$self->{session_timeout}m'::interval)))|; + my @ids = selectall_array_query($::form, $dbh, $query); - do_query($main::form, $dbh, $query); + if (@ids) { + $dbh->begin_work; - $query = - qq|DELETE FROM auth.session - WHERE (mtime < (now() - '$self->{session_timeout}m'::interval))|; + SL::SessionFile->destroy_session($_) for @ids; - do_query($main::form, $dbh, $query); + $query = qq|DELETE FROM auth.session_content + WHERE session_id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|; + do_query($main::form, $dbh, $query, @ids); - $dbh->commit(); + $query = qq|DELETE FROM auth.session + WHERE id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|; + do_query($main::form, $dbh, $query, @ids); + + $dbh->commit(); + } $main::lxdebug->leave_sub(); } @@ -615,7 +660,7 @@ sub save_session { my $dbh = $provided_dbh || $self->dbconnect(1); - $::lxdebug->leave_sub && return unless $dbh; + $::lxdebug->leave_sub && return unless $dbh && $session_id; $dbh->begin_work unless $provided_dbh; @@ -651,12 +696,23 @@ sub set_session_value { $main::lxdebug->enter_sub(); my $self = shift; - my %params = @_; + my @params = @_; $self->{SESSION} ||= { }; - while (my ($key, $value) = each %params) { - $self->{SESSION}->{ $key } = YAML::Dump(ref($value) eq 'HASH' ? { data => $value } : $value); + while (@params) { + my $key = shift @params; + + if (ref $key eq 'HASH') { + my $value = { data => $key->{value}, + auto_restore => $key->{auto_restore}, + }; + $self->{SESSION}->{ $key->{key} } = YAML::Dump($value); + + } else { + my $value = shift @params; + $self->{SESSION}->{ $key } = YAML::Dump(ref($value) eq 'HASH' ? { data => $value } : $value); + } } $main::lxdebug->leave_sub(); @@ -697,7 +753,7 @@ sub create_unique_sesion_value { my $key = "$$-" . ($now[0] * 1000000 + $now[1]) . "-"; $self->{unique_counter} ||= 0; - $self->{unique_counter}++ while exists $self->{SESSION}->{$key . $self->{unique_counter}}; + $self->{unique_counter}++ while exists $self->{SESSION}->{$key . ($self->{unique_counter} + 1)}; $self->{unique_counter}++; $value = { expiration => $params{expiration} ? ($now[0] + $params{expiration}) * 1000000 + $now[1] : undef, @@ -779,6 +835,14 @@ sub session_tables_present { $main::lxdebug->enter_sub(); my $self = shift; + + # Only re-check for the presence of auth tables if either the check + # hasn't been done before of if they weren't present. + if ($self->{session_tables_present}) { + $main::lxdebug->leave_sub(); + return $self->{session_tables_present}; + } + my $dbh = $self->dbconnect(1); if (!$dbh) { @@ -794,9 +858,11 @@ sub session_tables_present { my ($count) = selectrow_query($main::form, $dbh, $query); + $self->{session_tables_present} = 2 == $count; + $main::lxdebug->leave_sub(); - return 2 == $count; + return $self->{session_tables_present}; } # -------------------------------------- @@ -823,7 +889,6 @@ sub all_rights_full { ["customer_vendor_edit", $locale->text("Create and edit customers and vendors")], ["part_service_assembly_edit", $locale->text("Create and edit parts, services, assemblies")], ["project_edit", $locale->text("Create and edit projects")], - ["license_edit", $locale->text("Manage license keys")], ["--ar", $locale->text("AR")], ["sales_quotation_edit", $locale->text("Create and edit sales quotations")], ["sales_order_edit", $locale->text("Create and edit sales orders")], @@ -1117,7 +1182,7 @@ sub load_rights_for_user { my $dbh = $self->dbconnect; my ($query, $sth, $row, $rights); - $rights = { map { $rights->{$_} = 0 } all_rights() }; + $rights = { map { $_ => 0 } all_rights() }; $query = qq|SELECT gr."right", gr.granted @@ -1155,11 +1220,30 @@ SL::Auth - Authentication and session handling =over 4 +=item C =item C -Store all key/value pairs in C<%values> in the session. All of these -values are copied back into C<$::form> in the next request -automatically. +Store all values of C<@values> or C<%values> in the session. Each +member of C<@values> is tested if it is a hash reference. If it is +then it must contain the keys C and C and can optionally +contain the key C. In this case C is associated +with C and restored to C<$::form> upon the next request +automatically if C is trueish or if C is a scalar +value. + +If the current member of C<@values> is not a hash reference then it +will be used as the C and the next entry of C<@values> is used as +the C to store. In this case setting C is not +possible. + +Therefore the following two invocations are identical: + + $::auth-Eset_session_value(name =E "Charlie"); + $::auth-Eset_session_value({ key =E "name", value =E "Charlie" }); + +All of these values are copied back into C<$::form> for the next +request automatically if they're scalar values or if they have +C set to trueish. The values can be any Perl structure. They are stored as YAML dumps.