Skip to content
Snippets Groups Projects
Commit c38d15a8 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

Merge branch 'dev' into f-doc-query

parents b5854939 f1730eb4
No related branches found
No related tags found
2 merge requests!96DOC: Added CITATION.cff to the list of files in the release guide where the...,!89DOC: enhance query documentation
Pipeline #35475 passed
...@@ -32,8 +32,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -32,8 +32,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### ### Fixed ###
* Denying a role permission has no effect
[#196](https://gitlab.com/caosdb/caosdb-server/-/issues/196). See security
notes below.
* Missing RecordType leads to unexpected server error
[#166](https://gitlab.com/caosdb/caosdb-server/-/issues/166)
### Security ### ### Security ###
* Fixed [#196](https://gitlab.com/caosdb/caosdb-server/-/issues/196). This was
an error in the authorization procedure which allowed unprivileged users
execute insert, update or delete transactions on entities. However, the
unprivileged users would also need the correct entity permissions to do that.
Without backup, this means possible data loss. Also there was the possibility
to spam the database by creating unwanted entities.
### Documentation ### ### Documentation ###
- Nested queries. - Nested queries.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* `>=Java 11` * `>=Java 11`
* `>=Apache Maven 3.6.0` * `>=Apache Maven 3.6.0`
* `>=Make 4.2` * `>=Make 4.2`
* `>=gcc 8` (if PAM authentication is required)
* `libpam` (if PAM authentication is required) * `libpam` (if PAM authentication is required)
* More dependencies are being pulled and installed automatically by Maven. See the complete list of dependencies in the [pom.xml](pom.xml) * More dependencies are being pulled and installed automatically by Maven. See the complete list of dependencies in the [pom.xml](pom.xml)
......
...@@ -15,12 +15,18 @@ See [DEPENDENCIES.md](DEPENDENCIES.md). ...@@ -15,12 +15,18 @@ See [DEPENDENCIES.md](DEPENDENCIES.md).
On Debian, the required packages can be installed with: On Debian, the required packages can be installed with:
apt-get install git make mariadb-server maven openjdk-11-jdk-headless \ apt-get install make mariadb-server maven openjdk-11-jdk-headless \
python3-pip screen libpam0g-dev unzip python3-pip libpam0g-dev unzip
Note that installing MariaDB will uninstall existing MySQL packages and vice Note that installing MariaDB will uninstall existing MySQL packages and vice
versa. versa.
#### Install the requirements on Fedora
On Fedora, the required packages can be installed with:
sudo dnf install make pam-devel mariadb-server mariadb python3 java-17-openjdk-headless unzip gcc
### System ### System
* `>=Linux 4.0.0`, `x86_64`, e.g. Ubuntu 18.04 * `>=Linux 4.0.0`, `x86_64`, e.g. Ubuntu 18.04
...@@ -160,20 +166,47 @@ sources (if you called `make run` previously). ...@@ -160,20 +166,47 @@ sources (if you called `make run` previously).
## Setup Eclipse ## Setup Eclipse
1. Open Eclipse (recommended version: Oxygen.1a Release (4.7.1a)) 1. Open Eclipse (tested with 2022-R12)
2. `File > New > Java Project`: Choose a project name and specify the location 2. File > Import > Maven > Existing Maven Projects: Specify location.
of this repo. The JRE and Project layout should be configured automatically. 3. You will most likely encounter "Plugin execution not covered by lifecycle
Now, the project should initially have two source-folders: `./src/main/java` configuration: ..." errors. Adapt the file
and `./src/test/java`. After a build, another one, `<eclipse-workspace>/.metadata/.plugins/org.eclipse.m2e.core/lifecycle-mapping-metadata.xml`.
`./target/generated-sources/antlr4` should be generated. If there are more
than these three source-folders, reconfigure the projects source folders Example:
appropriately with `Project > Properties > Java Build Path > Source`.
3. In the `Package Explorer` view, right-click on the project and `Configure > ```xml
Convert to Maven Project`. <?xml version="1.0" encoding="UTF-8"?>
4. In the `Package Explorer` view, right-click on the project and `Maven > <lifecycleMappingMetadata>
Update Project`. <pluginExecutions>
5. Usually a build of the project is started automatically. Otherwise `Project > <pluginExecution>
Build Project`. <pluginExecutionFilter>
<groupId>com.coveo</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<versionRange>2.5.1</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<versionRange>1.4</versionRange>
<goals>
<goal>create-metadata</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
```
Done! Done!
......
...@@ -67,7 +67,7 @@ MYSQL_DATABASE_NAME=caosdb ...@@ -67,7 +67,7 @@ MYSQL_DATABASE_NAME=caosdb
# User name for connecting to mysql # User name for connecting to mysql
MYSQL_USER_NAME=caosdb MYSQL_USER_NAME=caosdb
# Password for the user # Password for the user
MYSQL_USER_PASSWORD=caosdb MYSQL_USER_PASSWORD=random1234
# Schema of mysql procedures and tables which is required by this CaosDB instance # Schema of mysql procedures and tables which is required by this CaosDB instance
MYSQL_SCHEMA_VERSION=v5.0 MYSQL_SCHEMA_VERSION=v5.0
......
...@@ -555,7 +555,7 @@ public abstract class Job { ...@@ -555,7 +555,7 @@ public abstract class Job {
* *
* @param entity the entity to be resolved. * @param entity the entity to be resolved.
* @return the resolved entity. * @return the resolved entity.
* @throws EntityWasNotUniqueException if the resolution failed due to ambuiguity of the name. * @throws EntityWasNotUniqueException if the resolution failed due to ambiguity of the name.
*/ */
protected EntityInterface resolve(final EntityInterface entity) protected EntityInterface resolve(final EntityInterface entity)
throws EntityWasNotUniqueException { throws EntityWasNotUniqueException {
......
/* /*
* ** header v3.0
* This file is a part of the CaosDB Project. * This file is a part of the CaosDB Project.
* *
* Copyright (C) 2018 Research Group Biomedical Physics, * Copyright (C) 2018 Research Group Biomedical Physics,
* Max-Planck-Institute for Dynamics and Self-Organization Göttingen * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
* Copyright (C) 2023 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2023 IndiScale <info@indiscale.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
...@@ -17,17 +18,17 @@ ...@@ -17,17 +18,17 @@
* *
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ** end header
*/ */
package org.caosdb.server.jobs.core; package org.caosdb.server.jobs.core;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.caosdb.server.accessControl.ACMPermissions; import org.caosdb.server.accessControl.ACMPermissions;
import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; import org.caosdb.server.entity.DeleteEntity;
import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.EntityInterface;
import org.caosdb.server.entity.wrapper.Parent; import org.caosdb.server.entity.InsertEntity;
import org.caosdb.server.entity.Role;
import org.caosdb.server.entity.UpdateEntity;
import org.caosdb.server.jobs.ContainerJob; import org.caosdb.server.jobs.ContainerJob;
import org.caosdb.server.jobs.JobAnnotation; import org.caosdb.server.jobs.JobAnnotation;
import org.caosdb.server.jobs.TransactionStage; import org.caosdb.server.jobs.TransactionStage;
...@@ -35,6 +36,14 @@ import org.caosdb.server.transaction.Retrieve; ...@@ -35,6 +36,14 @@ import org.caosdb.server.transaction.Retrieve;
import org.caosdb.server.utils.EntityStatus; import org.caosdb.server.utils.EntityStatus;
import org.caosdb.server.utils.ServerMessages; import org.caosdb.server.utils.ServerMessages;
/**
* Checks the TRANSACTION:* permissions before a transaction begins.
*
* <p>Users need TRANSACTION:INSERT:?ENTITY_ROLE? permission to insert an entity of the particular
* entity role. Likewise, they need the TRANSACTION:UPDATE or TRANSACTION:DELETE permissions.
*
* @author Timm Fitschen <f.fitschen@indiscale.com>
*/
@JobAnnotation(stage = TransactionStage.INIT) @JobAnnotation(stage = TransactionStage.INIT)
public class AccessControl extends ContainerJob { public class AccessControl extends ContainerJob {
...@@ -46,12 +55,15 @@ public class AccessControl extends ContainerJob { ...@@ -46,12 +55,15 @@ public class AccessControl extends ContainerJob {
super(permission, description); super(permission, description);
} }
public final String toString(String entityRole) { public final String toString(Role entityRole) {
return toString().replace(ENTITY_ROLE_PARAMETER, entityRole); String roleString = entityRole == null ? "" : entityRole.toString();
return toString().replace(ENTITY_ROLE_PARAMETER, roleString);
} }
public final String toString(String transaction, String entityRole) { public final String toString(String transaction, Role entityRole) {
return "TRANSACTION:" + transaction + (entityRole != null ? (":" + entityRole) : ""); return "TRANSACTION:"
+ transaction
+ (entityRole != null ? (":" + entityRole.toString()) : "");
} }
public static String init() { public static String init() {
...@@ -80,38 +92,26 @@ public class AccessControl extends ContainerJob { ...@@ -80,38 +92,26 @@ public class AccessControl extends ContainerJob {
protected void run() { protected void run() {
final Subject subject = SecurityUtils.getSubject(); final Subject subject = SecurityUtils.getSubject();
// subject has complete permissions for this kind of transaction
if (subject.isPermitted(
TRANSACTION_PERMISSIONS.toString(getTransaction().getClass().getSimpleName(), null))) {
return;
}
if (getTransaction() instanceof Retrieve) { if (getTransaction() instanceof Retrieve) {
return; return;
} }
for (final EntityInterface e : getContainer()) { for (final EntityInterface e : getContainer()) {
// per role permission if (e instanceof InsertEntity) {
if (subject.isPermitted( if (subject.isPermitted(INSERT.toString(e.getRole()))) {
TRANSACTION_PERMISSIONS.toString( continue;
getTransaction().getClass().getSimpleName(), e.getRole().toString()))) {
continue;
}
// special annotations permission
if (e.hasParents() && e.getParents().size() == 1) {
final Parent par1 = e.getParents().get(0);
if (par1.hasId() && !par1.getId().isTemporary()) {
execute(new RetrieveSparseEntity(par1));
} }
if (par1.hasName() } else if (e instanceof DeleteEntity) {
&& par1.getName().equals("CommentAnnotation") if (subject.isPermitted(DELETE.toString(e.getRole()))) {
&& subject.isPermitted( continue;
getTransaction().getClass().getSimpleName() + ":CommentAnnotation")) { }
} else if (e instanceof UpdateEntity) {
if (subject.isPermitted(UPDATE.toString(e.getRole()))) {
continue; continue;
} }
} }
e.setEntityStatus(EntityStatus.UNQUALIFIED); e.setEntityStatus(EntityStatus.UNQUALIFIED);
e.addMessage(ServerMessages.AUTHORIZATION_ERROR); e.addMessage(ServerMessages.AUTHORIZATION_ERROR);
} }
......
...@@ -119,7 +119,7 @@ public class Inheritance extends EntityJob { ...@@ -119,7 +119,7 @@ public class Inheritance extends EntityJob {
} }
// implement properties // implement properties
if (getEntity().hasProperties()) { if (getEntity().getEntityStatus() == EntityStatus.QUALIFIED && getEntity().hasProperties()) {
propertyLoop: propertyLoop:
for (final Property property : getEntity().getProperties()) { for (final Property property : getEntity().getProperties()) {
final ArrayList<Property> transfer = new ArrayList<>(); final ArrayList<Property> transfer = new ArrayList<>();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment