/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.societies.integration.test.ct.datamanagement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.context.model.MalformedCtxIdentifierException; import org.societies.api.identity.IIdentity; import org.societies.api.identity.InvalidFormatException; import org.societies.api.identity.util.DataIdentifierFactory; import org.societies.api.identity.util.RequestorUtils; import org.societies.api.internal.privacytrust.privacy.util.dataobfuscation.DataWrapperFactory; import org.societies.api.internal.privacytrust.privacy.util.dataobfuscation.LocationCoordinatesUtils; import org.societies.api.internal.privacytrust.privacy.util.dataobfuscation.NameUtils; import org.societies.api.internal.privacytrust.privacyprotection.model.listener.IDataObfuscationListener; import org.societies.api.internal.privacytrust.privacyprotection.model.listener.IPrivacyDataManagerListener; import org.societies.api.internal.schema.privacytrust.privacy.model.dataobfuscation.DataWrapper; import org.societies.api.internal.schema.privacytrust.privacy.model.dataobfuscation.LocationCoordinates; import org.societies.api.internal.schema.privacytrust.privacy.model.dataobfuscation.Name; import org.societies.api.privacytrust.privacy.model.PrivacyException; import org.societies.api.privacytrust.privacy.model.privacypolicy.Action; import org.societies.api.privacytrust.privacy.model.privacypolicy.Decision; import org.societies.api.privacytrust.privacy.model.privacypolicy.ResponseItem; import org.societies.api.privacytrust.privacy.model.privacypolicy.constants.ActionConstants; import org.societies.api.privacytrust.privacy.util.privacypolicy.ResponseItemUtils; import org.societies.api.schema.identity.DataIdentifier; import org.societies.api.schema.identity.DataIdentifierScheme; import org.societies.api.schema.identity.RequestorBean; import org.societies.integration.test.IntegrationTest; import org.societies.integration.test.userfeedback.UserFeedbackMockResult; import org.societies.integration.test.userfeedback.UserFeedbackType; /** * @author Olivier Maridat (Trialog) * */ public class PrivacyDataManagerTest extends IntegrationTest { private static Logger LOG = LoggerFactory.getLogger(PrivacyDataManagerTest.class); private RequestorBean requestor; private CountDownLatch lock; private boolean succeed; private String errorMsg; private Exception errorException; private DataWrapper obfuscatedDataWrapper; private ResponseItem retrievedPermission; private long timestampSetUp; private long timestampTearDown; @Before public void setUp() { timestampSetUp = System.currentTimeMillis(); LOG.info("[#"+testCaseNumber+"] "+getClass().getSimpleName()+"::setUp"); // Dependency injection not ready if (!TestCase.isDepencyInjectionDone()) { fail("[Dependency Injection] "+getClass().getSimpleName()+" not ready"); } // Data requestor = RequestorUtils.create(TestCase.getReceiverJid()); // Init lock = new CountDownLatch(1); succeed = false; errorMsg = ""; errorException = null; obfuscatedDataWrapper = null; } @After public void tearDown() { LOG.info("[#"+testCaseNumber+"] tearDown"); timestampTearDown = System.currentTimeMillis(); LOG.info("[#"+testCaseNumber+"] Lasts: "+(timestampTearDown-timestampSetUp)+"ms"); } /* --- ACCESS CONTROL --- */ @Test public void testCheckPermission() { String testTitle = new String("CheckPermission: retrieve a privacy for the first time"); LOG.info("[#"+testCaseNumber+"] "+testTitle); try { // Owner ID IIdentity currentJid = TestCase.commManager.getIdManager().getThisNetworkNode(); // Random Data ID // DataIdentifier dataId = DataIdentifierFactory.fromUri(DataIdentifierScheme.CONTEXT+"://"+currentJid+"/ENTITY/person/1/ATTRIBUTE/name/13"); Random randomer = new Random((new Date()).getTime()); String randomValue = ""+randomer.nextInt(200); DataIdentifier randomDataId = DataIdentifierFactory.fromUri(DataIdentifierScheme.CIS+"://"+currentJid+"/"+randomValue); // Action list List<Action> actionsRead = new ArrayList<Action>(); actionsRead.add(new Action(ActionConstants.READ)); // Prepare UserFeedback TestCase.getUserFeedbackMocker().addReply(UserFeedbackType.CHECKBOXLIST, new UserFeedbackMockResult(1, "READ")); // -- Call TestCase.privacyDataManagerRemote.checkPermission(RequestorUtils.toRequestor(requestor, TestCase.commManager.getIdManager()), randomDataId, actionsRead, new IPrivacyDataManagerListener() { @Override public void onAccessControlChecked(ResponseItem permission) { succeed = true; retrievedPermission = permission; lock.countDown(); } @Override public void onAccessControlCancelled(String msg) { succeed = false; errorMsg = "Access control cancelled. "+msg; lock.countDown(); } @Override public void onAccessControlAborted(String msg, Exception e) { succeed = false; errorMsg = "Access control aborted. "+msg; errorException = e; lock.countDown(); } @Override public void onAccessControlChecked(List<org.societies.api.schema.privacytrust.privacy.model.privacypolicy.ResponseItem> permissions) { succeed = true; try { retrievedPermission = ResponseItemUtils.toResponseItem(permissions.get(0)); } catch(Exception e) { succeed = false; onAccessControlAborted("No permission retrieved", e); } finally { lock.countDown(); } } }); boolean releaseBeforeTimeout = lock.await(TestCase.getTimeout(), TimeUnit.MILLISECONDS); // Check timeout if (!releaseBeforeTimeout) { succeed = false; errorMsg = "Access control aborted due to timeout"; errorException = new TimeoutException("Access control aborted due to timeout: more then "+TestCase.getTimeout()+"ms to do this operation."); } // -- Verify // Error if (!succeed) { LOG.error("[#"+testCaseNumber+"] Error: "+errorMsg, errorException); fail("Error: "+errorMsg); } // Success assertNotNull("No permission retrieved", retrievedPermission); assertNotNull("No (real) permission retrieved", retrievedPermission.getDecision()); assertEquals("Bad permission retrieved", Decision.PERMIT.name(), retrievedPermission.getDecision().name()); LOG.info("[#"+testCaseNumber+"] Retrieved permission: "+retrievedPermission.toXMLString()); } catch (PrivacyException e) { LOG.error("[#"+testCaseNumber+"] [PrivacyException access control error] "+testTitle, e); fail("PrivacyException access control error ("+e.getMessage()+") "+testTitle); } catch (InterruptedException e) { LOG.error("[#"+testCaseNumber+"] [InterruptedException access control error] "+testTitle, e); fail("InterruptedException access control error ("+e.getMessage()+") "+testTitle); } catch (MalformedCtxIdentifierException e) { LOG.error("[#"+testCaseNumber+"] [MalformedCtxIdentifierException access control error] "+testTitle, e); fail("MalformedCtxIdentifierException access control error ("+e.getMessage()+") "+testTitle); } catch (InvalidFormatException e) { LOG.error("[#"+testCaseNumber+"] [InvalidFormatException access control error] "+testTitle, e); fail("InvalidFormatException access control error ("+e.getMessage()+") "+testTitle); } } /* --- OBFUSCATION --- */ @Test public void testObfuscateDataName() { String testTitle = "ObfuscateData: name"; LOG.info("[#"+testCaseNumber+"] "+testTitle); try { DataWrapper wrapper = DataWrapperFactory.getNameWrapper("Olivier", "Maridat"); TestCase.privacyDataManagerRemote.obfuscateData(requestor, wrapper, new IDataObfuscationListener() { @Override public void onObfuscationDone(DataWrapper data) { succeed = true; obfuscatedDataWrapper = data; lock.countDown(); } @Override public void onObfuscationCancelled(String msg) { succeed = false; errorMsg = msg; lock.countDown(); } @Override public void onObfuscationAborted(String msg, Exception e) { succeed = false; errorMsg = msg; errorException = e; lock.countDown(); } }); boolean releaseBeforeTimeout = lock.await(TestCase.getTimeout(), TimeUnit.MILLISECONDS); // Check timeout if (!releaseBeforeTimeout) { succeed = false; errorMsg = "Obfuscation aborted due to timeout"; errorException = new TimeoutException("Obfuscation aborted due to timeout: more then "+TestCase.getTimeout()+"ms to do this operation."); } // -- Verify // Error if (!succeed) { LOG.error("[#"+testCaseNumber+"] Error: "+errorMsg, errorException); fail("Error: "+errorMsg); } // Success assertNotNull("Obfuscated data wrapper should not be null", obfuscatedDataWrapper); Name originalData = DataWrapperFactory.retrieveName(wrapper); Name obfuscatedData = DataWrapperFactory.retrieveName(obfuscatedDataWrapper); LOG.info("[#"+testCaseNumber+"] Orginal name: "+NameUtils.toString(originalData)); LOG.info("[#"+testCaseNumber+"] Obfuscated name: "+NameUtils.toString(obfuscatedData)); } catch (PrivacyException e) { LOG.error("[#"+testCaseNumber+"] [PrivacyException obfuscator error] "+testTitle, e); fail("PrivacyException obfuscator error ("+e.getMessage()+") "+testTitle); } catch (InterruptedException e) { LOG.error("[#"+testCaseNumber+"] [InterruptedException obfuscator error] "+testTitle, e); fail("InterruptedException obfuscator error ("+e.getMessage()+") "+testTitle); } } @Test public void testObfuscateDataLocationCoordinates() { String testTitle = new String("ObfuscateData: coordinate location"); LOG.info("[#"+testCaseNumber+"] "+testTitle); try { DataWrapper dataWrapper = DataWrapperFactory.getLocationCoordinatesWrapper(48.856666, 2.350987, 542.0); TestCase.privacyDataManagerRemote.obfuscateData(requestor, dataWrapper, new IDataObfuscationListener() { @Override public void onObfuscationDone(DataWrapper data) { succeed = true; obfuscatedDataWrapper = data; lock.countDown(); } @Override public void onObfuscationCancelled(String msg) { succeed = false; errorMsg = msg; lock.countDown(); } @Override public void onObfuscationAborted(String msg, Exception e) { succeed = false; errorMsg = msg; errorException = e; lock.countDown(); } }); boolean releaseBeforeTimeout = lock.await(TestCase.getTimeout(), TimeUnit.MILLISECONDS); // Check timeout if (!releaseBeforeTimeout) { succeed = false; errorMsg = "Obfuscation aborted due to timeout"; errorException = new TimeoutException("Obfuscation aborted due to timeout: more then "+TestCase.getTimeout()+"ms to do this operation."); } // -- Verify // Error if (!succeed) { LOG.error("[#"+testCaseNumber+"] Error: "+errorMsg, errorException); fail("Error: "+errorMsg); } // Success assertNotNull("Obfuscated data wrapper should not be null", obfuscatedDataWrapper); LocationCoordinates originalData = DataWrapperFactory.retrieveLocationCoordinates(dataWrapper); LocationCoordinates obfuscatedData = DataWrapperFactory.retrieveLocationCoordinates(obfuscatedDataWrapper); LOG.info("[#"+testCaseNumber+"] Orginal name: "+LocationCoordinatesUtils.toJsonString(originalData)); LOG.info("[#"+testCaseNumber+"] Obfuscated name: "+LocationCoordinatesUtils.toJsonString(obfuscatedData)); } catch (PrivacyException e) { LOG.error("[#"+testCaseNumber+"] [PrivacyException obfuscator error] "+testTitle, e); fail("PrivacyException obfuscator error ("+e.getMessage()+") "+testTitle); } catch (InterruptedException e) { LOG.error("[#"+testCaseNumber+"] [InterruptedException obfuscator error] "+testTitle, e); fail("InterruptedException obfuscator error ("+e.getMessage()+") "+testTitle); } } }