Kundenstatistik: Link bei den Rechnungen, Übersetzungen
[kivitendo-erp.git] / SL / Auth.pm
index 5d0b3c8..82be3b8 100644 (file)
@@ -55,12 +55,23 @@ sub init {
 sub reset {
   my ($self, %params) = @_;
 
-  $self->{SESSION}            = { };
-  $self->{FULL_RIGHTS}        = { };
-  $self->{RIGHTS}             = { };
-  $self->{unique_counter}     = 0;
-  $self->{column_information} = SL::Auth::ColumnInformation->new(auth => $self);
-  $self->{column_information}->_fetch;
+  $self->{SESSION}        = { };
+  $self->{FULL_RIGHTS}    = { };
+  $self->{RIGHTS}         = { };
+  $self->{unique_counter} = 0;
+
+  if ($self->is_db_connected) {
+    # reset is called during request shutdown already. In case of a
+    # completely new auth DB this would fail and generate an error
+    # message even if the user is currently trying to create said auth
+    # DB. Therefore only fetch the column information if a connection
+    # has been established.
+    $self->{column_information} = SL::Auth::ColumnInformation->new(auth => $self);
+    $self->{column_information}->_fetch;
+  } else {
+    delete $self->{column_information};
+  }
+
   $self->{authenticator}->reset;
 
   $self->client(undef);
@@ -247,6 +258,7 @@ sub dbconnect {
   $self->{dbh} = SL::DBConnect->connect($dsn, $cfg->{user}, $cfg->{password}, { pg_enable_utf8 => 1, AutoCommit => 1 });
 
   if (!$may_fail && !$self->{dbh}) {
+    delete $self->{dbh};
     $main::form->error($main::locale->text('The connection to the authentication database failed:') . "\n" . $DBI::errstr);
   }
 
@@ -262,6 +274,11 @@ sub dbdisconnect {
   }
 }
 
+sub is_db_connected {
+  my ($self) = @_;
+  return !!$self->{dbh};
+}
+
 sub check_tables {
   my ($self, $dbh)    = @_;
 
@@ -936,7 +953,7 @@ sub all_rights_full {
   my ($self) = @_;
 
   @{ $self->{master_rights} ||= do {
-      $self->dbconnect->selectall_arrayref("SELECT name, description, category FROM auth.master_rights ORDER BY id");
+      $self->dbconnect->selectall_arrayref("SELECT name, description, category FROM auth.master_rights ORDER BY position");
     }
   }
 }
@@ -1060,23 +1077,36 @@ sub evaluate_rights_ary {
 
   my $value  = 0;
   my $action = '|';
+  my $negate = 0;
 
   foreach my $el (@{$ary}) {
     if (ref $el eq "ARRAY") {
+      my $val = evaluate_rights_ary($el);
+      $val    = !$val if $negate;
+      $negate = 0;
       if ($action eq '|') {
-        $value |= evaluate_rights_ary($el);
+        $value |= $val;
       } else {
-        $value &= evaluate_rights_ary($el);
+        $value &= $val;
       }
 
     } elsif (($el eq '&') || ($el eq '|')) {
       $action = $el;
 
+    } elsif ($el eq '!') {
+      $negate = !$negate;
+
     } elsif ($action eq '|') {
-      $value |= $el;
+      my $val = $el;
+      $val    = !$val if $negate;
+      $negate = 0;
+      $value |= $val;
 
     } else {
-      $value &= $el;
+      my $val = $el;
+      $val    = !$val if $negate;
+      $negate = 0;
+      $value &= $val;
 
     }
   }
@@ -1292,6 +1322,11 @@ close the database connection.
 Creating a new database handle on each request can take up to 30% of the
 pre-request startup time, so we want to avoid that for fast ajax calls.
 
+=item C<assert, $right, $dont_abort>
+
+Checks if current user has the C<$right>. If C<$dont_abort> is falsish
+the request dies with a access denied error, otherwise returns true or false.
+
 =back
 
 =head1 BUGS