diff options
2 files changed, 118 insertions, 28 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java index 9a3c423e03..dbd303a08c 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java @@ -20,8 +20,10 @@ import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration; import org.eclipse.emf.cdo.net4j.CDONet4jUtil; import org.eclipse.emf.cdo.security.Realm; import org.eclipse.emf.cdo.security.RealmUtil; +import org.eclipse.emf.cdo.security.SecurityFactory; import org.eclipse.emf.cdo.security.SecurityItem; import org.eclipse.emf.cdo.security.User; +import org.eclipse.emf.cdo.security.UserPassword; import org.eclipse.emf.cdo.server.IPermissionManager; import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; @@ -32,10 +34,12 @@ import org.eclipse.emf.cdo.spi.common.revision.ManagedRevisionProvider; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.spi.server.InternalSessionManager; import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.net4j.Net4jUtil; import org.eclipse.net4j.acceptor.IAcceptor; import org.eclipse.net4j.connector.IConnector; +import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.container.IManagedContainer; import org.eclipse.net4j.util.lifecycle.ILifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; @@ -43,6 +47,7 @@ import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.net4j.util.security.IUserManager; import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.util.EcoreUtil; import java.util.HashMap; import java.util.Map; @@ -57,7 +62,7 @@ public class SecurityManager implements ISecurityManager, IUserManager, IPermiss private final String realmPath; - private IManagedContainer container; + private final IManagedContainer container; private IAcceptor acceptor; @@ -136,12 +141,66 @@ public class SecurityManager implements ISecurityManager, IUserManager, IPermiss return realmPath; } - public void addUser(String userID, char[] password) + public final IManagedContainer getContainer() { + return container; } - public void removeUser(String userID) + public Realm getRealm() { + return realm; + } + + public User getUser(String userID) + { + synchronized (users) + { + User user = users.get(userID); + if (user == null) + { + EList<SecurityItem> items = realm.getItems(); + user = RealmUtil.findUser(items, userID); + if (user != null) + { + users.put(userID, user); + } + } + + return user; + } + } + + public void addUser(final String userID, final char[] password) + { + modify(new RealmOperation() + { + public void execute(Realm realm) + { + UserPassword userPassword = SecurityFactory.eINSTANCE.createUserPassword(); + userPassword.setEncrypted(new String(password)); + + User user = SecurityFactory.eINSTANCE.createUser(); + user.setId(userID); + user.setPassword(userPassword); + + realm.getItems().add(user); + } + }); + } + + public void removeUser(final String userID) + { + modify(new RealmOperation() + { + public void execute(Realm realm) + { + User user = getUser(userID); + if (user != null) + { + EcoreUtil.remove(user); + } + } + }); } public byte[] encrypt(String userID, byte[] data, String algorithmName, byte[] salt, int count) @@ -150,51 +209,61 @@ public class SecurityManager implements ISecurityManager, IUserManager, IPermiss return null; } + public void modify(RealmOperation operation) + { + synchronized (transaction) + { + operation.execute(realm); + + try + { + transaction.commit(); + } + catch (CommitException ex) + { + throw WrappedException.wrap(ex); + } + } + } + public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext, String userID) { User user = getUser(userID); CDORevisionProvider revisionProvider = new ManagedRevisionProvider(repository.getRevisionManager(), securityContext); - return getPermission(revision, revisionProvider, user); + return getPermission(revision, revisionProvider, securityContext, user); } public void handleTransactionBeforeCommitting(ITransaction transaction, CommitContext commitContext, OMMonitor monitor) throws RuntimeException { + CDOBranchPoint securityContext = commitContext.getBranchPoint(); String userID = commitContext.getUserID(); User user = getUser(userID); - for (InternalCDORevision revision : commitContext.getNewObjects()) - { - getPermission(revision, commitContext, user); - - } + handleRevisionsBeforeCommitting(commitContext, securityContext, user, commitContext.getNewObjects()); + handleRevisionsBeforeCommitting(commitContext, securityContext, user, commitContext.getDirtyObjects()); } - public void handleTransactionAfterCommitted(ITransaction transaction, CommitContext commitContext, OMMonitor monitor) + private void handleRevisionsBeforeCommitting(CommitContext commitContext, CDOBranchPoint securityContext, User user, + InternalCDORevision[] revisions) { - // Do nothing - } - - private User getUser(String userID) - { - synchronized (users) + for (InternalCDORevision revision : revisions) { - User user = users.get(userID); - if (user == null) + CDOPermission permission = getPermission(revision, commitContext, securityContext, user); + if (permission != CDOPermission.WRITE) { - EList<SecurityItem> items = realm.getItems(); - user = RealmUtil.findUser(items, userID); - if (user != null) - { - users.put(userID, user); - } + throw new SecurityException("User " + user + " is not allowed to write to " + revision); } - - return user; } } - private CDOPermission getPermission(CDORevision revision, CDORevisionProvider revisionProvider, User user) + public void handleTransactionAfterCommitted(ITransaction transaction, CommitContext commitContext, OMMonitor monitor) + { + // Do nothing + } + + protected CDOPermission getPermission(CDORevision revision, CDORevisionProvider revisionProvider, + CDOBranchPoint securityContext, User user) { return null; } diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/ISecurityManager.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/ISecurityManager.java index ee035770b7..250c8b0e69 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/ISecurityManager.java +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/ISecurityManager.java @@ -4,16 +4,37 @@ * 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.server.security; +import org.eclipse.emf.cdo.security.Realm; +import org.eclipse.emf.cdo.security.User; +import org.eclipse.emf.cdo.server.IRepository; + /** + * Protects a given {@link IRepository repository}. + * + * @see SecurityManagerUtil#createSecurityManager(org.eclipse.emf.cdo.server.IRepository, String) * @author Eike Stepper */ public interface ISecurityManager { + public Realm getRealm(); + + public User getUser(String userID); + + public void modify(RealmOperation operation); + /** + * Modifies a security {@link Realm realm} in a safe transaction. + * + * @author Eike Stepper + */ + public interface RealmOperation + { + public void execute(Realm realm); + } } |