Datenbank anlegen: Super-User-Rechte abfragen, sofern nötig
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 12 Oct 2017 12:59:05 +0000 (14:59 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 12 Oct 2017 12:59:05 +0000 (14:59 +0200)
SL/Controller/Admin.pm
SL/DBUtils.pm
SL/User.pm
locale/de/all
templates/webpages/admin/create_dataset.html

index 3126b4d..9937c5b 100644 (file)
@@ -12,6 +12,7 @@ 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;
@@ -401,19 +402,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';
@@ -645,7 +651,7 @@ sub create_dataset_form {
   $::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')));
+  $self->render('admin/create_dataset', title => (t8('Database Administration') . " / " . t8('Create Dataset')), superuser => $params{superuser});
 }
 
 sub delete_dataset_form {
@@ -697,5 +703,56 @@ 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}));
+}
 
 1;
index 54cf7da..c9c70c9 100644 (file)
@@ -392,6 +392,13 @@ sub like {
   return "%" . SL::Util::trim($string // '') . "%";
 }
 
+sub role_is_superuser {
+  my ($dbh, $login)  = @_;
+  my ($is_superuser) = $dbh->selectrow_array(qq|SELECT usesuper FROM pg_user WHERE usename = ?|, undef, $login);
+
+  return $is_superuser;
+}
+
 1;
 
 
index a271e77..68fd2c5 100644 (file)
@@ -130,7 +130,7 @@ sub _handle_superuser_privileges {
   my $dbh = SL::DBConnect->connect($dbconnect_form{dbconnect}, $dbconnect_form{dbuser}, $dbconnect_form{dbpasswd}, SL::DBConnect->get_options);
   return (%result, error => $::locale->text('The credentials (username & password) for connecting database are wrong.')) if !$dbh;
 
-  my ($is_superuser) = $dbh->selectrow_array(qq|SELECT usesuper FROM pg_user WHERE usename = ?|, undef, $dbconnect_form{dbuser});
+  my $is_superuser = SL::DBUtils::role_is_superuser($dbh, $dbconnect_form{dbuser});
 
   $dbh->disconnect;
 
index cb53050..2495b5f 100755 (executable)
@@ -847,11 +847,13 @@ $self->{texts} = {
   'Database Host'               => 'Datenbankcomputer',
   'Database ID'                 => 'Datenbank-ID',
   'Database Management'         => 'Datenbankadministration',
+  'Database Superuser'          => 'Datenbank-Super-Benutzer',
   'Database User'               => 'Datenbankbenutzer',
   'Database host and port'      => 'Datenbankhost und -port',
   'Database login (#1)'         => 'Datenbankanmeldung (#1)',
   'Database name'               => 'Datenbankname',
   'Database settings'           => 'Datenbankeinstellungen',
+  'Database superuser privileges are required for parts of the database modifications.' => 'Für einige Teile der Datenbankänderungen werden Datenbank-Super-Benutzer-Rechte benötigt.',
   'Database superuser privileges are required for the update.' => 'Datenbank-Super-Benutzer-Rechte werden für das Update benötigt.',
   'Database template'           => 'Datenbankvorlage',
   'Database update error:'      => 'Fehler beim Datenbankupgrade:',
@@ -1974,6 +1976,7 @@ $self->{texts} = {
   'No start date given, setting to #1' => 'Kein Startdatum gegeben, setze Startdatum auf #1',
   'No such job #1 in the database.' => 'Hintergrund-Job #1 existiert nicht mehr.',
   'No summary account'          => 'Kein Sammelkonto',
+  'No superuser credentials were entered.' => 'Es wurden keine Super-Benutzer-Anmeldedaten eingegeben.',
   'No template has been selected yet.' => 'Es wurde noch keine Vorlage ausgewählt.',
   'No text blocks have been created for this position.' => 'Für diese Position wurden noch keine Textblöcke angelegt.',
   'No text has been entered yet.' => 'Es wurde noch kein Text eingegeben.',
index 7a879d8..48998c6 100644 (file)
   [% LxERP.t8('In the latter case the tables needed by kivitendo will be created in that database.') %]
  </p>
 
+ [% IF !superuser.have_privileges %]
+  <p>
+   [% LxERP.t8("Database superuser privileges are required for parts of the database modifications.") %]
+   [% LxERP.t8("Please provide corresponding credentials.") %]
+  </p>
+ [% END %]
+
  <table border="0">
   <tr>
    <th valign="top" align="right" nowrap>[% LxERP.t8('Existing Datasets') %]</th>
    <td>[% L.input_tag('db', FORM.db, class="initial_focus") %]</td>
   </tr>
 
+  [% IF !superuser.have_privileges %]
+   <tr>
+    <th align="right" nowrap>[% LxERP.t8("Database Superuser") %]</th>
+    <td>[% L.input_tag("database_superuser_user", superuser.username) %]</td>
+   </tr>
+
+   <tr>
+    <th align="right" nowrap>[% LxERP.t8("Password") %]</th>
+    <td>[% L.input_tag("database_superuser_password", superuser.password, type="password") %]</td>
+   </tr>
+  [% END %]
+
   <tr>
    <td colspan="1"> </td>
    <td><hr size="1" noshade></td>