diff --git a/src/main/java/org/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java index 3e49b08f2c0771f7770818b412dfa564763db48b..4550eebfc7fac884bcb781fc85112f9c811aae15 100644 --- a/src/main/java/org/caosdb/server/entity/Entity.java +++ b/src/main/java/org/caosdb/server/entity/Entity.java @@ -540,7 +540,8 @@ public class Entity extends AbstractObservable implements EntityInterface { return getToElementStrategy().toElement(this, getSerializeFieldStrategy()); } - private SetFieldStrategy getSerializeFieldStrategy() { + @Override + public SetFieldStrategy getSerializeFieldStrategy() { if (this.serializeFieldStrategy == null) { this.serializeFieldStrategy = new SetFieldStrategy(getSelections()); } diff --git a/src/main/java/org/caosdb/server/entity/EntityInterface.java b/src/main/java/org/caosdb/server/entity/EntityInterface.java index 46726df63dcedb651e0762f54a7b2cdafb5041d7..b26a40572e7258849b08ecaef052dd6151dd15b7 100644 --- a/src/main/java/org/caosdb/server/entity/EntityInterface.java +++ b/src/main/java/org/caosdb/server/entity/EntityInterface.java @@ -199,4 +199,6 @@ public interface EntityInterface * AbstractCollectionDatatype's elements' data type is an instance of ReferenceDatatype. */ public abstract boolean isReferenceList(); + + public abstract SetFieldStrategy getSerializeFieldStrategy(); } diff --git a/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java index 01c374ecb5c6ac073981db6f44a34989a0e6822e..f8ccfa9385163efadec1be4ed901e151ef4ec35d 100644 --- a/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java @@ -580,4 +580,9 @@ public class EntityWrapper implements EntityInterface { public void setSerializeFieldStrategy(SetFieldStrategy s) { this.entity.setSerializeFieldStrategy(s); } + + @Override + public SetFieldStrategy getSerializeFieldStrategy() { + return this.entity.getSerializeFieldStrategy(); + } } diff --git a/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java b/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java index 2d6b696c235052974326dbfca110be32604c3981..a858728466732faea86db7083b6ba60b25e6544e 100644 --- a/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java @@ -135,10 +135,11 @@ public class SetFieldStrategy { if (this.cache == null) { this.cache = new HashMap<String, Boolean>(); - // always include the id, version and the name + // always include the id, version, role and the name this.cache.put("id", true); this.cache.put("version", true); this.cache.put("name", true); + this.cache.put("role", true); // ... and the referenced entity. this.cache.put("_referenced", true); diff --git a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java index d9ac193c104c9cb643897a0cabc97ff2f42cbb9a..97253fde681de1bd8a49eb40400c37fc76605cba 100644 --- a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java +++ b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java @@ -24,6 +24,7 @@ package org.caosdb.server.grpc; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.NoSuchElementException; import java.util.TimeZone; import org.caosdb.api.entity.v1.AtomicDataType; import org.caosdb.api.entity.v1.CollectionValues; @@ -69,8 +70,8 @@ import org.caosdb.server.entity.Message; import org.caosdb.server.entity.Role; import org.caosdb.server.entity.StatementStatus; import org.caosdb.server.entity.container.ParentContainer; -import org.caosdb.server.entity.container.PropertyContainer; import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.SetFieldStrategy; import org.caosdb.server.permissions.EntityACI; import org.caosdb.server.permissions.EntityPermission; @@ -97,24 +98,25 @@ public class CaosDBToGrpcConverters { public EntityResponse.Builder convert(final EntityInterface from) { + SetFieldStrategy s = from.getSerializeFieldStrategy(); final Builder entityBuilder = Entity.newBuilder(); - if (from.hasId()) { + if (from.hasId() && s.isToBeSet("id")) { entityBuilder.setId(Integer.toString(from.getId())); } - if (from.getRole() != null) { + if (from.getRole() != null && s.isToBeSet("role")) { entityBuilder.setRole(convert(from.getRole())); } - if (from.hasName()) { + if (from.hasName() && s.isToBeSet("name")) { entityBuilder.setName(from.getName()); } - if (from.hasDescription()) { + if (from.hasDescription() && s.isToBeSet("description")) { entityBuilder.setDescription(from.getDescription()); } - if (from.hasDatatype()) { + if (from.hasDatatype() && s.isToBeSet("datatype")) { entityBuilder.setDataType(convert(from.getDatatype())); } - if (from.hasValue()) { + if (from.hasValue() && s.isToBeSet("value")) { try { from.parseValue(); } catch (final Message e) { @@ -125,17 +127,20 @@ public class CaosDBToGrpcConverters { entityBuilder.setValue(convert(from.getValue())); } final String unit = getStringUnit(from); - if (unit != null) { + if (unit != null && s.isToBeSet("unit")) { entityBuilder.setUnit(unit); } if (from.hasProperties()) { - entityBuilder.addAllProperties(convert(from.getProperties())); + entityBuilder.addAllProperties(convertProperties(from)); } - if (from.hasParents()) { + if (from.hasParents() && s.isToBeSet("parent")) { entityBuilder.addAllParents(convert(from.getParents())); } if (from.hasFileProperties()) { - entityBuilder.setFileDescriptor(convert(from.getFileProperties())); + FileDescriptor.Builder fileDescriptor = convert(s, from.getFileProperties()); + if (fileDescriptor != null) { + entityBuilder.setFileDescriptor(fileDescriptor); + } } final EntityResponse.Builder responseBuilder = EntityResponse.newBuilder(); @@ -146,10 +151,18 @@ public class CaosDBToGrpcConverters { return responseBuilder; } - private FileDescriptor.Builder convert(FileProperties fileProperties) { - FileDescriptor.Builder result = FileDescriptor.newBuilder(); - result.setPath(fileProperties.getPath()); - result.setSize(fileProperties.getSize()); + private FileDescriptor.Builder convert(SetFieldStrategy s, FileProperties fileProperties) { + FileDescriptor.Builder result = null; + if (s.isToBeSet("path")) { + result = FileDescriptor.newBuilder(); + result.setPath(fileProperties.getPath()); + } + if (s.isToBeSet("size")) { + if (result == null) { + result = FileDescriptor.newBuilder(); + } + result.setSize(fileProperties.getSize()); + } return result; } @@ -216,23 +229,24 @@ public class CaosDBToGrpcConverters { final org.caosdb.api.entity.v1.Property.Builder builder = org.caosdb.api.entity.v1.Property.newBuilder(); - if (from.hasId()) { + SetFieldStrategy s = from.getSerializeFieldStrategy(); + if (from.hasId() && s.isToBeSet("id")) { builder.setId(from.getId().toString()); } - if (from.hasName()) { + if (from.hasName() && s.isToBeSet("name")) { builder.setName(from.getName()); } - if (from.hasDescription()) { + if (from.hasDescription() && s.isToBeSet("description")) { builder.setDescription(from.getDescription()); } - if (from.hasDatatype()) { + if (from.hasDatatype() && s.isToBeSet("datatype")) { builder.setDataType(convert(from.getDatatype())); } final String unit = getStringUnit(from); - if (unit != null) { + if (unit != null && s.isToBeSet("unit")) { builder.setUnit(unit); } - if (from.hasValue()) { + if (from.hasValue() && s.isToBeSet("value")) { try { from.parseValue(); } catch (final Message e) { @@ -242,7 +256,9 @@ public class CaosDBToGrpcConverters { } builder.setValue(convert(from.getValue())); } - builder.setImportance(convert(from.getStatementStatus())); + if (s.isToBeSet("importance")) { + builder.setImportance(convert(from.getStatementStatus())); + } return builder.build(); } @@ -429,20 +445,42 @@ public class CaosDBToGrpcConverters { return ReferenceDataType.newBuilder().setName(datatype.getName()); } - public Iterable<? extends org.caosdb.api.entity.v1.Property> convert( - final PropertyContainer from) { - final Iterator<org.caosdb.server.entity.wrapper.Property> iterator = from.iterator(); + public Iterable<? extends org.caosdb.api.entity.v1.Property> convertProperties( + final EntityInterface from) { + + final Iterator<org.caosdb.server.entity.wrapper.Property> iterator = + from.getProperties().iterator(); return () -> new Iterator<>() { + private Property property; + @Override public boolean hasNext() { - return iterator.hasNext(); + while (iterator.hasNext()) { + this.property = iterator.next(); + if (from.getSerializeFieldStrategy().isToBeSet(this.property.getName())) { + this.property.setSerializeFieldStrategy( + from.getSerializeFieldStrategy().forProperty(this.property)); + return true; + } + } + return false; } @Override public org.caosdb.api.entity.v1.Property next() { - return convert(iterator.next()); + if (this.property == null) { + // trigger this.property to be non-null + if (!hasNext()) { + throw new NoSuchElementException("The iterator has no more elements."); + } + } + + Property next_property = this.property; + this.property = null; + + return convert(next_property); } }; } @@ -466,26 +504,28 @@ public class CaosDBToGrpcConverters { public void appendMessages( final EntityInterface from, final org.caosdb.api.entity.v1.EntityResponse.Builder builder) { - if (from.hasMessage(Message.MessageType.Error.toString())) { + SetFieldStrategy s = from.getSerializeFieldStrategy(); + if (from.hasMessage(Message.MessageType.Error.toString()) && s.isToBeSet("error")) { builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); } - if (from.hasMessage(Message.MessageType.Warning.toString())) { + if (from.hasMessage(Message.MessageType.Warning.toString()) && s.isToBeSet("warning")) { builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); } - if (from.hasMessage(Message.MessageType.Info.toString())) { + if (from.hasMessage(Message.MessageType.Info.toString()) && s.isToBeSet("info")) { builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); } } public void appendMessages( final EntityInterface from, final org.caosdb.api.entity.v1.IdResponse.Builder builder) { - if (from.hasMessage(Message.MessageType.Error.toString())) { + SetFieldStrategy s = from.getSerializeFieldStrategy(); + if (from.hasMessage(Message.MessageType.Error.toString()) && s.isToBeSet("error")) { builder.addAllErrors(convert(from.getMessages(Message.MessageType.Error.toString()))); } - if (from.hasMessage(Message.MessageType.Warning.toString())) { + if (from.hasMessage(Message.MessageType.Warning.toString()) && s.isToBeSet("warning")) { builder.addAllWarnings(convert(from.getMessages(Message.MessageType.Warning.toString()))); } - if (from.hasMessage(Message.MessageType.Info.toString())) { + if (from.hasMessage(Message.MessageType.Info.toString()) && s.isToBeSet("info")) { builder.addAllInfos(convert(from.getMessages(Message.MessageType.Info.toString()))); } } diff --git a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java index c234e61048ba7af730dd7928d0b64ff587c005cc..f3f1779497d00f89f21b5dc84fbb82b048e73caf 100644 --- a/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java +++ b/src/main/java/org/caosdb/server/grpc/EntityTransactionServiceImpl.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.TimeZone; import java.util.UUID; import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; import org.caosdb.api.entity.v1.DeleteRequest; import org.caosdb.api.entity.v1.DeleteResponse; import org.caosdb.api.entity.v1.Entity; @@ -52,10 +53,12 @@ import org.caosdb.server.entity.DeleteEntity; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.FileProperties; import org.caosdb.server.entity.InsertEntity; +import org.caosdb.server.entity.Message; import org.caosdb.server.entity.RetrieveEntity; import org.caosdb.server.entity.UpdateEntity; import org.caosdb.server.entity.container.RetrieveContainer; import org.caosdb.server.entity.container.WritableContainer; +import org.caosdb.server.permissions.EntityPermission; import org.caosdb.server.transaction.Retrieve; import org.caosdb.server.transaction.RetrieveACL; import org.caosdb.server.transaction.UpdateACL; @@ -136,13 +139,19 @@ public class EntityTransactionServiceImpl extends EntityTransactionServiceImplBa final EntityResponse.Builder entityResponse = caosdbToGrpc.convert(entity); if ((download_files_container || entity.getFlags().containsKey("download_files")) && entity.hasFileProperties()) { - if (fileDownload == null) { - fileDownload = fileTransmissionService.registerFileDownload(null); + try { + entity.checkPermission(EntityPermission.RETRIEVE_FILE); + if (fileDownload == null) { + fileDownload = fileTransmissionService.registerFileDownload(null); + } + entity.getFileProperties().retrieveFromFileSystem(); + entityResponse.setDownloadId( + fileTransmissionService.registerFileDownload( + fileDownload.getId(), entity.getFileProperties())); + } catch (AuthenticationException exc) { + entityResponse.addErrors(caosdbToGrpc.convert(ServerMessages.AUTHORIZATION_ERROR)); + entityResponse.addInfos(caosdbToGrpc.convert(new Message(exc.getMessage()))); } - entity.getFileProperties().retrieveFromFileSystem(); - entityResponse.setDownloadId( - fileTransmissionService.registerFileDownload( - fileDownload.getId(), entity.getFileProperties())); } builder .addResponsesBuilder()