From 6f99f43826ee4493f9b16ed106c2072ec160b808 Mon Sep 17 00:00:00 2001
From: jakubs <jakubs>
Date: Wed, 31 Oct 2012 14:56:41 +0000
Subject: [PATCH] SP-365 BIS-245 search service should filter on calling user

SVN: 27434
---
 .../v1/IDataSetRegistrationTransaction.java   |  12 +-
 .../api/v1/impl/AbstractDataSetImmutable.java |   6 +-
 .../api/v1/impl/AuthorizationHelper.java      | 115 ++++++++++++++
 .../api/v1/impl/AuthorizationService.java     | 104 +++++-------
 .../api/v1/impl/DataSetImmutable.java         |   4 +-
 .../impl/DataSetRegistrationTransaction.java  |  12 ++
 .../api/v1/impl/DataSetUpdatable.java         |   4 +-
 .../api/v1/impl/SearchService.java            |   6 +-
 ...aSetRegistrationTransactionV2Delegate.java |   6 +
 .../v2/IDataSetRegistrationTransactionV2.java |  11 +-
 ...capsulatedFilteredBasicOpenBISService.java | 148 ++++++++++++++++++
 .../server/EncapsulatedOpenBISService.java    |   8 +
 .../jython/PluginScriptRunnerFactory.java     |  27 +++-
 .../shared/DataSetProcessingContext.java      |   3 +
 .../IEncapsulatedBasicOpenBISService.java     |  88 +++++++++++
 .../shared/IEncapsulatedOpenBISService.java   |  62 ++------
 .../dss/generic/shared/ServiceProvider.java   |   4 +-
 .../plugin.properties                         |   3 +
 .../searchServiceAggregationService.py        |  41 +++++
 .../systemtests/QueryFacadeTest.java          | 131 +++++++++++++++-
 ...AggregationServiceReportingPluginTest.java |   8 +-
 21 files changed, 656 insertions(+), 147 deletions(-)
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationHelper.java
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedFilteredBasicOpenBISService.java
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedBasicOpenBISService.java
 create mode 100644 datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/plugin.properties
 create mode 100644 datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/searchServiceAggregationService.py

diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
index 34e9361a187..c7d0dd83a5e 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
@@ -263,12 +263,22 @@ public interface IDataSetRegistrationTransaction
     String createNewFile(IDataSet dst, String dstInDataset, String fileName);
 
     /**
-     * Retrieve the search service for this transaction
+     * Retrieve the search service for this transaction. If the user is available for this
+     * transaction, then the search service results will be filtered for this user.
      * 
      * @return The search service for this transaction.
      */
     ISearchService getSearchService();
 
+    /**
+     * Retrieve the search service for this transaction. It returns the results unfiltered by the
+     * user, even if the user is available.
+     * 
+     * @return The search service for this transaction.
+     */
+    ISearchService getSearchServiceUnfiltered();
+
+
     /**
      * @return A service which can be used to get authorization information about a user.
      */
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractDataSetImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractDataSetImmutable.java
index f5b7c11882f..f0b8213eb9d 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractDataSetImmutable.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractDataSetImmutable.java
@@ -20,7 +20,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.Translator;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType;
@@ -37,9 +37,9 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm;
  */
 abstract class AbstractDataSetImmutable implements IDataSetImmutable 
 {
-    protected final IEncapsulatedOpenBISService service;
+    protected final IEncapsulatedBasicOpenBISService service;
 
-    AbstractDataSetImmutable(IEncapsulatedOpenBISService service)
+    AbstractDataSetImmutable(IEncapsulatedBasicOpenBISService service)
     {
         this.service = service;
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationHelper.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationHelper.java
new file mode 100644
index 00000000000..c591c37d4ed
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationHelper.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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.systemsx.cisd.etlserver.registrator.api.v1.impl;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import ch.systemsx.cisd.common.action.IMapper;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+
+/**
+ * @author Jakub Straszewski
+ */
+public class AuthorizationHelper
+{
+    public static <T> List<T> filterToVisibleDatasets(IEncapsulatedOpenBISService openBisService,
+            String user, List<T> datasets,
+            IMapper<T, String> codeMapper)
+    {
+        // create a list of codes
+        List<String> dataSetCodes = new LinkedList<String>();
+        for (T dataSet : datasets)
+        {
+            dataSetCodes.add(codeMapper.map(dataSet));
+        }
+
+        // call service - to filter the codes
+        List<String> filteredCodes = openBisService.filterToVisibleDataSets(user, dataSetCodes);
+        // put filtered codes to the set
+        Set<String> filteredSet = new HashSet<String>(filteredCodes);
+
+        // filter original values to those returned by the service call
+        List<T> resultList = new LinkedList<T>();
+        for (T dataSet : datasets)
+        {
+            if (filteredSet.contains(codeMapper.map(dataSet)))
+            {
+                resultList.add(dataSet);
+            }
+        }
+        return resultList;
+    }
+
+    public static <T> List<T> filterToVisibleExperiments(
+            IEncapsulatedOpenBISService openBisService, String user, List<T> experiments,
+            IMapper<T, String> identifierMapper)
+    {
+        // create a list of codes
+        List<String> experimentIds = new LinkedList<String>();
+        for (T exp : experiments)
+        {
+            experimentIds.add(identifierMapper.map(exp));
+        }
+
+        // call service - to filter the codes
+        List<String> filteredCodes = openBisService.filterToVisibleExperiments(user, experimentIds);
+        // put filtered codes to the set
+        Set<String> filteredSet = new HashSet<String>(filteredCodes);
+
+        // filter original values to those returned by the service call
+        List<T> resultList = new LinkedList<T>();
+        for (T exp : experiments)
+        {
+            if (filteredSet.contains(identifierMapper.map(exp)))
+            {
+                resultList.add(exp);
+            }
+        }
+        return resultList;
+    }
+
+    public static <T> List<T> filterToVisibleSamples(IEncapsulatedOpenBISService openBisService,
+            String user, List<T> samples, IMapper<T, String> identifierMapper)
+    {
+        // create a list of codes
+        List<String> sampleIds = new LinkedList<String>();
+        for (T sample : samples)
+        {
+            sampleIds.add(identifierMapper.map(sample));
+        }
+
+        // call service - to filter the codes
+        List<String> filteredCodes = openBisService.filterToVisibleSamples(user, sampleIds);
+        // put filtered codes to the set
+        Set<String> filteredSet = new HashSet<String>(filteredCodes);
+
+        // filter original values to those returned by the service call
+        List<T> resultList = new LinkedList<T>();
+        for (T sample : samples)
+        {
+            if (filteredSet.contains(identifierMapper.map(sample)))
+            {
+                resultList.add(sample);
+            }
+        }
+        return resultList;
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationService.java
index b6ec5ee533c..06c4154c2bf 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AuthorizationService.java
@@ -16,11 +16,9 @@
 
 package ch.systemsx.cisd.etlserver.registrator.api.v1.impl;
 
-import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
+import ch.systemsx.cisd.common.action.IMapper;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.authorization.IAuthorizationService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable;
@@ -45,86 +43,58 @@ public class AuthorizationService implements IAuthorizationService
         return openBisService.doesUserHaveRole(user, role, spaceOrNull);
     }
 
+
     @Override
     public List<IDataSetImmutable> filterToVisibleDatasets(String user,
             List<IDataSetImmutable> datasets)
     {
-        // create a list of codes
-        List<String> dataSetCodes = new LinkedList<String>();
-        for (IDataSetImmutable dataSet : datasets)
-        {
-            dataSetCodes.add(dataSet.getDataSetCode());
-        }
-
-        // call service - to filter the codes
-        List<String> filteredCodes = openBisService.filterToVisibleDataSets(user, dataSetCodes);
-        // put filtered codes to the set
-        Set<String> filteredSet = new HashSet<String>(filteredCodes);
-
-        // filter original values to those returned by the service call
-        List<IDataSetImmutable> resultList = new LinkedList<IDataSetImmutable>();
-        for (IDataSetImmutable dataSet : datasets)
-        {
-            if (filteredSet.contains(dataSet.getDataSetCode()))
+        // waiting for lambdas... (x) => x.getDataSetCode();
+        IMapper<IDataSetImmutable, String> codeMapper = new IMapper<IDataSetImmutable, String>()
             {
-                resultList.add(dataSet);
-            }
-        }
-        return resultList;
+                @Override
+                public String map(IDataSetImmutable item)
+                {
+                    return item.getDataSetCode();
+                }
+            };
+
+        return AuthorizationHelper.filterToVisibleDatasets(openBisService, user, datasets,
+                codeMapper);
     }
 
+
     @Override
     public List<IExperimentImmutable> filterToVisibleExperiments(String user,
             List<IExperimentImmutable> experiments)
     {
-        // create a list of codes
-        List<String> experimentIds = new LinkedList<String>();
-        for (IExperimentImmutable exp : experiments)
-        {
-            experimentIds.add(exp.getExperimentIdentifier());
-        }
-
-        // call service - to filter the codes
-        List<String> filteredCodes = openBisService.filterToVisibleExperiments(user, experimentIds);
-        // put filtered codes to the set
-        Set<String> filteredSet = new HashSet<String>(filteredCodes);
-
-        // filter original values to those returned by the service call
-        List<IExperimentImmutable> resultList = new LinkedList<IExperimentImmutable>();
-        for (IExperimentImmutable exp : experiments)
-        {
-            if (filteredSet.contains(exp.getExperimentIdentifier()))
-            {
-                resultList.add(exp);
-            }
-        }
-        return resultList;
+        IMapper<IExperimentImmutable, String> idMapper =
+                new IMapper<IExperimentImmutable, String>()
+                    {
+                        @Override
+                        public String map(IExperimentImmutable item)
+                        {
+                            return item.getExperimentIdentifier();
+                        }
+                    };
+
+        return AuthorizationHelper.filterToVisibleExperiments(openBisService, user, experiments,
+                idMapper);
+
     }
 
     @Override
     public List<ISampleImmutable> filterToVisibleSamples(String user, List<ISampleImmutable> samples)
     {
-        // create a list of codes
-        List<String> sampleIds = new LinkedList<String>();
-        for (ISampleImmutable sample : samples)
-        {
-            sampleIds.add(sample.getSampleIdentifier());
-        }
-
-        // call service - to filter the codes
-        List<String> filteredCodes = openBisService.filterToVisibleSamples(user, sampleIds);
-        // put filtered codes to the set
-        Set<String> filteredSet = new HashSet<String>(filteredCodes);
-
-        // filter original values to those returned by the service call
-        List<ISampleImmutable> resultList = new LinkedList<ISampleImmutable>();
-        for (ISampleImmutable sample : samples)
-        {
-            if (filteredSet.contains(sample.getSampleIdentifier()))
+
+        IMapper<ISampleImmutable, String> idMapper = new IMapper<ISampleImmutable, String>()
             {
-                resultList.add(sample);
-            }
-        }
-        return resultList;
+                @Override
+                public String map(ISampleImmutable item)
+                {
+                    return item.getSampleIdentifier();
+                }
+            };
+
+        return AuthorizationHelper.filterToVisibleSamples(openBisService, user, samples, idMapper);
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java
index 999de7c7025..d0147441778 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExternalDataManagementSystemImmutable;
@@ -42,7 +42,7 @@ public class DataSetImmutable extends AbstractDataSetImmutable
 {
     protected final ExternalData dataSet;
 
-    public DataSetImmutable(ExternalData dataSet, IEncapsulatedOpenBISService service)
+    public DataSetImmutable(ExternalData dataSet, IEncapsulatedBasicOpenBISService service)
     {
         super(service);
         this.dataSet = dataSet;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
index 2680dc96389..bdeedcb2eb9 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
@@ -659,6 +659,18 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
 
     @Override
     public ISearchService getSearchService()
+    {
+        if (getUserId() == null)
+            return getSearchServiceUnfiltered();
+        else
+            return new SearchService(
+                    openBisService
+                            .getBasicFilteredOpenBISService(getStateAsLiveState()
+                            .getUserId()));
+    }
+
+    @Override
+    public ISearchService getSearchServiceUnfiltered()
     {
         return new SearchService(openBisService);
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetUpdatable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetUpdatable.java
index 14828c8a7a7..1b58c490c6b 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetUpdatable.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetUpdatable.java
@@ -23,7 +23,7 @@ import java.util.List;
 import java.util.Set;
 
 import ch.systemsx.cisd.etlserver.registrator.api.v1.IDataSetUpdatable;
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExternalDataManagementSystemImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmutable;
@@ -54,7 +54,7 @@ public class DataSetUpdatable extends DataSetImmutable implements IDataSetUpdata
 
     private final DataSetBatchUpdateDetails updateDetails;
 
-    public DataSetUpdatable(ExternalData dataSet, IEncapsulatedOpenBISService service)
+    public DataSetUpdatable(ExternalData dataSet, IEncapsulatedBasicOpenBISService service)
     {
         super(dataSet, service);
         if (dataSet.getProperties() == null)
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
index 2a7a0e28072..dd14d52ff45 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
@@ -24,7 +24,7 @@ import java.util.Set;
 
 import ch.systemsx.cisd.common.collection.CollectionUtils;
 import ch.systemsx.cisd.common.collection.CollectionUtils.ICollectionFilter;
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IMaterialImmutable;
@@ -52,9 +52,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierF
  */
 public class SearchService implements ISearchService
 {
-    private final IEncapsulatedOpenBISService openBisService;
+    private final IEncapsulatedBasicOpenBISService openBisService;
 
-    public SearchService(IEncapsulatedOpenBISService openBisService)
+    public SearchService(IEncapsulatedBasicOpenBISService openBisService)
     {
         this.openBisService = openBisService;
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
index 004ea32cf2f..f2f14321d80 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
@@ -222,6 +222,12 @@ public class DataSetRegistrationTransactionV2Delegate implements IDataSetRegistr
         return transaction.getSearchService();
     }
 
+    @Override
+    public ISearchService getSearchServiceUnfiltered()
+    {
+        return transaction.getSearchServiceUnfiltered();
+    }
+
     @Override
     public IAuthorizationService getAuthorizationService()
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
index 3607b9be167..492ee3f3e0c 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
@@ -250,12 +250,21 @@ public interface IDataSetRegistrationTransactionV2
     String createNewFile(IDataSet dst, String dstInDataset, String fileName);
 
     /**
-     * Retrieve the search service for this transaction
+     * Retrieve the search service for this transaction. If the user is available for this
+     * transaction, then the search service results will be filtered for this user.
      * 
      * @return The search service for this transaction.
      */
     ISearchService getSearchService();
 
+    /**
+     * Retrieve the search service for this transaction. It returns the results unfiltered by the
+     * user, even if the user is available.
+     * 
+     * @return The search service for this transaction.
+     */
+    ISearchService getSearchServiceUnfiltered();
+
     /**
      * @return A service which can be used to get authorization information about a user.
      */
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedFilteredBasicOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedFilteredBasicOpenBISService.java
new file mode 100644
index 00000000000..9e37cb62975
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedFilteredBasicOpenBISService.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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.systemsx.cisd.openbis.dss.generic.server;
+
+import java.util.Collection;
+import java.util.List;
+
+import ch.systemsx.cisd.common.action.IMapper;
+import ch.systemsx.cisd.common.exception.UserFailureException;
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.AuthorizationHelper;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * The basic version of encapsulated openbis service, that calls the etl service and filters the
+ * result to visible only to the specified user.
+ * 
+ * @author Jakub Straszewski
+ */
+public class EncapsulatedFilteredBasicOpenBISService implements IEncapsulatedBasicOpenBISService
+{
+    private final IETLLIMSService etlService;
+
+    private final String systemSessionToken;
+
+    private final IEncapsulatedOpenBISService encapsulatedService;
+
+    private final String userName;
+
+    public EncapsulatedFilteredBasicOpenBISService(String userName, IETLLIMSService etlService,
+            IEncapsulatedOpenBISService encapsulatedService, String systemSessionToken)
+    {
+        this.etlService = etlService;
+        this.encapsulatedService = encapsulatedService;
+
+        this.systemSessionToken = systemSessionToken;
+
+        this.userName = userName;
+    }
+
+    @Override
+    public DataSetTypeWithVocabularyTerms getDataSetType(String dataSetTypeCode)
+    {
+
+        return etlService.getDataSetType(systemSessionToken, dataSetTypeCode);
+    }
+
+    @Override
+    public List<Sample> searchForSamples(SearchCriteria searchCriteria)
+    {
+        IMapper<Sample, String> idMapper = new IMapper<Sample, String>()
+            {
+                @Override
+                public String map(Sample item)
+                {
+                    return item.getIdentifier();
+                }
+            };
+
+        List<Sample> samples = etlService.searchForSamples(systemSessionToken, searchCriteria);
+
+        return AuthorizationHelper.filterToVisibleSamples(encapsulatedService, userName, samples,
+                idMapper);
+
+    }
+
+    @Override
+    public List<ExternalData> searchForDataSets(SearchCriteria searchCriteria)
+    {
+        IMapper<ExternalData, String> codeMapper = new IMapper<ExternalData, String>()
+            {
+                @Override
+                public String map(ExternalData item)
+                {
+                    return item.getCode();
+                }
+            };
+
+        List<ExternalData> datasets =
+                etlService.searchForDataSets(systemSessionToken, searchCriteria);
+
+        return AuthorizationHelper.filterToVisibleDatasets(encapsulatedService, userName, datasets,
+                codeMapper);
+    }
+
+    @Override
+    public List<Experiment> listExperiments(ProjectIdentifier projectIdentifier)
+    {
+        IMapper<Experiment, String> codeMapper = new IMapper<Experiment, String>()
+            {
+                @Override
+                public String map(Experiment item)
+                {
+                    return item.getIdentifier();
+                }
+            };
+
+        List<Experiment> datasets =
+                etlService.listExperiments(systemSessionToken, projectIdentifier);
+
+        return AuthorizationHelper.filterToVisibleExperiments(encapsulatedService, userName,
+                datasets, codeMapper);
+    }
+
+    @Override
+    public Collection<VocabularyTerm> listVocabularyTerms(String vocabularyCode)
+            throws UserFailureException
+    {
+        return etlService.listVocabularyTerms(systemSessionToken, vocabularyCode);
+    }
+
+    @Override
+    public Vocabulary tryGetVocabulary(String code)
+    {
+        return etlService.tryGetVocabulary(systemSessionToken, code);
+    }
+
+    @Override
+    public List<Material> listMaterials(ListMaterialCriteria criteria, boolean withProperties)
+    {
+        return etlService.listMaterials(systemSessionToken, criteria, withProperties);
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
index 2ff59c99040..020f327ba9e 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
@@ -28,6 +28,7 @@ import ch.systemsx.cisd.common.exception.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.openbis.common.api.client.ServiceFinder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedBasicOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
@@ -154,6 +155,13 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer
         this.session = sessionHolder;
     }
 
+    @Override
+    public IEncapsulatedBasicOpenBISService getBasicFilteredOpenBISService(String user)
+    {
+        return new EncapsulatedFilteredBasicOpenBISService(user, service, this,
+                session.getSessionToken());
+    }
+
     private IShareIdManager getShareIdManager()
     {
         if (shareIdManager == null)
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/PluginScriptRunnerFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/PluginScriptRunnerFactory.java
index 24835dc6aaf..2923145a56f 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/PluginScriptRunnerFactory.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/PluginScriptRunnerFactory.java
@@ -30,6 +30,7 @@ import ch.systemsx.cisd.common.jython.evaluator.EvaluatorException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.shared.basic.string.StringUtils;
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.SearchService;
 import ch.systemsx.cisd.etlserver.registrator.api.v2.IDataSetRegistrationTransactionV2;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent;
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.api.IDataSet;
@@ -60,6 +61,8 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
 
     private final static String SEARCH_SERVICE_VARIABLE_NAME = "searchService";
 
+    private final static String SEARCH_SERVICE_UNFILTERED_VARIABLE_NAME = "searchServiceUnfiltered";
+
     private final static String DATA_SOURCE_QUERY_SERVICE_VARIABLE_NAME = "queryService";
 
     private final static String MAIL_SERVICE_VARIABLE_NAME = "mailService";
@@ -96,7 +99,7 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
         {
             AbstractAggregationServiceReportingPluginScriptRunner.InputData inputData =
                     createInputDataForReportingPluginScriptRunner(context, scriptString);
-            
+
             return new AggregationServiceReportingPluginScriptRunner(inputData);
         } catch (EvaluatorException ex)
         {
@@ -139,6 +142,7 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
                         contentProvider, contentProviderUnfiltered);
         return inputData;
     }
+
     /**
      * Factory method for creating an IReportingPluginScriptRunner for a given processing context.
      */
@@ -206,7 +210,10 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
     protected Evaluator createEvaluator(String scriptString, DataSetProcessingContext context)
     {
         final Evaluator evaluator = new Evaluator("", null, scriptString, false);
-        evaluator.set(SEARCH_SERVICE_VARIABLE_NAME, createSearchService());
+
+        evaluator.set(SEARCH_SERVICE_VARIABLE_NAME, createUserSearchService(context));
+        evaluator.set(SEARCH_SERVICE_UNFILTERED_VARIABLE_NAME, createUnfilteredSearchService());
+
         evaluator.set(MAIL_SERVICE_VARIABLE_NAME, createMailService(context));
         evaluator.set(DATA_SOURCE_QUERY_SERVICE_VARIABLE_NAME, createDataSourceQueryService());
         evaluator.set(AUTHORIZATION_SERVICE, createAuthorizationService());
@@ -220,7 +227,16 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
         return evaluator;
     }
 
-    protected ISearchService createSearchService()
+    protected ISearchService createUserSearchService(DataSetProcessingContext context)
+    {
+        if (context.getUserId() == null)
+            return createUnfilteredSearchService();
+        else
+            return new SearchService(ServiceProvider.getOpenBISService()
+                    .getBasicFilteredOpenBISService(context.getUserId()));
+    }
+
+    protected ISearchService createUnfilteredSearchService()
     {
         return ServiceProvider.getSearchService();
     }
@@ -287,7 +303,7 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
                 this.contentProviders = contentProviders;
             }
         }
-        
+
         final Evaluator evaluator;
 
         final DataSetContentProvider[] contentProviders;
@@ -315,7 +331,7 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
             evaluator.releaseResources();
         }
     }
-    
+
     private static class AggregationServiceReportingPluginScriptRunner extends
             AbstractAggregationServiceReportingPluginScriptRunner implements
             IAggregationServiceReportingPluginScriptRunner
@@ -349,7 +365,6 @@ public class PluginScriptRunnerFactory implements IPluginScriptRunnerFactory
     {
         private final static String FUNCTION_NAME = "process";
 
-
         DbModifyingAggregationServiceReportingPluginScriptRunner(
                 AbstractAggregationServiceReportingPluginScriptRunner.InputData inputData)
         {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/DataSetProcessingContext.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/DataSetProcessingContext.java
index c1334a1a34a..c08f80f7ba1 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/DataSetProcessingContext.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/DataSetProcessingContext.java
@@ -50,6 +50,9 @@ public class DataSetProcessingContext
 
     private final IHierarchicalContentProvider hierarchicalContentProvider;
 
+    /**
+     * Session token of a user on behalf of who, the script is executed.
+     */
     private final String sessionTokenOrNull;
 
     private final ISessionWorkspaceProvider sessionWorkspaceProviderOrNull;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedBasicOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedBasicOpenBISService.java
new file mode 100644
index 00000000000..7fcd3356fb2
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedBasicOpenBISService.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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.systemsx.cisd.openbis.dss.generic.shared;
+
+import java.util.Collection;
+import java.util.List;
+
+import ch.systemsx.cisd.common.exception.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * The basic subset of the {@link IEncapsulatedOpenBISService}, that requires only service and a
+ * sessionToken.
+ * 
+ * @author Jakub Straszewski
+ */
+public interface IEncapsulatedBasicOpenBISService
+{
+    /**
+     * Returns the data set type together with assigned property types for the specified data set
+     * type code.
+     */
+    @ManagedAuthentication
+    public DataSetTypeWithVocabularyTerms getDataSetType(String dataSetTypeCode);
+
+    /**
+     * {@link IETLLIMSService#searchForSamples(String, SearchCriteria)}
+     */
+    @ManagedAuthentication
+    public List<Sample> searchForSamples(SearchCriteria searchCriteria);
+
+    /**
+     * {@link IETLLIMSService#searchForDataSets(String, SearchCriteria)}
+     */
+    @ManagedAuthentication
+    public List<ExternalData> searchForDataSets(SearchCriteria searchCriteria);
+
+    /**
+     * {@link IETLLIMSService#listExperiments(String, ProjectIdentifier)}
+     */
+    @ManagedAuthentication
+    public List<Experiment> listExperiments(ProjectIdentifier projectIdentifier);
+
+    /**
+     * Lists vocabulary terms.
+     */
+    @ManagedAuthentication
+    public Collection<VocabularyTerm> listVocabularyTerms(String vocabularyCode)
+            throws UserFailureException;
+
+    /**
+     * Returns a vocabulary with given code
+     */
+    @ManagedAuthentication
+    public Vocabulary tryGetVocabulary(String code);
+
+    /**
+     * Lists materials using given criteria.
+     * 
+     * @return a sorted list of {@link Material}.
+     */
+    @ManagedAuthentication
+    public List<Material> listMaterials(ListMaterialCriteria criteria, boolean withProperties);
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
index 798cd88f6a2..50371e28074 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
@@ -16,19 +16,16 @@
 
 package ch.systemsx.cisd.openbis.dss.generic.shared;
 
-import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
 import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
-import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.EntityOperationsState;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletedDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
@@ -38,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocationNode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
@@ -51,8 +47,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationResult;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetShareId;
@@ -75,9 +69,17 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
  * @see IETLLIMSService
  * @author Christian Ribeaud
  */
-public interface IEncapsulatedOpenBISService
+public interface IEncapsulatedOpenBISService extends IEncapsulatedBasicOpenBISService
 {
 
+    /**
+     * Get the basic version of this service, that will filter the results.
+     * 
+     * @param userName The user used for filtering.
+     */
+    @ManagedAuthentication
+    public IEncapsulatedBasicOpenBISService getBasicFilteredOpenBISService(String userName);
+
     /**
      * Tries to get the data set location for the specified data set code, using the ETL server's
      * session token.
@@ -179,27 +181,6 @@ public interface IEncapsulatedOpenBISService
     @ManagedAuthentication
     public Material tryGetMaterial(MaterialIdentifier materialIdentifier);
 
-    /**
-     * Lists materials using given criteria.
-     * 
-     * @return a sorted list of {@link Material}.
-     */
-    @ManagedAuthentication
-    public List<Material> listMaterials(ListMaterialCriteria criteria, boolean withProperties);
-
-    /**
-     * Lists vocabulary terms.
-     */
-    @ManagedAuthentication
-    public Collection<VocabularyTerm> listVocabularyTerms(String vocabularyCode)
-            throws UserFailureException;
-
-    /**
-     * Returns a vocabulary with given code
-     */
-    @ManagedAuthentication
-    public Vocabulary tryGetVocabulary(String code);
-
     /**
      * Gets the experiment type with assigned property types for the specified experiment type code.
      */
@@ -212,13 +193,6 @@ public interface IEncapsulatedOpenBISService
     @ManagedAuthentication
     public SampleType getSampleType(String sampleTypeCode) throws UserFailureException;
 
-    /**
-     * Returns the data set type together with assigned property types for the specified data set
-     * type code.
-     */
-    @ManagedAuthentication
-    public DataSetTypeWithVocabularyTerms getDataSetType(String dataSetTypeCode);
-
     /**
      * Lists all data sets of the specified experiment ID.
      */
@@ -463,30 +437,12 @@ public interface IEncapsulatedOpenBISService
     public AtomicEntityOperationResult performEntityOperations(
             AtomicEntityOperationDetails operationDetails);
 
-    /**
-     * {@link IETLLIMSService#searchForSamples(String, SearchCriteria)}
-     */
-    @ManagedAuthentication
-    public List<Sample> searchForSamples(SearchCriteria searchCriteria);
-
-    /**
-     * {@link IETLLIMSService#searchForDataSets(String, SearchCriteria)}
-     */
-    @ManagedAuthentication
-    public List<ExternalData> searchForDataSets(SearchCriteria searchCriteria);
-
     /**
      * {@link IETLLIMSService#listProjects(String)}
      */
     @ManagedAuthentication
     public List<Project> listProjects();
 
-    /**
-     * {@link IETLLIMSService#listExperiments(String, ProjectIdentifier)}
-     */
-    @ManagedAuthentication
-    public List<Experiment> listExperiments(ProjectIdentifier projectIdentifier);
-
     /**
      * {@link IETLLIMSService#removeDataSetsPermanently(String, List, String)}
      */
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
index cf7fc52967f..8b24d1930d2 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
@@ -22,14 +22,14 @@ import org.springframework.beans.factory.BeanFactory;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 
+import com.marathon.util.spring.StreamSupportingHttpInvokerServiceExporter;
+
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.authorization.IAuthorizationService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISearchService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 
-import com.marathon.util.spring.StreamSupportingHttpInvokerServiceExporter;
-
 /**
  * Provider of remote service onto openBIS.
  * 
diff --git a/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/plugin.properties b/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/plugin.properties
new file mode 100644
index 00000000000..599c79c414b
--- /dev/null
+++ b/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/plugin.properties
@@ -0,0 +1,3 @@
+label = Test Search Service Aggregation Reporting
+class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.JythonAggregationService
+script-path = searchServiceAggregationService.py
\ No newline at end of file
diff --git a/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/searchServiceAggregationService.py b/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/searchServiceAggregationService.py
new file mode 100644
index 00000000000..96688d69591
--- /dev/null
+++ b/datastore_server/sourceTest/core-plugins/generic-test/1/dss/reporting-plugins/search-service-aggregation-service/searchServiceAggregationService.py
@@ -0,0 +1,41 @@
+from ch.systemsx.cisd.openbis.generic.shared.api.v1.dto import SearchCriteria
+from ch.systemsx.cisd.openbis.generic.shared.dto.identifier import ProjectIdentifier
+
+def result(tableBuilder, value):
+  row = tableBuilder.addRow()
+  row.setCell("result", value)
+
+def aggregate(parameters, tableBuilder):
+  tableBuilder.addHeader("result")
+  
+  mode = parameters.get('mode')
+  
+  if (mode == 'datasetsAll'):
+    searchCriteria = SearchCriteria()
+    dataSets = searchServiceUnfiltered.searchForDataSets(searchCriteria)
+    result(tableBuilder, len(dataSets))
+
+  if (mode == 'datasetsFiltered'):
+    searchCriteria = SearchCriteria()
+    dataSets = searchService.searchForDataSets(searchCriteria)
+    result(tableBuilder, len(dataSets))
+
+  if (mode == 'samplesAll'):
+    searchCriteria = SearchCriteria()
+    samples = searchServiceUnfiltered.searchForSamples(searchCriteria)
+    result(tableBuilder, len(samples))
+
+  if (mode == 'samplesFiltered'):
+    searchCriteria = SearchCriteria()
+    samples = searchService.searchForSamples(searchCriteria)
+    result(tableBuilder, len(samples))
+    
+  if (mode == 'experimentsAll'):
+    projectId = parameters.get('projectId')
+    experiments = searchServiceUnfiltered.listExperiments(projectId)
+    result(tableBuilder, len(experiments))
+
+  if (mode == 'experimentsFiltered'):
+    projectId = parameters.get('projectId')
+    experiments = searchService.listExperiments(projectId)
+    result(tableBuilder, len(experiments))    
\ No newline at end of file
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/QueryFacadeTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/QueryFacadeTest.java
index 43244dc80d7..4a5cc44294d 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/QueryFacadeTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/QueryFacadeTest.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -46,13 +47,17 @@ public class QueryFacadeTest extends SystemTestCase
 
     private IQueryApiFacade queryFacade;
 
-    private IQueryApiFacade observerFacade;
+    private Map<String, IQueryApiFacade> facades;
 
     @BeforeMethod
     public void beforeMethod()
     {
         queryFacade = createServiceFacade("test");
-        observerFacade = createServiceFacade("observer");
+
+        facades = new HashMap<String, IQueryApiFacade>();
+        facades.put("test", queryFacade);
+        facades.put("observer", createServiceFacade("observer"));
+        facades.put("test_space", createServiceFacade("test_space"));
     }
 
     @Test
@@ -187,7 +192,7 @@ public class QueryFacadeTest extends SystemTestCase
         File content = new File(new File(new File(store, "42"), "a"), "1");
         content.mkdirs();
 
-        observerFacade.createReportFromAggregationService(service, parameters);
+        facades.get("observer").createReportFromAggregationService(service, parameters);
     }
 
     /**
@@ -206,7 +211,7 @@ public class QueryFacadeTest extends SystemTestCase
         content.mkdirs();
 
         QueryTableModel table =
-                observerFacade.createReportFromAggregationService(service, parameters);
+                facades.get("observer").createReportFromAggregationService(service, parameters);
 
         assertEquals("[name]", getHeaders(table).toString());
         assertEquals("[1]", Arrays.asList(table.getRows().get(0)).toString());
@@ -228,8 +233,7 @@ public class QueryFacadeTest extends SystemTestCase
         File content = new File(new File(new File(store, "42"), "a"), "1");
         content.mkdirs();
 
-        QueryTableModel table =
- queryFacade.createReportFromAggregationService(service, parameters);
+        QueryTableModel table = queryFacade.createReportFromAggregationService(service, parameters);
 
         assertEquals("[name]", getHeaders(table).toString());
         assertEquals("[1]", Arrays.asList(table.getRows().get(0)).toString());
@@ -292,4 +296,119 @@ public class QueryFacadeTest extends SystemTestCase
         }
         return latestFile;
     }
+
+    /**
+     * The testcase, that checks whether the results of the search service calls for different users
+     */
+    @Test
+    public void testDataSetSearchServiceInAggregationService() throws Exception
+    {
+        int allTest = getSearchServiceAggregationServiceResult("datasetsAll", facades.get("test"));
+        int allObserver =
+                getSearchServiceAggregationServiceResult("datasetsAll", facades.get("observer"));
+
+        int filteredTest =
+                getSearchServiceAggregationServiceResult("datasetsFiltered", facades.get("test"));
+        int filteredObserver =
+                getSearchServiceAggregationServiceResult("datasetsFiltered",
+                        facades.get("test_space"));
+
+        assertEquals(allTest, allObserver);
+        assertEquals(allTest, filteredTest);
+        assertTrue("There are " + allTest
+                + " datasets, and observer should see less, but he did see " + filteredObserver,
+                allTest > filteredObserver);
+        assertTrue("There should be some datasets visible to the observer, but there are no",
+                filteredObserver > 0);
+    }
+
+    /**
+     * Test searching for samples via search service for different users
+     */
+    @Test
+    public void testSampleSearchServiceInAggregationService() throws Exception
+    {
+        int allTest = getSearchServiceAggregationServiceResult("samplesAll", facades.get("test"));
+        int allObserver =
+                getSearchServiceAggregationServiceResult("samplesAll", facades.get("observer"));
+
+        int filteredTest =
+                getSearchServiceAggregationServiceResult("samplesFiltered", facades.get("test"));
+        int filteredObserver =
+                getSearchServiceAggregationServiceResult("samplesFiltered", facades.get("observer"));
+        int filteredObserver2 =
+                getSearchServiceAggregationServiceResult("samplesFiltered",
+                        facades.get("test_space"));
+
+        assertEquals(allTest, allObserver);
+        assertEquals(allTest, filteredTest);
+        assertTrue("There are " + allTest
+                + " samples, and observer should see less, but he did see " + filteredObserver,
+                allTest > filteredObserver);
+        assertTrue("There are " + allTest
+                + " samples, and test_space should see less, but he did see " + filteredObserver,
+                allTest > filteredObserver2);
+        assertTrue("There should be some samples visible to the observer, but there are no",
+                filteredObserver > 0);
+        assertTrue("There should be some samples visible to the test_space, but there are no",
+                filteredObserver2 > 0);
+    }
+
+    /**
+     * Check listing experiments for different users via search service
+     */
+    @Test
+    public void testExperimentSearchServiceInAggregationService() throws Exception
+    {
+        int allNemoTest =
+                getSearchServiceAggregationServiceResult("experimentsAll", facades.get("test"),
+                        "projectId", "/CISD/NEMO");
+        int allNemoObserver =
+                getSearchServiceAggregationServiceResult("experimentsAll", facades.get("observer"),
+                        "projectId", "/CISD/NEMO");
+
+        assertTrue(allNemoTest > 0);
+        assertEquals(allNemoTest, allNemoObserver);
+
+        int filteredNemoTest =
+                getSearchServiceAggregationServiceResult("experimentsFiltered",
+                        facades.get("test"), "projectId", "/CISD/NEMO");
+        int filteredNemoObserver =
+                getSearchServiceAggregationServiceResult("experimentsFiltered",
+                        facades.get("observer"), "projectId", "/CISD/NEMO");
+        int filteredNemoTestSpace =
+                getSearchServiceAggregationServiceResult("experimentsFiltered",
+                        facades.get("test_space"), "projectId", "/CISD/NEMO");
+
+        assertEquals(allNemoTest, filteredNemoTest);
+        assertEquals(0, filteredNemoObserver);
+        assertEquals(0, filteredNemoTestSpace);
+
+        int filteredTestSpace =
+                getSearchServiceAggregationServiceResult("experimentsFiltered",
+                        facades.get("test_space"), "projectId", "/TEST-SPACE/TEST-PROJECT");
+
+        assertTrue(filteredTestSpace > 0);
+    }
+
+    private int getSearchServiceAggregationServiceResult(String mode, IQueryApiFacade facade,
+            String... params)
+    {
+        HashMap<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("mode", mode);
+
+        for (int i = 0; 2 * i + 1 < params.length; i += 2)
+        {
+            parameters.put(params[2 * i], params[2 * i + 1]);
+        }
+
+        AggregationServiceDescription service =
+                getAggregationServiceDescription("search-service-aggregation-service");
+
+        QueryTableModel table = facade.createReportFromAggregationService(service, parameters);
+
+        assertEquals("[result]", getHeaders(table).toString());
+        assertEquals(1, table.getRows().size());
+        return Integer.parseInt(table.getRows().get(0)[0].toString());
+    }
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/JythonBasedAggregationServiceReportingPluginTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/JythonBasedAggregationServiceReportingPluginTest.java
index 241967c522f..d691fa0b27f 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/JythonBasedAggregationServiceReportingPluginTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/jython/JythonBasedAggregationServiceReportingPluginTest.java
@@ -220,7 +220,13 @@ public class JythonBasedAggregationServiceReportingPluginTest extends AbstractFi
                 private static final long serialVersionUID = 1L;
 
                 @Override
-                protected ISearchService createSearchService()
+                protected ISearchService createUnfilteredSearchService()
+                {
+                    return searchService;
+                }
+
+                @Override
+                protected ISearchService createUserSearchService(DataSetProcessingContext dscontext)
                 {
                     return searchService;
                 }
-- 
GitLab