]> wagnertech.de Git - mfinanz.git/blobdiff - SL/Controller/Admin.pm
restart apache2 in postinst
[mfinanz.git] / SL / Controller / Admin.pm
index 634dd27ff4aca241c7c4d85e3efec566c5d41781..082b94ff8481987bcb46a742443cbd1473327ad1 100644 (file)
@@ -12,16 +12,18 @@ use SL::Common ();
 use SL::DB::AuthUser;
 use SL::DB::AuthGroup;
 use SL::DB::Printer;
+use SL::DBUtils ();
 use SL::Helper::Flash;
 use SL::Locale::String qw(t8);
 use SL::System::InstallationLock;
 use SL::User;
+use SL::Version;
 use SL::Layout::AdminLogin;
 
 use Rose::Object::MakeMethods::Generic
 (
   'scalar --get_set_init' => [ qw(client user group printer db_cfg is_locked
-                                  all_dateformats all_numberformats all_countrycodes all_countrymodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights all_printers
+                                  all_dateformats all_numberformats all_countrycodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights all_printers
                                   all_dbsources all_used_dbsources all_accounting_methods all_inventory_systems all_profit_determinations all_charts) ],
 );
 
@@ -29,7 +31,7 @@ __PACKAGE__->run_before(\&setup_layout);
 __PACKAGE__->run_before(\&setup_client, only => [ qw(list_printers new_printer edit_printer save_printer delete_printer) ]);
 
 sub get_auth_level { "admin" };
-sub keep_auth_vars {
+sub keep_auth_vars_in_form {
   my ($class, %params) = @_;
   return $params{action} eq 'login';
 }
@@ -82,10 +84,9 @@ sub action_create_auth_tables {
   $::auth->set_session_value('admin_password', $::lx_office_conf{authentication}->{admin_password});
   $::auth->create_or_refresh_session;
 
-  return if $self->apply_dbupgrade_scripts;
+  my $scripts_applied = $self->apply_dbupgrade_scripts;
 
-  my $group = (SL::DB::Manager::AuthGroup->get_all(limit => 1))[0];
-  if (!$group) {
+  if (! SL::DB::Manager::AuthGroup->get_all_count) {
     SL::DB::AuthGroup->new(
       name        => t8('Full Access'),
       description => t8('Full access to all functions'),
@@ -93,7 +94,7 @@ sub action_create_auth_tables {
     )->save;
   }
 
-  $self->action_login;
+  $self->action_login unless $scripts_applied;
 }
 
 #
@@ -115,11 +116,10 @@ sub action_new_user {
   my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
   $self->user(SL::DB::AuthUser->new(
     config_values => {
-      vclimit      => 200,
       countrycode  => $defaults->language('de'),
       numberformat => $defaults->numberformat('1.000,00'),
       dateformat   => $defaults->dateformat('dd.mm.yy'),
-      stylesheet   => "kivitendo.css",
+      stylesheet   => "design40.css",
       menustyle    => "neu",
     },
   ));
@@ -137,6 +137,8 @@ sub action_save_user {
   my $params = delete($::form->{user})          || { };
   my $props  = delete($params->{config_values}) || { };
   my $is_new = !$params->{id};
+  my $check_previously_used = delete($::form->{check_previously_used}) || 0;
+  my $assign_documents = delete($::form->{assign_documents}) || 0;
 
   # Assign empty arrays if the browser doesn't send those controls.
   $params->{clients} ||= [];
@@ -149,9 +151,29 @@ sub action_save_user {
   my @errors = $self->user->validate;
 
   if (@errors) {
-    flash('error', @errors);
-    $self->edit_user_form(title => $is_new ? t8('Create a new user') : t8('Edit User'));
-    return;
+    $self->js->flash('error', $_) foreach @errors;
+    return $self->js->render();
+  }
+
+  # check if given login name was previously used and show a dialog if so
+  if ($is_new && $check_previously_used && $self->check_loginname_previously_used()) {
+    $self->js->run('show_loginname_previously_used_dialog');
+    return $self->js->render();
+  }
+
+  # rename previous usernames in employee table, if not set to assign
+  if ($is_new && !$assign_documents) {
+    my $clients = SL::DB::Manager::AuthClient->get_all_sorted;
+    for my $client (@$clients) {
+      my $now = DateTime->now_local;
+      my $timestamp = $now->format_cldr('yyyyMMddHHmmss');
+
+      my $dbh = $client->dbconnect(AutoCommit => 1);
+      next if !$dbh;
+      $dbh->do(qq|UPDATE employee SET login = ? WHERE login = ?;|,undef,
+               $params->{'login'} . $timestamp, $params->{'login'});
+      $dbh->disconnect;
+    }
   }
 
   $self->user->save;
@@ -402,19 +424,24 @@ sub action_create_dataset_login {
 
 sub action_create_dataset {
   my ($self) = @_;
-  $self->create_dataset_form;
+
+  my %superuser = $self->check_database_superuser_privileges(no_credentials_not_an_error => 1);
+  $self->create_dataset_form(superuser => \%superuser);
 }
 
 sub action_do_create_dataset {
   my ($self) = @_;
 
+  my %superuser = $self->check_database_superuser_privileges;
+
   my @errors;
   push @errors, t8("Dataset missing!")          if !$::form->{db};
   push @errors, t8("Default currency missing!") if !$::form->{defaultcurrency};
+  push @errors, $superuser{error}               if !$superuser{have_privileges} && $superuser{error};
 
   if (@errors) {
     flash('error', @errors);
-    return $self->create_dataset_form;
+    return $self->create_dataset_form(superuser => \%superuser);
   }
 
   $::form->{encoding} = 'UNICODE';
@@ -446,7 +473,7 @@ sub action_do_delete_dataset {
 
   if (@errors) {
     flash('error', @errors);
-    return $self->create_dataset_form;
+    return $self->delete_dataset_form;
   }
 
   User->new->dbdelete($::form);
@@ -500,7 +527,7 @@ sub init_all_groups        { SL::DB::Manager::AuthGroup ->get_all_sorted
 sub init_all_printers      { SL::DB::Manager::Printer   ->get_all_sorted                                                     }
 sub init_all_dateformats   { [ qw(mm/dd/yy dd/mm/yy dd.mm.yy yyyy-mm-dd)      ]                                              }
 sub init_all_numberformats { [ '1,000.00', '1000.00', '1.000,00', '1000,00', "1'000.00" ]                                    }
-sub init_all_stylesheets   { [ qw(lx-office-erp.css Mobile.css kivitendo.css) ]                                              }
+sub init_all_stylesheets   { [ qw(lx-office-erp.css Mobile.css kivitendo.css design40.css) ]                                 }
 sub init_all_dbsources             { [ sort User->dbsources($::form)                               ] }
 sub init_all_used_dbsources        { { map { (join(':', $_->dbhost || 'localhost', $_->dbport || 5432, $_->dbname) => $_->name) } @{ $_[0]->all_clients }  } }
 sub init_all_accounting_methods    { [ { id => 'accrual',   name => t8('Accrual accounting')  }, { id => 'cash',     name => t8('Cash accounting')       } ] }
@@ -552,11 +579,6 @@ sub init_all_countrycodes {
   return [ map { id => $_, title => $cc{$_} }, sort { $cc{$a} cmp $cc{$b} } keys %cc ];
 }
 
-sub init_all_countrymodes {
-  my %cm = SL::DefaultManager->country_modes;
-  return [ map { id => $_, title => "$_ ($cm{$_})" }, sort keys %cm ];
-}
-
 #
 # filters
 #
@@ -578,7 +600,7 @@ sub setup_client {
   my ($self) = @_;
 
   $self->client(SL::DB::Manager::AuthClient->get_default || $self->all_clients->[0]) if !$self->client;
-  $::auth->set_client($self->client->id);
+  $::auth->set_client($self->client->id) if $self->client;
 }
 
 #
@@ -595,8 +617,8 @@ sub use_multiselect_js {
 sub login_form {
   my ($self, %params) = @_;
   $::request->layout(SL::Layout::AdminLogin->new);
-  my $version         = $::form->read_version;
-  $self->render('admin/adminlogin', title => t8('kivitendo v#1 administration', $version), %params, version => $version);
+  my $version         = SL::Version->get_version;
+  $self->render('admin/adminlogin', title => t8('kivitendo v#1 administration', $version), %params, version => $version );
 }
 
 sub edit_user_form {
@@ -638,15 +660,20 @@ sub create_dataset_form {
 
   my $defaults = SL::DefaultManager->new($::lx_office_conf{system}->{default_manager});
   $::form->{favicon} = "favicon.ico";
-  $::form->{countrymode}          = $defaults->country('DE');
-  $::form->{chart}                = $defaults->chart_of_accounts('Germany-DATEV-SKR03EU');
-  $::form->{defaultcurrency}      = $defaults->currency('EUR');
-  $::form->{precision}            = $defaults->precision(0.01);
-  $::form->{accounting_method}    = $defaults->accounting_method('cash');
-  $::form->{inventory_system}     = $defaults->inventory_system('periodic');
-  $::form->{profit_determination} = $defaults->profit_determination('balance');
-
-  $self->render('admin/create_dataset', title => (t8('Database Administration') . " / " . t8('Create Dataset')));
+  $::form->{countrymode}             = $defaults->country('DE');
+  $::form->{chart}                   = $defaults->chart_of_accounts('Germany-DATEV-SKR03EU');
+  $::form->{defaultcurrency}         = $defaults->currency('EUR');
+  $::form->{precision}               = $defaults->precision(0.01);
+  $::form->{accounting_method}       = $defaults->accounting_method('cash');
+  $::form->{inventory_system}        = $defaults->inventory_system('periodic');
+  $::form->{profit_determination}    = $defaults->profit_determination('balance');
+  $::form->{feature_balance}         = $defaults->feature_balance(1);
+  $::form->{feature_datev}           = $defaults->feature_datev(1);
+  $::form->{feature_erfolgsrechnung} = $defaults->feature_erfolgsrechnung(0);
+  $::form->{feature_eurechnung}      = $defaults->feature_eurechnung(1);
+  $::form->{feature_ustva}           = $defaults->feature_ustva(1);
+
+  $self->render('admin/create_dataset', title => (t8('Database Administration') . " / " . t8('Create Dataset')), superuser => $params{superuser});
 }
 
 sub delete_dataset_form {
@@ -698,5 +725,74 @@ sub is_user_used_for_task_server {
   return join ', ', sort_by { lc } map { $_->name } @{ SL::DB::Manager::AuthClient->get_all(where => [ task_server_user_id => $user->id ]) };
 }
 
+sub check_database_superuser_privileges {
+  my ($self, %params) = @_;
+
+  my %dbconnect_form = %{ $::form };
+  my %result         = (
+    username => $dbconnect_form{dbuser},
+    password => $dbconnect_form{dbpasswd},
+  );
+
+  my $check_privileges = sub {
+    my $dbh = SL::DBConnect->connect($dbconnect_form{dbconnect}, $result{username}, $result{password}, SL::DBConnect->get_options);
+    return (error => $::locale->text('The credentials (username & password) for connecting database are wrong.')) if !$dbh;
+
+    my $is_superuser = SL::DBUtils::role_is_superuser($dbh, $result{username});
+
+    $dbh->disconnect;
+
+    return (have_privileges => $is_superuser);
+  };
+
+  User::dbconnect_vars(\%dbconnect_form, $dbconnect_form{dbdefault});
+
+  %result = (
+    %result,
+    $check_privileges->(),
+  );
+
+  if (!$result{have_privileges}) {
+    $result{username} = $::form->{database_superuser_user};
+    $result{password} = $::form->{database_superuser_password};
+
+    if ($::form->{database_superuser_user}) {
+      %result = (
+        %result,
+        $check_privileges->(),
+      );
+    }
+  }
+
+  if ($result{have_privileges}) {
+    $::auth->set_session_value(database_superuser_username => $result{username}, database_superuser_password => $result{password});
+    return %result;
+  }
+
+  $::auth->delete_session_value(qw(database_superuser_username database_superuser_password));
+
+  return ()                                                                            if !$::form->{database_superuser_user} && $params{no_credentials_not_an_error};
+  return (%result, error => $::locale->text('No superuser credentials were entered.')) if !$::form->{database_superuser_user};
+  return %result                                                                       if $result{error};
+  return (%result, error => $::locale->text('The database user \'#1\' does not have superuser privileges.', $result{username}));
+}
+
+sub check_loginname_previously_used() {
+  my ($self) = @_;
+
+  my $clients = SL::DB::Manager::AuthClient->get_all_sorted;
+  for my $client (@$clients) {
+    my $dbh = $client->dbconnect();
+    next if !$dbh;
+    my ($result) = $dbh->selectrow_array(qq|SELECT login FROM employee WHERE login = ?;|,undef,
+                                        $self->user->{'login'});
+    $dbh->disconnect;
+
+    if ($result) {
+      return 1;
+    }
+  }
+  return 0;
+}
 
 1;