diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/IPersonRoleAssignmentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/IPersonRoleAssignmentTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..72fdd201d7a7daecb5e565e6419c1abd1dfecc99 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/IPersonRoleAssignmentTranslator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.person; + +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.fetchoptions.RoleAssignmentFetchOptions; +import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.common.IObjectToManyRelationTranslator; + +/** + * + * + * @author Franz-Josef Elmer + */ +public interface IPersonRoleAssignmentTranslator extends IObjectToManyRelationTranslator<RoleAssignment, RoleAssignmentFetchOptions> +{ + +} diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonQuery.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonQuery.java index 8b04ac98981a7d9ff6f973ece791f1be26fac10e..a0ed80d1d356f44f6d72eb3354749905d07487dd 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonQuery.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonQuery.java @@ -42,4 +42,8 @@ public interface PersonQuery extends ObjectQuery @Select(sql = "select id as objectId, pers_id_registerer as relatedId from persons where id = any(?{1})", parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE) public List<ObjectRelationRecord> getRegistratorIds(LongSet personIds); + @Select(sql = "select pers_id_grantee as objectId, id as relatedId from role_assignments where pers_id_grantee = any(?{1})", + parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE) + public List<ObjectRelationRecord> getRoleAssignmentIds(LongSet personIds); + } diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonRoleAssignmentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonRoleAssignmentTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..7c9e32449c95f46f26cc5042c1bab90254644fa6 --- /dev/null +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonRoleAssignmentTranslator.java @@ -0,0 +1,69 @@ +/* + * Copyright 2017 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.person; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.fetchoptions.RoleAssignmentFetchOptions; +import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationContext; +import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.common.ObjectRelationRecord; +import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.common.ObjectToManyRelationTranslator; +import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.roleassignment.IRoleAssignmentTranslator; + +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import net.lemnik.eodsql.QueryTool; + +/** + * + * + * @author Franz-Josef Elmer + */ +@Component +public class PersonRoleAssignmentTranslator + extends ObjectToManyRelationTranslator<RoleAssignment, RoleAssignmentFetchOptions> + implements IPersonRoleAssignmentTranslator +{ + @Autowired + private IRoleAssignmentTranslator roleAssignmentTranslator; + + @Override + protected List<ObjectRelationRecord> loadRecords(LongOpenHashSet objectIds) + { + PersonQuery query = QueryTool.getManagedQuery(PersonQuery.class); + return query.getRoleAssignmentIds(objectIds); + } + + @Override + protected Map<Long, RoleAssignment> translateRelated(TranslationContext context, Collection<Long> relatedIds, + RoleAssignmentFetchOptions relatedFetchOptions) + { + return roleAssignmentTranslator.translate(context, relatedIds, relatedFetchOptions); + } + + @Override + protected Collection<RoleAssignment> createCollection() + { + return new ArrayList<>(); + } +} \ No newline at end of file diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonTranslator.java index 05d4aba8eba11e0d7fce35e34261b2474d589958..ce04766431dd3ef341bd3f7f103ce709b7929e39 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonTranslator.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/person/PersonTranslator.java @@ -17,12 +17,14 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.person; import java.util.Collection; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.AbstractCachingTranslator; import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationContext; import ch.ethz.sis.openbis.generic.server.asapi.v3.translator.TranslationResults; @@ -43,6 +45,9 @@ public class PersonTranslator extends AbstractCachingTranslator<Long, Person, Pe @Autowired private IPersonRegistratorTranslator registratorTranslator; + @Autowired + private IPersonRoleAssignmentTranslator roleAssignmentTranslator; + @Override protected Person createObject(TranslationContext context, Long personId, PersonFetchOptions fetchOptions) { @@ -68,6 +73,11 @@ public class PersonTranslator extends AbstractCachingTranslator<Long, Person, Pe relations.put(IPersonRegistratorTranslator.class, registratorTranslator.translate(context, personIds, fetchOptions.withRegistrator())); } + if (fetchOptions.hasRoleAssignments()) + { + relations.put(IPersonRoleAssignmentTranslator.class, roleAssignmentTranslator.translate(context, personIds, fetchOptions.withRoleAssignments())); + } + return relations; } @@ -96,5 +106,11 @@ public class PersonTranslator extends AbstractCachingTranslator<Long, Person, Pe result.setRegistrator(relations.get(IPersonRegistratorTranslator.class, personId)); result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator()); } - } + + if (fetchOptions.hasRoleAssignments()) + { + result.setRoleAssignments((List<RoleAssignment>) relations.get(IPersonRoleAssignmentTranslator.class, personId)); + result.getFetchOptions().withRoleAssignmentsUsing(fetchOptions.withRoleAssignments()); + } +} } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/Person.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/Person.js index 6ac8de9b00d3c23df5c96110d879ea98db4a4654..15fe44182040951ebbe7ca4169bc26ccbc020c5e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/Person.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/Person.js @@ -18,6 +18,7 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) { prototype.active = null; prototype.space = null; prototype.registrator = null; + prototype.roleAssignments = null; prototype.getFetchOptions = function() { return this.fetchOptions; }; @@ -86,12 +87,26 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) { prototype.setRegistrator = function(registrator) { this.registrator = registrator; }; + prototype.getRoleAssignments = function() { + if (this.getFetchOptions() && this.getFetchOptions().hasRoleAssignments()) { + return this.roleAssignments; + } else { + throw new exceptions.NotFetchedException("RoleAssignments have not been fetched."); + } + }; + prototype.setRoleAssignments = function(roleAssignments) { + this.roleAssignments = roleAssignments; + }; }, { fetchOptions : "PersonFetchOptions", permId : "PersonPermId", registrationDate : "Date", space : "Space", - registrator : "Person" + registrator : "Person", + roleAssignments : { + name : "List", + arguments : [ "RoleAssignment" ] + } }); return Person; }) \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/fetchoptions/PersonFetchOptions.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/fetchoptions/PersonFetchOptions.js index e976267203ffe4eca6bc95a41001881bb6c54c13..e5c6e8737cef7449f8037e66c853478df0405258 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/fetchoptions/PersonFetchOptions.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/person/fetchoptions/PersonFetchOptions.js @@ -2,7 +2,8 @@ * Class automatically generated with * {@link ch.ethz.sis.openbis.generic.shared.api.v3.dto.generators.DtoGenerator} */ -define([ "require", "stjs", "as/dto/common/fetchoptions/FetchOptions", "as/dto/space/fetchoptions/SpaceFetchOptions", "as/dto/person/fetchoptions/PersonSortOptions" ], function(require, stjs, FetchOptions) { +define([ "require", "stjs", "as/dto/common/fetchoptions/FetchOptions", "as/dto/space/fetchoptions/SpaceFetchOptions", + "as/dto/person/fetchoptions/PersonSortOptions", "as/dto/roleassignment/fetchoptions/RoleAssignmentFetchOptions" ], function(require, stjs, FetchOptions) { var PersonFetchOptions = function() { }; stjs.extend(PersonFetchOptions, FetchOptions, [ FetchOptions ], function(constructor, prototype) { @@ -10,6 +11,7 @@ define([ "require", "stjs", "as/dto/common/fetchoptions/FetchOptions", "as/dto/s constructor.serialVersionUID = 1; prototype.space = null; prototype.registrator = null; + prototype.roleAssignments = null; prototype.sort = null; prototype.withSpace = function() { if (this.space == null) { @@ -36,6 +38,19 @@ define([ "require", "stjs", "as/dto/common/fetchoptions/FetchOptions", "as/dto/s prototype.hasRegistrator = function() { return this.registrator != null; }; + prototype.withRoleAssignments = function() { + if (this.roleAssignments == null) { + var RoleAssignmentsFetchOptions = require("as/dto/roleassignment/fetchoptions/RoleAssignmentFetchOptions"); + this.roleAssignments = new RoleAssignmentsFetchOptions(); + } + return this.roleAssignments; + }; + prototype.withRoleAssignmentsUsing = function(fetchOptions) { + return this.roleAssignments = fetchOptions; + }; + prototype.hasRoleAssignments = function() { + return this.roleAssignments != null; + }; prototype.sortBy = function() { if (this.sort == null) { var PersonSortOptions = require("as/dto/person/fetchoptions/PersonSortOptions"); @@ -49,6 +64,7 @@ define([ "require", "stjs", "as/dto/common/fetchoptions/FetchOptions", "as/dto/s }, { space : "SpaceFetchOptions", registrator : "PersonFetchOptions", + roleAssignments : "RoleAssignmentFetchOptions", sort : "PersonSortOptions" }); return PersonFetchOptions; diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPersonTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPersonTest.java index 51f9a9f838870353aa60c5b87ce98c1bcbb15591..2b7cdf7f0ee214a58c7d01d4fc57ca23f7addadc 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPersonTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPersonTest.java @@ -27,6 +27,7 @@ import org.testng.annotations.Test; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.search.PersonSearchCriteria; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; /** @@ -40,18 +41,21 @@ public class SearchPersonTest extends AbstractTest public void testSearchPersonByUserId() { // Given - String sessionToken = v3api.login(TEST_SPACE_USER, PASSWORD); + String sessionToken = v3api.login(TEST_USER, PASSWORD); PersonSearchCriteria searchCriteria = new PersonSearchCriteria(); searchCriteria.withUserId().thatStartsWith("observer"); PersonFetchOptions fetchOptions = new PersonFetchOptions(); fetchOptions.withSpace(); + fetchOptions.withRoleAssignments().withSpace(); // Then List<Person> persons = v3api.searchPersons(sessionToken, searchCriteria, fetchOptions).getObjects(); // When - assertEquals(render(persons), "observer: John Observer observer@o.o\n" - + "observer_cisd: John ObserverCISD observer_cisd@o.o\n"); + assertEquals(render(persons), "observer: John Observer observer@o.o, home space:CISD, " + + "[SPACE_OBSERVER Space TESTGROUP]\n" + + "observer_cisd: John ObserverCISD observer_cisd@o.o, home space:CISD, " + + "[SPACE_ADMIN Space TESTGROUP, SPACE_OBSERVER Space CISD]\n"); } private String render(List<Person> persons) @@ -80,10 +84,24 @@ public class SearchPersonTest extends AbstractTest Space space = person.getSpace(); if (space != null) { - builder.append(" home space:").append(space.getCode()); + builder.append(", home space:").append(space.getCode()); } + List<RoleAssignment> roleAssignments = person.getRoleAssignments(); + String string = renderAssignments(roleAssignments); + builder.append(", ").append(string); return builder.toString(); } + + private String renderAssignments(List<RoleAssignment> roleAssignments) + { + List<String> renderedAssignments = new ArrayList<>(); + for (RoleAssignment roleAssignment : roleAssignments) + { + renderedAssignments.add(roleAssignment.getRoleLevel() + "_" + roleAssignment.getRole() + " " + roleAssignment.getSpace()); + } + Collections.sort(renderedAssignments); + return renderedAssignments.toString(); + } private void appendTo(StringBuilder builder, String stringOrNull) { diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/Person.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/Person.java index e4d87c116f89eb55de3858c65e2057e8ba89e6af..5aeaf73e119ceafec68f9083ff35d4c20d6782e3 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/Person.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/Person.java @@ -22,6 +22,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.ISpaceHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.NotFetchedException; import ch.systemsx.cisd.base.annotation.JsonObject; @@ -29,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.io.Serializable; import java.util.Date; +import java.util.List; /* * Class automatically generated with DtoGenerator @@ -68,6 +70,9 @@ public class Person implements Serializable, IPermIdHolder, IRegistrationDateHol @JsonProperty private Person registrator; + @JsonProperty + private List<RoleAssignment> roleAssignments; + // Method automatically generated with DtoGenerator @JsonIgnore public PersonFetchOptions getFetchOptions() @@ -216,6 +221,24 @@ public class Person implements Serializable, IPermIdHolder, IRegistrationDateHol this.registrator = registrator; } + + @JsonIgnore + public List<RoleAssignment> getRoleAssignments() + { + if (getFetchOptions() != null && getFetchOptions().hasRoleAssignments()) + { + return roleAssignments; + } + else + { + throw new NotFetchedException("Role assignments have not been fetched."); + } + } + + public void setRoleAssignments(List<RoleAssignment> roleAssignments) + { + this.roleAssignments = roleAssignments; + } // Method automatically generated with DtoGenerator @Override public String toString() diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/fetchoptions/PersonFetchOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/fetchoptions/PersonFetchOptions.java index 3fab3a8da3f4135f23eddb72e48535ed0924776f..976b0ad38071ddaf1bbfa491cf64605d6dec97eb 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/fetchoptions/PersonFetchOptions.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/person/fetchoptions/PersonFetchOptions.java @@ -19,6 +19,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.FetchOptions import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.FetchOptionsToStringBuilder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.fetchoptions.PersonFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.fetchoptions.RoleAssignmentFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions; import ch.systemsx.cisd.base.annotation.JsonObject; import com.fasterxml.jackson.annotation.JsonProperty; @@ -38,6 +39,9 @@ public class PersonFetchOptions extends FetchOptions<Person> implements Serializ @JsonProperty private PersonFetchOptions registrator; + @JsonProperty + private RoleAssignmentFetchOptions roleAssignments; + @JsonProperty private PersonSortOptions sort; @@ -85,6 +89,25 @@ public class PersonFetchOptions extends FetchOptions<Person> implements Serializ return registrator != null; } + public RoleAssignmentFetchOptions withRoleAssignments() + { + if (roleAssignments == null) + { + roleAssignments = new RoleAssignmentFetchOptions(); + } + return roleAssignments; + } + + public RoleAssignmentFetchOptions withRoleAssignmentsUsing(RoleAssignmentFetchOptions fetchOptions) + { + return roleAssignments = fetchOptions; + } + + public boolean hasRoleAssignments() + { + return roleAssignments != null; + } + // Method automatically generated with DtoGenerator @Override public PersonSortOptions sortBy()