Admin: Teile von admin.pl in neuen Controller Admin verschoben; Mandanten anzeigen
authorMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 5 Jun 2013 09:33:10 +0000 (11:33 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 13 Jun 2013 14:24:19 +0000 (16:24 +0200)
32 files changed:
SL/Auth.pm
SL/Controller/Admin.pm [new file with mode: 0644]
SL/Controller/Base.pm
SL/DB.pm
SL/DB/AuthClient.pm
SL/DB/AuthGroup.pm
SL/DB/AuthUser.pm
SL/DB/Manager/AuthClient.pm [new file with mode: 0644]
SL/DB/Manager/AuthGroup.pm [new file with mode: 0644]
SL/DB/Manager/AuthUser.pm [new file with mode: 0644]
SL/DBConnect.pm
SL/Dispatcher.pm
SL/Dispatcher/AuthHandler.pm
SL/Dispatcher/AuthHandler/Admin.pm
bin/mozilla/admin.pl
css/kivitendo/main.css
css/lx-office-erp/main.css
locale/de/all
templates/webpages/admin/adminlogin.html
templates/webpages/admin/backup_dataset.html
templates/webpages/admin/backup_dataset_email_done.html
templates/webpages/admin/check_auth_database.html
templates/webpages/admin/check_auth_tables.html
templates/webpages/admin/dbadmin.html
templates/webpages/admin/dbcreate.html
templates/webpages/admin/dbdelete.html
templates/webpages/admin/dbupgrade_all_done.html
templates/webpages/admin/delete_dataset.html
templates/webpages/admin/list_users.html
templates/webpages/admin/restore_dataset_start_footer.html
templates/webpages/admin/update_dataset.html
templates/webpages/dbupgrade/footer.html

index 23a9771..420724b 100644 (file)
@@ -566,7 +566,7 @@ sub restore_session {
 
   if (!$session_id) {
     $main::lxdebug->leave_sub();
-    return SESSION_NONE;
+    return $self->session_restore_result(SESSION_NONE());
   }
 
   my ($dbh, $query, $sth, $cookie, $ref, $form);
@@ -576,7 +576,7 @@ sub restore_session {
   # Don't fail if the auth DB doesn't yet.
   if (!( $dbh = $self->dbconnect(1) )) {
     $::lxdebug->leave_sub;
-    return SESSION_NONE;
+    return $self->session_restore_result(SESSION_NONE());
   }
 
   # Don't fail if the "auth" schema doesn't exist yet, e.g. if the
@@ -586,7 +586,7 @@ sub restore_session {
   if (!($sth = $dbh->prepare($query)) || !$sth->execute($session_id)) {
     $sth->finish if $sth;
     $::lxdebug->leave_sub;
-    return SESSION_NONE;
+    return $self->session_restore_result(SESSION_NONE());
   }
 
   $cookie = $sth->fetchrow_hashref;
@@ -605,7 +605,7 @@ sub restore_session {
   if ($cookie_is_bad) {
     $self->destroy_session();
     $main::lxdebug->leave_sub();
-    return $cookie ? SESSION_EXPIRED : SESSION_NONE;
+    return $self->session_restore_result($cookie ? SESSION_EXPIRED() : SESSION_NONE());
   }
 
   if ($self->{column_information}->has('auto_restore')) {
@@ -616,7 +616,15 @@ sub restore_session {
 
   $main::lxdebug->leave_sub();
 
-  return SESSION_OK;
+  return $self->session_restore_result(SESSION_OK());
+}
+
+sub session_restore_result {
+  my $self = shift;
+  if (@_) {
+    $self->{session_restore_result} = $_[0];
+  }
+  return $self->{session_restore_result};
 }
 
 sub _load_without_auto_restore_column {
diff --git a/SL/Controller/Admin.pm b/SL/Controller/Admin.pm
new file mode 100644 (file)
index 0000000..04d9c75
--- /dev/null
@@ -0,0 +1,181 @@
+package SL::Controller::Admin;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use IO::File;
+
+use SL::DB::AuthUser;
+use SL::DB::AuthGroup;
+use SL::Helper::Flash;
+use SL::Locale::String qw(t8);
+
+use Rose::Object::MakeMethods::Generic
+(
+  'scalar --get_set_init' => [ qw(client user nologin_file_name db_cfg) ],
+);
+
+__PACKAGE__->run_before(\&setup_layout);
+
+sub get_auth_level { "admin" };
+sub keep_auth_vars {
+  my ($class, %params) = @_;
+  return $params{action} eq 'login';
+}
+
+#
+# actions
+#
+
+sub action_login {
+  my ($self) = @_;
+
+  return $self->login_form if !$::form->{do_login};
+  return                   if !$self->authenticate_root;
+  return                   if !$self->check_auth_db_and_tables;
+  return                   if  $self->apply_dbupgrade_scripts;
+  $self->redirect_to(action => 'list_clients_and_users');
+}
+
+sub action_logout {
+  my ($self) = @_;
+  $::auth->destroy_session;
+  $self->redirect_to(action => 'login');
+}
+
+sub action_apply_dbupgrade_scripts {
+  my ($self) = @_;
+
+  return if $self->apply_dbupgrade_scripts;
+  $self->action_list_clients_and_users;
+}
+
+sub action_create_auth_db {
+  my ($self) = @_;
+
+  $::auth->create_database(superuser          => $::form->{db_superuser},
+                           superuser_password => $::form->{db_superuser_password},
+                           template           => $::form->{db_template});
+  $self->check_auth_db_and_tables;
+}
+
+sub action_create_auth_tables {
+  my ($self) = @_;
+
+  $::auth->create_tables;
+  $::auth->set_session_value('admin_password', $::lx_office_conf{authentication}->{admin_password});
+  $::auth->create_or_refresh_session;
+
+  my $group = (SL::DB::Manager::AuthGroup->get_all(limit => 1))[0];
+  if (!$group) {
+    SL::DB::AuthGroup->new(
+      name        => t8('Full Access'),
+      description => t8('Full access to all functions'),
+      rights      => [ map { SL::DB::AuthGroupRight->new(right => $_, granted => 1) } SL::Auth::all_rights() ],
+    )->save;
+  }
+
+  if (!$self->apply_dbupgrade_scripts) {
+    $self->action_login;
+  }
+}
+
+sub action_list_clients_and_users {
+  my ($self) = @_;
+
+  $self->render(
+    "admin/list_users",
+    CLIENTS => SL::DB::Manager::AuthClient->get_all_sorted,
+    USERS   => SL::DB::Manager::AuthUser->get_all_sorted,
+    LOCKED  => (-e $self->nologin_file_name),
+    title   => "kivitendo " . $::locale->text('Administration'),
+  );
+}
+
+sub action_unlock_system {
+  my ($self) = @_;
+  unlink $self->nologin_file_name;
+  flash_later('info', t8('Lockfile removed!'));
+  $self->redirect_to(action => 'list_clients_and_users');
+}
+
+sub action_lock_system {
+  my ($self) = @_;
+
+  my $fh = IO::File->new($self->nologin_file_name, "w");
+  if (!$fh) {
+    $::form->error(t8('Cannot create Lock!'));
+
+  } else {
+    $fh->close;
+    flash_later('info', t8('Lockfile created!'));
+    $self->redirect_to(action => 'list_clients_and_users');
+  }
+}
+
+#
+# initializers
+#
+
+sub init_db_cfg            { $::lx_office_conf{'authentication/database'}               }
+sub init_nologin_file_name { $::lx_office_conf{paths}->{userspath} . '/nologin';        }
+sub init_client            { SL::DB::AuthClient->new(id => $::form->{client_id})->load; }
+sub init_user              { SL::DB::AuthUser  ->new(id => $::form->{user_id}  )->load; }
+
+#
+# filters
+#
+
+sub setup_layout {
+  my ($self, $action) = @_;
+
+  $::request->layout(SL::Layout::Dispatcher->new(style => 'admin'));
+  $::request->layout->use_stylesheet("lx-office-erp.css");
+  $::form->{favicon} = "favicon.ico";
+}
+
+#
+# helpers
+#
+
+sub login_form {
+  my ($self, %params) = @_;
+  $::request->layout->focus('#admin_password');
+  $self->render('admin/adminlogin', title => t8('kivitendo v#1 administration', $::form->{version}), %params);
+}
+
+sub check_auth_db_and_tables {
+  my ($self) = @_;
+
+  if (!$::auth->check_database) {
+    $self->render('admin/check_auth_database', title => t8('Authentification database creation'));
+    return 0;
+  }
+
+  if (!$::auth->check_tables) {
+    $self->render('admin/check_auth_tables', title => t8('Authentification tables creation'));
+    return 0;
+  }
+
+  return 1;
+}
+
+sub apply_dbupgrade_scripts {
+  return SL::DBUpgrade2->new(form => $::form, dbdriver => 'Pg', auth => 1)->apply_admin_dbupgrade_scripts(1);
+}
+
+sub authenticate_root {
+  my ($self) = @_;
+
+  return 1 if $::auth->authenticate_root($::form->{'{AUTH}admin_password'}) == $::auth->OK();
+
+  $::auth->punish_wrong_login;
+  $::auth->delete_session_value('admin_password');
+
+  $self->login_form(error => t8('Incorrect Password!'));
+
+  return undef;
+}
+
+1;
index c6977d0..88f10b7 100644 (file)
@@ -562,13 +562,16 @@ C<user> (authentication as a normal user suffices) with a possible
 future value C<none> (which would require no authentication but is not
 yet implemented).
 
-=item C<keep_auth_vars_in_form>
+=item C<keep_auth_vars_in_form %params>
 
 May be overridden by a controller. If falsish (the default) all form
 variables whose name starts with C<{AUTH}> are removed before the
 request is routed. Only controllers that handle login requests
 themselves should return trueish for this function.
 
+C<$params{action}> contains the action name that the request will be
+dispatched to.
+
 =item C<controller_name>
 
 Returns the name of the curernt controller package without the
index 0125114..28626ac 100644 (file)
--- a/SL/DB.pm
+++ b/SL/DB.pm
@@ -49,7 +49,7 @@ sub _register_db {
   my %connect_settings;
   my $initial_sql;
 
-  if ($type eq 'KIVITENDO_AUTH') {
+  if (($type eq 'KIVITENDO_AUTH') && $::auth && $::auth->{DB_config} && $::auth->session_tables_present) {
     %connect_settings = ( driver          => 'Pg',
                           database        => $::auth->{DB_config}->{db},
                           host            => $::auth->{DB_config}->{host} || 'localhost',
@@ -58,11 +58,9 @@ sub _register_db {
                           password        => $::auth->{DB_config}->{password},
                           connect_options => { pg_enable_utf8 => $::locale && $::locale->is_utf8,
                                              });
-  } elsif (!%::myconfig) {
-    $type = 'KIVITENDO_EMPTY';
-    %connect_settings = ( driver => 'Pg' );
+  }
 
-  } else {
+  if (!%connect_settings && %::myconfig) {
     my $european_dates = 0;
     if ($::myconfig{dateformat}) {
       $european_dates = 1 if $_dateformats{ $::myconfig{dateformat} }
@@ -80,6 +78,11 @@ sub _register_db {
                           european_dates  => $european_dates);
   }
 
+  if (!%connect_settings) {
+    $type = 'KIVITENDO_EMPTY';
+    %connect_settings = ( driver => 'Pg' );
+  }
+
   my %flattened_settings = _flatten_settings(%connect_settings);
 
   $domain = 'KIVITENDO' if $type =~ m/^KIVITENDO/;
index 5291da2..a37c930 100644 (file)
@@ -6,12 +6,11 @@ package SL::DB::AuthClient;
 use strict;
 
 use SL::DB::MetaSetup::AuthClient;
+use SL::DB::Manager::AuthClient;
 
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
 __PACKAGE__->meta->schema('auth');
 
-__PACKAGE__->meta->make_manager_class;
-
 __PACKAGE__->meta->add_relationship(
   users => {
     type      => 'many to many',
index 3d30177..ce47bd3 100644 (file)
@@ -6,11 +6,9 @@ package SL::DB::AuthGroup;
 use strict;
 
 use SL::DB::MetaSetup::AuthGroup;
+use SL::DB::Manager::AuthGroup;
 use SL::DB::AuthGroupRight;
 
-# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
-__PACKAGE__->meta->make_manager_class;
-
 __PACKAGE__->meta->schema('auth');
 
 __PACKAGE__->meta->add_relationship(
index c1b46b4..41644eb 100644 (file)
@@ -8,11 +8,9 @@ use strict;
 use List::Util qw(first);
 
 use SL::DB::MetaSetup::AuthUser;
+use SL::DB::Manager::AuthUser;
 use SL::DB::AuthUserGroup;
 
-# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
-__PACKAGE__->meta->make_manager_class;
-
 __PACKAGE__->meta->schema('auth');
 
 __PACKAGE__->meta->add_relationship(
@@ -44,4 +42,15 @@ sub get_config_value {
   return $cfg ? $cfg->cfg_value : undef;
 }
 
+sub config_values {
+  my $self = shift;
+
+  if (0 != scalar(@_)) {
+    my %settings = (ref($_[0]) || '') eq 'HASH' ? %{ $_[0] } : @_;
+    $self->configs([ map { SL::DB::AuthUserConfig->new(cfg_key => $_, cfg_value => $settings{$_}) } keys %settings ]);
+  }
+
+  return { map { ($_->cfg_key => $_->cfg_value) } @{ $self->configs } };
+}
+
 1;
diff --git a/SL/DB/Manager/AuthClient.pm b/SL/DB/Manager/AuthClient.pm
new file mode 100644 (file)
index 0000000..ccfb97e
--- /dev/null
@@ -0,0 +1,20 @@
+package SL::DB::Manager::AuthClient;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Paginated;
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::AuthClient' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'name', 1 ],
+           columns => { SIMPLE => 'ALL' } );
+}
+
+1;
diff --git a/SL/DB/Manager/AuthGroup.pm b/SL/DB/Manager/AuthGroup.pm
new file mode 100644 (file)
index 0000000..985f834
--- /dev/null
@@ -0,0 +1,20 @@
+package SL::DB::Manager::AuthGroup;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Paginated;
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::AuthGroup' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'name', 1 ],
+           columns => { SIMPLE => 'ALL' } );
+}
+
+1;
diff --git a/SL/DB/Manager/AuthUser.pm b/SL/DB/Manager/AuthUser.pm
new file mode 100644 (file)
index 0000000..8095622
--- /dev/null
@@ -0,0 +1,20 @@
+package SL::DB::Manager::AuthUser;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Paginated;
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::AuthUser' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'login', 1 ],
+           columns => { SIMPLE => 'ALL' } );
+}
+
+1;
index 8dc9787..3ad5dfd 100644 (file)
@@ -7,6 +7,13 @@ use DBI;
 sub connect {
   shift;
 
+  # print STDERR "Starting full caller dump:\n";
+  # my $level = 0;
+  # while (my ($dummy, $filename, $line, $subroutine) = caller $level) {
+  #   print STDERR "  ${subroutine} from ${filename}:${line}\n";
+  #   $level++;
+  # }
+
   return DBI->connect(@_) unless $::lx_office_conf{debug} && $::lx_office_conf{debug}->{dbix_log4perl};
 
   require Log::Log4perl;
index 01b6aff..1261aa7 100644 (file)
@@ -59,16 +59,18 @@ sub interface_type {
   return $self->{interface} eq 'cgi' ? 'CGI' : 'FastCGI';
 }
 
+sub is_admin_request {
+  my %params = @_;
+  return ($params{script} eq 'admin.pl') || (($params{routing_type} eq 'controller') && ($params{script_name} eq 'Admin'));
+}
+
 sub pre_request_checks {
+  my (%params) = @_;
+
   _check_for_old_config_files();
 
-  if (!$::auth->session_tables_present) {
-    if ($::form->{script} eq 'admin.pl') {
-      ::run();
-      ::end_of_request();
-    } else {
-      show_error('login_screen/auth_db_unreachable');
-    }
+  if (!$::auth->session_tables_present && !is_admin_request(%params)) {
+    show_error('login_screen/auth_db_unreachable');
   }
 
   if ($::request->type !~ m/^ (?: html | js | json ) $/x) {
@@ -231,9 +233,12 @@ sub handle_request {
   }
 
   eval {
-    pre_request_checks();
+    pre_request_checks(script => $script, action => $action, routing_type => $routing_type, script_name => $script_name);
 
-    $::form->error($::locale->text('System currently down for maintenance!')) if -e ($::lx_office_conf{paths}->{userspath} . "/nologin") && $script ne 'admin';
+    if (   (-e ($::lx_office_conf{paths}->{userspath} . "/nologin"))
+        && !is_admin_request(script => $script, script_name => $script_name, routing_type => $routing_type)) {
+      $::form->error($::locale->text('System currently down for maintenance!'));
+    }
 
     # For compatibility with a lot of database upgrade scripts etc:
     # Re-write request to old 'login.pl?action=login' to new
@@ -246,15 +251,8 @@ sub handle_request {
     if (($script eq 'login') && !$action) {
       print $::request->{cgi}->redirect('controller.pl?action=LoginScreen/user_login');
 
-    } elsif ($script eq 'admin') {
-      $::form->{titlebar} = "kivitendo " . $::locale->text('Version') . " $::form->{version}";
-      ::run($session_result);
-
     } else {
-      if (SL::Auth::SESSION_EXPIRED == $session_result) {
-        print $::request->{cgi}->redirect('controller.pl?action=LoginScreen/user_login&error=session');
-        ::end_of_request();
-      }
+      $self->redirect_to_login($script) if SL::Auth::SESSION_EXPIRED == $session_result;
 
       my %auth_result = $self->{auth_handler}->handle(
         routing_type => $routing_type,
@@ -320,6 +318,13 @@ sub handle_request {
   $::lxdebug->leave_sub;
 }
 
+sub redirect_to_login {
+  my ($self, $script) = @_;
+  my $action          = $script =~ m/^admin/i ? 'Admin/login' : 'LoginScreen/user_login&error=session';
+  print $::request->cgi->redirect("controller.pl?action=${action}");
+  ::end_of_request();
+}
+
 sub unrequire_bin_mozilla {
   my $self = shift;
   return unless $self->_interface_is_fcgi;
index 4c352bd..449d684 100644 (file)
@@ -1,4 +1,4 @@
-  package SL::Dispatcher::AuthHandler;
+package SL::Dispatcher::AuthHandler;
 
 use strict;
 
@@ -18,7 +18,7 @@ sub handle {
   my $handler_name                     = "SL::Dispatcher::AuthHandler::" . ucfirst($auth_level);
   $self->{handlers}                  ||= {};
   $self->{handlers}->{$handler_name} ||= $handler_name->new;
-  my $ok = $self->{handlers}->{$handler_name}->handle;
+  my $ok = $self->{handlers}->{$handler_name}->handle(%param);
 
   return (
     auth_level     => $auth_level,
@@ -40,7 +40,7 @@ sub get_auth_level {
 sub get_keep_auth_vars {
   my ($self, %param) = @_;
 
-  return $param{routing_type} eq 'controller' ? "SL::Controller::$param{controller}"->keep_auth_vars_in_form : 0;
+  return $param{routing_type} eq 'controller' ? "SL::Controller::$param{controller}"->keep_auth_vars_in_form(action => $param{action}) : 0;
 }
 
 1;
index a7b649c..baacc67 100644 (file)
@@ -6,11 +6,14 @@ use parent qw(Rose::Object);
 use SL::Layout::Dispatcher;
 
 sub handle {
+  my ($self, %params) = @_;
+
   %::myconfig = ();
 
   return 1 if  $::auth->get_api_token_cookie;
   return 1 if  $::form->{'{AUTH}admin_password'} && ($::auth->authenticate_root($::form->{'{AUTH}admin_password'})            == $::auth->OK());
   return 1 if !$::form->{'{AUTH}admin_password'} && ($::auth->authenticate_root($::auth->get_session_value('admin_password')) == $::auth->OK());
+  return 1 if $params{action} eq 'login';
 
   $::request->{layout} = SL::Layout::Dispatcher->new(style => 'admin');
 
index 464c6de..67c5969 100755 (executable)
@@ -47,6 +47,8 @@ use Sys::Hostname;
 
 use SL::Auth;
 use SL::Auth::PasswordPolicy;
+use SL::DB::AuthClient;
+use SL::DB::AuthUser;
 use SL::Form;
 use SL::Iconv;
 use SL::Mailer;
@@ -105,7 +107,6 @@ sub run {
     } else {
       if ($auth->session_tables_present()) {
         delete $::form->{'{AUTH}admin_password'};
-        _apply_dbupgrade_scripts();
       }
 
       call_sub($locale->findsub($form->{action}));
@@ -130,99 +131,6 @@ sub adminlogin {
   print $form->parse_html_template('admin/adminlogin');
 }
 
-sub login {
-  check_auth_db_and_tables();
-  list_users();
-}
-
-sub logout {
-  $main::auth->destroy_session();
-  adminlogin();
-}
-
-sub check_auth_db_and_tables {
-  my $form   = $main::form;
-  my $locale = $main::locale;
-
-  my %params;
-
-  map { $params{"db_${_}"} = $main::auth->{DB_config}->{$_} } keys %{ $auth->{DB_config} };
-
-  $params{admin_password} = $::lx_office_conf{authentication}->{admin_password};
-
-  if (!$main::auth->check_database()) {
-    $form->{title} = $locale->text('Authentification database creation');
-    $form->header();
-    print $form->parse_html_template('admin/check_auth_database', \%params);
-
-    ::end_of_request();
-  }
-
-  if (!$main::auth->check_tables()) {
-    $form->{title} = $locale->text('Authentification tables creation');
-    $form->header();
-    print $form->parse_html_template('admin/check_auth_tables', \%params);
-
-    ::end_of_request();
-  }
-}
-
-sub create_auth_db {
-  my $form = $main::form;
-
-  $main::auth->create_database('superuser'          => $form->{db_superuser},
-                               'superuser_password' => $form->{db_superuser_password},
-                               'template'           => $form->{db_template});
-  login();
-}
-
-sub create_auth_tables {
-  my $form   = $main::form;
-  my $locale = $main::locale;
-
-  $main::auth->create_tables();
-  $main::auth->set_session_value('admin_password', $form->{'{AUTH}admin_password'});
-  $main::auth->create_or_refresh_session();
-
-  my $memberfile = $::lx_office_conf{paths}->{memberfile};
-  if (!-f $memberfile) {
-    # New installation -- create a standard group with full access
-    my %members;
-    my $group = {
-      'name'        => $locale->text('Full Access'),
-      'description' => $locale->text('Full access to all functions'),
-      'rights'      => { map { $_ => 1 } SL::Auth::all_rights() },
-      'members'     => [ map { $_->{id} } values %members ],
-    };
-
-    $main::auth->save_group($group);
-  }
-
-  _apply_dbupgrade_scripts();
-  login();
-}
-
-sub list_users {
-  my $form    = $main::form;
-  my $locale  = $main::locale;
-
-  my %members = $main::auth->read_all_users();
-
-  delete $members{"root login"};
-
-  for (values %members) {
-    $_->{templates} =~ s|.*/||;
-    $_->{login_url} =  $::locale->is_utf8 ? Encode::encode('utf-8-strict', $_->{login}) : $_->{login_url};
-  }
-
-  $form->{title}   = "kivitendo " . $locale->text('Administration');
-  $form->{LOCKED}  = -e _nologin_file_name();
-  $form->{MEMBERS} = [ @members{sort { lc $a cmp lc $b } keys %members} ];
-
-  $form->header();
-  print $form->parse_html_template("admin/list_users");
-}
-
 sub add_user {
   $::form->{title}   = "kivitendo " . $::locale->text('Administration') . " / " . $::locale->text('Add User');
 
@@ -249,9 +157,6 @@ sub edit_user {
   # get user
   my $user = User->new(id => $::form->{user}{id});
 
-  # strip basedir from templates directory
-  $user->{templates} =~ s|.*/||;
-
   edit_user_form($user);
 }
 
@@ -923,32 +828,6 @@ sub restore_dataset_start {
   rmdir $tmpdir;
 }
 
-sub unlock_system {
-  my $form   = $main::form;
-  my $locale = $main::locale;
-
-  unlink _nologin_file_name();;
-
-  $form->{callback} = "admin.pl?action=list_users";
-
-  $form->redirect($locale->text('Lockfile removed!'));
-
-}
-
-sub lock_system {
-  my $form   = $main::form;
-  my $locale = $main::locale;
-
-  open(FH, ">", _nologin_file_name())
-    or $form->error($locale->text('Cannot create Lock!'));
-  close(FH);
-
-  $form->{callback} = "admin.pl?action=list_users";
-
-  $form->redirect($locale->text('Lockfile created!'));
-
-}
-
 sub yes {
   call_sub($main::form->{yes_nextsub});
 }
@@ -1006,14 +885,6 @@ sub dispatcher {
   $form->error($locale->text('No action defined.'));
 }
 
-sub _apply_dbupgrade_scripts {
-  ::end_of_request() if SL::DBUpgrade2->new(form => $::form, dbdriver => 'Pg', auth => 1)->apply_admin_dbupgrade_scripts(1);
-}
-
-sub _nologin_file_name {
-  return $::lx_office_conf{paths}->{userspath} . '/nologin';
-}
-
 sub _search_templates {
   my %templates = SL::Template->available_templates;
 
index 3653c52..e765fbf 100644 (file)
@@ -370,3 +370,8 @@ label {
   color: #ccc;
   font-style: italic;
 }
+
+.link_separator {
+  margin-left: 6px;
+  margin-right: 6px;
+}
index 799cbab..27a3aa2 100644 (file)
@@ -423,3 +423,8 @@ label {
   color: #aaa;
   font-style: italic;
 }
+
+.link_separator {
+  margin-left: 6px;
+  margin-right: 6px;
+}
index 1301aeb..8400806 100755 (executable)
@@ -127,6 +127,7 @@ $self->{texts} = {
   'Add Accounts Receivables Transaction' => 'Debitorenbuchung erfassen',
   'Add Assembly'                => 'Erzeugnis erfassen',
   'Add Buchungsgruppe'          => 'Buchungsgruppe erfassen',
+  'Add Client'                  => 'Neuer Mandant',
   'Add Credit Note'             => 'Gutschrift erfassen',
   'Add Customer'                => 'Kunde erfassen',
   'Add Delivery Note'           => 'Lieferschein erfassen',
@@ -439,6 +440,7 @@ $self->{texts} = {
   'Client #1'                   => 'Mandant #1',
   'Client Configuration'        => 'Mandantenkonfiguration',
   'Client Configuration saved!' => 'Mandantenkonfiguration gespeichert!',
+  'Client list'                 => 'Mandantenliste',
   'Client name'                 => 'Mandantenname',
   'Close'                       => 'Ãœbernehmen',
   'Close Books up to'           => 'Die Bücher abschließen bis zum',
@@ -1031,7 +1033,7 @@ $self->{texts} = {
   'If you have not chosen for example the category revenue for a tax and you choose an revenue account to create a transfer in the general ledger, this tax will not be displayed in the tax dropdown.' => 'Wenn Sie z.B. die Kategory Erlös für eine Steuer nicht gewählt haben und ein Erlöskonto beim Erstellen einer Dialogbuchung wählen, wird diese Steuer auch nicht im Dropdown-Menü für die Steuern angezeigt.',
   'If you see this message, you most likely just setup your LX-Office and haven\'t added any entry types. If this is the case, the option is accessible for administrators in the System menu.' => 'Wenn Sie diese Meldung sehen haben Sie wahrscheinlich ein frisches LX-Office Setup und noch keine Buchungsgruppen eingerichtet. Ein Administrator kann dies im Systemmen&uuml; erledigen.',
   'If you select a base unit then you also have to enter a factor.' => 'Wenn Sie eine Basiseinheit auswählen, dann müssen Sie auch einen Faktor eingeben.',
-  'If you want to change any of these parameters then press the &quot;Back&quot; button, edit the file &quot;config/kivitendo.conf&quot; and login into the admin module again.' => 'Wenn Sie einen der Parameter &auml;ndern wollen, so dr&uuml;cken Sie auf den &quot;Zur&uuml;ck&quot;-Button, bearbeiten Sie die Datei &quot;config/kivitendo.conf&quot;, und melden Sie sich erneut im Administrationsbereich an.',
+  'If you want to change any of these parameters then press the "Back" button, edit the file "config/kivitendo.conf" and login into the admin module again.' => 'Wenn Sie einen der Parameter Ã¤ndern wollen, so drücken Sie auf den "Zurück"-Button, bearbeiten Sie die Datei "config/kivitendo.conf", und melden Sie sich erneut im Administrationsbereich an.',
   'If you want to delete such a dataset you have to edit the user(s) that are using the dataset in question and have them use another dataset.' => 'Wenn Sie eine solche Datenbank l&ouml;schen wollen, so m&uuml;ssen Sie zuerst die Benutzer bearbeiten, die die fragliche Datenbank benutzen, und sie so &auml;ndern, dass sie eine andere Datenbank benutzen.',
   'If you want to set up the authentication database yourself then log in to the administration panel. kivitendo will then create the database and tables for you.' => 'Wenn Sie die Authentifizierungs-Datenbank selber einrichten wollen, so melden Sie sich im Administrationsbereich an. kivitendo wird dann die Datenbank und die erforderlichen Tabellen für Sie anlegen.',
   'If your old bins match exactly Bins in the Warehouse CLICK on <b>AUTOMATICALLY MATCH BINS</b>.' => 'Falls die alte Lagerplatz-Beschreibung in Stammdaten genau mit einem Lagerplatz in einem vorhandenem Lager Ã¼bereinstimmt, KLICK auf <b>LAGERPLÄTZE AUTOMATISCH ZUWEISEN</b>',
@@ -1047,6 +1049,7 @@ $self->{texts} = {
   'Import result'               => 'Import-Ergebnis',
   'Import summary'              => 'Import-Zusammenfassung',
   'In order to do that hit the button "Delete transaction".' => 'Drücken Sie dafür auf den Button "Buchung löschen".',
+  'In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.' => 'Um kivitendo zu nutzen, müssen Sie mindestens einen Mandanten und einen Benutzer anlegen sowie dem Benutzer den Zugriff auf diesen Mandanten gewähren.',
   'In the latter case the tables needed by kivitendo will be created in that database.' => 'In letzterem Fall werden die von kivitendo benötigten Tabellen in dieser existierenden Datenbank angelegt.',
   'In version 2.4.0 the administrator has to enter a list of units in the administrative section.' => 'Vor Version 2.4.0 musste der Benutzer die Konten bei jeder Ware und jeder Dienstleistung einzeln ausw&auml;hlen.',
   'In-line'                     => 'im Text',
@@ -1155,7 +1158,6 @@ $self->{texts} = {
   'Language saved!'             => 'Sprache gespeichert!',
   'Languages'                   => 'Sprachen',
   'Languages and translations'  => 'Sprachen und Ãœbersetzungen',
-  'Last Action'                 => 'Letzte Aktivität',
   'Last Article Number'         => 'Letzte Artikelnummer',
   'Last Assembly Number'        => 'Letzte Erzeugnisnummer',
   'Last Cost'                   => 'Einkaufspreis',
@@ -1320,6 +1322,7 @@ $self->{texts} = {
   'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => 'Für diesen Lieferanten wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Ãœberweisungen für den Lieferanten anlegen.',
   'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerpl&auml;tze angelegt.',
   'No business has been created yet.' => 'Es wurden noch kein Kunden-/Lieferantentyp erfasst.',
+  'No clients have been created yet.' => 'Es wurden noch keine Mandanten angelegt.',
   'No contact selected to delete' => 'Keine Ansprechperson zum Löschen ausgewählt',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No data was found.'          => 'Es wurden keine Daten gefunden.',
@@ -1343,6 +1346,7 @@ $self->{texts} = {
   'No transaction selected!'    => 'Keine Transaktion ausgewählt',
   'No transfers were executed in this export.' => 'In diesem SEPA-Export wurden keine Ãœberweisungen ausgeführt.',
   'No unknown units where found.' => 'Es wurden keine unbekannten Einheiten gefunden.',
+  'No users have been created yet.' => 'Es wurden noch keine Benutzer angelegt.',
   'No valid number entered for pricegroup "#1".' => 'Für Preisgruppe "#1" wurde keine gültige Nummer eingegeben.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No warehouse has been created yet or the quantity of the bins is not configured yet.' => 'Es wurde noch kein Lager angelegt, bzw. die dazugehörigen Lagerplätze sind noch nicht konfiguriert.',
@@ -2320,8 +2324,8 @@ $self->{texts} = {
   'User Config'                 => 'Einstellungen',
   'User Login'                  => 'Als Benutzer anmelden',
   'User access'                 => 'Benutzerzugriff',
-  'User data migration'         => 'Benutzerdatenmigration',
   'User deleted!'               => 'Benutzer gelöscht!',
+  'User list'                   => 'Benutzerliste',
   'User login'                  => 'Benutzeranmeldung',
   'User name'                   => 'Benutzername',
   'User saved!'                 => 'Benutzer gespeichert!',
@@ -2535,14 +2539,13 @@ $self->{texts} = {
   'invoice_list'                => 'debitorenbuchungsliste',
   'kivitendo'                   => 'kivitendo',
   'kivitendo Homepage'          => 'Infos zu kivitendo',
-  'kivitendo administration'    => 'kivitendo Administration',
   'kivitendo can fix these problems automatically.' => 'kivitendo kann solche Probleme automatisch beheben.',
   'kivitendo has been extended to handle multiple clients within a single installation.' => 'kivitendo wurde um Mandantenfähigkeit erweitert.',
-  'kivitendo has been switched to group-based access restrictions.' => 'kivitendo wurde auf eine gruppenbasierte Benutzerzugriffsverwaltung umgestellt.',
   'kivitendo has found one or more problems in the general ledger.' => 'kivitendo hat ein oder mehrere Probleme im Hauptbuch gefunden.',
   'kivitendo is about to update the database [ #1 ].' => 'kivitendo wird gleich die Datenbank [ #1 ] aktualisieren.',
   'kivitendo is now able to manage warehouses instead of just tracking the amount of goods in your system.' => 'kivitendo enth&auml;lt jetzt auch echte Lagerverwaultung anstatt reiner Mengenz&auml;hlung.',
   'kivitendo needs to update the authentication database before you can proceed.' => 'kivitendo muss die Authentifizierungsdatenbank aktualisieren, bevor Sie fortfahren können.',
+  'kivitendo v#1 administration' => 'kivitendo v#1 Administration',
   'kivitendo website (external)' => 'kivitendo-Webseite (extern)',
   'kivitendo will then update the database automatically.' => 'kivitendo wird die Datenbank daraufhin automatisch aktualisieren.',
   'lead deleted!'               => 'Kundenquelle gelöscht',
@@ -2567,7 +2570,6 @@ $self->{texts} = {
   'not configured'              => 'nicht konfiguriert',
   'not delivered'               => 'nicht geliefert',
   'not executed'                => 'nicht ausgeführt',
-  'not logged in'               => 'nicht eingeloggt',
   'not running'                 => 'läuft nicht',
   'not set'                     => 'nicht gesetzt',
   'not shipped'                 => 'nicht geliefert',
index 8cbaf29..263bef8 100644 (file)
@@ -1,20 +1,22 @@
 [%- USE T8 %]
 [% USE HTML %]
-[% USE LxERP%]
+[% USE LxERP %][%- USE L -%]
  <center>
   <table class="login" border="3" cellpadding="20">
    <tr>
     <td class="login" align="center">
      <a href="http://www.kivitendo.de" target="_top"><img src="image/kivitendo.png" border="0"></a>
-     <h1>[% 'kivitendo administration' | $T8 %] [% version %]</h1>
+     <h1>[% LxERP.t8('kivitendo v#1 administration', FORM.version) %]</h1>
 
-     [% IF error %]
-     <p><span class="message_error_login">[% error %]</span></p>
-     [% END %]
+[% IF error %]
+     <p><span class="message_error_login">[% HTML.escape(error) %]</span></p>
+[% END %]
 
      <p>
 
-      <form method="post" action="admin.pl">
+      <form method="post" action="controller.pl">
+       [%- L.hidden_tag("action",   'Admin/login') %]
+       [%- L.hidden_tag("do_login", 1) %]
 
        <table width="100%">
         <tr>
           <table>
            <tr>
             <th align="right">[% 'Password' | $T8 %]</th>
-            <td><input class="login" type="password" name="{AUTH}admin_password" id="admin_password" size="30" tabindex="1"></td>
+            <td>[%- L.input_tag("{AUTH}admin_password", '', type="password", class="login", id="admin_password", size="30") %]</td>
            </tr>
           </table>
 
           <br>
-          <input type="submit" value="[% 'Login' | $T8 %]" tabindex="2">
+
+          [% L.submit_tag('dummy', LxERP.t8('Login')) %]
 
          </td>
         </tr>
        </table>
-
-       <input type="hidden" name="action" value="login">
       </form>
 
     </td>
@@ -45,7 +46,3 @@
    &nbsp;|&nbsp;
    <a href="doc/kivitendo-Dokumentation.pdf" target="_top">[%- LxERP.t8('Documentation') %]</a>
   </p>
-
-  <script type='text/javascript'>
-    $('#admin_password').focus();
-  </script>
index 128d460..4306460 100644 (file)
 
    </table>
 
-   <input name="callback" type="hidden" value="admin.pl?action=list_users">
+   <input name="callback" type="hidden" value="controller.pl?action=Admin/list_clients_and_users">
    <input type="hidden" name="nextsub" value="backup_dataset_start">
-   <input type="hidden" name="back_nextsub" value="list_users">
 
    <hr size="3" noshade>
 
    <br>
 
    <input type="submit" class="submit" name="action" value="[% 'Continue' | $T8 %]">
-   <a href="admin.pl?action=pg_database_administration">[% 'Back' | $T8 %]</a>
+   <a href="controller.pl?action=Admin/list_clients_and_users">[% 'Back' | $T8 %]</a>
 
   </form>
 
index e1573a6..a70a2ee 100644 (file)
@@ -1,11 +1,8 @@
 [%- USE T8 %]
 [%- USE LxERP %]
-[%- USE HTML %]
+[%- USE HTML %][%- USE L -%]
  <h1>[% title %]</h1>
 
  <p>[% LxERP.t8('The dataset backup has been sent via email to #1.', to) | html %]</p>
 
- <form method="post" action="admin.pl">
-  <input type="hidden" name="nextsub" value="list_users">
-  <input type="submit" name="action" value="[% 'Continue' | $T8 %]">
- </form>
+ <p>[% L.link("controller.pl?action=Admin/list_clients_and_users", LxERP.t8("Continue")) %]
index c40b8ec..2a3c51d 100644 (file)
@@ -1,9 +1,11 @@
 [%- USE T8 %]
-[%- USE HTML %]
+[%- USE HTML %][%- USE L -%][%- USE LxERP -%]
 
  <h1>[% title %]</h1>
 
- <form method="post" action="admin.pl">
+ <form method="post" action="controller.pl">
+  [%- L.hidden_tag("action", 'Admin/create_auth_db') %]
+  [%- L.hidden_tag("{AUTH}admin_password", LXCONFIG.authentication.admin_password) %]
 
   <p>
    [% 'The database for user management and authentication does not exist. You can create let kivitendo create it with the following parameters:' | $T8 %]
   <table border="0">
    <tr>
     <td>[% 'Host' | $T8 %]:</td>
-    <td>[% HTML.escape(db_host) %]</td>
+    <td>[% HTML.escape(SELF.db_cfg.host) %]</td>
    </tr>
    <tr>
     <td>[% 'Port' | $T8 %]:</td>
-    <td>[% HTML.escape(db_port) %]</td>
+    <td>[% HTML.escape(SELF.db_cfg.port) %]</td>
    </tr>
    <tr>
     <td>[% 'User name' | $T8 %]:</td>
-    <td>[% HTML.escape(db_user) %]</td>
+    <td>[% HTML.escape(SELF.db_cfg.user) %]</td>
    </tr>
    <tr>
     <td>[% 'Database name' | $T8 %]:</td>
-    <td>[% HTML.escape(db_db) %]</td>
+    <td>[% HTML.escape(SELF.db_cfg.db) %]</td>
    </tr>
   </table>
 
    [% 'If the database user listed above does not have the right to create a database then enter the name and password of the superuser below:' | $T8 %]
   </p>
 
-  <table border="0"
+  <table border="0">
    <tr>
     <td>[% 'Superuser name' | $T8 %]:</td>
-    <td><input name="db_superuser"></td>
+    <td>[% L.input_tag('db_superuser', '') %]</td>
    </tr>
 
    <tr>
     <td>[% 'Password' | $T8 %]:</td>
-    <td><input type="password" name="db_superuser_password"></td>
+    <td>[% L.input_tag('db_superuser_password', '', type='password') %]</td>
    </tr>
   </table>
 
-  <input type="hidden" name="{AUTH}admin_password" value="[% HTML.escape(admin_password) %]">
-  <input type="hidden" name="action" value="create_auth_db">
-
-  <input type="submit" class="submit" value="[% 'Create Dataset' | $T8 %]">
-  <input type="button" class="submit" onclick="history.back()" value="[% 'Back' | $T8 %]">
-
+  [% L.submit_tag("dummy", LxERP.t8("Create Dataset")) %]
+  [% L.button_tag("history.back()", LxERP.t8("Back")) %]
  </form>
index 0e1d80a..13a89f4 100644 (file)
@@ -1,5 +1,5 @@
 [%- USE T8 %]
-[%- USE HTML %]
+[%- USE HTML %][%- USE LxERP -%][%- USE L -%]
 
  <h1>[% title %]</h1>
 
  <table border="0">
   <tr>
    <td>[% 'Host' | $T8 %]:</td>
-   <td>[% HTML.escape(db_host) %]</td>
+   <td>[% HTML.escape(SELF.db_cfg.host) %]</td>
   </tr>
   <tr>
    <td>[% 'Port' | $T8 %]:</td>
-   <td>[% HTML.escape(db_port) %]</td>
+   <td>[% HTML.escape(SELF.db_cfg.port) %]</td>
   </tr>
   <tr>
    <td>[% 'User name' | $T8 %]:</td>
-   <td>[% HTML.escape(db_user) %]</td>
+   <td>[% HTML.escape(SELF.db_cfg.user) %]</td>
   </tr>
   <tr>
    <td>[% 'Database name' | $T8 %]:</td>
-   <td>[% HTML.escape(db_db) %]</td>
+   <td>[% HTML.escape(SELF.db_cfg.db) %]</td>
   </tr>
  </table>
 
  <p>
-  [% 'If you want to change any of these parameters then press the &quot;Back&quot; button, edit the file &quot;config/kivitendo.conf&quot; and login into the admin module again.' | $T8 %]
+  [% 'If you want to change any of these parameters then press the "Back" button, edit the file "config/kivitendo.conf" and login into the admin module again.' | $T8 %]
  </p>
 
- <form method="post" action="admin.pl">
-
-  <input type="hidden" name="{AUTH}admin_password" value="[% HTML.escape(admin_password) %]">
-  <input type="hidden" name="action" value="create_auth_tables">
-
-  <input type="submit" class="submit" value="[% 'Create tables' | $T8 %]">
-  <input type="button" class="submit" onclick="history.back()" value="[% 'Back' | $T8 %]">
+ <form method="post" action="controller.pl">
+  [%- L.hidden_tag("action", 'Admin/create_auth_tables') %]
+  [%- L.hidden_tag("{AUTH}admin_password", LXCONFIG.authentication.admin_password) %]
 
+  [% L.submit_tag("dummy", LxERP.t8("Create tables")) %]
+  [% L.button_tag("history.back()", LxERP.t8("Back")) %]
  </form>
index 23fb805..bccd514 100644 (file)
@@ -3,7 +3,7 @@
   <h1>[% title %]</h1>
 
   <form method="post" action="admin.pl">
-   <a href="admin.pl?action=list_users">[% 'Back' | $T8 %]</a>
+   <a href="controller.pl?action=Admin/list_clients_and_users">[% 'Back' | $T8 %]</a>
 
    <table>
     <tr>
@@ -48,7 +48,7 @@
        </tr>
       </table>
 
-      <input name="callback" type="hidden" value="admin.pl?action=list_users">
+      <input name="callback" type="hidden" value="controller.pl?action=Admin/list_clients_and_users">
 
       <br>
       <input type="submit" class="submit" name="action" value="[% 'Create Dataset' | $T8 %]">
index b42c746..67a19f7 100644 (file)
@@ -1,14 +1,8 @@
 [%- USE T8 %]
 [%- USE HTML %]
-[%- USE LxERP %]
+[%- USE LxERP %][%- USE L -%]
   <h1>[% title %]</h1>
 
-  <form method="post" action="admin.pl">
+  <p>[% LxERP.t8('The dataset #1 has been successfully created.', db) | html %]</p>
 
-   <p>[% LxERP.t8('The dataset #1 has been successfully created.', db) | html %]</p>
-
-   <input type="hidden" name="nextsub" value="list_users">
-
-   <p><input type="submit" class="submit" name="action" value="[% 'Continue' | $T8 %]"></p>
-
-  </form>
+  <p>[% L.link("controller.pl?action=Admin/list_clients_and_users", LxERP.t8("Continue")) %]</p>
index a7aa798..65f3311 100644 (file)
@@ -1,13 +1,8 @@
 [%- USE T8 %]
 [%- USE LxERP %]
-[%- USE HTML %]
+[%- USE HTML %][%- USE L -%]
   <h1>[% title %]</h1>
 
-  <form method="post" action="admin.pl">
+  <p>[% LxERP.t8('The database #1 has been successfully deleted.', db) | html %]</p>
 
-   <p>[% LxERP.t8('The database #1 has been successfully deleted.', db) | html %]</p>
-
-   <input type="hidden" name="nextsub" value="list_users">
-
-   <p><input type="submit" class="submit" name="action" value="[% 'Continue' | $T8 %]"></p>
-  </form>
+  <p>[% L.link("controller.pl?action=Admin/list_clients_and_users", LxERP.t8("Continue")) %]</p>
index b88757a..aa38297 100644 (file)
@@ -1,5 +1,5 @@
 [%- USE T8 %]
-[% USE HTML%]
+[% USE HTML%][%- USE LxERP -%][%- USE L -%]
 [% IF NOTHING_TO_DO %]
  <p>[% 'No datasets have been selected.' | $T8 %]</p>
 
@@ -10,9 +10,4 @@
  <p>[% 'All database upgrades have been applied.' | $T8 %]</p>
 [% END %]
 
-<form method="post" action="admin.pl">
- <input type="hidden" name="nextsub" value="list_users">
-
- <input type="submit" name="action" value="[% 'Continue' | $T8 %]">
-</form>
-
+<p>[% L.link("controller.pl?action=Admin/list_clients_and_users", LxERP.t8("Continue")) %]</p>
index e66dadf..8c99616 100644 (file)
@@ -18,7 +18,7 @@
   <input type="hidden" name="dbpasswd"  value="[% HTML.escape(dbpasswd) %]">
   <input type="hidden" name="dbdefault" value="[% HTML.escape(dbdefault) %]">
 
-  <input name="callback" type="hidden" value="admin.pl?action=list_users">
+  <input name="callback" type="hidden" value="controller.pl?action=Admin/list_clients_and_users">
 
 
   <input type="hidden" name="nextsub" value="dbdelete">
index 67a2d62..0d75e6b 100644 (file)
@@ -1,59 +1,90 @@
 [%- USE T8 %]
-[%- USE HTML %]
+[%- USE HTML %][%- USE LxERP -%][%- USE L -%]
  <h1>[% title %]</h1>
 
  <form method="post" action="admin.pl">
 
-  <p>
-   <table width="100%">
-    <tr>
-     <th class="listtop">[% 'Login Name' | $T8 %]</th>
-     <th class="listtop">[% 'Name' | $T8 %]</th>
-     <th class="listtop">[% 'Company' | $T8 %]</th>
-     <th class="listtop">[% 'Templates' | $T8 %]</th>
-     <th class="listtop">[% 'Print' | $T8 %]</th>
-     <th class="listtop">[% 'Language' | $T8 %]</th>
-     <th class="listtop">[% 'Dataset' | $T8 %]</th>
-     <th class="listtop">[% 'Host' | $T8 %]</th>
-     <th class="listtop">[% 'Last Action' | $T8 %]</th>
-<!-- <th class="listtop">[% 'Driver' | $T8 %]</th> -->
-    </tr>
+  <div class="tabwidget">
+   <ul>
+    <li><a href="#client_list">[%- LxERP.t8("Client list") %]</a></li>
+    <li><a href="#user_list">[%- LxERP.t8("User list") %]</a></li>
+   </ul>
 
-    [% FOREACH row = MEMBERS %]
-     <tr class="listrow[% loop.count % 2 %]">
-      <td>&nbsp;<a href="admin.pl?action=edit&user.id=[% HTML.url(row.id) %]">[% HTML.escape(row.login) %]</a></td>
-      <td>&nbsp;[% HTML.escape(row.name) %]</td>
-      <td>&nbsp;[% HTML.escape(row.company) %]</td>
-      <td>&nbsp;[% HTML.escape(row.templates) %]</td>
-      <td>&nbsp;[% HTML.escape(row.template_format) %]</td>
-      <td>&nbsp;[% HTML.escape(row.countrycode) %]</td>
-      <td>&nbsp;[% HTML.escape(row.dbname) %]</td>
-      <td>&nbsp;[% IF row.dbhost %][% HTML.escape(row.dbhost) %][% ELSE %]localhost[% END %]</td>
-      <td>&nbsp;
-        [% IF( row.last_action ) %]
-          [% HTML.escape(row.last_action) %]
-        [% ELSE %]
-          [% 'not logged in' | $T8 %]
-        [% END %]</td>
-<!--  <td>&nbsp;[% HTML.escape(row.dbdriver) %]</td> -->
+   <div id="client_list">
+[%- IF !CLIENTS.size %]
+    <p>
+     [% LxERP.t8("No clients have been created yet.") %]
+     [% LxERP.t8("In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.") %]
+    </p>
+
+[%- ELSE %]
+    <table width="100%">
+     <tr>
+      <th class="listtop">[% 'Client name' | $T8 %]</th>
+      <th class="listtop">[% 'Database ID' | $T8 %]</th>
+      <th class="listtop">[% 'Database name' | $T8 %]</th>
+      <th class="listtop">[% 'Database Host' | $T8 %]</th>
+      <th class="listtop">[% 'Database User' | $T8 %]</th>
+     </tr>
+
+ [%- FOREACH client = CLIENTS %]
+     <tr class="listrow">
+      <td><a href="admin.pl?action=edit_client&client.id=[% HTML.url(client.id) %]">[% HTML.escape(client.name) %]</a></td>
+      <td>[% HTML.escape(client.id) %]</td>
+      <td>[% HTML.escape(client.dbname) %]</td>
+      <td>[% HTML.escape(client.dbhost) %][% IF client.dbport %]:[%- HTML.escape(client.dbport) %][%- END %]</td>
+      <td>[% HTML.escape(client.dbuser) %]</td>
      </tr>
-    [% END %]
+ [%- END %]
+    </table>
+[%- END %]
+   </div>
 
-   </table>
-  <hr size="3" noshade>
-  </p>
+   <div id="user_list">
+[%- IF !USERS.size %]
+    <p>
+     [% LxERP.t8("No users have been created yet.") %]
+     [% LxERP.t8("In order to use kivitendo you have to create at least one client, one user, and grant that user access to the client.") %]
+    </p>
 
+[%- ELSE %]
+    <table width="100%">
+     <tr>
+      <th class="listtop">[% 'Login Name' | $T8 %]</th>
+      <th class="listtop">[% 'Name' | $T8 %]</th>
+      <th class="listtop">[% 'Language' | $T8 %]</th>
+     </tr>
+
+ [% FOREACH user = USERS %]
+  [%- SET config = user.config_values %]
+     <tr class="listrow">
+      <td><a href="admin.pl?action=edit&user.id=[% HTML.url(user.id) %]">[% HTML.escape(user.login) %]</a></td>
+      <td>[% HTML.escape(config.name) %]</td>
+      <td>[% HTML.escape(config.countrycode) %]</td>
+     </tr>
+ [% END %]
+    </table>
+[%- END %]
+   </div>
+  </div>
 
-  <input type="submit" class="submit" name="action" value="[% 'Add User' | $T8 %]">
-  <input type="submit" class="submit" name="action" value="[% 'Edit groups' | $T8 %]">
-  <input type="submit" class="submit" name="action" value="[% 'Pg Database Administration' | $T8 %]">
-  <input type="submit" class="submit" name="action" value="[% 'Printer Management' | $T8 %]">
+  [% L.link(SELF.url_for(action="add_client"), LxERP.t8("Add Client")) %]
+  <span class="link_separator">|</span>
+  [% L.link(SELF.url_for(action="add_user"), LxERP.t8("Add User")) %]
+  <span class="link_separator">|</span>
+  [% L.link(SELF.url_for(action="edit_groups"), LxERP.t8("Edit groups")) %]
+  <span class="link_separator">|</span>
+  [% L.link(SELF.url_for(action="pg_database_administration", controller="admin.pl"), LxERP.t8("Pg Database Administration")) %]
+  <span class="link_separator">|</span>
+  [% L.link(SELF.url_for(action="printer_management", controller="admin.pl"), LxERP.t8("Printer Management")) %]
+  <span class="link_separator">|</span>
   [% IF LOCKED %]
-   <input type="submit" class="submit" name="action" value="[% 'Unlock System' | $T8 %]">
-   [% ELSE %]
-   <input type="submit" class="submit" name="action" value="[% 'Lock System' | $T8 %]">
+   [% L.link(SELF.url_for(action="unlock_system"), LxERP.t8("Unlock System")) %]
+  [% ELSE %]
+   [% L.link(SELF.url_for(action="lock_system"), LxERP.t8("Lock System")) %]
   [% END %]
-  <input type="submit" class="submit" name="action" value="[% 'Logout' | $T8 %]">
+  <span class="link_separator">|</span>
+  [% L.link(SELF.url_for(action="logout"), LxERP.t8("Logout")) %]
 
   <div style="background-color: #FFFFDA; font-size: 12px; padding: 0.5em; max-width: 720px; margin: 1em;">
   <p>[% 'Click on login name to edit!' | $T8 %]</p>
index baece7d..fd414dc 100644 (file)
@@ -1,6 +1,6 @@
 [%- USE T8 %]
 [%- USE LxERP %]
-[% USE HTML %] </pre>
+[% USE HTML %][%- USE L -%] </pre>
 
  <hr>
 
@@ -9,7 +9,6 @@
   [%- LxERP.t8('The program\'s exit code was #1 (&quot;0&quot; usually means that everything went OK).', retval) | html %]
  </p>
 
- <form method="post" action="admin.pl">
-  <input type="hidden" name="nextsub" value="list_users">
-  <input type="submit" name="action" value="[% 'Continue' | $T8 %]">
- </form>
+ <p>
+  [% L.link("controller.pl?action=Admin/list_clients_and_users", LxERP.t8("Continue")) %]
+ </p>
index 293ab88..fddf5c3 100644 (file)
@@ -39,7 +39,7 @@
 
    <input type="hidden" name="rowcount" value="[% NEED_UPDATES.size %]">
 
-   <input name="callback" type="hidden" value="admin.pl?action=list_users">
+   <input name="callback" type="hidden" value="controller.pl?action=Admin/list_clients_and_users">
    <input type="hidden" name="nextsub" value="dbupdate">
 
    <hr size="3" noshade>
index b1a2a50..187eed4 100644 (file)
@@ -1,10 +1,9 @@
 [%- USE T8 %]
 [% USE HTML %]<p>[% '...done' | $T8 %]</p>
 
-<form action="[% IF is_admin %]admin.pl[% ELSE %]login.pl[% END %]">
+<form action="[% IF is_admin %]controller.pl[% ELSE %]login.pl[% END %]">
 
- <input type="hidden" name="action" value="[% IF is_admin %]login[% ELSE %]company_logo[% END %]">
+ <input type="hidden" name="action" value="[% IF is_admin %]Admin/login[% ELSE %]company_logo[% END %]">
 
  <p><input type="submit" value="[% 'Continue' | $T8 %]"></p>
 </form>
-