blob: b75a8a3adada92205c633a3e97b0931923a3dae4 [file] [log] [blame]
/*
* Copyright (c) 2004-2013 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.security.Access;
import org.eclipse.emf.cdo.security.Group;
import org.eclipse.emf.cdo.security.Realm;
import org.eclipse.emf.cdo.security.ResourcePermission;
import org.eclipse.emf.cdo.security.Role;
import org.eclipse.emf.cdo.security.SecurityFactory;
import org.eclipse.emf.cdo.security.User;
import org.eclipse.emf.cdo.server.security.ISecurityManager;
import org.eclipse.emf.cdo.server.security.SecurityManagerUtil;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
import org.eclipse.emf.cdo.tests.config.impl.SessionConfig;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.ConcurrentAccessException;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.security.IPasswordCredentials;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
import org.eclipse.net4j.util.security.PasswordCredentials;
import org.eclipse.net4j.util.security.PasswordCredentialsProvider;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Tests ensuring that the permissions are correctly computed, no matter what passive update mode is chosen.
* @author Alex Lagarde <alex.lagarde@obeo.fr>
*/
@CleanRepositoriesBefore
@CleanRepositoriesAfter
public class Bugzilla_417483_Test extends AbstractCDOTest
{
/**
* Login for use with write rights.
*/
private static final String USER_WITH_WRITE_RIGHTS_ID = "Stepper";
/**
* Password for use with write rights.
*/
private static final String USER_WITH_WRITE_RIGHTS_PASSWORD = "12345";
/**
* Login for use without write rights.
*/
private static final String USER_WITHOUT_WRITE_RIGHTS_ID = "Lagarde";
/**
* Password for use without write rights.
*/
private static final String USER_WITHOUT_WRITE_RIGHTS_PASSWORD = "54321";
/**
* Boolean used by the
*/
private boolean loginWithUserWithoutRights;
@Override
protected void doSetUp() throws Exception
{
super.doSetUp();
// Define 2 users:
// - one with all rights
// - one without write rights (but all read rights)
ISecurityManager securityManager = startRepository();
securityManager.modify(new ISecurityManager.RealmOperation()
{
public void execute(Realm realm)
{
// User with write rights
User userwithWriteRights = realm.addUser(USER_WITH_WRITE_RIGHTS_ID, USER_WITH_WRITE_RIGHTS_PASSWORD);
userwithWriteRights.getGroups().add(realm.getGroup("Users"));
userwithWriteRights.getRoles().add(realm.getRole("All Objects Writer"));
// User with only read rights
ResourcePermission readlAllPermision = SecurityFactory.eINSTANCE.createResourcePermission();
readlAllPermision.setPattern(".*");
readlAllPermision.setAccess(Access.READ);
Role roleWithoutWriteRights = realm.addRole("User without Write - Role");
roleWithoutWriteRights.getPermissions().add(readlAllPermision);
Group groupWithoutWriteRights = realm.addGroup("User without Write - Group");
groupWithoutWriteRights.getRoles().add(roleWithoutWriteRights);
User userwithoutWriteRights = realm.addUser(USER_WITHOUT_WRITE_RIGHTS_ID, USER_WITHOUT_WRITE_RIGHTS_PASSWORD);
userwithoutWriteRights.getGroups().add(groupWithoutWriteRights);
}
});
}
/**
* Ensures that the permissions are correctly computed when integrating changes with the {@link PassiveUpdateMode#CHANGES} update mode.
*/
public void testPermissionWithChangesPassiveUpdateMode() throws Exception
{
doTestPermissionWithPassiveUpdates(PassiveUpdateMode.CHANGES);
}
/**
* Ensures that the permissions are correctly computed when integrating changes with the {@link PassiveUpdateMode#ADDITIONS} update mode.
*/
public void testPermissionWithAdditionPassiveUpdateMode() throws Exception
{
doTestPermissionWithPassiveUpdates(PassiveUpdateMode.ADDITIONS);
}
/**
* Ensures that the permissions are correctly computed when integrating changes with the {@link PassiveUpdateMode#INVALIDATIONS} update mode.
*/
public void testPermissionWithInvalidationPassiveUpdateMode() throws Exception
{
doTestPermissionWithPassiveUpdates(PassiveUpdateMode.INVALIDATIONS);
}
/**
* Ensures that the permissions are correctly computed, with the given {@link PassiveUpdateMode}.
*/
protected void doTestPermissionWithPassiveUpdates(PassiveUpdateMode passiveUpdateMode)
throws ConcurrentAccessException, CommitException, InterruptedException
{
// Step 1: Both users open transaction on the repository
CDOSession userWithWriteRightSession = openSession();
CDOTransaction userWithWriteRightTransaction = userWithWriteRightSession.openTransaction();
loginWithUserWithoutRights = true;
CDOSession userWithoutWriteRightSession = openSession();
userWithoutWriteRightSession.options().setPassiveUpdateMode(passiveUpdateMode);
CDOTransaction userWithoutWriteRightTransaction = userWithoutWriteRightSession.openTransaction();
assertEquals(USER_WITH_WRITE_RIGHTS_ID, userWithWriteRightSession.getUserID());
assertEquals(USER_WITHOUT_WRITE_RIGHTS_ID, userWithoutWriteRightSession.getUserID());
// Step 2: User with write rights creates a resource and commits
CDOResource resource = userWithWriteRightTransaction.createResource(getResourcePath("/res"));
assertEquals(true, resource.cdoRevision().isWritable());
Category resourceRoot = getModel1Factory().createCategory();
resource.getContents().add(resourceRoot);
userWithWriteRightTransaction.commit();
// => User without rights should be able to integrate changes without permission issues
CDOResource resourceWithoutWrite = userWithoutWriteRightTransaction.getResource(getResourcePath("/res"));
assertEquals(1, resourceWithoutWrite.getContents().size());
// => Trigger loading of resource root so that invalidation are sent
resourceWithoutWrite.getContents().iterator().next();
// Step 3: User with write rights modifies the resource root and commits
resourceRoot.setName("RENAMMED");
final CountDownLatch latch = new CountDownLatch(1);
userWithoutWriteRightSession.addListener(new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof CDOSessionInvalidationEvent)
{
latch.countDown();
}
}
});
userWithWriteRightTransaction.commit();
// => User without rights should be able to integrate changes without permission issues
boolean notified = latch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
assertEquals("Timeout: user without Write Rights should have been notified of changes", true, notified);
}
/**
* Starts a repository with security enabled.
* @return the {@link ISecurityManager} associated to the started repository
*/
private ISecurityManager startRepository()
{
// Create & register security manager
ISecurityManager securityManager = SecurityManagerUtil.createSecurityManager("/security", getServerContainer());
getTestProperties().put(RepositoryConfig.PROP_TEST_SECURITY_MANAGER, securityManager);
// Create & register a credential provider allowing to logging with one user or another
IPasswordCredentialsProvider credentialsProvider = new PasswordCredentialsProvider(USER_WITH_WRITE_RIGHTS_ID,
USER_WITH_WRITE_RIGHTS_PASSWORD)
{
@Override
public IPasswordCredentials getCredentials()
{
if (loginWithUserWithoutRights)
{
return new PasswordCredentials(USER_WITHOUT_WRITE_RIGHTS_ID, USER_WITHOUT_WRITE_RIGHTS_PASSWORD.toCharArray());
}
return super.getCredentials();
}
};
getTestProperties().put(SessionConfig.PROP_TEST_CREDENTIALS_PROVIDER, credentialsProvider);
// Start repository
getRepository();
return securityManager;
}
}