diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java index 25398ad3b48c841b1455ea21c0c1df150cac8e76..d743e2fbe8062e4fbbc3132eb300f4915f097c91 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java @@ -20,17 +20,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.hibernate.Query; +import org.hibernate.Session; + import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory; -import ch.systemsx.cisd.openbis.generic.shared.authorization.SpaceOwnerKind; import ch.systemsx.cisd.openbis.generic.shared.authorization.IAuthorizationDataProvider; import ch.systemsx.cisd.openbis.generic.shared.authorization.RoleWithIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.authorization.SpaceOwnerKind; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.ArrayPredicate; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.CollectionPredicate; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.IPredicate; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetAccessPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; @@ -242,6 +246,18 @@ public final class PredicateExecutor } } + @SuppressWarnings("unchecked") + public DataSetAccessPE tryGetDatasetAccessData(String dataSetCode) + { + Session sess = daoFactory.getSessionFactory().getCurrentSession(); + Query query = sess.getNamedQuery(DataSetAccessPE.DATASET_ACCESS_QUERY_NAME); + query = query.setReadOnly(true); + List<DataSetAccessPE> results = query.setString(0, dataSetCode).list(); + if (results.size() < 1) + return null; + return results.get(0); + } + public GroupPE tryToGetGroup(SpaceOwnerKind kind, TechId techId) { switch (kind) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/IAuthorizationDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/IAuthorizationDataProvider.java index 4138938c6da115187d395e29026504e9c90c289b..1753a1c5a3a0daf77b93d0863f285fd5f042e654 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/IAuthorizationDataProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/IAuthorizationDataProvider.java @@ -20,6 +20,7 @@ import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.IDatabaseInstanceFinder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetAccessPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomColumnPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomFilterPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE; @@ -46,6 +47,11 @@ public interface IAuthorizationDataProvider extends IDatabaseInstanceFinder */ public ProjectPE tryToGetProject(String dataSetCode); + /** + * Returns the information necessary to determine if a user is allowed to access this dataset. + */ + public DataSetAccessPE tryGetDatasetAccessData(String dataSetCode); + /** * Returns the group of an entity with given <var>entityKind</var> and <var>techId</var> * @@ -67,7 +73,7 @@ public interface IAuthorizationDataProvider extends IDatabaseInstanceFinder * Returns the grid custom column with given <var>techId</var> */ public GridCustomColumnPE getGridCustomColumn(TechId techId); - + /** * Returns the query with specified ID. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/AbstractGroupPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/AbstractGroupPredicate.java index eff6b487d8bfd0d46a59688ef1a093be103dcaad..9617d1068e0d37215201ab1c753943ef2724b7a1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/AbstractGroupPredicate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/AbstractGroupPredicate.java @@ -49,8 +49,16 @@ abstract class AbstractGroupPredicate<T> extends AbstractDatabaseInstancePredica final DatabaseInstancePE databaseInstance, final String groupCodeOrNull) { final String databaseInstanceUUID = databaseInstance.getUuid(); + return evaluate(person, allowedRoles, databaseInstanceUUID, databaseInstance.getCode(), + groupCodeOrNull); + } + + protected Status evaluate(final PersonPE person, final List<RoleWithIdentifier> allowedRoles, + final String databaseInstanceUUID, final String databaseInstanceCode, + final String groupCodeOrNull) + { final GroupIdentifier fullGroupIdentifier = - new GroupIdentifier(databaseInstance.getCode(), groupCodeOrNull); + new GroupIdentifier(databaseInstanceCode, groupCodeOrNull); ensureGroupExists(fullGroupIdentifier, databaseInstanceUUID, groupCodeOrNull); final boolean matching = isMatching(allowedRoles, databaseInstanceUUID, groupCodeOrNull); if (matching) @@ -59,7 +67,7 @@ abstract class AbstractGroupPredicate<T> extends AbstractDatabaseInstancePredica } return Status.createError(String.format( "User '%s' does not have enough privileges to access data in the space '%s'.", - person.getUserId(), new GroupIdentifier(databaseInstance.getCode(), groupCodeOrNull))); + person.getUserId(), new GroupIdentifier(databaseInstanceCode, groupCodeOrNull))); } private void ensureGroupExists(final GroupIdentifier groupIdentifier, @@ -91,7 +99,8 @@ abstract class AbstractGroupPredicate<T> extends AbstractDatabaseInstancePredica { final RoleLevel roleGroup = role.getRoleLevel(); if (roleGroup.equals(RoleLevel.SPACE) - && equalIdentifier(role.getAssignedGroup(), databaseInstanceUUID, groupCodeOrNull)) + && equalIdentifier(role.getAssignedGroup(), databaseInstanceUUID, + groupCodeOrNull)) { return true; } else if (roleGroup.equals(RoleLevel.INSTANCE) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java index bfa30a6e430cb9c48faddc05c9d60433f98c5efd..39cc630f7cc0c7ee4c5529a7cff1948bac15dbb3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java @@ -20,15 +20,13 @@ import java.util.List; import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.openbis.generic.shared.authorization.RoleWithIdentifier; -import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; -import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetAccessPE; import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; -import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE; /** * A {@link IPredicate} based on a list of data set codes. - * - * @author Franz-Josef Elmer + * + * @author Franz-Josef Elmer */ public class DataSetCodePredicate extends AbstractGroupPredicate<String> { @@ -37,23 +35,23 @@ public class DataSetCodePredicate extends AbstractGroupPredicate<String> { return "data set code"; } - @Override Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles, String dataSetCode) { assert initialized : "Predicate has not been initialized"; - - ProjectPE project = authorizationDataProvider.tryToGetProject(dataSetCode); - if (project != null) + + DataSetAccessPE accessData = authorizationDataProvider.tryGetDatasetAccessData(dataSetCode); + + if (accessData != null) { - GroupPE group = project.getGroup(); - DatabaseInstancePE databaseInstance = group.getDatabaseInstance(); - String code = group.getCode(); - return evaluate(person, allowedRoles, databaseInstance, code); + String dbInstanceUUID = accessData.getDatabaseInstanceUuid(); + String dbInstanceCode = accessData.getDatabaseInstanceCode(); + String groupCode = accessData.getGroupCode(); + Status result = + evaluate(person, allowedRoles, dbInstanceUUID, dbInstanceCode, groupCode); + return result; } return Status.OK; } - - } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java index d1eaec1b8431378b5f966f5254267ee03fc24940..f6937c57ab5bca4ae1b306ae9c6b60e2709576d4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java @@ -23,6 +23,9 @@ import javax.persistence.NamedNativeQuery; import javax.persistence.SqlResultSetMapping; /** + * A PE for retrieving only the information necessary to determine if a user/person can access a + * data set. + * * @author Chandrasekhar Ramakrishnan */ @Entity @@ -55,6 +58,22 @@ public class DataSetAccessPE public final static String DATASET_ACCESS_QUERY_NAME = "dataset_access"; + /** + * A factory method that should only be used for testing. + */ + public static DataSetAccessPE createDataSetAccessPEForTest(String dataSetId, + String dataSetCode, String groupCode, String databaseInstanceUuid, + String databaseInstanceCode) + { + DataSetAccessPE newMe = new DataSetAccessPE(); + newMe.setDataSetId(dataSetId); + newMe.setDataSetCode(dataSetCode); + newMe.setGroupCode(groupCode); + newMe.setDatabaseInstanceUuid(databaseInstanceUuid); + newMe.setDatabaseInstanceCode(databaseInstanceCode); + return newMe; + } + void setDataSetId(String dataSetId) { this.dataSetId = dataSetId; diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicateTest.java index a29e34b45cde4ff9cb7813628fba82660fbae87b..3dc9b1f0b4ff857228e9543eab582bf373a7a020 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicateTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicateTest.java @@ -21,6 +21,7 @@ import org.testng.annotations.Test; import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.openbis.generic.shared.authorization.AuthorizationTestCase; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetAccessPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE; /** @@ -33,11 +34,15 @@ public class DataSetCodePredicateTest extends AuthorizationTestCase { final ProjectPE project = new ProjectPE(); project.setGroup(createGroup()); + final DataSetAccessPE accessData = + DataSetAccessPE.createDataSetAccessPEForTest("1", "d1", SPACE_CODE, "global_" + + INSTANCE_CODE, INSTANCE_CODE); + context.checking(new Expectations() { { - one(provider).tryToGetProject("d1"); - will(returnValue(project)); + one(provider).tryGetDatasetAccessData("d1"); + will(returnValue(accessData)); } }); DataSetCodePredicate predicate = new DataSetCodePredicate();