From 25c9bae99389233f0575602b5e21138279ad6ed5 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Thu, 26 Oct 2023 00:21:30 +0200
Subject: [PATCH 01/15] REL: initiate next release cycle

---
 CHANGELOG.md          | 14 ++++++++++++++
 RELEASE_GUIDELINES.md |  4 ++--
 pom.xml               |  2 +-
 src/doc/conf.py       |  4 ++--
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e13710c7..fc91c68a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [Unreleased]
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Removed
+
+### Fixed
+
+### Security
+
 ## [0.12.0] - 2023-10-25
 (Timm Fitschen)
 
diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md
index 2da13c6e..f6f3c872 100644
--- a/RELEASE_GUIDELINES.md
+++ b/RELEASE_GUIDELINES.md
@@ -40,11 +40,11 @@ guidelines of the CaosDB Project
   * `CHANGELOG.md`: Re-add the `[Unreleased]` section.
 
 11. Add a gitlab release in the respective repository:
-    https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/releases
+    https://gitlab.com/linkahead/linkahead-server/-/releases
 
     Add a description, which can be a copy&paste from the CHANGELOG, possibly prepended by:
     ```md
 # Changelog
 
-[See full changelog](https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/blob/${TAG}/CHANGELOG.md)
+[See full changelog](https://gitlab.com/linkahead/linkahead-server/-/blob/${TAG}/CHANGELOG.md)
     ```
diff --git a/pom.xml b/pom.xml
index 2607b1ed..abe5e282 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.caosdb</groupId>
   <artifactId>caosdb-server</artifactId>
-  <version>0.12.0</version>
+  <version>0.13.0-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>CaosDB Server</name>
   <scm>
diff --git a/src/doc/conf.py b/src/doc/conf.py
index 57b60c2b..530d8d65 100644
--- a/src/doc/conf.py
+++ b/src/doc/conf.py
@@ -26,9 +26,9 @@ copyright = '2023, IndiScale GmbH'
 author = 'Daniel Hornung, Timm Fitschen'
 
 # The short X.Y version
-version = '0.12.0'
+version = '0.13.0'
 # The full version, including alpha/beta/rc tags
-release = '0.12.0'
+release = '0.13.0-dev'
 
 
 # -- General configuration ---------------------------------------------------
-- 
GitLab


From 77c77cb70f1c6dd9e41671fa9fb5b34112d5286f Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Thu, 2 Nov 2023 09:41:49 +0100
Subject: [PATCH 02/15] MAINT: cleanup unused classes

---
 .../java/org/caosdb/server/CaosDBServer.java  |   7 -
 .../server/database/BackendTransaction.java   |   6 -
 .../MySQL/MySQLInsertLogRecord.java           |  60 ---------
 .../MySQL/MySQLRetrieveLogRecord.java         | 125 ------------------
 .../interfaces/InsertLogRecordImpl.java       |  32 -----
 .../interfaces/RetrieveLogRecordImpl.java     |  33 -----
 .../backend/transaction/InsertLogRecord.java  |  44 ------
 .../transaction/RetrieveLogRecord.java        |  54 --------
 .../server/resource/ServerLogsResource.java   |  83 ------------
 .../InsertLogRecordTransaction.java           |  56 --------
 .../RetrieveLogRecordTransaction.java         |  84 ------------
 11 files changed, 584 deletions(-)
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java
 delete mode 100644 src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java
 delete mode 100644 src/main/java/org/caosdb/server/resource/ServerLogsResource.java
 delete mode 100644 src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java
 delete mode 100644 src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java

diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java
index 8c75cf51..4b7c0fe1 100644
--- a/src/main/java/org/caosdb/server/CaosDBServer.java
+++ b/src/main/java/org/caosdb/server/CaosDBServer.java
@@ -73,7 +73,6 @@ import org.caosdb.server.resource.LogoutResource;
 import org.caosdb.server.resource.PermissionRulesResource;
 import org.caosdb.server.resource.RolesResource;
 import org.caosdb.server.resource.ScriptingResource;
-import org.caosdb.server.resource.ServerLogsResource;
 import org.caosdb.server.resource.ServerPropertiesResource;
 import org.caosdb.server.resource.SharedFileResource;
 import org.caosdb.server.resource.ThumbnailsResource;
@@ -746,12 +745,6 @@ public class CaosDBServer extends Application {
     protectedRouter.attach("/Role/{specifier}", RolesResource.class);
     protectedRouter.attach("/PermissionRules/{specifier}", PermissionRulesResource.class);
     protectedRouter.attach("/PermissionRules/{realm}/{specifier}", PermissionRulesResource.class);
-    protectedRouter
-        .attach("/ServerLogs/", ServerLogsResource.class)
-        .setMatchingMode(Template.MODE_STARTS_WITH);
-    protectedRouter
-        .attach("/ServerLogs", ServerLogsResource.class)
-        .setMatchingMode(Template.MODE_STARTS_WITH);
     protectedRouter.attach("/login?username={username}", AuthenticationResource.class);
     protectedRouter.attach("/logout", LogoutResource.class);
     protectedRouter.attach("/_server_properties", ServerPropertiesResource.class);
diff --git a/src/main/java/org/caosdb/server/database/BackendTransaction.java b/src/main/java/org/caosdb/server/database/BackendTransaction.java
index c014972a..534c7bc1 100644
--- a/src/main/java/org/caosdb/server/database/BackendTransaction.java
+++ b/src/main/java/org/caosdb/server/database/BackendTransaction.java
@@ -37,7 +37,6 @@ import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetUpdateabl
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityDatatype;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityProperties;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertLinCon;
-import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertLogRecord;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertParents;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertRole;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertSparseEntity;
@@ -51,7 +50,6 @@ import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAllU
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveCurrentMaxId;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveDatatypes;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveEntityACL;
-import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveLogRecord;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveParents;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePasswordValidator;
 import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePermissionRules;
@@ -95,7 +93,6 @@ import org.caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl;
 import org.caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl;
 import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl;
 import org.caosdb.server.database.backend.interfaces.InsertLinConImpl;
-import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl;
 import org.caosdb.server.database.backend.interfaces.InsertParentsImpl;
 import org.caosdb.server.database.backend.interfaces.InsertRoleImpl;
 import org.caosdb.server.database.backend.interfaces.InsertSparseEntityImpl;
@@ -109,7 +106,6 @@ import org.caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesIm
 import org.caosdb.server.database.backend.interfaces.RetrieveCurrentMaxIdImpl;
 import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl;
 import org.caosdb.server.database.backend.interfaces.RetrieveEntityACLImpl;
-import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl;
 import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl;
 import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl;
 import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl;
@@ -213,8 +209,6 @@ public abstract class BackendTransaction implements Undoable {
       setImpl(SetPermissionRulesImpl.class, MySQLSetPermissionRules.class);
       setImpl(RetrievePermissionRulesImpl.class, MySQLRetrievePermissionRules.class);
       setImpl(UpdateUserRolesImpl.class, MySQLUpdateUserRoles.class);
-      setImpl(InsertLogRecordImpl.class, MySQLInsertLogRecord.class);
-      setImpl(RetrieveLogRecordImpl.class, MySQLRetrieveLogRecord.class);
       setImpl(SetQueryTemplateDefinitionImpl.class, MySQLSetQueryTemplateDefinition.class);
       setImpl(
           RetrieveQueryTemplateDefinitionImpl.class, MySQLRetrieveQueryTemplateDefinition.class);
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java
deleted file mode 100644
index 6807808d..00000000
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.implementation.MySQL;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.access.Access;
-import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public class MySQLInsertLogRecord extends MySQLTransaction implements InsertLogRecordImpl {
-
-  public MySQLInsertLogRecord(final Access access) {
-    super(access);
-  }
-
-  public static final String STMT_INSERT_LOG_RECORD =
-      "INSERT INTO logging (level, logger, message, millis, logRecord) VALUES (?,?,?,?,?)";
-
-  @Override
-  public void insert(final List<LogRecord> toBeFlushed) throws TransactionException {
-    try {
-      final PreparedStatement prepInsert = prepareStatement(STMT_INSERT_LOG_RECORD);
-      for (final LogRecord record : toBeFlushed) {
-        prepInsert.setInt(1, record.getLevel().intValue());
-        prepInsert.setString(2, record.getLoggerName());
-        prepInsert.setString(3, record.getMessage());
-        prepInsert.setLong(4, record.getMillis());
-        prepInsert.setObject(5, record);
-        prepInsert.executeUpdate();
-      }
-    } catch (final SQLException e) {
-      throw new TransactionException(e);
-    } catch (final ConnectionException e) {
-      throw new TransactionException(e);
-    }
-  }
-}
diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java
deleted file mode 100644
index bba36d2e..00000000
--- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.implementation.MySQL;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.access.Access;
-import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public class MySQLRetrieveLogRecord extends MySQLTransaction implements RetrieveLogRecordImpl {
-
-  public MySQLRetrieveLogRecord(final Access access) {
-    super(access);
-  }
-
-  public static final String STMT_RETRIEVE_LOG = "SELECT logRecord FROM logging";
-  public static final String WHERE = " WHERE ";
-  public static final String AND = " AND ";
-  public static final String LOGGER_COND = "logger LIKE ?";
-  public static final String MESSAGE_COND = "message LIKE ?";
-
-  public static final String LEVEL_COND(final Level level) {
-    return "level=" + level.intValue();
-  }
-
-  private static String getWhereClause(
-      final String logger, final Level level, final String message) {
-
-    if (logger != null || level != null || message != null) {
-      final StringBuilder sb = new StringBuilder();
-
-      if (logger != null) {
-        sb.append(LOGGER_COND);
-      }
-      if (level != null) {
-        if (sb.length() > 0) {
-          sb.append(AND);
-        }
-        sb.append(LEVEL_COND(level));
-      }
-      if (message != null) {
-        if (sb.length() > 0) {
-          sb.append(AND);
-        }
-        sb.append(MESSAGE_COND);
-      }
-      return WHERE + sb.toString();
-    }
-    return "";
-  }
-
-  @Override
-  public List<LogRecord> retrieve(final String logger, final Level level, final String message)
-      throws TransactionException {
-    final List<LogRecord> ret = new LinkedList<LogRecord>();
-
-    final String stmtStr = STMT_RETRIEVE_LOG + getWhereClause(logger, level, message);
-
-    try {
-      final PreparedStatement stmt = prepareStatement(stmtStr);
-      int index = 1;
-      if (logger != null) {
-        stmt.setString(index++, logger);
-      }
-      if (message != null) {
-        stmt.setString(index++, message);
-      }
-      ResultSet rs = null;
-      try {
-        rs = stmt.executeQuery();
-
-        while (rs.next()) {
-          final byte[] bytes = rs.getBytes("logRecord");
-
-          final ObjectInputStream s = new ObjectInputStream(new ByteArrayInputStream(bytes));
-          final Object o = s.readObject();
-          ret.add((LogRecord) o);
-        }
-      } finally {
-        if (rs != null && !rs.isClosed()) {
-          rs.close();
-        }
-      }
-    } catch (final ClassNotFoundException e) {
-      throw new TransactionException(e);
-    } catch (final IOException e) {
-      throw new TransactionException(e);
-    } catch (final SQLException e) {
-      throw new TransactionException(e);
-    } catch (final ConnectionException e) {
-      throw new TransactionException(e);
-    }
-
-    return ret;
-  }
-}
diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java
deleted file mode 100644
index 78bab8e2..00000000
--- a/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.interfaces;
-
-import java.util.List;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public interface InsertLogRecordImpl extends BackendTransactionImpl {
-
-  public void insert(List<LogRecord> toBeFlushed) throws TransactionException;
-}
diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java
deleted file mode 100644
index b6646d26..00000000
--- a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.interfaces;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public interface RetrieveLogRecordImpl extends BackendTransactionImpl {
-
-  List<LogRecord> retrieve(String logger, Level level, String message) throws TransactionException;
-}
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java
deleted file mode 100644
index 3ce27add..00000000
--- a/src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.transaction;
-
-import java.util.List;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.BackendTransaction;
-import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public class InsertLogRecord extends BackendTransaction {
-
-  private final List<LogRecord> toBeFlushed;
-
-  public InsertLogRecord(final List<LogRecord> toBeFlushed) {
-    this.toBeFlushed = toBeFlushed;
-  }
-
-  @Override
-  protected void execute() throws TransactionException {
-    final InsertLogRecordImpl t = getImplementation(InsertLogRecordImpl.class);
-    t.insert(this.toBeFlushed);
-  }
-}
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java
deleted file mode 100644
index eae8a965..00000000
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.database.backend.transaction;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import org.caosdb.server.database.BackendTransaction;
-import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl;
-import org.caosdb.server.database.exceptions.TransactionException;
-
-public class RetrieveLogRecord extends BackendTransaction {
-
-  private final Level level;
-  private final String logger;
-  private List<LogRecord> logRecords;
-  private final String message;
-
-  public RetrieveLogRecord(final String logger, final Level level, final String message) {
-    this.logger = logger;
-    this.level = level;
-    this.message = message;
-  }
-
-  @Override
-  protected void execute() throws TransactionException {
-    final RetrieveLogRecordImpl t = getImplementation(RetrieveLogRecordImpl.class);
-    this.logRecords = t.retrieve(this.logger, this.level, this.message);
-  }
-
-  public List<LogRecord> getLogRecords() {
-    return this.logRecords;
-  }
-}
diff --git a/src/main/java/org/caosdb/server/resource/ServerLogsResource.java b/src/main/java/org/caosdb/server/resource/ServerLogsResource.java
deleted file mode 100644
index acc1833d..00000000
--- a/src/main/java/org/caosdb/server/resource/ServerLogsResource.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.resource;
-
-import java.io.IOException;
-import java.security.NoSuchAlgorithmException;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.XMLFormatter;
-import org.caosdb.server.CaosDBException;
-import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException;
-import org.caosdb.server.transaction.RetrieveLogRecordTransaction;
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-
-public class ServerLogsResource extends AbstractCaosDBServerResource {
-
-  @Override
-  protected Representation httpGetInChildClass()
-      throws ConnectionException,
-          IOException,
-          SQLException,
-          CaosDBException,
-          NoSuchAlgorithmException,
-          Exception {
-
-    Level level = null;
-    String message = null;
-    final String logger =
-        getRequest().getResourceRef().getRemainingPart(true, false).replaceAll("/", ".");
-    final Form form = getRequest().getResourceRef().getQueryAsForm(true);
-    if (form != null) {
-      final String levelStr = form.getFirstValue("level");
-      if (levelStr != null) {
-        try {
-          level = Level.parse(levelStr);
-        } catch (final IllegalArgumentException e) {
-          level = Level.OFF;
-        }
-      }
-      message = form.getFirstValue("message");
-    }
-
-    final RetrieveLogRecordTransaction t = new RetrieveLogRecordTransaction(logger, level, message);
-    t.execute();
-
-    generateRootElement();
-    final List<LogRecord> logRecords = t.getLogRecords();
-
-    final XMLFormatter xmlFormatter = new XMLFormatter();
-    String ret = xmlFormatter.getHead(null);
-    for (final LogRecord r : logRecords) {
-      ret += xmlFormatter.format(r);
-    }
-    ret += xmlFormatter.getTail(null);
-
-    return new StringRepresentation(ret, MediaType.TEXT_XML);
-  }
-}
diff --git a/src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java b/src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java
deleted file mode 100644
index 950d9b8d..00000000
--- a/src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.transaction;
-
-import java.util.List;
-import java.util.logging.LogRecord;
-import org.caosdb.datetime.UTCDateTime;
-import org.caosdb.server.database.DatabaseAccessManager;
-import org.caosdb.server.database.access.Access;
-import org.caosdb.server.database.backend.transaction.InsertLogRecord;
-
-public class InsertLogRecordTransaction implements TransactionInterface {
-
-  private final List<LogRecord> toBeFlushed;
-  private UTCDateTime timestamp;
-
-  public InsertLogRecordTransaction(final List<LogRecord> toBeFlushed) {
-    this.timestamp = UTCDateTime.SystemMillisToUTCDateTime(System.currentTimeMillis());
-    this.toBeFlushed = toBeFlushed;
-  }
-
-  @Override
-  public void execute() throws Exception {
-    final Access access = DatabaseAccessManager.getInstance().acquireReadAccess(this);
-    try {
-      execute(new InsertLogRecord(this.toBeFlushed), access);
-    } finally {
-      access.release();
-    }
-  }
-
-  @Override
-  public UTCDateTime getTimestamp() {
-    return timestamp;
-  }
-}
diff --git a/src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java
deleted file mode 100644
index 2f6cafd6..00000000
--- a/src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ** header v3.0
- * This file is a part of the CaosDB Project.
- *
- * Copyright (C) 2018 Research Group Biomedical Physics,
- * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- * ** end header
- */
-package org.caosdb.server.transaction;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import org.apache.shiro.SecurityUtils;
-import org.caosdb.datetime.UTCDateTime;
-import org.caosdb.server.accessControl.ACMPermissions;
-import org.caosdb.server.database.DatabaseAccessManager;
-import org.caosdb.server.database.access.Access;
-import org.caosdb.server.database.backend.transaction.RetrieveLogRecord;
-
-public class RetrieveLogRecordTransaction implements TransactionInterface {
-
-  private List<LogRecord> logRecords;
-  private final String logger;
-  private final Level level;
-  private final String message;
-  private UTCDateTime timestamp;
-
-  public RetrieveLogRecordTransaction(
-      final String logger, final Level level, final String message) {
-    this.level = level;
-    this.timestamp = UTCDateTime.SystemMillisToUTCDateTime(System.currentTimeMillis());
-    if (message != null && message.isEmpty()) {
-      this.message = null;
-    } else if (message != null) {
-      this.message = message.replaceAll("\\*", "%");
-    } else {
-      this.message = null;
-    }
-    if (logger != null && logger.isEmpty()) {
-      this.logger = null;
-    } else if (logger != null) {
-      this.logger = logger.replaceAll("\\*", "%");
-    } else {
-      this.logger = logger;
-    }
-  }
-
-  @Override
-  public void execute() throws Exception {
-    SecurityUtils.getSubject().checkPermission(ACMPermissions.PERMISSION_RETRIEVE_SERVERLOGS);
-    final Access access = DatabaseAccessManager.getInstance().acquireReadAccess(this);
-    try {
-      this.logRecords =
-          execute(new RetrieveLogRecord(this.logger, this.level, this.message), access)
-              .getLogRecords();
-    } finally {
-      access.release();
-    }
-  }
-
-  public List<LogRecord> getLogRecords() {
-    return this.logRecords;
-  }
-
-  @Override
-  public UTCDateTime getTimestamp() {
-    return timestamp;
-  }
-}
-- 
GitLab


From 89af47e233256e90f30d98c2973b331aa25e2bd4 Mon Sep 17 00:00:00 2001
From: fspreck <f.spreckelsen@indiscale.com>
Date: Fri, 24 Nov 2023 16:14:43 +0100
Subject: [PATCH 03/15] DOC: Improve inline comments in usersource.ini.template

---
 conf/core/usersources.ini.template | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/conf/core/usersources.ini.template b/conf/core/usersources.ini.template
index fb328572..d54d91d2 100644
--- a/conf/core/usersources.ini.template
+++ b/conf/core/usersources.ini.template
@@ -46,11 +46,14 @@ class = org.caosdb.server.accessControl.Pam
 # scripts or the misc/pam_authentication/ldap_authentication.sh script here.
 ; pam_script = ./misc/pam_authentication/pam_authentication.sh
 default_status = ACTIVE
-# Only users which fulfill these criteria are accepted.
+# Only users which fulfill these criteria are accepted. The values are
+# user/group name(s) separated by whitespaces
 ;include.user = [uncomment and put your users here]
 ;include.group = [uncomment and put your groups here]
 ;exclude.user = [uncomment and put excluded users here]
 ;exclude.group = [uncomment and put excluded groups here]
 
 # It is typically necessary to add at least one admin
-;user.[uncomment a set a username here].roles = administration
+;user.[uncomment and set a username here].roles = administration
+# Several roles are separated by commas
+;user.[uncomment and set a username here].roles = role1, role2, role with spaces
-- 
GitLab


From f832e3f5e0b8f4a0d10134dee5427e0e8a2611c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 11:31:05 +0100
Subject: [PATCH 04/15] wip

---
 .../transaction/RetrieveFullEntityTransaction.java       | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index 92f5aa84..f5b897ad 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -26,6 +26,7 @@ package org.caosdb.server.database.backend.transaction;
 
 import java.util.LinkedList;
 import java.util.List;
+import org.apache.shiro.SecurityUtils;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
 import org.caosdb.server.datatype.CollectionValue;
@@ -38,6 +39,8 @@ import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.container.Container;
 import org.caosdb.server.entity.wrapper.Property;
+import org.caosdb.server.permissions.EntityACL;
+import org.caosdb.server.permissions.EntityPermission;
 import org.caosdb.server.query.Query;
 import org.caosdb.server.query.Query.Selection;
 import org.caosdb.server.utils.EntityStatus;
@@ -220,6 +223,12 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
   private void resolveReferenceValue(
       final ReferenceValue value, final List<Selection> selections, final String propertyName) {
     final RetrieveEntity ref = new RetrieveEntity(value.getId());
+
+    // check whether the referenced entity may be retrieved
+    final EntityACL entityACL = ref.getEntityACL();
+    if (!entityACL.isPermitted(SecurityUtils.getSubject(), EntityPermission.RETRIEVE_ENTITY)) {
+      return;
+    }
     // recursion! (Only for the matching selections)
     retrieveFullEntity(ref, getSubSelects(selections, propertyName));
     value.setEntity(ref, true);
-- 
GitLab


From 692181d358f042773c47395495c95502b982f0c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:15:46 +0100
Subject: [PATCH 05/15] wip

---
 .../backend/transaction/RetrieveFullEntityTransaction.java | 7 +++++--
 src/main/java/org/caosdb/server/entity/RetrieveEntity.java | 2 ++
 src/main/java/org/caosdb/server/query/Query.java           | 4 ++++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index f5b897ad..a45a86a1 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -31,6 +31,7 @@ import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
 import org.caosdb.server.datatype.CollectionValue;
 import org.caosdb.server.datatype.IndexedSingleValue;
+import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.datatype.ReferenceValue;
 import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.EntityInterface;
@@ -60,6 +61,7 @@ import org.caosdb.server.utils.EntityStatus;
 public class RetrieveFullEntityTransaction extends BackendTransaction {
 
   private final Container<? extends EntityInterface> container;
+  private final Principal principal;
 
   public RetrieveFullEntityTransaction(final EntityInterface entity) {
     final Container<EntityInterface> c = new Container<>();
@@ -67,8 +69,9 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     this.container = c;
   }
 
-  public RetrieveFullEntityTransaction(final Container<? extends EntityInterface> container) {
+  public RetrieveFullEntityTransaction(final Container<? extends EntityInterface> container, final Principal principal) {
     this.container = container;
+    this.principal = principal;
   }
 
   public RetrieveFullEntityTransaction(final EntityID id) {
@@ -226,7 +229,7 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
 
     // check whether the referenced entity may be retrieved
     final EntityACL entityACL = ref.getEntityACL();
-    if (!entityACL.isPermitted(SecurityUtils.getSubject(), EntityPermission.RETRIEVE_ENTITY)) {
+    if (!entityACL.isPermitted(this.principal, EntityPermission.RETRIEVE_ENTITY)) {
       return;
     }
     // recursion! (Only for the matching selections)
diff --git a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
index 00a120fb..887e7d12 100644
--- a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
+++ b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
@@ -24,6 +24,8 @@
  */
 package org.caosdb.server.entity;
 
+//TODO document the use of this class; it seems to exist of only constructors
+
 public class RetrieveEntity extends Entity {
 
   public RetrieveEntity() {
diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index 117176ec..29361d3a 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -77,6 +77,10 @@ import org.caosdb.server.transaction.WriteTransaction;
 import org.jdom2.Element;
 import org.slf4j.Logger;
 
+
+// TODO Document: The query is initialized with a RetrieveTransaction and its
+// Container. The container is filled by the Query with the resulting IDs. The
+// Retrieve transaction then handles the retrieve of all respective Entities.
 public class Query implements QueryInterface, ToElementable, EntityTransactionInterface {
 
   /** Class which represents the selection of (sub)properties. */
-- 
GitLab


From d10a588130c9e37145356077f65944b86c2f46a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:31:20 +0100
Subject: [PATCH 06/15] wip

---
 .../RetrieveFullEntityTransaction.java        | 26 ++++++++++++-------
 .../caosdb/server/entity/RetrieveEntity.java  |  2 +-
 .../java/org/caosdb/server/query/Query.java   |  1 -
 .../caosdb/server/transaction/Retrieve.java   |  2 +-
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index a45a86a1..e4d198c2 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -26,12 +26,11 @@ package org.caosdb.server.database.backend.transaction;
 
 import java.util.LinkedList;
 import java.util.List;
-import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
 import org.caosdb.server.datatype.CollectionValue;
 import org.caosdb.server.datatype.IndexedSingleValue;
-import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.datatype.ReferenceValue;
 import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.EntityInterface;
@@ -61,17 +60,24 @@ import org.caosdb.server.utils.EntityStatus;
 public class RetrieveFullEntityTransaction extends BackendTransaction {
 
   private final Container<? extends EntityInterface> container;
-  private final Principal principal;
+  private final Subject subject;
 
   public RetrieveFullEntityTransaction(final EntityInterface entity) {
     final Container<EntityInterface> c = new Container<>();
     c.add(entity);
     this.container = c;
+    this.subject = null;
   }
 
-  public RetrieveFullEntityTransaction(final Container<? extends EntityInterface> container, final Principal principal) {
+  public RetrieveFullEntityTransaction(
+      final Container<? extends EntityInterface> container, final Subject subject) {
     this.container = container;
-    this.principal = principal;
+    this.subject = subject;
+  }
+
+  public RetrieveFullEntityTransaction(final Container<? extends EntityInterface> container) {
+    this.container = container;
+    this.subject = null;
   }
 
   public RetrieveFullEntityTransaction(final EntityID id) {
@@ -227,10 +233,12 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
       final ReferenceValue value, final List<Selection> selections, final String propertyName) {
     final RetrieveEntity ref = new RetrieveEntity(value.getId());
 
-    // check whether the referenced entity may be retrieved
-    final EntityACL entityACL = ref.getEntityACL();
-    if (!entityACL.isPermitted(this.principal, EntityPermission.RETRIEVE_ENTITY)) {
-      return;
+    if (this.subject != null) {
+      // check whether the referenced entity may be retrieved
+      final EntityACL entityACL = ref.getEntityACL();
+      if (!entityACL.isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
+        return;
+      }
     }
     // recursion! (Only for the matching selections)
     retrieveFullEntity(ref, getSubSelects(selections, propertyName));
diff --git a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
index 887e7d12..69df103a 100644
--- a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
+++ b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
@@ -24,7 +24,7 @@
  */
 package org.caosdb.server.entity;
 
-//TODO document the use of this class; it seems to exist of only constructors
+// TODO document the use of this class; it seems to exist of only constructors
 
 public class RetrieveEntity extends Entity {
 
diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index 29361d3a..507dc9d4 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -77,7 +77,6 @@ import org.caosdb.server.transaction.WriteTransaction;
 import org.jdom2.Element;
 import org.slf4j.Logger;
 
-
 // TODO Document: The query is initialized with a RetrieveTransaction and its
 // Container. The container is filled by the Query with the resulting IDs. The
 // Retrieve transaction then handles the retrieve of all respective Entities.
diff --git a/src/main/java/org/caosdb/server/transaction/Retrieve.java b/src/main/java/org/caosdb/server/transaction/Retrieve.java
index 643c1201..54500c59 100644
--- a/src/main/java/org/caosdb/server/transaction/Retrieve.java
+++ b/src/main/java/org/caosdb/server/transaction/Retrieve.java
@@ -114,7 +114,7 @@ public class Retrieve extends Transaction<RetrieveContainer> {
 
   private void retrieveFullEntities(final RetrieveContainer container, final Access access)
       throws Exception {
-    execute(new RetrieveFullEntityTransaction(container), access);
+    execute(new RetrieveFullEntityTransaction(container, getTransactor()), access);
   }
 
   @Override
-- 
GitLab


From 543beea1d88a2eb5cf59f225529db547cfeba404 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:40:20 +0100
Subject: [PATCH 07/15] wip

---
 .../backend/transaction/RetrieveFullEntityTransaction.java       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index e4d198c2..3a42e0dd 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -234,6 +234,7 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     final RetrieveEntity ref = new RetrieveEntity(value.getId());
 
     if (this.subject != null) {
+        System.out.println(this.subject.getUsername())
       // check whether the referenced entity may be retrieved
       final EntityACL entityACL = ref.getEntityACL();
       if (!entityACL.isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
-- 
GitLab


From 0ba66b383eb0c5a6fc5647c6964cbb3a0e85e703 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:43:37 +0100
Subject: [PATCH 08/15] up

---
 .../backend/transaction/RetrieveFullEntityTransaction.java    | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index 3a42e0dd..e407935f 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -27,8 +27,10 @@ package org.caosdb.server.database.backend.transaction;
 import java.util.LinkedList;
 import java.util.List;
 import org.apache.shiro.subject.Subject;
+
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
+import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.datatype.CollectionValue;
 import org.caosdb.server.datatype.IndexedSingleValue;
 import org.caosdb.server.datatype.ReferenceValue;
@@ -234,7 +236,7 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     final RetrieveEntity ref = new RetrieveEntity(value.getId());
 
     if (this.subject != null) {
-        System.out.println(this.subject.getUsername())
+      System.out.println(((Principal) this.subject.getPrincipal()).getUsername());
       // check whether the referenced entity may be retrieved
       final EntityACL entityACL = ref.getEntityACL();
       if (!entityACL.isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
-- 
GitLab


From 73494876176fea77382e66753897bbc9324badcf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:45:19 +0100
Subject: [PATCH 09/15] up

---
 .../backend/transaction/RetrieveFullEntityTransaction.java     | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index e407935f..6143091a 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -27,10 +27,9 @@ package org.caosdb.server.database.backend.transaction;
 import java.util.LinkedList;
 import java.util.List;
 import org.apache.shiro.subject.Subject;
-
+import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
-import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.datatype.CollectionValue;
 import org.caosdb.server.datatype.IndexedSingleValue;
 import org.caosdb.server.datatype.ReferenceValue;
-- 
GitLab


From 9b088c44e265de47493f5b456296d0416677d2da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Sat, 2 Dec 2023 12:51:34 +0100
Subject: [PATCH 10/15] wip

---
 caosdb-webui                                             | 2 +-
 .../transaction/RetrieveFullEntityTransaction.java       | 9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/caosdb-webui b/caosdb-webui
index d5f9090e..e6fef9f3 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit d5f9090eca25a92fc44dbeeba305768e8d9f4bcb
+Subproject commit e6fef9f35da49dfea5b11f99b872d15c35fd043d
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index 6143091a..7ed78405 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -236,15 +236,18 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
 
     if (this.subject != null) {
       System.out.println(((Principal) this.subject.getPrincipal()).getUsername());
+
+      // final EntityInterface e =
+      // execute(new RetrieveSparseEntity(q.getKey(), null), query.getAccess()).getEntity();
       // check whether the referenced entity may be retrieved
+      // recursion! (Only for the matching selections)
+      retrieveFullEntity(ref, getSubSelects(selections, propertyName));
       final EntityACL entityACL = ref.getEntityACL();
       if (!entityACL.isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
         return;
       }
+      value.setEntity(ref, true);
     }
-    // recursion! (Only for the matching selections)
-    retrieveFullEntity(ref, getSubSelects(selections, propertyName));
-    value.setEntity(ref, true);
   }
 
   /**
-- 
GitLab


From b7e714e65e5576a86f50457e91f69eaab7136d60 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Fri, 8 Dec 2023 14:55:31 +0100
Subject: [PATCH 11/15] BUG: Fix filtering of unreadable referenced entities in
 queries

---
 .../RetrieveFullEntityTransaction.java        |  30 +---
 .../entity/xml/EntityToElementStrategy.java   |  14 +-
 .../java/org/caosdb/server/query/POV.java     |  12 +-
 .../caosdb/server/transaction/UpdateACL.java  |   3 +-
 .../server/transaction/WriteTransaction.java  |   4 +-
 .../transaction/RetrieveFullEntityTest.java   | 169 +++++++++++++++++-
 6 files changed, 198 insertions(+), 34 deletions(-)

diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
index 7ed78405..bfb1497d 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTransaction.java
@@ -27,7 +27,6 @@ package org.caosdb.server.database.backend.transaction;
 import java.util.LinkedList;
 import java.util.List;
 import org.apache.shiro.subject.Subject;
-import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.database.BackendTransaction;
 import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
 import org.caosdb.server.datatype.CollectionValue;
@@ -40,7 +39,6 @@ import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.Role;
 import org.caosdb.server.entity.container.Container;
 import org.caosdb.server.entity.wrapper.Property;
-import org.caosdb.server.permissions.EntityACL;
 import org.caosdb.server.permissions.EntityPermission;
 import org.caosdb.server.query.Query;
 import org.caosdb.server.query.Query.Selection;
@@ -63,11 +61,10 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
   private final Container<? extends EntityInterface> container;
   private final Subject subject;
 
-  public RetrieveFullEntityTransaction(final EntityInterface entity) {
-    final Container<EntityInterface> c = new Container<>();
-    c.add(entity);
-    this.container = c;
-    this.subject = null;
+  @SuppressWarnings("unchecked")
+  public RetrieveFullEntityTransaction(final EntityInterface entity, Subject subject) {
+    this(new Container<>(), subject);
+    ((Container<EntityInterface>) this.container).add(entity);
   }
 
   public RetrieveFullEntityTransaction(
@@ -76,13 +73,8 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     this.subject = subject;
   }
 
-  public RetrieveFullEntityTransaction(final Container<? extends EntityInterface> container) {
-    this.container = container;
-    this.subject = null;
-  }
-
-  public RetrieveFullEntityTransaction(final EntityID id) {
-    this(new RetrieveEntity(id));
+  public RetrieveFullEntityTransaction(final EntityID id, Subject subject) {
+    this(new RetrieveEntity(id), subject);
   }
 
   @Override
@@ -235,15 +227,11 @@ public class RetrieveFullEntityTransaction extends BackendTransaction {
     final RetrieveEntity ref = new RetrieveEntity(value.getId());
 
     if (this.subject != null) {
-      System.out.println(((Principal) this.subject.getPrincipal()).getUsername());
-
-      // final EntityInterface e =
-      // execute(new RetrieveSparseEntity(q.getKey(), null), query.getAccess()).getEntity();
-      // check whether the referenced entity may be retrieved
       // recursion! (Only for the matching selections)
       retrieveFullEntity(ref, getSubSelects(selections, propertyName));
-      final EntityACL entityACL = ref.getEntityACL();
-      if (!entityACL.isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
+
+      // check whether the referenced entity is readable
+      if (!ref.getEntityACL().isPermitted(this.subject, EntityPermission.RETRIEVE_ENTITY)) {
         return;
       }
       value.setEntity(ref, true);
diff --git a/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java
index 35d94aa7..bbe1749c 100644
--- a/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java
+++ b/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java
@@ -169,14 +169,16 @@ public class EntityToElementStrategy implements ToElementStrategy {
         // processing SELECT Queries.
         final EntityInterface ref = ((ReferenceValue) entity.getValue()).getEntity();
         if (ref != null) {
-          if (entity.hasDatatype()) {
-            setDatatype(entity, element);
-          }
           ref.addToElement(element, serializeFieldStrategy);
-          // the referenced entity has been appended. Return here to suppress
-          // adding the reference id as well.
-          return;
+        } else {
+          entity.getValue().addToElement(element);
+        }
+        if (entity.hasDatatype()) {
+          setDatatype(entity, element);
         }
+        // the referenced entity has been appended. Return here to suppress
+        // adding the reference id as well.
+        return;
       } else if (entity.isReferenceList() && serializeFieldStrategy.isToBeSet("_referenced")) {
         // Append the all referenced entities. This needs to be done when we are
         // processing SELECT Queries.
diff --git a/src/main/java/org/caosdb/server/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java
index 6ee5f9d0..597495f2 100644
--- a/src/main/java/org/caosdb/server/query/POV.java
+++ b/src/main/java/org/caosdb/server/query/POV.java
@@ -405,6 +405,12 @@ public class POV implements EntityFilterInterface {
     }
     final long t2 = System.currentTimeMillis();
     query.addBenchmark(measurement(".initPOVRefidsTable()"), t2 - t1);
+
+    if (this.refIdsTable != null) {
+      query.getQuery().filterIntermediateResult(this.refIdsTable);
+    }
+    final long t3 = System.currentTimeMillis();
+    query.addBenchmark(measurement(".filterRefidsWithoutRetrievePermission"), t3 - t2);
     try (PreparedStatement stmt =
         query.getConnection().prepareCall("call initPOVPropertiesTable(?,?,?)")) {
       // initPOVPropertiesTable(in pid INT UNSIGNED, in pname
@@ -455,12 +461,12 @@ public class POV implements EntityFilterInterface {
         }
       }
     }
-    final long t3 = System.currentTimeMillis();
-    query.addBenchmark(measurement(""), t3 - t2);
+    final long t4 = System.currentTimeMillis();
+    query.addBenchmark(measurement(""), t4 - t3);
 
     if (this.refIdsTable != null) {
       query.getQuery().applyQueryTemplates(query, this.refIdsTable);
-      query.addBenchmark(measurement(".applyQueryTemplates()"), System.currentTimeMillis() - t3);
+      query.addBenchmark(measurement(".applyQueryTemplates()"), System.currentTimeMillis() - t4);
     }
 
     if (hasSubProperty() && this.targetSet != null) {
diff --git a/src/main/java/org/caosdb/server/transaction/UpdateACL.java b/src/main/java/org/caosdb/server/transaction/UpdateACL.java
index 289b5d53..4bb27c23 100644
--- a/src/main/java/org/caosdb/server/transaction/UpdateACL.java
+++ b/src/main/java/org/caosdb/server/transaction/UpdateACL.java
@@ -67,7 +67,8 @@ public class UpdateACL extends Transaction<TransactionContainer>
       oldContainer.add(new UpdateEntity(e.getId(), null));
     }
 
-    RetrieveFullEntityTransaction t = new RetrieveFullEntityTransaction(oldContainer);
+    RetrieveFullEntityTransaction t =
+        new RetrieveFullEntityTransaction(oldContainer, getTransactor());
     execute(t, getAccess());
 
     // the entities in this container only have an id and an ACL. -> Replace
diff --git a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java
index 939d0bf6..08f80915 100644
--- a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java
+++ b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java
@@ -165,10 +165,10 @@ public class WriteTransaction extends Transaction<WritableContainer>
 
     // Retrieve a container which contains all IDs of those entities
     // which are to be updated.
-    execute(new RetrieveFullEntityTransaction(oldContainer), getAccess());
+    execute(new RetrieveFullEntityTransaction(oldContainer, getTransactor()), getAccess());
 
     // Retrieve all entities which are to be deleted.
-    execute(new RetrieveFullEntityTransaction(deleteContainer), getAccess());
+    execute(new RetrieveFullEntityTransaction(deleteContainer, getTransactor()), getAccess());
 
     // Check if any updates are to be processed.
     for (final EntityInterface entity : getContainer()) {
diff --git a/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
index cfd8fcc9..bb209f0e 100644
--- a/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
+++ b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java
@@ -23,8 +23,21 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.Callable;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.Permission;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.ExecutionException;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.Subject;
+import org.caosdb.server.CaosDBServer;
+import org.caosdb.server.accessControl.Principal;
 import org.caosdb.server.datatype.ReferenceValue;
 import org.caosdb.server.entity.Entity;
 import org.caosdb.server.entity.EntityID;
@@ -32,15 +45,168 @@ import org.caosdb.server.entity.EntityInterface;
 import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.wrapper.Property;
 import org.caosdb.server.entity.xml.PropertyToElementStrategyTest;
+import org.caosdb.server.permissions.EntityACL;
 import org.caosdb.server.query.Query.Selection;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 public class RetrieveFullEntityTest {
 
+  @BeforeAll
+  public static void setup() throws IOException {
+    CaosDBServer.initServerProperties();
+  }
+
   @Test
   public void testRetrieveSubEntities() {
     final RetrieveFullEntityTransaction r =
-        new RetrieveFullEntityTransaction(new EntityID("0")) {
+        new RetrieveFullEntityTransaction(
+            new EntityID("0"),
+            new Subject() {
+
+              @Override
+              public Object getPrincipal() {
+                return new Principal("Bla", "Blub");
+              }
+
+              @Override
+              public PrincipalCollection getPrincipals() {
+                return null;
+              }
+
+              @Override
+              public boolean isPermitted(String permission) {
+                assertEquals(
+                    permission, org.caosdb.server.permissions.EntityPermission.RETRIEVE_ENTITY);
+                return true;
+              }
+
+              @Override
+              public boolean isPermitted(Permission permission) {
+                return false;
+              }
+
+              @Override
+              public boolean[] isPermitted(String... permissions) {
+                return null;
+              }
+
+              @Override
+              public boolean[] isPermitted(List<Permission> permissions) {
+                return null;
+              }
+
+              @Override
+              public boolean isPermittedAll(String... permissions) {
+                return false;
+              }
+
+              @Override
+              public boolean isPermittedAll(Collection<Permission> permissions) {
+                return false;
+              }
+
+              @Override
+              public void checkPermission(String permission) throws AuthorizationException {}
+
+              @Override
+              public void checkPermission(Permission permission) throws AuthorizationException {}
+
+              @Override
+              public void checkPermissions(String... permissions) throws AuthorizationException {}
+
+              @Override
+              public void checkPermissions(Collection<Permission> permissions)
+                  throws AuthorizationException {}
+
+              @Override
+              public boolean hasRole(String roleIdentifier) {
+                return false;
+              }
+
+              @Override
+              public boolean[] hasRoles(List<String> roleIdentifiers) {
+                return null;
+              }
+
+              @Override
+              public boolean hasAllRoles(Collection<String> roleIdentifiers) {
+                return false;
+              }
+
+              @Override
+              public void checkRole(String roleIdentifier) throws AuthorizationException {}
+
+              @Override
+              public void checkRoles(Collection<String> roleIdentifiers)
+                  throws AuthorizationException {}
+
+              @Override
+              public void checkRoles(String... roleIdentifiers) throws AuthorizationException {}
+
+              @Override
+              public void login(AuthenticationToken token) throws AuthenticationException {}
+
+              @Override
+              public boolean isAuthenticated() {
+                return false;
+              }
+
+              @Override
+              public boolean isRemembered() {
+                return false;
+              }
+
+              @Override
+              public Session getSession() {
+                return null;
+              }
+
+              @Override
+              public Session getSession(boolean create) {
+                return null;
+              }
+
+              @Override
+              public void logout() {}
+
+              @Override
+              public <V> V execute(Callable<V> callable) throws ExecutionException {
+                return null;
+              }
+
+              @Override
+              public void execute(Runnable runnable) {}
+
+              @Override
+              public <V> Callable<V> associateWith(Callable<V> callable) {
+                return null;
+              }
+
+              @Override
+              public Runnable associateWith(Runnable runnable) {
+                return null;
+              }
+
+              @Override
+              public void runAs(PrincipalCollection principals)
+                  throws NullPointerException, IllegalStateException {}
+
+              @Override
+              public boolean isRunAs() {
+                return false;
+              }
+
+              @Override
+              public PrincipalCollection getPreviousPrincipals() {
+                return null;
+              }
+
+              @Override
+              public PrincipalCollection releaseRunAs() {
+                return null;
+              }
+            }) {
 
           /** Mock-up */
           @Override
@@ -53,6 +219,7 @@ public class RetrieveFullEntityTest {
             assertEquals("description", selections.get(0).getSelector());
 
             e.setDescription("A heart-shaped window.");
+            e.setEntityACL(new EntityACL());
           }
           ;
         };
-- 
GitLab


From 0fc5f9ea6d0a56b286cc7d08a48bd0ca0bac9b7e Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Fri, 8 Dec 2023 15:05:37 +0100
Subject: [PATCH 12/15] DOC: add class docs for RetrieveEntity

---
 .../java/org/caosdb/server/entity/RetrieveEntity.java  | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
index 69df103a..e1b9e8c0 100644
--- a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
+++ b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java
@@ -24,8 +24,14 @@
  */
 package org.caosdb.server.entity;
 
-// TODO document the use of this class; it seems to exist of only constructors
-
+/**
+ * Entity which is to be retrieved (i.e. read-only).
+ *
+ * <p>This class only exposes those constructors which are necessary for Entity which are to be
+ * retrieved (e.g. Entity(id)) and hide the others (e.g. Entity(XML-Represenation)).
+ *
+ * @author Timm Fitschen <t.fitschen@indiscale.com>
+ */
 public class RetrieveEntity extends Entity {
 
   public RetrieveEntity() {
-- 
GitLab


From 41cbc56785fdb2d0d0fc0117d72ed5994a41668a Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Fri, 8 Dec 2023 15:13:19 +0100
Subject: [PATCH 13/15] DOC: add class docs to Query class

---
 src/main/java/org/caosdb/server/query/Query.java | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java
index 507dc9d4..168b7ac8 100644
--- a/src/main/java/org/caosdb/server/query/Query.java
+++ b/src/main/java/org/caosdb/server/query/Query.java
@@ -72,14 +72,21 @@ import org.caosdb.server.permissions.EntityPermission;
 import org.caosdb.server.query.CQLParser.CqContext;
 import org.caosdb.server.query.CQLParsingErrorListener.ParsingError;
 import org.caosdb.server.transaction.EntityTransactionInterface;
+import org.caosdb.server.transaction.Retrieve;
 import org.caosdb.server.transaction.Transaction;
 import org.caosdb.server.transaction.WriteTransaction;
 import org.jdom2.Element;
 import org.slf4j.Logger;
 
-// TODO Document: The query is initialized with a RetrieveTransaction and its
-// Container. The container is filled by the Query with the resulting IDs. The
-// Retrieve transaction then handles the retrieve of all respective Entities.
+/**
+ * This class represents a single, complete Query execution from the parsing of the query string to
+ * the resulting list of entity ids.
+ *
+ * <p>This class handles caching of queries and checking retrieve permissions as well. It does not,
+ * however, retrieve the resulting entities; this is handled by the {@link Retrieve} class.
+ *
+ * @author Timm Fitschen <t.fitschen@indiscale.com>
+ */
 public class Query implements QueryInterface, ToElementable, EntityTransactionInterface {
 
   /** Class which represents the selection of (sub)properties. */
-- 
GitLab


From 6710ba3ef5a2aa251721326eef5cb7c5437269ea Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Fri, 8 Dec 2023 15:18:57 +0100
Subject: [PATCH 14/15] REVERT: unrelated changes

---
 caosdb-webui | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/caosdb-webui b/caosdb-webui
index e6fef9f3..d5f9090e 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit e6fef9f35da49dfea5b11f99b872d15c35fd043d
+Subproject commit d5f9090eca25a92fc44dbeeba305768e8d9f4bcb
-- 
GitLab


From dcd5e48d7b47e824821f96b575e1cad7349dc86f Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Wed, 13 Dec 2023 16:13:58 +0100
Subject: [PATCH 15/15] REL: prepare release 0.12.1

---
 CHANGELOG.md    | 29 ++++++++++++++++++++---------
 CITATION.cff    |  4 ++--
 caosdb-webui    |  2 +-
 pom.xml         |  2 +-
 src/doc/conf.py |  4 ++--
 5 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc91c68a..22e9479e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,20 +5,31 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [Unreleased]
-
-### Added
-
-### Changed
-
-### Deprecated
-
-### Removed
+## [0.12.1] - 2023-12-13
+(Timm Fitschen)
 
 ### Fixed
 
+* Insufficient permission checks during subproperty filters of SELECT queries
+  when an entity with retrieve permissions references one without
+  [linkahead-server#244](https://gitlab.com/linkahead/linkahead-server/-/issues/244)
+* Insufficient permission checks in queries when a name of an invisible record
+  is used in a filter where a visible record references the invisible one
+  [linkahead-server#242](https://gitlab.com/linkahead/linkahead-server/-/issues/242)
+
 ### Security
 
+This is an important security patch release. The bugs
+[linkahead-server#244](https://gitlab.com/linkahead/linkahead-server/-/issues/244)
+and
+[linkahead-server#242](https://gitlab.com/linkahead/linkahead-server/-/issues/242)
+possibly leak sensitive data when an attacker with read access to linkahead
+(i.e. the attacker needs an active user account or anonymous needs to be
+enabled) can guess the name of entities or properties of referenced entities
+and construct a malicious FIND or SELECT statement and when the attacker has
+read permissions for an entity which references the entities containing the
+sensitive information. See the bug reports for more information.
+
 ## [0.12.0] - 2023-10-25
 (Timm Fitschen)
 
diff --git a/CITATION.cff b/CITATION.cff
index a7c72943..77f72467 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -23,6 +23,6 @@ authors:
     given-names: Stefan
     orcid: https://orcid.org/0000-0001-7214-8125
 title: "CaosDB - Server"
-version: 0.12.0
+version: 0.12.1
 doi: 10.3390/data4020083
-date-released: 2023-10-25
+date-released: 2023-12-13
diff --git a/caosdb-webui b/caosdb-webui
index d5f9090e..6e4db2f9 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit d5f9090eca25a92fc44dbeeba305768e8d9f4bcb
+Subproject commit 6e4db2f99e1d441bbda9ccca85fae45526018406
diff --git a/pom.xml b/pom.xml
index abe5e282..82ac0c1e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.caosdb</groupId>
   <artifactId>caosdb-server</artifactId>
-  <version>0.13.0-SNAPSHOT</version>
+  <version>0.12.1</version>
   <packaging>jar</packaging>
   <name>CaosDB Server</name>
   <scm>
diff --git a/src/doc/conf.py b/src/doc/conf.py
index 530d8d65..e1471488 100644
--- a/src/doc/conf.py
+++ b/src/doc/conf.py
@@ -26,9 +26,9 @@ copyright = '2023, IndiScale GmbH'
 author = 'Daniel Hornung, Timm Fitschen'
 
 # The short X.Y version
-version = '0.13.0'
+version = '0.12.1'
 # The full version, including alpha/beta/rc tags
-release = '0.13.0-dev'
+release = '0.12.1'
 
 
 # -- General configuration ---------------------------------------------------
-- 
GitLab