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

Merge branch 'f-get-owner' into 'dev'

fix caosdb-deploy#225

Closes caosdb-deploy#225

See merge request !47
parents dbe43993 de85a6cf
No related branches found
No related tags found
1 merge request!47fix caosdb-deploy#225
Pipeline #17319 failed
Showing with 96 additions and 48 deletions
...@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security ### Security
* [caosdb-deploy#225](https://gitlab.indiscale.com/caosdb/src/caosdb-deploy/-/issues/225) - Denied Edit permission leads to retrieve permission.
## [v0.6.0] - 2021-11-17 ## [v0.6.0] - 2021-11-17
(Timm Fitschen) (Timm Fitschen)
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
<dependency> <dependency>
<groupId>org.apache.shiro</groupId> <groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId> <artifactId>shiro-core</artifactId>
<version>1.5.3</version> <version>1.8.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
......
...@@ -326,6 +326,8 @@ public class CaosDBServer extends Application { ...@@ -326,6 +326,8 @@ public class CaosDBServer extends Application {
// ChecksumUpdater // ChecksumUpdater
ChecksumUpdater.start(); ChecksumUpdater.start();
ThreadContext.remove();
} }
} else { } else {
logger.info("NO BACKEND"); logger.info("NO BACKEND");
...@@ -566,9 +568,9 @@ public class CaosDBServer extends Application { ...@@ -566,9 +568,9 @@ public class CaosDBServer extends Application {
setSessionCookies(response); setSessionCookies(response);
} finally { } finally {
// remove subject from this thread so that we can reuse the // remove subject and all other session data from this thread so
// thread. // that we can reuse the thread.
ThreadContext.unbindSubject(); ThreadContext.remove();
} }
} }
......
...@@ -27,7 +27,7 @@ import java.util.HashMap; ...@@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.Permission;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.caosdb.server.CaosDBException; import org.caosdb.server.CaosDBException;
...@@ -301,10 +301,8 @@ public abstract class Job { ...@@ -301,10 +301,8 @@ public abstract class Job {
} }
protected final void checkPermission(final EntityInterface entity, final Permission permission) protected final void checkPermission(final EntityInterface entity, final Permission permission)
throws Message { throws AuthorizationException {
if (!entity.getEntityACL().isPermitted(SecurityUtils.getSubject(), permission)) { entity.checkPermission(permission);
throw ServerMessages.AUTHORIZATION_ERROR;
}
} }
/** /**
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
package org.caosdb.server.jobs.core; package org.caosdb.server.jobs.core;
import java.util.List; import java.util.List;
import org.apache.shiro.authz.AuthorizationException;
import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; import org.caosdb.server.database.exceptions.EntityWasNotUniqueException;
import org.caosdb.server.datatype.AbstractCollectionDatatype; import org.caosdb.server.datatype.AbstractCollectionDatatype;
...@@ -97,13 +98,15 @@ public final class CheckDatatypePresent extends EntityJob { ...@@ -97,13 +98,15 @@ public final class CheckDatatypePresent extends EntityJob {
// finally, no data type // finally, no data type
throw ServerMessages.PROPERTY_HAS_NO_DATATYPE; throw ServerMessages.PROPERTY_HAS_NO_DATATYPE;
} }
} catch (final Message m) { } catch (final Message m) {
if (m == ServerMessages.ENTITY_DOES_NOT_EXIST) { if (m == ServerMessages.ENTITY_DOES_NOT_EXIST) {
getEntity().addError(ServerMessages.UNKNOWN_DATATYPE); getEntity().addError(ServerMessages.UNKNOWN_DATATYPE);
} else { } else {
getEntity().addError(m); getEntity().addError(m);
} }
} catch (AuthorizationException exc) {
getEntity().addError(ServerMessages.AUTHORIZATION_ERROR);
getEntity().addInfo(exc.getMessage());
} catch (final EntityDoesNotExistException exc) { } catch (final EntityDoesNotExistException exc) {
getEntity().addError(ServerMessages.UNKNOWN_DATATYPE); getEntity().addError(ServerMessages.UNKNOWN_DATATYPE);
} catch (final EntityWasNotUniqueException exc) { } catch (final EntityWasNotUniqueException exc) {
...@@ -152,8 +155,8 @@ public final class CheckDatatypePresent extends EntityJob { ...@@ -152,8 +155,8 @@ public final class CheckDatatypePresent extends EntityJob {
} }
} }
private void assertAllowedToUse(final EntityInterface datatype) throws Message { private void assertAllowedToUse(final EntityInterface datatype) {
checkPermission(datatype, EntityPermission.USE_AS_DATA_TYPE); datatype.checkPermission(EntityPermission.USE_AS_DATA_TYPE);
} }
private void checkIfOverride() throws Message { private void checkIfOverride() throws Message {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
package org.caosdb.server.jobs.core; package org.caosdb.server.jobs.core;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import org.apache.shiro.authz.AuthorizationException;
import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; import org.caosdb.server.database.exceptions.EntityWasNotUniqueException;
import org.caosdb.server.entity.Affiliation; import org.caosdb.server.entity.Affiliation;
...@@ -118,13 +119,16 @@ public class CheckParValid extends EntityJob { ...@@ -118,13 +119,16 @@ public class CheckParValid extends EntityJob {
} }
} }
addError(parent, ServerMessages.ENTITY_DOES_NOT_EXIST); parent.addError(ServerMessages.ENTITY_DOES_NOT_EXIST);
} catch (final Message m) { } catch (final Message m) {
addError(parent, m); parent.addError(m);
} catch (AuthorizationException e) {
parent.addError(ServerMessages.AUTHORIZATION_ERROR);
parent.addInfo(e.getMessage());
} catch (final EntityDoesNotExistException exc) { } catch (final EntityDoesNotExistException exc) {
addError(parent, ServerMessages.ENTITY_DOES_NOT_EXIST); parent.addError(ServerMessages.ENTITY_DOES_NOT_EXIST);
} catch (final EntityWasNotUniqueException exc) { } catch (final EntityWasNotUniqueException exc) {
addError(parent, ServerMessages.ENTITY_NAME_DUPLICATES); parent.addError(ServerMessages.ENTITY_NAME_DUPLICATES);
} }
} }
} }
...@@ -191,12 +195,7 @@ public class CheckParValid extends EntityJob { ...@@ -191,12 +195,7 @@ public class CheckParValid extends EntityJob {
throw ServerMessages.AFFILIATION_ERROR; throw ServerMessages.AFFILIATION_ERROR;
} }
private void assertAllowedToUse(final EntityInterface entity) throws Message { private void assertAllowedToUse(final EntityInterface entity) {
checkPermission(entity, EntityPermission.USE_AS_PARENT); entity.checkPermission(EntityPermission.USE_AS_PARENT);
}
private void addError(final EntityInterface parent, final Message m) {
parent.addError(m);
parent.setEntityStatus(EntityStatus.UNQUALIFIED);
} }
} }
...@@ -25,6 +25,7 @@ package org.caosdb.server.jobs.core; ...@@ -25,6 +25,7 @@ package org.caosdb.server.jobs.core;
import static org.caosdb.server.utils.ServerMessages.ENTITY_DOES_NOT_EXIST; import static org.caosdb.server.utils.ServerMessages.ENTITY_DOES_NOT_EXIST;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import org.apache.shiro.authz.AuthorizationException;
import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; import org.caosdb.server.database.exceptions.EntityWasNotUniqueException;
import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.EntityInterface;
...@@ -124,32 +125,23 @@ public class CheckPropValid extends EntityJob { ...@@ -124,32 +125,23 @@ public class CheckPropValid extends EntityJob {
} }
} }
} catch (final Message m) { } catch (final Message m) {
addError(property, m); property.addError(m);
} catch (AuthorizationException e) {
property.addError(ServerMessages.AUTHORIZATION_ERROR);
property.addInfo(e.getMessage());
} catch (final EntityDoesNotExistException e) { } catch (final EntityDoesNotExistException e) {
addError(property, ENTITY_DOES_NOT_EXIST); property.addError(ENTITY_DOES_NOT_EXIST);
} catch (final EntityWasNotUniqueException e) { } catch (final EntityWasNotUniqueException e) {
addError(property, ServerMessages.ENTITY_NAME_DUPLICATES); property.addError(ServerMessages.ENTITY_NAME_DUPLICATES);
} }
} }
// process names // process names
appendJob(ProcessNameProperties.class); appendJob(ProcessNameProperties.class);
// final ProcessNameProperties processNameProperties = new
// ProcessNameProperties();
// processNameProperties.init(getMode(), getEntity(), getContainer(),
// getTransaction());
// getTransaction().getSchedule().add(processNameProperties);
// getTransaction().getSchedule().runJob(processNameProperties);
} }
private void assertAllowedToUse(final EntityInterface property) throws Message { private void assertAllowedToUse(final EntityInterface property) {
checkPermission(property, EntityPermission.USE_AS_PROPERTY); property.checkPermission(EntityPermission.USE_AS_PROPERTY);
}
private void addError(final EntityInterface property, final Message m) {
property.addError(m);
property.setEntityStatus(EntityStatus.UNQUALIFIED);
} }
private static void deriveOverrideStatus(final Property child, final EntityInterface parent) { private static void deriveOverrideStatus(final Property child, final EntityInterface parent) {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
package org.caosdb.server.jobs.core; package org.caosdb.server.jobs.core;
import org.apache.shiro.authz.AuthorizationException;
import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; import org.caosdb.server.database.exceptions.EntityWasNotUniqueException;
import org.caosdb.server.datatype.CollectionValue; import org.caosdb.server.datatype.CollectionValue;
...@@ -71,13 +72,13 @@ public class CheckRefidValid extends EntityJob implements Observer { ...@@ -71,13 +72,13 @@ public class CheckRefidValid extends EntityJob implements Observer {
} }
} catch (final Message m) { } catch (final Message m) {
getEntity().addError(m); getEntity().addError(m);
getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); } catch (AuthorizationException exc) {
getEntity().addError(ServerMessages.AUTHORIZATION_ERROR);
getEntity().addInfo(exc.getMessage());
} catch (final EntityDoesNotExistException e) { } catch (final EntityDoesNotExistException e) {
getEntity().addError(ServerMessages.REFERENCED_ENTITY_DOES_NOT_EXIST); getEntity().addError(ServerMessages.REFERENCED_ENTITY_DOES_NOT_EXIST);
getEntity().setEntityStatus(EntityStatus.UNQUALIFIED);
} catch (final EntityWasNotUniqueException e) { } catch (final EntityWasNotUniqueException e) {
getEntity().addError(ServerMessages.REFERENCE_NAME_DUPLICATES); getEntity().addError(ServerMessages.REFERENCE_NAME_DUPLICATES);
getEntity().setEntityStatus(EntityStatus.UNQUALIFIED);
} }
} }
...@@ -139,8 +140,8 @@ public class CheckRefidValid extends EntityJob implements Observer { ...@@ -139,8 +140,8 @@ public class CheckRefidValid extends EntityJob implements Observer {
} }
} }
private void assertAllowedToUse(final EntityInterface referencedEntity) throws Message { private void assertAllowedToUse(final EntityInterface referencedEntity) {
checkPermission(referencedEntity, EntityPermission.USE_AS_REFERENCE); referencedEntity.checkPermission(EntityPermission.USE_AS_REFERENCE);
} }
@Override @Override
......
/* /*
* ** 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) 2021 IndiScale GmbH <info@indiscale.com>
* Copyright (C) 2021 Timm Fitschen <t.fitschen@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
...@@ -18,11 +19,12 @@ ...@@ -18,11 +19,12 @@
* 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.permissions; package org.caosdb.server.permissions;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set;
public final class EntityACI { public final class EntityACI {
...@@ -72,4 +74,16 @@ public final class EntityACI { ...@@ -72,4 +74,16 @@ public final class EntityACI {
map.put("bitSet", getBitSet()); map.put("bitSet", getBitSet());
return map; return map;
} }
public boolean isGrant() {
return EntityACL.isAllowance(bitSet);
}
public boolean isPriority() {
return EntityACL.isPriorityBitSet(bitSet);
}
public Set<EntityPermission> getPermission() {
return EntityACL.getPermissionsFromBitSet(bitSet);
}
} }
...@@ -191,7 +191,9 @@ public class EntityACL { ...@@ -191,7 +191,9 @@ public class EntityACL {
public static final List<ResponsibleAgent> getOwners(final Collection<EntityACI> acl) { public static final List<ResponsibleAgent> getOwners(final Collection<EntityACI> acl) {
final List<ResponsibleAgent> owners = new ArrayList<>(); final List<ResponsibleAgent> owners = new ArrayList<>();
for (final EntityACI aci : acl) { for (final EntityACI aci : acl) {
if (isOwnerBitSet(aci.getBitSet()) && !aci.getResponsibleAgent().equals(OWNER_ROLE)) { if (aci.isGrant()
&& isOwnerBitSet(aci.getBitSet())
&& !aci.getResponsibleAgent().equals(OWNER_ROLE)) {
owners.add(aci.getResponsibleAgent()); owners.add(aci.getResponsibleAgent());
} }
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
package org.caosdb.server.permissions; package org.caosdb.server.permissions;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
...@@ -30,6 +31,7 @@ import java.io.IOException; ...@@ -30,6 +31,7 @@ import java.io.IOException;
import java.util.BitSet; import java.util.BitSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Set;
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.CaosDBServer; import org.caosdb.server.CaosDBServer;
...@@ -395,4 +397,37 @@ public class EntityACLTest { ...@@ -395,4 +397,37 @@ public class EntityACLTest {
assertTrue(EntityACL.isPriorityBitSet(aci.getBitSet())); assertTrue(EntityACL.isPriorityBitSet(aci.getBitSet()));
} }
} }
@Test
public void testOwnership() {
EntityACLFactory f = new EntityACLFactory();
f.grant(
org.caosdb.server.permissions.Role.create("the_owner"), false, EntityPermission.EDIT_ACL);
f.deny(
org.caosdb.server.permissions.Role.create("someone_else"),
false,
EntityPermission.EDIT_ACL);
EntityACL acl = f.create();
assertEquals(1, acl.getOwners().size());
assertEquals("the_owner", acl.getOwners().get(0).toString());
}
@Test
public void testPermissionsFor() {
EntityACLFactory f = new EntityACLFactory();
f.deny(org.caosdb.server.permissions.Role.ANONYMOUS_ROLE, false, EntityPermission.EDIT_ACL);
f.grant(org.caosdb.server.permissions.Role.OWNER_ROLE, false, "*");
EntityACL acl = f.create();
Subject anonymous = SecurityUtils.getSubject();
anonymous.login(AnonymousAuthenticationToken.getInstance());
assertTrue(AuthenticationUtils.isAnonymous(anonymous));
assertNotNull(acl);
assertTrue(acl.getOwners().isEmpty());
final Set<EntityPermission> permissionsFor =
EntityACL.getPermissionsFor(anonymous, acl.getRules());
assertFalse(permissionsFor.contains(EntityPermission.RETRIEVE_ENTITY));
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment