From 2092dcc58f47b1b7904afe36de4b3da2bc123a54 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Tue, 11 Sep 2012 09:16:27 +0000
Subject: [PATCH] BIS-142 Moving authorization annotations from several
 interfaces to their implementations. Introducing system test
 ServerAuthorizationTest.

SVN: 26581
---
 .../proteomics/server/PhosphoNetXServer.java  |  43 +++++--
 .../server/ProteomicsDataServiceInternal.java |  19 ++-
 .../server/ServerInterfaceRegressionTest.java |  45 ++++++++
 .../server/api/v1/ProteomicsDataService.java  |  11 ++
 .../api/v1/ServerInterfaceRegressionTest.java |  37 ++++++
 .../proteomics/shared/IPhosphoNetXServer.java |  53 +++------
 .../IProteomicsDataServiceInternal.java       |  41 ++-----
 .../shared/api/v1/IProteomicsDataService.java |  33 ++----
 .../sourceTest/core-plugins/.gitignore        |   0
 .../AbstractProteomicsSystemTestCase.java     | 108 +++++++++++++++++
 .../systemtests/ServerAuthorizationTest.java  | 109 ++++++++++++++++++
 11 files changed, 397 insertions(+), 102 deletions(-)
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ServerInterfaceRegressionTest.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ServerInterfaceRegressionTest.java
 create mode 100644 rtd_phosphonetx/sourceTest/core-plugins/.gitignore
 create mode 100644 rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/AbstractProteomicsSystemTestCase.java
 create mode 100644 rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/ServerAuthorizationTest.java

diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/PhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/PhosphoNetXServer.java
index c6996f582f1..b5e8bf34cde 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/PhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/PhosphoNetXServer.java
@@ -34,7 +34,11 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyDAO;
 import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlugin;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
@@ -77,7 +81,7 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
 
     @Resource(name = ResourceNames.PROTEOMICS_BO_FACTORY)
     private IBusinessObjectFactory specificBOFactory;
-    
+
     public PhosphoNetXServer()
     {
         super();
@@ -103,6 +107,7 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public Vocabulary getTreatmentTypeVocabulary(String sessionToken) throws UserFailureException
     {
         IVocabularyDAO vocabularyDAO = getDAOFactory().getVocabularyDAO();
@@ -111,9 +116,10 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<AbundanceColumnDefinition> getAbundanceColumnDefinitionsForProteinByExperiment(
-            String sessionToken, TechId experimentID, String treatmentTypeOrNull)
-            throws UserFailureException
+            String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
+            TechId experimentID, String treatmentTypeOrNull) throws UserFailureException
     {
         Session session = getSession(sessionToken);
         ISampleProvider sampleProvider = specificBOFactory.createSampleProvider(session);
@@ -145,9 +151,11 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
-    public List<ProteinInfo> listProteinsByExperiment(String sessionToken, TechId experimentId,
-            double falseDiscoveryRate, AggregateFunction function, String treatmentTypeCode,
-            boolean aggregateOnOriginal) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public List<ProteinInfo> listProteinsByExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
+            TechId experimentId, double falseDiscoveryRate, AggregateFunction function,
+            String treatmentTypeCode, boolean aggregateOnOriginal) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
         ISampleProvider sampleProvider = specificBOFactory.createSampleProvider(session);
@@ -161,7 +169,9 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<ProteinSummary> listProteinSummariesByExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
             TechId experimentId) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
@@ -171,8 +181,10 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
-    public ProteinByExperiment getProteinByExperiment(String sessionToken, TechId experimentID,
-            TechId proteinReferenceID) throws UserFailureException
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public ProteinByExperiment getProteinByExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
+            TechId experimentID, TechId proteinReferenceID) throws UserFailureException
     {
         Session session = getSession(sessionToken);
         IProteinQueryDAO proteinQueryDAO = specificDAOFactory.getProteinQueryDAO(experimentID);
@@ -181,7 +193,8 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
                 proteinQueryDAO.tryToGetProteinReference(proteinReferenceID.getId());
         if (proteinReference == null)
         {
-            throw new UserFailureException("No protein reference found for ID: " + proteinReferenceID);
+            throw new UserFailureException("No protein reference found for ID: "
+                    + proteinReferenceID);
         }
         proteinByExperiment.setId(proteinReferenceID);
         AccessionNumberBuilder builder =
@@ -196,6 +209,7 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<ProteinSequence> listProteinSequencesByProteinReference(String sessionToken,
             TechId experimentID, TechId proteinReferenceID) throws UserFailureException
     {
@@ -206,23 +220,28 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<DataSetProtein> listProteinsByExperimentAndReference(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
             TechId experimentId, TechId proteinReferenceID) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
         IProteinSequenceTable sequenceTable = specificBOFactory.createProteinSequenceTable(session);
         sequenceTable.loadByReference(experimentId, proteinReferenceID);
-        IDataSetProteinTable dataSetProteinTable = specificBOFactory.createDataSetProteinTable(session);
-        dataSetProteinTable.load(getExperimentPermIDFor(experimentId), proteinReferenceID, sequenceTable);
+        IDataSetProteinTable dataSetProteinTable =
+                specificBOFactory.createDataSetProteinTable(session);
+        dataSetProteinTable.load(getExperimentPermIDFor(experimentId), proteinReferenceID,
+                sequenceTable);
         return dataSetProteinTable.getDataSetProteins();
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(String sessionToken,
             TechId experimentID, TechId proteinReferenceID) throws UserFailureException
     {
         final Session session = getSession(sessionToken);
-        
+
         IProteinDetailsBO proteinDetailsBO = specificBOFactory.createProteinDetailsBO(session);
         proteinDetailsBO.loadByExperimentAndReference(experimentID, proteinReferenceID);
         ProteinDetails detailsOrNull = proteinDetailsBO.getDetailsOrNull();
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
index 7107e641cf6..a3cc949876f 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
@@ -36,6 +36,11 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodeCollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ExperimentValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.IValidator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
@@ -43,6 +48,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 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.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
@@ -118,12 +124,15 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
+    @ReturnValueFilter(validatorClass = RawDataSampleValidator.class)
     public List<MsInjectionSample> listRawDataSamples(String sessionToken)
     {
         return loadAllRawDataSamples(getSession(sessionToken));
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public void processRawData(String sessionToken, String dataSetProcessingKey,
             long[] rawDataSampleIDs, String dataSetType)
     {
@@ -154,7 +163,9 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public void processDataSets(String sessionToken, String dataSetProcessingKey,
+            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class)
             List<String> dataSetCodes)
     {
         Session session = getSession(sessionToken);
@@ -162,6 +173,8 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
+    @ReturnValueFilter(validatorClass = ExperimentValidator.class)
     public List<Experiment> listExperiments(String sessionToken, String experimentTypeCode)
     {
         checkSession(sessionToken);
@@ -176,7 +189,10 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     }
 
     @Override
-    public List<ExternalData> listDataSetsByExperiment(String sessionToken, TechId experimentID)
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
+    public List<ExternalData> listDataSetsByExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
+            TechId experimentID)
     {
         final Session session = getSession(sessionToken);
 
@@ -186,6 +202,7 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public void processProteinResultDataSets(String sessionToken, String dataSetProcessingKey,
             String experimentType, long[] searchExperimentIDs)
     {
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ServerInterfaceRegressionTest.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ServerInterfaceRegressionTest.java
new file mode 100644
index 00000000000..b644caadb0e
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ServerInterfaceRegressionTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.plugin.proteomics.server;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.RegressionTestCase;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.IPhosphoNetXServer;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.IProteomicsDataServiceInternal;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ServerInterfaceRegressionTest extends RegressionTestCase
+{
+    @Test
+    public void testServerAnnotations()
+    {
+        assertMandatoryMethodAnnotations(IPhosphoNetXServer.class, PhosphoNetXServer.class);
+    }
+
+    @Test
+    public void testDataServiceInternalAnnotations()
+    {
+        assertMandatoryMethodAnnotations(IProteomicsDataServiceInternal.class,
+                ProteomicsDataServiceInternal.class);
+    }
+    
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ProteomicsDataService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ProteomicsDataService.java
index cce0d4404fc..8d803069916 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ProteomicsDataService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ProteomicsDataService.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.common.spring.IInvocationLoggerContext;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
@@ -43,6 +44,7 @@ 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.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
@@ -98,6 +100,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<MsInjectionDataInfo> listRawDataSamples(String sessionToken, String userID)
     {
         checkSession(sessionToken);
@@ -174,6 +177,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<DataStoreServerProcessingPluginInfo> listDataStoreServerProcessingPluginInfos(
             String sessionToken)
     {
@@ -211,6 +215,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
 
     @Override
     @SuppressWarnings("deprecation")
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processingRawData(String sessionToken, String userID, String dataSetProcessingKey,
             long[] rawDataSampleIDs, String dataSetType)
     {
@@ -227,6 +232,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processDataSets(String sessionToken, String userID, String dataSetProcessingKey,
             List<String> dataSetCodes)
     {
@@ -242,6 +248,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.Experiment> listSearchExperiments(
             String sessionToken, String userID)
     {
@@ -249,6 +256,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.Experiment> listExperiments(
             String sessionToken, String userID, String experimentTypeCode)
     {
@@ -288,6 +296,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<DataSet> listDataSetsByExperiment(String sessionToken, String userID,
             long experimentID)
     {
@@ -316,6 +325,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processSearchData(String sessionToken, String userID, String dataSetProcessingKey,
             long[] searchExperimentIDs)
     {
@@ -324,6 +334,7 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     @Override
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processProteinResultDataSets(String sessionToken, String userID,
             String dataSetProcessingKey, String experimentTypeCode, long[] experimentIDs)
     {
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ServerInterfaceRegressionTest.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ServerInterfaceRegressionTest.java
new file mode 100644
index 00000000000..97ffb0dda1f
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/api/v1/ServerInterfaceRegressionTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.proteomics.server.api.v1;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.RegressionTestCase;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.IProteomicsDataService;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ServerInterfaceRegressionTest extends RegressionTestCase
+{
+    @Test
+    public void testServerAnnotations()
+    {
+        assertMandatoryMethodAnnotations(IProteomicsDataService.class, ProteomicsDataService.class,
+                "logout: RolesAllowed\n" + "tryToAuthenticateAtRawDataServer: RolesAllowed\n");
+    }
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IPhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IPhosphoNetXServer.java
index 283ca2b1b07..10215981305 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IPhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IPhosphoNetXServer.java
@@ -22,11 +22,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.basic.dto.AbundanceColumnDefinition;
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.basic.dto.AggregateFunction;
@@ -38,60 +34,43 @@ import ch.systemsx.cisd.openbis.plugin.proteomics.shared.basic.dto.ProteinSequen
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.basic.dto.ProteinSummary;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 public interface IPhosphoNetXServer extends IServer
 {
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public Vocabulary getTreatmentTypeVocabulary(String sessionToken) throws UserFailureException;
 
-    
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     @CacheData
     public List<AbundanceColumnDefinition> getAbundanceColumnDefinitionsForProteinByExperiment(
-            String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
-            TechId experimentID, String treatmentTypeOrNull) throws UserFailureException; 
-    
+            String sessionToken, TechId experimentID, String treatmentTypeOrNull)
+            throws UserFailureException;
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     @CacheData
-    public List<ProteinInfo> listProteinsByExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
-            TechId experimentId, double falseDiscoveryRate, AggregateFunction function,
-            String treatmentTypeCode, boolean aggregateOnOriginal) throws UserFailureException;
-    
-    
+    public List<ProteinInfo> listProteinsByExperiment(String sessionToken, TechId experimentId,
+            double falseDiscoveryRate, AggregateFunction function, String treatmentTypeCode,
+            boolean aggregateOnOriginal) throws UserFailureException;
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     @CacheData
     public List<ProteinSummary> listProteinSummariesByExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId)
-            throws UserFailureException;
-    
+            TechId experimentId) throws UserFailureException;
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public ProteinByExperiment getProteinByExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
-            TechId experimentId, TechId proteinReferenceID) throws UserFailureException;
-    
+    public ProteinByExperiment getProteinByExperiment(String sessionToken, TechId experimentId,
+            TechId proteinReferenceID) throws UserFailureException;
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<ProteinSequence> listProteinSequencesByProteinReference(String sessionToken,
             TechId experimentID, TechId proteinReferenceID) throws UserFailureException;
-    
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<DataSetProtein> listProteinsByExperimentAndReference(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class)
             TechId experimentId, TechId proteinReferenceID) throws UserFailureException;
-    
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(
-            String sessionToken, TechId experimentID, TechId proteinReferenceID)
-            throws UserFailureException;
+    public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(String sessionToken,
+            TechId experimentID, TechId proteinReferenceID) throws UserFailureException;
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IProteomicsDataServiceInternal.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IProteomicsDataServiceInternal.java
index 3a8749fbf68..558f8850504 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IProteomicsDataServiceInternal.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/IProteomicsDataServiceInternal.java
@@ -21,22 +21,12 @@ import java.util.List;
 import org.springframework.transaction.annotation.Transactional;
 
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodeCollectionPredicate;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ExperimentValidator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 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.RoleWithHierarchy;
-import ch.systemsx.cisd.openbis.plugin.proteomics.shared.authorization.validator.RawDataSampleValidator;
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.dto.MsInjectionSample;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 public interface IProteomicsDataServiceInternal extends IServer
@@ -46,36 +36,25 @@ public interface IProteomicsDataServiceInternal extends IServer
      * the specified user is allow to read.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
-    @ReturnValueFilter(validatorClass = RawDataSampleValidator.class)
     public List<MsInjectionSample> listRawDataSamples(String sessionToken);
-    
+
     @Deprecated
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public void processRawData(String sessionToken, String dataSetProcessingKey,
             long[] rawDataSampleIDs, String dataSetType);
-    
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
-    public void processDataSets(
-            String sessionToken,
-            String dataSetProcessingKey,
-            @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes);
-    
+    public void processDataSets(String sessionToken, String dataSetProcessingKey,
+            List<String> dataSetCodes);
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
-    @ReturnValueFilter(validatorClass = ExperimentValidator.class)
     public List<Experiment> listExperiments(String sessionToken, String experimentTypeCode);
-    
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
-    public List<ExternalData> listDataSetsByExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentID);
-    
+    public List<ExternalData> listDataSetsByExperiment(String sessionToken, TechId experimentID);
+
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public void processProteinResultDataSets(String sessionToken, String dataSetProcessingKey,
             String experimentTypeCode, long[] searchExperimentIDs);
-    
-}
\ No newline at end of file
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/api/v1/IProteomicsDataService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/api/v1/IProteomicsDataService.java
index d8a4cd42b23..ee54257cece 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/api/v1/IProteomicsDataService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/shared/api/v1/IProteomicsDataService.java
@@ -21,8 +21,6 @@ import java.util.List;
 import org.springframework.transaction.annotation.Transactional;
 
 import ch.systemsx.cisd.common.api.IRpcService;
-import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.plugin.proteomics.client.api.v1.IProteomicsDataApiFacade;
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.DataSet;
 import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.DataStoreServerProcessingPluginInfo;
@@ -31,7 +29,7 @@ import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.MsInjectionD
 
 /**
  * Interface used by {@link IProteomicsDataApiFacade}.
- *
+ * 
  * @author Franz-Josef Elmer
  */
 public interface IProteomicsDataService extends IRpcService
@@ -64,14 +62,12 @@ public interface IProteomicsDataService extends IRpcService
      * the specified user is allowed to read.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<MsInjectionDataInfo> listRawDataSamples(String sessionToken, String userID);
 
     /**
      * Lists all processing plugins on DSS.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<DataStoreServerProcessingPluginInfo> listDataStoreServerProcessingPluginInfos(
             String sessionToken);
 
@@ -82,17 +78,15 @@ public interface IProteomicsDataService extends IRpcService
      */
     @Deprecated
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processingRawData(String sessionToken, String userID, String dataSetProcessingKey,
             long[] rawDataSampleIDs, String dataSetType);
-    
+
     /**
      * Processes the specified data sets by the DSS processing plug-in of specified key for the
      * specified user. Implementations should check that the specified user is allowed to read
      * specified data sets.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processDataSets(String sessionToken, String userID, String dataSetProcessingKey,
             List<String> dataSetCodes);
 
@@ -102,23 +96,22 @@ public interface IProteomicsDataService extends IRpcService
      */
     @Deprecated
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public List<Experiment> listSearchExperiments(String sessionToken, String userID);
 
     /**
      * Returns all experiments of specified type which the specified user is allowed to read.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
-    public List<Experiment> listExperiments(String sessionToken, String userID, String experimentTypeCode);
-    
+    public List<Experiment> listExperiments(String sessionToken, String userID,
+            String experimentTypeCode);
+
     /**
      * Returns all data sets of specified experiment which the specified user is allowed to read.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
-    public List<DataSet> listDataSetsByExperiment(String sessionToken, String userID, long experimentID);
-    
+    public List<DataSet> listDataSetsByExperiment(String sessionToken, String userID,
+            long experimentID);
+
     /**
      * Processes the data sets of specified experiments of type <tt>MS_SEARCH</tt> by the DSS
      * processing plug-in of specified key for the specified user. It will be checked if the
@@ -126,17 +119,15 @@ public interface IProteomicsDataService extends IRpcService
      */
     @Deprecated
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processSearchData(String sessionToken, String userID, String dataSetProcessingKey,
             long[] searchExperimentIDs);
-    
+
     /**
-     * Processes the data sets of specified experiments by the DSS
-     * processing plug-in of specified key for the specified user. It will be checked if the
-     * experiments are of specified type and if the user is allowed to read them.
+     * Processes the data sets of specified experiments by the DSS processing plug-in of specified
+     * key for the specified user. It will be checked if the experiments are of specified type and
+     * if the user is allowed to read them.
      */
     @Transactional
-    @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     public void processProteinResultDataSets(String sessionToken, String userID,
             String dataSetProcessingKey, String experimentTypeCode, long[] experimentIDs);
 
diff --git a/rtd_phosphonetx/sourceTest/core-plugins/.gitignore b/rtd_phosphonetx/sourceTest/core-plugins/.gitignore
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/AbstractProteomicsSystemTestCase.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/AbstractProteomicsSystemTestCase.java
new file mode 100644
index 00000000000..9d5627b6868
--- /dev/null
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/AbstractProteomicsSystemTestCase.java
@@ -0,0 +1,108 @@
+/*
+ * 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.proteomics.systemtests;
+
+import ch.systemsx.cisd.openbis.datastoreserver.systemtests.SystemTestCase;
+import ch.systemsx.cisd.openbis.generic.server.ICommonServerForInternalUse;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Grantee;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+import ch.systemsx.cisd.openbis.plugin.proteomics.server.api.v1.Constants;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.IPhosphoNetXServer;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.IProteomicsDataServiceInternal;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.ResourceNames;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.IProteomicsDataService;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractProteomicsSystemTestCase extends SystemTestCase
+{
+
+    /**
+     *
+     *
+     */
+    public AbstractProteomicsSystemTestCase()
+    {
+        super();
+    }
+
+    @Override
+    protected String getApplicationContextLocation()
+    {
+        return "classpath:proteomics-applicationContext.xml";
+    }
+
+    protected String registerPerson(String userID)
+    {
+        ICommonServerForInternalUse commonServer = getCommonServer();
+        String systemSessionToken = commonServer .tryToAuthenticateAsSystem().getSessionToken();
+        commonServer.registerPerson(systemSessionToken, userID);
+        return userID;
+    }
+
+    protected void assignInstanceRole(String userID, RoleCode roleCode)
+    {
+        ICommonServerForInternalUse commonServer = getCommonServer();
+        String systemSessionToken = commonServer.tryToAuthenticateAsSystem().getSessionToken();
+        commonServer.registerInstanceRole(systemSessionToken, roleCode,
+                Grantee.createPerson(userID));
+    }
+
+    protected void assignSpaceRole(String userID, RoleCode roleCode, SpaceIdentifier spaceIdentifier)
+    {
+        ICommonServerForInternalUse commonServer = getCommonServer();
+        String systemSessionToken = commonServer.tryToAuthenticateAsSystem().getSessionToken();
+        commonServer.registerSpaceRole(systemSessionToken, roleCode, spaceIdentifier,
+                Grantee.createPerson(userID));
+    }
+
+    protected String authenticateAs(String user)
+    {
+        return getCommonServer().tryToAuthenticate(user, "password").getSessionToken();
+    }
+
+    protected ICommonServerForInternalUse getCommonServer()
+    {
+        return getBean(ch.systemsx.cisd.openbis.generic.shared.ResourceNames.COMMON_SERVER);
+    }
+
+    protected IProteomicsDataServiceInternal getDataServiceInternal()
+    {
+        return getBean(Constants.PROTEOMICS_DATA_SERVICE_INTERNAL);
+    }
+
+    protected IProteomicsDataService getDataService()
+    {
+        return getBean(Constants.PROTEOMICS_DATA_SERVICE);
+    }
+
+    protected IPhosphoNetXServer getServer()
+    {
+        return getBean(ResourceNames.PROTEOMICS_PLUGIN_SERVER);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T getBean(String beanId)
+    {
+        return (T) applicationContext.getBean(beanId);
+    }
+
+}
\ No newline at end of file
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/ServerAuthorizationTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/ServerAuthorizationTest.java
new file mode 100644
index 00000000000..a21d116b54a
--- /dev/null
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/proteomics/systemtests/ServerAuthorizationTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.proteomics.systemtests;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+import ch.systemsx.cisd.openbis.plugin.proteomics.shared.IProteomicsDataServiceInternal;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+@Test(groups = { "slow", "systemtest" })
+public class ServerAuthorizationTest extends AbstractProteomicsSystemTestCase 
+{
+    private static final String USER_A = "USER_A";
+    private static final String USER_INSTANCE_OBSERVER = "USER_B";
+
+    private static final SpaceIdentifier SPACE_A = new SpaceIdentifier("CISD", "CISD");
+    
+    @BeforeClass
+    public void createTestUsers()
+    {
+        assignSpaceRole(registerPerson(USER_A), RoleCode.ETL_SERVER, SPACE_A);
+        assignInstanceRole(registerPerson(USER_INSTANCE_OBSERVER), RoleCode.OBSERVER);
+    }
+    
+    @Test(expectedExceptions = AuthorizationFailureException.class)
+    public void testForServerSetSessionUserFailedBecauseOfAuthorization()
+    {
+        String sessionToken = authenticateAs(USER_A);
+        getServer().setSessionUser(sessionToken, "abc");
+    }
+    
+    @Test(expectedExceptions = AuthorizationFailureException.class)
+    public void testListProteinSummariesByExperimentFailedBecauseOfAuthorization()
+    {
+        String sessionToken = authenticateAs(USER_A);
+        getServer().listProteinSummariesByExperiment(sessionToken, new TechId(42));
+    }
+    
+    @Test(expectedExceptions = AuthorizationFailureException.class)
+    public void testForDataServiceInternalSetSessionUserFailedBecauseOfAuthorization()
+    {
+        IProteomicsDataServiceInternal dataServiceInternal = getDataServiceInternal();
+        String sessionToken = dataServiceInternal.tryToAuthenticate(USER_A, "abc").getSessionToken();
+        dataServiceInternal.setSessionUser(sessionToken, "abc");
+    }
+    
+    @Test(expectedExceptions = AuthorizationFailureException.class)
+    public void testForDataServiceInternalListExperimentsFailedBecauseOfAuthorization()
+    {
+        IProteomicsDataServiceInternal dataServiceInternal = getDataServiceInternal();
+        String sessionToken = dataServiceInternal.tryToAuthenticate(USER_A, "abc").getSessionToken();
+        dataServiceInternal.listExperiments(sessionToken, "MS_SEARCH");
+    }
+    
+    @Test
+    public void testForDataServiceListExperimentsFailedBecauseOfAuthorization()
+    {
+        String sessionToken = authenticateAs(USER_A);
+        try
+        {
+            getDataService().listExperiments(sessionToken, USER_A, "MS_SEARCH");
+            fail("AuthorizationFailureException expected");
+        } catch (AuthorizationFailureException ex)
+        {
+            assertEquals("Authorization failure: ERROR: \"None of method roles "
+                    + "'[INSTANCE_OBSERVER, INSTANCE_ADMIN]' "
+                    + "could be found in roles of user 'USER_A'.\".", ex.getMessage());
+        }
+    }
+
+    @Test
+    public void testForDataServiceListExperimentsFailedBecauseOfAuthorizationOnSecondLevel()
+    {
+        String sessionToken = authenticateAs(USER_INSTANCE_OBSERVER);
+        try
+        {
+            getDataService().listExperiments(sessionToken, USER_A, "MS_SEARCH");
+            fail("AuthorizationFailureException expected");
+        } catch (AuthorizationFailureException ex)
+        {
+            assertEquals("Authorization failure: ERROR: \"None of method roles "
+                    + "'[SPACE_USER, SPACE_POWER_USER, SPACE_ADMIN, INSTANCE_ADMIN]' "
+                    + "could be found in roles of user 'USER_A'.\".", ex.getMessage());
+        }
+    }
+}
-- 
GitLab