diff options
author | Eike Stepper | 2013-09-27 09:28:33 +0000 |
---|---|---|
committer | Eike Stepper | 2013-09-29 09:40:31 +0000 |
commit | 48c07bf1f2acc05313f6f4b3bfaee8db208b1d66 (patch) | |
tree | 482a121fa8d603ac3e0a3016a0ee52cff685b66b | |
parent | 5f0ddac06df136a2a0b7c46fe33400386da92a53 (diff) | |
download | cdo-48c07bf1f2acc05313f6f4b3bfaee8db208b1d66.tar.gz cdo-48c07bf1f2acc05313f6f4b3bfaee8db208b1d66.tar.xz cdo-48c07bf1f2acc05313f6f4b3bfaee8db208b1d66.zip |
[418267] [Security] Cached permissions are not always properly updated
after commits
https://bugs.eclipse.org/bugs/show_bug.cgi?id=418267
56 files changed, 1511 insertions, 651 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocol.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocol.java index 6c06d3b4b6..78e1cb8dd6 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocol.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocol.java @@ -11,6 +11,15 @@ package org.eclipse.emf.cdo.common.protocol; import org.eclipse.emf.cdo.common.CDOCommonSession; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.common.security.CDOPermission; + +import java.io.IOException; +import java.util.Map; +import java.util.Set; /** * The communications protocol associated with a CDO {@link CDOCommonSession session}. @@ -22,7 +31,166 @@ import org.eclipse.emf.cdo.common.CDOCommonSession; * @apiviz.uses {@link CDODataInput} * @apiviz.uses {@link CDODataOutput} */ -public interface CDOProtocol +public interface CDOProtocol extends CDOProtocolConstants { public CDOCommonSession getSession(); + + /** + * @author Eike Stepper + * @since 4.3 + */ + public static class CommitNotificationInfo + { + public static final byte IMPACT_NONE = 0; + + public static final byte IMPACT_PERMISSIONS = 1; + + public static final byte IMPACT_REALM = 2; + + private int senderID; + + private CDOCommonSession sender; + + private CDORevisionProvider revisionProvider; + + private CDOCommitInfo commitInfo; + + private Map<CDOID, CDOPermission> newPermissions; + + private Set<? extends Object> impactedRules; + + private byte securityImpact = IMPACT_NONE; + + private boolean clearResourcePathCache; + + public CommitNotificationInfo() + { + } + + public CommitNotificationInfo(CDODataInput in) throws IOException + { + senderID = in.readInt(); + commitInfo = in.readCDOCommitInfo(); + clearResourcePathCache = in.readBoolean(); + securityImpact = in.readByte(); + + int size = in.readInt(); + if (size != 0) + { + newPermissions = CDOIDUtil.createMap(); + for (int i = 0; i < size; i++) + { + CDOID id = in.readCDOID(); + byte bits = in.readByte(); + + CDOPermission permission = CDOPermission.get(bits); + newPermissions.put(id, permission); + } + } + } + + public void write(CDODataOutput out) throws IOException + { + out.writeInt(senderID); + out.writeCDOCommitInfo(commitInfo); + out.writeBoolean(clearResourcePathCache); + out.writeByte(securityImpact); // Must come after writeCDOCommitInfo() + + // Must come after writeCDOCommitInfo() + if (newPermissions == null) + { + out.writeInt(0); + } + else + { + int size = newPermissions.size(); + out.writeInt(size); + + for (Map.Entry<CDOID, CDOPermission> entry : newPermissions.entrySet()) + { + CDOID id = entry.getKey(); + byte bits = entry.getValue().getBits(); + + out.writeCDOID(id); + out.writeByte(bits); + } + } + } + + public int getSenderID() + { + return senderID; + } + + public CDOCommonSession getSender() + { + return sender; + } + + public void setSender(CDOCommonSession sender) + { + this.sender = sender; + senderID = sender.getSessionID(); + } + + public CDORevisionProvider getRevisionProvider() + { + return revisionProvider; + } + + public void setRevisionProvider(CDORevisionProvider revisionProvider) + { + this.revisionProvider = revisionProvider; + } + + public CDOCommitInfo getCommitInfo() + { + return commitInfo; + } + + public void setCommitInfo(CDOCommitInfo commitInfo) + { + this.commitInfo = commitInfo; + } + + public Map<CDOID, CDOPermission> getNewPermissions() + { + return newPermissions; + } + + public void setNewPermissions(Map<CDOID, CDOPermission> newPermissions) + { + this.newPermissions = newPermissions; + } + + public Set<? extends Object> getImpactedRules() + { + return impactedRules; + } + + public void setImpactedRules(Set<? extends Object> impactedRules) + { + this.impactedRules = impactedRules; + } + + public byte getSecurityImpact() + { + return securityImpact; + } + + public void setSecurityImpact(byte securityImpact) + { + this.securityImpact = securityImpact; + } + + public boolean isClearResourcePathCache() + { + return clearResourcePathCache; + } + + public void setClearResourcePathCache(boolean clearResourcePathCache) + { + this.clearResourcePathCache = clearResourcePathCache; + } + } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java index 9e792bac32..15b8b8977d 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java @@ -28,7 +28,7 @@ public interface CDOProtocolConstants /** * @since 4.2 */ - public static final int PROTOCOL_VERSION = 15; + public static final int PROTOCOL_VERSION = 16; // Last update for permission transfers // ////////////////////////////////////////////////////////////////////// // Signal IDs diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java index eb4388888f..15352ef0db 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java @@ -303,39 +303,31 @@ public final class CDORevisionUtil } /** - * @since 4.0 + * @since 4.3 */ - public static String getResourceNodePath(CDORevision revision, CDORevisionProvider provider) + public static boolean isContained(CDOID child, CDOID container, CDORevisionProvider provider) { - StringBuilder builder = new StringBuilder(); - getResourceNodePath((InternalCDORevision)revision, provider, builder); - return builder.toString(); + InternalCDORevision revision = (InternalCDORevision)provider.getRevision(child); + return isContained(revision, container, provider); } - private static void getResourceNodePath(InternalCDORevision revision, CDORevisionProvider provider, - StringBuilder result) + /** + * @since 4.3 + */ + public static boolean isContained(InternalCDORevision child, CDOID container, CDORevisionProvider provider) { - InternalCDORevision container = getParentRevision(revision, provider); - if (container != null) + if (child.getID() == container) { - getResourceNodePath(container, provider, result); + return true; } - EAttribute attribute = getResourceNodeNameAttribute(revision); - if (attribute != null) + InternalCDORevision parent = getParentRevision(child, provider); + if (parent != null) { - int length = result.length(); - if (length == 0 || result.charAt(length - 1) != '/') - { - result.append("/"); - } - - String name = (String)revision.get(attribute, 0); - if (name != null) // Exclude root resource - { - result.append(name); - } + return isContained(parent, container, provider); } + + return false; } private static InternalCDORevision getParentRevision(InternalCDORevision revision, CDORevisionProvider provider) @@ -369,6 +361,51 @@ public final class CDORevisionUtil return (InternalCDORevision)provider.getRevision(parentID); } + /** + * @since 4.3 + */ + public static String getResourceNodePath(CDOID id, CDORevisionProvider provider) + { + CDORevision revision = provider.getRevision(id); + return getResourceNodePath(revision, provider); + } + + /** + * @since 4.0 + */ + public static String getResourceNodePath(CDORevision revision, CDORevisionProvider provider) + { + StringBuilder builder = new StringBuilder(); + getResourceNodePath((InternalCDORevision)revision, provider, builder); + return builder.toString(); + } + + private static void getResourceNodePath(InternalCDORevision revision, CDORevisionProvider provider, + StringBuilder result) + { + InternalCDORevision container = getParentRevision(revision, provider); + if (container != null) + { + getResourceNodePath(container, provider, result); + } + + EAttribute attribute = getResourceNodeNameAttribute(revision); + if (attribute != null) + { + int length = result.length(); + if (length == 0 || result.charAt(length - 1) != '/') + { + result.append("/"); + } + + String name = (String)revision.get(attribute, 0); + if (name != null) // Exclude root resource + { + result.append(name); + } + } + } + private static EAttribute getResourceNodeNameAttribute(CDORevision revision) { if (revision.isResourceNode()) diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java index a3e1a9f131..ee560a9e04 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java @@ -27,7 +27,6 @@ import org.eclipse.emf.cdo.common.lob.CDOLob; import org.eclipse.emf.cdo.common.lob.CDOLobInfo; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; -import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; @@ -84,13 +83,13 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO public CDOClientProtocol() { - super(CDOProtocolConstants.PROTOCOL_NAME); + super(PROTOCOL_NAME); } @Override public int getVersion() { - return CDOProtocolConstants.PROTOCOL_VERSION; + return PROTOCOL_VERSION; } public CDOSession getSession() @@ -466,28 +465,28 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO { switch (signalID) { - case CDOProtocolConstants.SIGNAL_AUTHENTICATION: + case SIGNAL_AUTHENTICATION: return new AuthenticationIndication(this); - case CDOProtocolConstants.SIGNAL_BRANCH_NOTIFICATION: + case SIGNAL_BRANCH_NOTIFICATION: return new BranchNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_REPOSITORY_TYPE_NOTIFICATION: + case SIGNAL_REPOSITORY_TYPE_NOTIFICATION: return new RepositoryTypeNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_REPOSITORY_STATE_NOTIFICATION: + case SIGNAL_REPOSITORY_STATE_NOTIFICATION: return new RepositoryStateNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_COMMIT_NOTIFICATION: + case SIGNAL_COMMIT_NOTIFICATION: return new CommitNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_REMOTE_SESSION_NOTIFICATION: + case SIGNAL_REMOTE_SESSION_NOTIFICATION: return new RemoteSessionNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE_NOTIFICATION: + case SIGNAL_REMOTE_MESSAGE_NOTIFICATION: return new RemoteMessageNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_LOCK_NOTIFICATION: + case SIGNAL_LOCK_NOTIFICATION: return new LockNotificationIndication(this); default: diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitNotificationIndication.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitNotificationIndication.java index 362928185c..b6c83795e2 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitNotificationIndication.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitNotificationIndication.java @@ -11,16 +11,14 @@ */ package org.eclipse.emf.cdo.internal.net4j.protocol; -import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; -import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.spi.cdo.InternalCDOSession; import java.io.IOException; -import java.util.HashSet; -import java.util.Set; /** * @author Eike Stepper @@ -35,21 +33,9 @@ public class CommitNotificationIndication extends CDOClientIndication @Override protected void indicating(CDODataInput in) throws IOException { - InternalCDOSession session = getSession(); - CDOCommitInfo commitInfo = in.readCDOCommitInfo(); - boolean clearResourcePathCache = in.readBoolean(); - - Set<CDOID> readOnly = null; - int size = in.readInt(); - if (size != 0) - { - readOnly = new HashSet<CDOID>(); - for (int i = 0; i < size; i++) - { - readOnly.add(in.readCDOID()); - } - } + CommitNotificationInfo info = new CDOProtocol.CommitNotificationInfo(in); - session.handleCommitNotification(commitInfo, clearResourcePathCache, readOnly); + InternalCDOSession session = getSession(); + session.handleCommitNotification(info); } } diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java index b2d5eaa12b..d72062c957 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java @@ -17,7 +17,6 @@ package org.eclipse.emf.cdo.internal.net4j.protocol; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.commit.CDOCommitData; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDProvider; @@ -304,38 +303,44 @@ public class CommitTransactionRequest extends CDOClientRequestWithMonitoring<Com protected CommitTransactionResult confirmingCheckError(CDODataInput in) throws IOException { boolean success = in.readBoolean(); - if (!success) + if (success) { - byte rollbackReason = in.readByte(); - String rollbackMessage = in.readString(); + return null; + } + + CommitTransactionResult result = new CommitTransactionResult(); + result.setIDProvider(idProvider); + result.setClearResourcePathCache(clearResourcePathCache); + result.setRollbackReason(in.readByte()); + result.setRollbackMessage(in.readString()); + result.setBranchPoint(in.readCDOBranchPoint()); + result.setPreviousTimeStamp(in.readLong()); - CDOBranchPoint branchPoint = in.readCDOBranchPoint(); - long previousTimeStamp = in.readLong(); + int size = in.readInt(); + if (size != 0) + { + List<CDOObjectReference> xRefs = new ArrayList<CDOObjectReference>(size); + result.setXRefs(xRefs); - List<CDOObjectReference> xRefs = null; - int size = in.readInt(); - if (size != 0) + for (int i = 0; i < size; i++) { - xRefs = new ArrayList<CDOObjectReference>(size); - for (int i = 0; i < size; i++) - { - CDOIDReference idReference = in.readCDOIDReference(); - xRefs.add(new CDOObjectReferenceImpl(transaction, idReference)); - } + CDOIDReference idReference = in.readCDOIDReference(); + xRefs.add(new CDOObjectReferenceImpl(transaction, idReference)); } - - return new CommitTransactionResult(idProvider, rollbackReason, rollbackMessage, branchPoint, previousTimeStamp, - xRefs, clearResourcePathCache); } - return null; + return result; } protected CommitTransactionResult confirmingResult(CDODataInput in) throws IOException { - CDOBranchPoint branchPoint = in.readCDOBranchPoint(); - long previousTimeStamp = in.readLong(); - return new CommitTransactionResult(idProvider, branchPoint, previousTimeStamp, clearResourcePathCache); + CommitTransactionResult result = new CommitTransactionResult(); + result.setIDProvider(idProvider); + result.setClearResourcePathCache(clearResourcePathCache); + result.setBranchPoint(in.readCDOBranchPoint()); + result.setPreviousTimeStamp(in.readLong()); + result.setClearPermissionCache(in.readBoolean()); + return result; } protected void confirmingMappingNewObjects(CDODataInput in, CommitTransactionResult result) throws IOException diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Directory.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Directory.java index 011deb9440..bddd41d7d5 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Directory.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Directory.java @@ -35,6 +35,21 @@ import org.eclipse.emf.common.util.EList; public interface Directory extends SecurityItem, SecurityItemContainer { /** + * @since 4.3 + */ + public static final String ROLES = "Roles"; + + /** + * @since 4.3 + */ + public static final String GROUPS = "Groups"; + + /** + * @since 4.3 + */ + public static final String USERS = "Users"; + + /** * Returns the value of the '<em><b>Items</b></em>' containment reference list. * The list contents are of type {@link org.eclipse.emf.cdo.security.SecurityItem}. * <!-- begin-user-doc --> diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Group.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Group.java index 09d295b23e..6a7b674cf0 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Group.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Group.java @@ -38,6 +38,11 @@ import org.eclipse.emf.common.util.EList; public interface Group extends Assignee { /** + * @since 4.3 + */ + public static final String ADMINISTRATORS = "Administrators"; + + /** * Returns the value of the '<em><b>Users</b></em>' reference list. * The list contents are of type {@link org.eclipse.emf.cdo.security.User}. * It is bidirectional and its opposite is '{@link org.eclipse.emf.cdo.security.User#getGroups <em>Groups</em>}'. diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/PermissionFilter.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/PermissionFilter.java index 7fddda83c4..abc7c8122a 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/PermissionFilter.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/PermissionFilter.java @@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; /** * <!-- begin-user-doc --> @@ -32,6 +33,8 @@ public interface PermissionFilter extends CDOObject boolean isApplicable(CDORevision revision, CDORevisionProvider revisionProvider, CDOBranchPoint securityContext, int level) throws Exception; + boolean isImpacted(CommitImpactContext context); + String format(); } // PermissionFilter diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Role.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Role.java index 8043046ae4..7f14079d72 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Role.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/Role.java @@ -35,6 +35,31 @@ import org.eclipse.emf.common.util.EList; public interface Role extends SecurityItem { /** + * @since 4.3 + */ + public static final String ADMINISTRATION = "Administration"; + + /** + * @since 4.3 + */ + public static final String RESOURCE_TREE_WRITER = "Resource Tree Writer"; + + /** + * @since 4.3 + */ + public static final String RESOURCE_TREE_READER = "Resource Tree Reader"; + + /** + * @since 4.3 + */ + public static final String ALL_OBJECTS_WRITER = "All Objects Writer"; + + /** + * @since 4.3 + */ + public static final String ALL_OBJECTS_READER = "All Objects Reader"; + + /** * Returns the value of the '<em><b>Assignees</b></em>' reference list. * The list contents are of type {@link org.eclipse.emf.cdo.security.Assignee}. * It is bidirectional and its opposite is '{@link org.eclipse.emf.cdo.security.Assignee#getRoles <em>Roles</em>}'. diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/User.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/User.java index 221815d0aa..0361c9148d 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/User.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/User.java @@ -45,6 +45,11 @@ import org.eclipse.emf.common.util.EList; public interface User extends Assignee { /** + * @since 4.3 + */ + public static final String ADMINISTRATOR = "Administrator"; + + /** * Returns the value of the '<em><b>Groups</b></em>' reference list. * The list contents are of type {@link org.eclipse.emf.cdo.security.Group}. * It is bidirectional and its opposite is '{@link org.eclipse.emf.cdo.security.Group#getUsers <em>Users</em>}'. diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassFilterImpl.java index e0503fbded..6ee35dba51 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassFilterImpl.java @@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.security.ClassFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.ecore.EClass; @@ -111,6 +112,11 @@ public class ClassFilterImpl extends PermissionFilterImpl implements ClassFilter return applicableClass == actualClass; } + public boolean isImpacted(CommitImpactContext context) + { + return false; + } + public String format() { String label = "?"; diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassPermissionImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassPermissionImpl.java index d115cb6d8a..3383a00258 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassPermissionImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ClassPermissionImpl.java @@ -82,4 +82,10 @@ public class ClassPermissionImpl extends PermissionImpl implements ClassPermissi return actualClass == applicableClass; } + @Override + public boolean isImpacted(CommitImpactContext context) + { + return false; + } + } // ClassPermissionImpl diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CombinedFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CombinedFilterImpl.java index 0a88182114..840c595588 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CombinedFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CombinedFilterImpl.java @@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.security.impl; import org.eclipse.emf.cdo.security.CombinedFilter; import org.eclipse.emf.cdo.security.PermissionFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; @@ -67,6 +68,19 @@ public abstract class CombinedFilterImpl extends PermissionFilterImpl implements return (EList<PermissionFilter>)eGet(SecurityPackage.Literals.COMBINED_FILTER__OPERANDS, true); } + public boolean isImpacted(CommitImpactContext context) + { + for (PermissionFilter operand : getOperands()) + { + if (operand.isImpacted(context)) + { + return true; + } + } + + return false; + } + public String format() { StringBuilder builder = new StringBuilder(); diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CachedList.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/DerivedList.java index 4b9aa265b3..14df3b5f97 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/CachedList.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/DerivedList.java @@ -17,7 +17,6 @@ import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.util.EcoreEList; import org.eclipse.emf.ecore.util.InternalEList; -import java.lang.ref.SoftReference; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; @@ -28,30 +27,18 @@ import java.util.Set; /** * @author Eike Stepper */ -abstract class CachedList<E extends EObject> implements InternalEList<E>, EStructuralFeature.Setting +abstract class DerivedList<E extends EObject> implements InternalEList<E>, EStructuralFeature.Setting { - private SoftReference<Object[]> cache; - - protected CachedList() + protected DerivedList() { } private InternalEList<E> getList() { - Object[] data = null; - if (cache != null) - { - data = cache.get(); - } - - if (data == null) - { - data = getData(); - cache = new SoftReference<Object[]>(data); - } - InternalEObject owner = getOwner(); EStructuralFeature feature = getFeature(); + Object[] data = getData(); + return new EcoreEList.UnmodifiableEList.FastCompare<E>(owner, feature, data.length, data); } @@ -321,7 +308,7 @@ abstract class CachedList<E extends EObject> implements InternalEList<E>, EStruc /** * @author Eike Stepper */ - static abstract class RecursionSafe<E extends EObject, O extends EObject> extends CachedList<E> + static abstract class RecursionSafe<E extends EObject, O extends EObject> extends DerivedList<E> { protected RecursionSafe() { diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ExpressionFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ExpressionFilterImpl.java index db7bda9a84..9701fa2776 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ExpressionFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ExpressionFilterImpl.java @@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.expressions.Expression; import org.eclipse.emf.cdo.expressions.impl.EvaluationContextImpl; import org.eclipse.emf.cdo.security.ExpressionFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.ecore.EClass; @@ -86,6 +87,12 @@ public class ExpressionFilterImpl extends ObjectFilterImpl implements Expression return (Boolean)expression.evaluate(evaluationContext); } + public boolean isImpacted(CommitImpactContext context) + { + // TODO Implement impact analysis in the expression model + return true; + } + public String format() { Expression expression = getExpression(); diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/FilterPermissionImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/FilterPermissionImpl.java index f526a6ad88..ba81320db1 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/FilterPermissionImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/FilterPermissionImpl.java @@ -103,4 +103,18 @@ public class FilterPermissionImpl extends PermissionImpl implements FilterPermis return true; } + @Override + public boolean isImpacted(CommitImpactContext context) + { + for (PermissionFilter filter : getFilters()) + { + if (filter.isImpacted(context)) + { + return true; + } + } + + return false; + } + } // FilterPermissionImpl diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/GroupImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/GroupImpl.java index 961e050b8f..3d6f3ad4fd 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/GroupImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/GroupImpl.java @@ -42,7 +42,7 @@ import java.util.Set; */ public class GroupImpl extends AssigneeImpl implements Group { - private EList<Group> allInheritedGroups = new CachedList.RecursionSafe<Group, Group>() + private EList<Group> allInheritedGroups = new DerivedList.RecursionSafe<Group, Group>() { @Override protected InternalEObject getOwner() @@ -71,7 +71,7 @@ public class GroupImpl extends AssigneeImpl implements Group } }; - private EList<Group> allInheritingGroups = new CachedList.RecursionSafe<Group, Group>() + private EList<Group> allInheritingGroups = new DerivedList.RecursionSafe<Group, Group>() { @Override protected InternalEObject getOwner() @@ -100,7 +100,7 @@ public class GroupImpl extends AssigneeImpl implements Group } }; - private EList<Role> allRoles = new CachedList.RecursionSafe<Role, Group>() + private EList<Role> allRoles = new DerivedList.RecursionSafe<Role, Group>() { @Override protected InternalEObject getOwner() diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/LinkedFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/LinkedFilterImpl.java index 79168e6ca1..2f5d1cb2f3 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/LinkedFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/LinkedFilterImpl.java @@ -16,6 +16,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.security.LinkedFilter; import org.eclipse.emf.cdo.security.PermissionFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.ecore.EClass; @@ -80,7 +81,14 @@ public class LinkedFilterImpl extends PermissionFilterImpl implements LinkedFilt protected boolean filter(CDORevision revision, CDORevisionProvider revisionProvider, CDOBranchPoint securityContext, int level) throws Exception { - return getFilter().isApplicable(revision, revisionProvider, securityContext, level + 1); + PermissionFilter filter = getFilter(); + return filter.isApplicable(revision, revisionProvider, securityContext, level + 1); + } + + public boolean isImpacted(CommitImpactContext context) + { + PermissionFilter filter = getFilter(); + return filter.isImpacted(context); } public String format() diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackageFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackageFilterImpl.java index e709786507..5426c53e63 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackageFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackageFilterImpl.java @@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.security.PackageFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EPackage; @@ -85,6 +86,11 @@ public class PackageFilterImpl extends PermissionFilterImpl implements PackageFi return actualPackage == applicablePackage; } + public boolean isImpacted(CommitImpactContext context) + { + return false; + } + public String format() { String label = "?"; diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackagePermissionImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackagePermissionImpl.java index 5cb2053909..e8ade3f45b 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackagePermissionImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PackagePermissionImpl.java @@ -83,4 +83,10 @@ public class PackagePermissionImpl extends PermissionImpl implements PackagePerm return actualPackage == applicablePackage; } + @Override + public boolean isImpacted(CommitImpactContext context) + { + return false; + } + } // PackagePermissionImpl diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PermissionImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PermissionImpl.java index 28a8585dce..17d28faf4b 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PermissionImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/PermissionImpl.java @@ -10,6 +10,9 @@ */ package org.eclipse.emf.cdo.security.impl; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.internal.security.PermissionUtil; import org.eclipse.emf.cdo.security.Access; import org.eclipse.emf.cdo.security.Permission; @@ -115,4 +118,50 @@ public abstract class PermissionImpl extends CDOObjectImpl implements Permission { return PermissionUtil.getUser(); } + + /** + * Should be overridden in subclasses to do proper impact analysis! + * + * @since 4.3 + */ + public boolean isImpacted(CommitImpactContext context) + { + return true; + } + + /** + * @author Eike Stepper + * @since 4.3 + */ + public interface CommitImpactContext + { + /** + * Returns the revisions of the new objects of the current commit. + * <p> + * Read only! + */ + public CDORevision[] getNewObjects(); + + /** + * Returns the revisions of the changed objects of the current commit. + * <p> + * Read only! + */ + public CDORevision[] getDirtyObjects(); + + /** + * Returns the revision deltas of the changed objects of the current commit. + * <p> + * Read only! + */ + public CDORevisionDelta[] getDirtyObjectDeltas(); + + /** + * Returns the CDOIDs of the detached objects of the current commit. + * <p> + * Read only! + */ + public CDOID[] getDetachedObjects(); + } + } // PermissionImpl diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/RealmImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/RealmImpl.java index 162dae5728..ab97b36e88 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/RealmImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/RealmImpl.java @@ -54,7 +54,7 @@ import org.eclipse.emf.ecore.InternalEObject; */ public class RealmImpl extends SecurityElementImpl implements Realm { - private EList<User> allUsers = new CachedList<User>() + private EList<User> allUsers = new DerivedList<User>() { @Override protected InternalEObject getOwner() @@ -76,7 +76,7 @@ public class RealmImpl extends SecurityElementImpl implements Realm } }; - private EList<Group> allGroups = new CachedList<Group>() + private EList<Group> allGroups = new DerivedList<Group>() { @Override protected InternalEObject getOwner() @@ -98,7 +98,7 @@ public class RealmImpl extends SecurityElementImpl implements Realm } }; - private EList<Role> allRoles = new CachedList<Role>() + private EList<Role> allRoles = new DerivedList<Role>() { @Override protected InternalEObject getOwner() @@ -120,7 +120,7 @@ public class RealmImpl extends SecurityElementImpl implements Realm } }; - private EList<Permission> allPermissions = new CachedList<Permission>() + private EList<Permission> allPermissions = new DerivedList<Permission>() { @Override protected InternalEObject getOwner() diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java index d401c68fa9..4651a79078 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java @@ -16,11 +16,15 @@ import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta; +import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.eresource.EresourcePackage; import org.eclipse.emf.cdo.security.PatternStyle; import org.eclipse.emf.cdo.security.ResourceFilter; import org.eclipse.emf.cdo.security.SecurityPackage; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.WrappedException; @@ -275,103 +279,10 @@ public class ResourceFilterImpl extends PermissionFilterImpl implements Resource return this; } - // private boolean includesExactAndUp(CDORevision revision, CDORevisionProvider revisionProvider) - // { - // if (!revision.isResourceNode()) - // { - // return false; - // } - // - // String revisionPath = CDORevisionUtil.getResourceNodePath(revision, revisionProvider); - // String path = getSubstitutedPath(); - // - // int length = revisionPath.length(); - // if (length > path.length()) - // { - // return false; - // } - // - // path = path.substring(0, length); - // return revisionPath.equals(path); - // } - // - // private boolean includesExactAndDown(CDORevision revision, CDORevisionProvider revisionProvider) - // { - // String revisionPath = CDORevisionUtil.getResourceNodePath(revision, revisionProvider); - // String path = getSubstitutedPath(); - // - // int length = path.length(); - // if (length > revisionPath.length()) - // { - // return false; - // } - // - // revisionPath = revisionPath.substring(0, length); - // return path.equals(revisionPath); - // } - // - // private boolean includesRegex(CDORevision revision, CDORevisionProvider revisionProvider) - // { - // if (pattern == null) - // { - // String path = substituteUserToken(getPath()); - // pattern = compilePattern(path); - // - // if (pattern == null) - // { - // return false; - // } - // } - // - // if (pattern == OMNI_PATTERN) - // { - // return true; - // } - // - // String revisionPath = CDORevisionUtil.getResourceNodePath(revision, revisionProvider); - // - // Matcher matcher = pattern.matcher(revisionPath); - // return matcher.matches(); - // } - // - // private String substituteUserToken(String string) - // { - // int pos = string.indexOf(USER_TOKEN); - // if (pos != -1) - // { - // String user = getUser(); - // if (user == null || user.length() == 0) - // { - // throw new IllegalStateException("User required for evaluation of path " + string); - // } - // - // string = string.substring(0, pos) + user + string.substring(pos + USER_TOKEN.length()); - // } - // - // return string; - // } - // - // private Pattern compilePattern(String value) - // { - // if (value == null) - // { - // return null; - // } - // - // if (OMNI_PATTERN.pattern().equals(value)) - // { - // return OMNI_PATTERN; - // } - // - // try - // { - // return Pattern.compile(value); - // } - // catch (PatternSyntaxException ex) - // { - // return null; - // } - // } + public boolean isImpacted(CommitImpactContext context) + { + return isResourceTreeImpacted(context); + } public String format() { @@ -589,6 +500,32 @@ public class ResourceFilterImpl extends PermissionFilterImpl implements Resource } } + public static boolean isResourceTreeImpacted(CommitImpactContext context) + { + InternalCDORevisionDelta[] revisionDeltas = (InternalCDORevisionDelta[])context.getDirtyObjectDeltas(); + + for (int i = 0; i < revisionDeltas.length; i++) + { + InternalCDORevisionDelta revisionDelta = revisionDeltas[i]; + + // Any tree move might impact this permission + CDOFeatureDelta containerDelta = revisionDelta.getFeatureDelta(CDOContainerFeatureDelta.CONTAINER_FEATURE); + if (containerDelta != null) + { + return true; + } + + // Any change of a resource node name might impact this permission + CDOFeatureDelta nameDelta = revisionDelta.getFeatureDelta(EresourcePackage.Literals.CDO_RESOURCE_NODE__NAME); + if (nameDelta != null) + { + return true; + } + } + + return false; + } + /** * @author Eike Stepper */ diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourcePermissionImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourcePermissionImpl.java index 989a165a8d..d3e8401112 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourcePermissionImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourcePermissionImpl.java @@ -113,6 +113,12 @@ public class ResourcePermissionImpl extends PermissionImpl implements ResourcePe return matcher.matches(); } + @Override + public boolean isImpacted(CommitImpactContext context) + { + return ResourceFilterImpl.isResourceTreeImpacted(context); + } + private Pattern compilePattern(String value) { if (value == null) diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/UserImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/UserImpl.java index 0ffb9d90fc..0525a34ecd 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/UserImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/UserImpl.java @@ -55,7 +55,7 @@ import java.util.Set; */ public class UserImpl extends AssigneeImpl implements User { - private EList<Group> allGroups = new CachedList<Group>() + private EList<Group> allGroups = new DerivedList<Group>() { @Override protected InternalEObject getOwner() @@ -84,7 +84,7 @@ public class UserImpl extends AssigneeImpl implements User } }; - private EList<Role> allRoles = new CachedList<Role>() + private EList<Role> allRoles = new DerivedList<Role>() { @Override protected InternalEObject getOwner() @@ -113,7 +113,7 @@ public class UserImpl extends AssigneeImpl implements User } }; - private EList<Permission> allPermissions = new CachedList<Permission>() + private EList<Permission> allPermissions = new DerivedList<Permission>() { @Override protected InternalEObject getOwner() @@ -141,7 +141,7 @@ public class UserImpl extends AssigneeImpl implements User } }; - private EList<Role> unassignedRoles = new CachedList<Role>() + private EList<Role> unassignedRoles = new DerivedList<Role>() { @Override protected InternalEObject getOwner() diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java index 64258e28b0..e328a7cc48 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java @@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; @@ -39,6 +40,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * Used during raw import. @@ -72,6 +74,7 @@ public class HibernateRawCommitContext implements InternalCommitContext return cdoRevision; } } + for (CDORevision cdoRevision : dirtyObjects) { if (id.equals(cdoRevision.getID())) @@ -79,6 +82,7 @@ public class HibernateRawCommitContext implements InternalCommitContext return cdoRevision; } } + return null; } @@ -88,6 +92,7 @@ public class HibernateRawCommitContext implements InternalCommitContext { branchPoint = new CDOHibernateBranchPointImpl(System.currentTimeMillis()); } + return branchPoint; } @@ -130,6 +135,25 @@ public class HibernateRawCommitContext implements InternalCommitContext return HibernateThreadContext.getCurrentStoreAccessor().getStore().getRepository().getPackageRegistry(); } + public ISession getSender() + { + return null; + } + + public CDOCommitInfo getCommitInfo() + { + return null; + } + + public boolean isClearPermissionCache() + { + return false; + } + + public void setSecurityImpact(byte securityImpact, Set<? extends Object> impactedRules) + { + } + public boolean isClearResourcePathCache() { return false; @@ -368,5 +392,4 @@ public class HibernateRawCommitContext implements InternalCommitContext T old = (T)data.put(key, value); return old; } - } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java index 3317903a30..0da248e629 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java @@ -18,7 +18,6 @@ import org.eclipse.emf.cdo.common.CDOCommonRepository; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; -import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.server.IRepositoryProvider; import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage; @@ -34,8 +33,6 @@ import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; -import java.util.Set; - /** * @author Eike Stepper */ @@ -51,14 +48,14 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement public CDOServerProtocol(IRepositoryProvider repositoryProvider) { - super(CDOProtocolConstants.PROTOCOL_NAME); + super(PROTOCOL_NAME); this.repositoryProvider = repositoryProvider; } @Override public int getVersion() { - return CDOProtocolConstants.PROTOCOL_VERSION; + return PROTOCOL_VERSION; } public InternalSession getSession() @@ -146,22 +143,20 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo) throws Exception { - sendCommitNotification(commitInfo, true); + throw new UnsupportedOperationException(); } @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) throws Exception { - sendCommitNotification(commitInfo, true, null); - + throw new UnsupportedOperationException(); } - public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly) - throws Exception + public void sendCommitNotification(CommitNotificationInfo info) throws Exception { if (LifecycleUtil.isActive(getChannel())) { - new CommitNotificationRequest(this, commitInfo, clearResourcePathCache, readOnly).sendAsync(); + new CommitNotificationRequest(this, info).sendAsync(); } else { @@ -215,142 +210,142 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement { switch (signalID) { - case CDOProtocolConstants.SIGNAL_OPEN_SESSION: + case SIGNAL_OPEN_SESSION: return new OpenSessionIndication(this); - case CDOProtocolConstants.SIGNAL_OPEN_VIEW: + case SIGNAL_OPEN_VIEW: return new OpenViewIndication(this); - case CDOProtocolConstants.SIGNAL_SWITCH_TARGET: + case SIGNAL_SWITCH_TARGET: return new SwitchTargetIndication(this); - case CDOProtocolConstants.SIGNAL_CLOSE_VIEW: + case SIGNAL_CLOSE_VIEW: return new CloseViewIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_PACKAGES: + case SIGNAL_LOAD_PACKAGES: return new LoadPackagesIndication(this); - case CDOProtocolConstants.SIGNAL_CREATE_BRANCH: + case SIGNAL_CREATE_BRANCH: return new CreateBranchIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_BRANCH: + case SIGNAL_LOAD_BRANCH: return new LoadBranchIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_SUB_BRANCHES: + case SIGNAL_LOAD_SUB_BRANCHES: return new LoadSubBranchesIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_BRANCHES: + case SIGNAL_LOAD_BRANCHES: return new LoadBranchesIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_REVISIONS: + case SIGNAL_LOAD_REVISIONS: return new LoadRevisionsIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_REVISION_BY_VERSION: + case SIGNAL_LOAD_REVISION_BY_VERSION: return new LoadRevisionByVersionIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_CHUNK: + case SIGNAL_LOAD_CHUNK: return new LoadChunkIndication(this); - case CDOProtocolConstants.SIGNAL_QUERY_LOBS: + case SIGNAL_QUERY_LOBS: return new QueryLobsIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_LOB: + case SIGNAL_LOAD_LOB: return new LoadLobIndication(this); - case CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION: + case SIGNAL_COMMIT_TRANSACTION: return new CommitTransactionIndication(this); - case CDOProtocolConstants.SIGNAL_COMMIT_DELEGATION: + case SIGNAL_COMMIT_DELEGATION: return new CommitDelegationIndication(this); - case CDOProtocolConstants.SIGNAL_XA_COMMIT_TRANSACTION_PHASE1: + case SIGNAL_XA_COMMIT_TRANSACTION_PHASE1: return new CommitXATransactionPhase1Indication(this); - case CDOProtocolConstants.SIGNAL_XA_COMMIT_TRANSACTION_PHASE2: + case SIGNAL_XA_COMMIT_TRANSACTION_PHASE2: return new CommitXATransactionPhase2Indication(this); - case CDOProtocolConstants.SIGNAL_XA_COMMIT_TRANSACTION_PHASE3: + case SIGNAL_XA_COMMIT_TRANSACTION_PHASE3: return new CommitXATransactionPhase3Indication(this); - case CDOProtocolConstants.SIGNAL_XA_COMMIT_TRANSACTION_CANCEL: + case SIGNAL_XA_COMMIT_TRANSACTION_CANCEL: return new CommitXATransactionCancelIndication(this); - case CDOProtocolConstants.SIGNAL_QUERY: + case SIGNAL_QUERY: return new QueryIndication(this); - case CDOProtocolConstants.SIGNAL_QUERY_CANCEL: + case SIGNAL_QUERY_CANCEL: return new QueryCancelIndication(this); - case CDOProtocolConstants.SIGNAL_REFRESH_SESSION: + case SIGNAL_REFRESH_SESSION: return new RefreshSessionIndication(this); - case CDOProtocolConstants.SIGNAL_DISABLE_PASSIVE_UPDATE: + case SIGNAL_DISABLE_PASSIVE_UPDATE: return new DisablePassiveUpdateIndication(this); - case CDOProtocolConstants.SIGNAL_SET_PASSIVE_UPDATE_MODE: + case SIGNAL_SET_PASSIVE_UPDATE_MODE: return new SetPassiveUpdateModeIndication(this); - case CDOProtocolConstants.SIGNAL_CHANGE_SUBSCRIPTION: + case SIGNAL_CHANGE_SUBSCRIPTION: return new ChangeSubscriptionIndication(this); - case CDOProtocolConstants.SIGNAL_REPOSITORY_TIME: + case SIGNAL_REPOSITORY_TIME: return new RepositoryTimeIndication(this); - case CDOProtocolConstants.SIGNAL_LOCK_OBJECTS: + case SIGNAL_LOCK_OBJECTS: return new LockObjectsIndication(this); - case CDOProtocolConstants.SIGNAL_UNLOCK_OBJECTS: + case SIGNAL_UNLOCK_OBJECTS: return new UnlockObjectsIndication(this); - case CDOProtocolConstants.SIGNAL_LOCK_DELEGATION: + case SIGNAL_LOCK_DELEGATION: return new LockDelegationIndication(this); - case CDOProtocolConstants.SIGNAL_UNLOCK_DELEGATION: + case SIGNAL_UNLOCK_DELEGATION: return new UnlockDelegationIndication(this); - case CDOProtocolConstants.SIGNAL_OBJECT_LOCKED: + case SIGNAL_OBJECT_LOCKED: return new ObjectLockedIndication(this); - case CDOProtocolConstants.SIGNAL_LOCK_AREA: + case SIGNAL_LOCK_AREA: return new LockAreaIndication(this); - case CDOProtocolConstants.SIGNAL_GET_REMOTE_SESSIONS: + case SIGNAL_GET_REMOTE_SESSIONS: return new GetRemoteSessionsIndication(this); - case CDOProtocolConstants.SIGNAL_UNSUBSCRIBE_REMOTE_SESSIONS: + case SIGNAL_UNSUBSCRIBE_REMOTE_SESSIONS: return new UnsubscribeRemoteSessionsIndication(this); - case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE: + case SIGNAL_REMOTE_MESSAGE: return new RemoteMessageIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_COMMIT_INFOS: + case SIGNAL_LOAD_COMMIT_INFOS: return new LoadCommitInfosIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_COMMIT_DATA: + case SIGNAL_LOAD_COMMIT_DATA: return new LoadCommitDataIndication(this); - case CDOProtocolConstants.SIGNAL_REPLICATE_REPOSITORY: + case SIGNAL_REPLICATE_REPOSITORY: return new ReplicateRepositoryIndication(this); - case CDOProtocolConstants.SIGNAL_REPLICATE_REPOSITORY_RAW: + case SIGNAL_REPLICATE_REPOSITORY_RAW: return new ReplicateRepositoryRawIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_CHANGE_SETS: + case SIGNAL_LOAD_CHANGE_SETS: return new LoadChangeSetsIndication(this); - case CDOProtocolConstants.SIGNAL_LOAD_MERGE_DATA: + case SIGNAL_LOAD_MERGE_DATA: return new LoadMergeDataIndication(this); - case CDOProtocolConstants.SIGNAL_HANDLE_REVISIONS: + case SIGNAL_HANDLE_REVISIONS: return new HandleRevisionsIndication(this); - case CDOProtocolConstants.SIGNAL_LOCK_STATE: + case SIGNAL_LOCK_STATE: return new LockStateIndication(this); - case CDOProtocolConstants.SIGNAL_ENABLE_LOCK_NOTIFICATION: + case SIGNAL_ENABLE_LOCK_NOTIFICATION: return new EnableLockNotificationIndication(this); - case CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE: + case SIGNAL_SET_LOCK_NOTIFICATION_MODE: return new SetLockNotificationModeIndication(this); default: diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitNotificationRequest.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitNotificationRequest.java index 166c8963ff..3210ac7088 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitNotificationRequest.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitNotificationRequest.java @@ -12,51 +12,28 @@ */ package org.eclipse.emf.cdo.server.internal.net4j.protocol; -import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; -import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import java.io.IOException; -import java.util.Set; /** * @author Eike Stepper */ public class CommitNotificationRequest extends CDOServerRequest { - private CDOCommitInfo commitInfo; + private CommitNotificationInfo info; - private boolean clearResourcePathCache; - - private Set<CDOID> readOnly; - - public CommitNotificationRequest(CDOServerProtocol serverProtocol, CDOCommitInfo commitInfo, - boolean clearResourcePathCache, Set<CDOID> readOnly) + public CommitNotificationRequest(CDOServerProtocol serverProtocol, CommitNotificationInfo info) { super(serverProtocol, CDOProtocolConstants.SIGNAL_COMMIT_NOTIFICATION); - this.commitInfo = commitInfo; - this.clearResourcePathCache = clearResourcePathCache; - this.readOnly = readOnly; + this.info = info; } @Override protected void requesting(CDODataOutput out) throws IOException { - out.writeCDOCommitInfo(commitInfo); - out.writeBoolean(clearResourcePathCache); - - if (readOnly != null) - { - out.writeInt(readOnly.size()); - for (CDOID id : readOnly) - { - out.writeCDOID(id); - } - } - else - { - out.writeInt(0); - } + info.write(out); } } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java index 863607b836..830c040cc7 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java @@ -378,6 +378,7 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori { out.writeCDOBranchPoint(commitContext.getBranchPoint()); out.writeLong(commitContext.getPreviousTimeStamp()); + out.writeBoolean(commitContext.isClearPermissionCache()); } protected void respondingMappingNewObjects(CDODataOutput out) throws Exception @@ -431,16 +432,20 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori protected void respondingNewPermissions(CDODataOutput out, IPermissionManager permissionManager, InternalSession session, InternalCDORevision[] revisions) throws Exception { - CDOBranchPoint securityContext = commitContext.getBranchPoint(); - - out.writeInt(revisions.length); - for (int i = 0; i < revisions.length; i++) + int size = revisions.length; + if (size != 0) { - InternalCDORevision revision = revisions[i]; - CDOPermission permission = permissionManager.getPermission(revision, securityContext, session); + CDOBranchPoint securityContext = commitContext.getBranchPoint(); + + out.writeInt(size); + for (int i = 0; i < size; i++) + { + InternalCDORevision revision = revisions[i]; + CDOPermission permission = permissionManager.getPermission(revision, securityContext, session); - out.writeCDOID(revision.getID()); - out.writeEnum(permission); + out.writeCDOID(revision.getID()); + out.writeEnum(permission); + } } } 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 5a2d5715b9..0ef4eaf529 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 @@ -12,8 +12,12 @@ package org.eclipse.emf.cdo.server.internal.security; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.common.security.CDOPermission; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.EresourcePackage; @@ -33,6 +37,8 @@ import org.eclipse.emf.cdo.security.SecurityFactory; import org.eclipse.emf.cdo.security.SecurityPackage; import org.eclipse.emf.cdo.security.User; import org.eclipse.emf.cdo.security.UserPassword; +import org.eclipse.emf.cdo.security.impl.PermissionImpl; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.cdo.server.CDOServerUtil; import org.eclipse.emf.cdo.server.IPermissionManager; import org.eclipse.emf.cdo.server.IRepository; @@ -42,8 +48,10 @@ import org.eclipse.emf.cdo.server.ITransaction; import org.eclipse.emf.cdo.server.internal.security.bundle.OM; import org.eclipse.emf.cdo.server.spi.security.InternalSecurityManager; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager; import org.eclipse.emf.cdo.spi.common.revision.ManagedRevisionProvider; +import org.eclipse.emf.cdo.spi.server.InternalCommitContext; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.spi.server.InternalSessionManager; import org.eclipse.emf.cdo.transaction.CDOTransaction; @@ -55,6 +63,9 @@ import org.eclipse.net4j.acceptor.IAcceptor; import org.eclipse.net4j.connector.IConnector; import org.eclipse.net4j.util.ArrayUtil; import org.eclipse.net4j.util.WrappedException; +import org.eclipse.net4j.util.collection.HashBag; +import org.eclipse.net4j.util.container.ContainerEventAdapter; +import org.eclipse.net4j.util.container.IContainer; import org.eclipse.net4j.util.container.IManagedContainer; import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.lifecycle.ILifecycle; @@ -68,9 +79,10 @@ import org.eclipse.net4j.util.security.IPasswordCredentials; import org.eclipse.emf.common.util.EList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * @author Eike Stepper @@ -97,6 +109,15 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage } }; + private final IListener sessionManagerListener = new ContainerEventAdapter<ISession>() + { + @Override + protected void onRemoved(IContainer<ISession> container, ISession session) + { + removeUserInfo(session); + } + }; + private final IAuthenticator authenticator = new Authenticator(); private final IPermissionManager permissionManager = new PermissionManager(); @@ -107,7 +128,9 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage private final IManagedContainer container; - private final Map<String, User> users = Collections.synchronizedMap(new HashMap<String, User>()); + private final Map<ISession, UserInfo> userInfos = new HashMap<ISession, UserInfo>(); + + private final HashBag<PermissionImpl> permissionBag = new HashBag<PermissionImpl>(); private final Object commitHandlerLock = new Object(); @@ -115,18 +138,22 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage private CommitHandler2[] commitHandlers2 = {}; + private PermissionImpl[] permissionArray = {}; + private InternalRepository repository; private IAcceptor acceptor; private IConnector connector; - private CDONet4jSession session; + private CDONet4jSession systemSession; private CDOView view; private Realm realm; + private CDOID realmID; + public SecurityManager(String realmPath, IManagedContainer container) { this.realmPath = realmPath; @@ -186,16 +213,10 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage public User getUser(String id) { - User item = users.get(id); + User item = realm.getUser(id); if (item == null) { - item = realm.getUser(id); - if (item == null) - { - throw new SecurityException("User " + id + " not found"); - } - - users.put(id, item); + throw new SecurityException("User " + id + " not found"); } return item; @@ -336,7 +357,7 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage public void modify(RealmOperation operation, boolean waitUntilReadable) { checkActive(); - CDOTransaction transaction = session.openTransaction(); + CDOTransaction transaction = systemSession.openTransaction(); try { @@ -483,8 +504,8 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage config.setRepositoryName(repositoryName); config.setUserID(SYSTEM_USER_ID); - session = config.openNet4jSession(); - CDOTransaction transaction = session.openTransaction(); + systemSession = config.openNet4jSession(); + CDOTransaction transaction = systemSession.openTransaction(); boolean firstTime = !transaction.hasResource(realmPath); if (firstTime) @@ -516,12 +537,14 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage transaction.close(); } - view = session.openView(); + view = systemSession.openView(); realm = view.getObject(realm); + realmID = realm.cdoID(); InternalSessionManager sessionManager = repository.getSessionManager(); sessionManager.setAuthenticator(authenticator); sessionManager.setPermissionManager(permissionManager); + sessionManager.addListener(sessionManagerListener); repository.addHandler(writeAccessHandler); SECURITY_MANAGERS.put(repository, this); @@ -531,29 +554,29 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage protected Realm createRealm() { Realm realm = SF.createRealm("Security Realm"); - realm.setDefaultRoleDirectory(addDirectory(realm, "Roles")); - realm.setDefaultGroupDirectory(addDirectory(realm, "Groups")); - realm.setDefaultUserDirectory(addDirectory(realm, "Users")); + realm.setDefaultRoleDirectory(addDirectory(realm, Directory.ROLES)); + realm.setDefaultGroupDirectory(addDirectory(realm, Directory.GROUPS)); + realm.setDefaultUserDirectory(addDirectory(realm, Directory.USERS)); // Create roles - Role allReaderRole = realm.addRole("All Objects Reader"); + Role allReaderRole = realm.addRole(Role.ALL_OBJECTS_READER); allReaderRole.getPermissions().add( SF.createFilterPermission(Access.READ, SF.createResourceFilter(".*", PatternStyle.REGEX))); - Role allWriterRole = realm.addRole("All Objects Writer"); + Role allWriterRole = realm.addRole(Role.ALL_OBJECTS_WRITER); allWriterRole.getPermissions().add( SF.createFilterPermission(Access.WRITE, SF.createResourceFilter(".*", PatternStyle.REGEX))); - Role treeReaderRole = realm.addRole("Resource Tree Reader"); + Role treeReaderRole = realm.addRole(Role.RESOURCE_TREE_READER); treeReaderRole.getPermissions().add( SF.createFilterPermission(Access.READ, SF.createPackageFilter(EresourcePackage.eINSTANCE))); - Role treeWriterRole = realm.addRole("Resource Tree Writer"); + Role treeWriterRole = realm.addRole(Role.RESOURCE_TREE_WRITER); treeWriterRole.getPermissions().add( SF.createFilterPermission(Access.WRITE, SF.createPackageFilter(EresourcePackage.eINSTANCE))); - Role adminRole = realm.addRole("Administration"); + Role adminRole = realm.addRole(Role.ADMINISTRATION); adminRole.getPermissions().add( SF.createFilterPermission(Access.WRITE, SF.createResourceFilter(realmPath, PatternStyle.EXACT, false))); adminRole.getPermissions().add( @@ -561,14 +584,14 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage // Create groups - Group adminsGroup = realm.addGroup("Administrators"); + Group adminsGroup = realm.addGroup(Group.ADMINISTRATORS); adminsGroup.getRoles().add(adminRole); - realm.addGroup("Users"); + realm.addGroup(Directory.USERS); // Create users - User adminUser = realm.addUser("Administrator", "0000"); + User adminUser = realm.addUser(User.ADMINISTRATOR, "0000"); adminUser.getGroups().add(adminsGroup); return realm; @@ -598,22 +621,33 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage return CDOPermission.NONE; } - protected CDOPermission getPermission(CDORevision revision, CDORevisionProvider revisionProvider, - CDOBranchPoint securityContext, ISession session, User user) + protected CDOPermission authorize(CDORevision revision, CDORevisionProvider revisionProvider, + CDOBranchPoint securityContext, ISession session, Access defaultAccess, Permission[] permissions) { - PermissionUtil.setUser(user.getId()); + boolean setUser = defaultAccess == null; + if (setUser) + { + UserInfo userInfo = getUserInfo(session); + User user = userInfo.getUser(); + + defaultAccess = user.getDefaultAccess(); + permissions = userInfo.getPermissions(); + + PermissionUtil.setUser(user.getId()); + } try { - CDOPermission result = convertPermission(user.getDefaultAccess()); + CDOPermission result = convertPermission(defaultAccess); if (result == CDOPermission.WRITE) { return result; } - EList<Permission> allPermissions = user.getAllPermissions(); - for (Permission permission : allPermissions) + for (int i = 0; i < permissions.length; i++) { + Permission permission = permissions[i]; + CDOPermission p = convertPermission(permission.getAccess()); if (p.ordinal() <= result.ordinal()) { @@ -635,8 +669,75 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage } finally { - PermissionUtil.setUser(null); + if (setUser) + { + PermissionUtil.setUser(null); + } + } + } + + protected UserInfo getUserInfo(ISession session) + { + UserInfo userInfo; + synchronized (userInfos) + { + userInfo = userInfos.get(session); + } + + if (userInfo == null) + { + userInfo = addUserInfo(session); + } + + return userInfo; + } + + protected UserInfo addUserInfo(ISession session) + { + String userID = session.getUserID(); + User user = getUser(userID); + UserInfo userInfo = new UserInfo(user); + + synchronized (userInfos) + { + userInfos.put(session, userInfo); + + Permission[] permissions = userInfo.getPermissions(); + for (int i = 0; i < permissions.length; i++) + { + Permission permission = permissions[i]; + permissionBag.add((PermissionImpl)permission); + } + + // Atomic update + permissionArray = permissionBag.toArray(new PermissionImpl[permissionBag.size()]); } + + return userInfo; + } + + protected UserInfo removeUserInfo(ISession session) + { + UserInfo userInfo; + synchronized (userInfos) + { + userInfo = userInfos.remove(session); + + if (userInfo != null) + { + Permission[] permissions = userInfo.getPermissions(); + for (int i = 0; i < permissions.length; i++) + { + Permission permission = permissions[i]; + permissionBag.remove(permission); + } + + // Atomic update + permissionArray = permissionBag.toArray(new PermissionImpl[permissionBag.size()]); + } + } + + return userInfo; } @Override @@ -649,11 +750,15 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage @Override protected void doDeactivate() throws Exception { - users.clear(); + userInfos.clear(); + permissionBag.clear(); + permissionArray = null; + realm = null; + realmID = null; - session.close(); - session = null; + systemSession.close(); + systemSession = null; view = null; connector.close(); @@ -673,6 +778,33 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage /** * @author Eike Stepper */ + private static final class UserInfo + { + private final User user; + + private final Permission[] permissions; + + public UserInfo(User user) + { + this.user = user; + EList<Permission> allPermissions = user.getAllPermissions(); + permissions = allPermissions.toArray(new Permission[allPermissions.size()]); + } + + public User getUser() + { + return user; + } + + public Permission[] getPermissions() + { + return permissions; + } + } + + /** + * @author Eike Stepper + */ private final class Authenticator implements IAuthenticator { public void authenticate(String userID, char[] password) throws SecurityException @@ -696,38 +828,26 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage */ private final class PermissionManager implements IPermissionManager { - public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext, ISession session) + @Deprecated + public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext, String userID) { - String userID = session.getUserID(); - if (SYSTEM_USER_ID.equals(userID)) - { - return CDOPermission.WRITE; - } - - return doGetPermission(revision, securityContext, session, userID); + throw new UnsupportedOperationException(); } - @Deprecated - public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext, String userID) + public CDOPermission getPermission(CDORevision revision, final CDOBranchPoint securityContext, + final ISession session) { + String userID = session.getUserID(); if (SYSTEM_USER_ID.equals(userID)) { return CDOPermission.WRITE; } - return doGetPermission(revision, securityContext, null, userID); - } - - private CDOPermission doGetPermission(CDORevision revision, final CDOBranchPoint securityContext, - final ISession session, String userID) - { if (revision.getEClass() == SecurityPackage.Literals.USER_PASSWORD) { return CDOPermission.NONE; } - User user = getUser(userID); - InternalCDORevisionManager revisionManager = repository.getRevisionManager(); CDORevisionProvider revisionProvider = new ManagedRevisionProvider(revisionManager, securityContext); @@ -741,13 +861,35 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage try { - return SecurityManager.this.getPermission(revision, revisionProvider, securityContext, session, user); + return authorize(revision, revisionProvider, securityContext, session, null, null); } finally { PermissionUtil.doneViewCreation(); } } + + public boolean hasAnyRule(ISession session, Set<? extends Object> rules) + { + String userID = session.getUserID(); + if (SYSTEM_USER_ID.equals(userID)) + { + return false; + } + + UserInfo userInfo = getUserInfo(session); + Permission[] userPermissions = userInfo.getPermissions(); + for (int i = 0; i < userPermissions.length; i++) + { + Permission userPermission = userPermissions[i]; + if (rules.contains(userPermission)) + { + return true; + } + } + + return false; + } } /** @@ -758,19 +900,20 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage public void handleTransactionBeforeCommitting(ITransaction transaction, final CommitContext commitContext, OMMonitor monitor) throws RuntimeException { - if (transaction.getSessionID() == session.getSessionID()) + if (transaction.getSessionID() == systemSession.getSessionID()) { // Access through ISecurityManager.modify(RealmOperation) handleCommit(commitContext, null); + ((InternalCommitContext)commitContext).setSecurityImpact(CommitNotificationInfo.IMPACT_REALM, null); return; } - CDOBranchPoint securityContext = commitContext.getBranchPoint(); - String userID = commitContext.getUserID(); - User user = getUser(userID); + UserInfo userInfo = getUserInfo(transaction.getSession()); + User user = userInfo.getUser(); handleCommit(commitContext, user); + PermissionUtil.setUser(user.getId()); PermissionUtil.initViewCreation(new ViewCreator() { public CDOView createView(CDORevisionProvider revisionProvider) @@ -781,28 +924,98 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage try { - permissionRevisionsBeforeCommitting(commitContext, securityContext, user, commitContext.getDirtyObjects()); + CDOBranchPoint securityContext = commitContext.getBranchPoint(); + ISession session = transaction.getSession(); + + Access userDefaultAccess = user.getDefaultAccess(); + Permission[] userPermissions = userInfo.getPermissions(); + + final InternalCDORevision[] revisions = commitContext.getDirtyObjects(); + final InternalCDORevisionDelta[] revisionDeltas = commitContext.getDirtyObjectDeltas(); + + // Check permissions on the commit changes and detect realm modifications + byte securityImpact = CommitNotificationInfo.IMPACT_NONE; + for (int i = 0; i < revisions.length; i++) + { + InternalCDORevision revision = revisions[i]; + CDOPermission permission = authorize(revision, commitContext, securityContext, session, userDefaultAccess, + userPermissions); + + if (permission != CDOPermission.WRITE) + { + throw new SecurityException("User " + commitContext.getUserID() + " is not allowed to write to " + revision); + } + + if (securityImpact != CommitNotificationInfo.IMPACT_REALM) + { + InternalCDORevisionDelta revisionDelta = revisionDeltas[i]; + if (CDORevisionUtil.isContained(revisionDelta.getID(), realmID, transaction)) // Use "before commit" state + { + securityImpact = CommitNotificationInfo.IMPACT_REALM; + } + } + } + + // Determine permissions that are impacted by the commit changes + Set<Permission> impactedRules = null; + if (securityImpact != CommitNotificationInfo.IMPACT_REALM) + { + PermissionImpl[] assignedPermissions = permissionArray; // Thread-safe + if (assignedPermissions.length != 0) + { + CommitImpactContext commitImpactContext = new PermissionImpl.CommitImpactContext() + { + public CDORevision[] getNewObjects() + { + return commitContext.getNewObjects(); + } + + public CDORevision[] getDirtyObjects() + { + return revisions; + } + + public CDORevisionDelta[] getDirtyObjectDeltas() + { + return revisionDeltas; + } + + public CDOID[] getDetachedObjects() + { + return commitContext.getDetachedObjects(); + } + }; + + for (int i = 0; i < assignedPermissions.length; i++) + { + PermissionImpl permission = assignedPermissions[i]; + if (permission.isImpacted(commitImpactContext)) + { + if (impactedRules == null) + { + impactedRules = new HashSet<Permission>(); + } + + impactedRules.add(permission); + } + } + + if (impactedRules != null) + { + securityImpact = CommitNotificationInfo.IMPACT_PERMISSIONS; + } + } + } + + ((InternalCommitContext)commitContext).setSecurityImpact(securityImpact, impactedRules); } finally { + PermissionUtil.setUser(null); PermissionUtil.doneViewCreation(); } } - private void permissionRevisionsBeforeCommitting(CommitContext commitContext, CDOBranchPoint securityContext, - User user, InternalCDORevision[] revisions) - { - ISession session = commitContext.getTransaction().getSession(); - for (InternalCDORevision revision : revisions) - { - CDOPermission permission = getPermission(revision, commitContext, securityContext, session, user); - if (permission != CDOPermission.WRITE) - { - throw new SecurityException("User " + user + " is not allowed to write to " + revision); - } - } - } - public void handleTransactionAfterCommitted(ITransaction transaction, final CommitContext commitContext, OMMonitor monitor) { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java index 7a29c97536..736e11e076 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java @@ -36,12 +36,12 @@ import org.eclipse.emf.cdo.common.lock.CDOLockUtil; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.model.EMFUtil; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionFactory; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; @@ -1046,16 +1046,16 @@ public class Repository extends Container<Object> implements InternalRepository @Deprecated public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache) { - sendCommitNotification(sender, commitInfo, clearResourcePathCache, null); + throw new UnsupportedOperationException(); } - public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider) + public void sendCommitNotification(CommitNotificationInfo info) { + CDOCommitInfo commitInfo = info.getCommitInfo(); boolean isFailureCommitInfo = commitInfo.getBranch() == null; if (isFailureCommitInfo || !commitInfo.isEmpty()) { - sessionManager.sendCommitNotification(sender, commitInfo, clearResourcePathCache, revisionProvider); + sessionManager.sendCommitNotification(info); commitInfoManager.notifyCommitInfoHandlers(commitInfo); } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java index 26e6b31855..75b3189233 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java @@ -23,6 +23,7 @@ import org.eclipse.emf.cdo.common.lob.CDOLobStore; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; @@ -950,7 +951,7 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd } public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache, - Map<CDOID, CDOPermission> permissions) + boolean clearPermissionCache, Map<CDOID, CDOPermission> permissions) { throw new UnsupportedOperationException(); } @@ -967,7 +968,7 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd throw new UnsupportedOperationException(); } - public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly) + public void handleCommitNotification(CommitNotificationInfo info) { throw new UnsupportedOperationException(); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java index 2d6b8d4049..a0e1968f32 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java @@ -22,6 +22,7 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevision; @@ -59,8 +60,8 @@ import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.core.runtime.Platform; import java.text.MessageFormat; -import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -407,17 +408,16 @@ public class Session extends Container<IView> implements InternalSession @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo) throws Exception { - sendCommitNotification(commitInfo, true); + throw new UnsupportedOperationException(); } @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) throws Exception { - sendCommitNotification(commitInfo, true, null); + throw new UnsupportedOperationException(); } - public void sendCommitNotification(final CDOCommitInfo commitInfo, boolean clearResourcePathCache, - final CDORevisionProvider revisionProvider) throws Exception + public void sendCommitNotification(CommitNotificationInfo notificationInfo) throws Exception { if (protocol == null) { @@ -429,123 +429,34 @@ public class Session extends Container<IView> implements InternalSession return; } - final IPermissionManager permissionManager = manager.getPermissionManager(); - final Set<CDOID> readOnly = new HashSet<CDOID>(); - final InternalView[] views = getViews(); - - protocol.sendCommitNotification(new DelegatingCommitInfo() + byte securityImpact = notificationInfo.getSecurityImpact(); + if (securityImpact == CommitNotificationInfo.IMPACT_PERMISSIONS) { - private final PassiveUpdateMode passiveUpdateMode = getPassiveUpdateMode(); - - private final boolean additions = passiveUpdateMode == PassiveUpdateMode.ADDITIONS; + IPermissionManager permissionManager = manager.getPermissionManager(); + Set<? extends Object> impactedRules = notificationInfo.getImpactedRules(); - private final boolean changes = passiveUpdateMode == PassiveUpdateMode.CHANGES; - - @Override - protected CDOCommitInfo getDelegate() + if (!permissionManager.hasAnyRule(this, impactedRules)) { - return commitInfo; - } - - @Override - public List<CDOIDAndVersion> getNewObjects() - { - final List<CDOIDAndVersion> newObjects = super.getNewObjects(); - return new IndexedList<CDOIDAndVersion>() - { - @Override - public CDOIDAndVersion get(int index) - { - CDORevision revision = (CDORevision)newObjects.get(index); - if (additions) - { - if (permissionManager == null) - { - // Return full revision - return revision; - } - - CDOPermission permission = permissionManager.getPermission(revision, commitInfo, Session.this); - if (permission != CDOPermission.NONE) - { - if (permission == CDOPermission.READ) - { - readOnly.add(revision.getID()); - } - - // Return full revision - return revision; - } - } - - // Prevent sending full revision by copying the id and version - return CDOIDUtil.createIDAndVersion(revision); - } - - @Override - public int size() - { - return newObjects.size(); - } - }; + securityImpact = CommitNotificationInfo.IMPACT_NONE; } + } - @Override - public List<CDORevisionKey> getChangedObjects() - { - final List<CDORevisionKey> changedObjects = super.getChangedObjects(); - return new IndexedList<CDORevisionKey>() - { - @Override - public CDORevisionKey get(int index) - { - CDORevisionDelta revisionDelta = (CDORevisionDelta)changedObjects.get(index); - CDOID id = revisionDelta.getID(); + CommitInfo sessionCommitInfo = new CommitInfo(notificationInfo); - if (changes || additions || hasSubscription(id, views)) - { - if (permissionManager == null) - { - // Return full delta - return revisionDelta; - } - - if (revisionProvider == null) - { - // Return full delta - return revisionDelta; - } - - CDORevision newRevision = revisionProvider.getRevision(id); - CDOPermission permission = permissionManager.getPermission(newRevision, commitInfo, Session.this); - if (permission != CDOPermission.NONE) - { - if (permission == CDOPermission.READ) - { - readOnly.add(id); - } - - // Return full delta - return revisionDelta; - } - } + CommitNotificationInfo sessionNotificationInfo = new CommitNotificationInfo(); + sessionNotificationInfo.setSender(notificationInfo.getSender()); + sessionNotificationInfo.setCommitInfo(sessionCommitInfo); + sessionNotificationInfo.setRevisionProvider(notificationInfo.getRevisionProvider()); + sessionNotificationInfo.setClearResourcePathCache(notificationInfo.isClearResourcePathCache()); + sessionNotificationInfo.setNewPermissions(sessionCommitInfo.getNewPermissions()); + sessionNotificationInfo.setSecurityImpact(securityImpact); - // Prevent sending full delta by copying the id and version - return CDORevisionUtil.copyRevisionKey(revisionDelta); - } - - @Override - public int size() - { - return changedObjects.size(); - } - }; - } - }, clearResourcePathCache, readOnly); + protocol.sendCommitNotification(sessionNotificationInfo); synchronized (lastUpdateTimeLock) { - lastUpdateTime = commitInfo.getTimeStamp(); + CDOCommitInfo originalCommitInfo = notificationInfo.getCommitInfo(); + lastUpdateTime = originalCommitInfo.getTimeStamp(); } } @@ -654,4 +565,151 @@ public class Session extends Container<IView> implements InternalSession manager = null; super.doDeactivate(); } + + /** + * @author Eike Stepper + */ + private final class CommitInfo extends DelegatingCommitInfo + { + private final CDOCommitInfo delegate; + + private final CDORevisionProvider revisionProvider; + + private final InternalView[] views; + + private final IPermissionManager permissionManager; + + private final Map<CDOID, CDOPermission> newPermissions; + + private final boolean additions; + + private final boolean changes; + + public CommitInfo(CommitNotificationInfo notificationInfo) + { + delegate = notificationInfo.getCommitInfo(); + revisionProvider = notificationInfo.getRevisionProvider(); + + views = getViews(); + permissionManager = manager.getPermissionManager(); + if (permissionManager != null) + { + newPermissions = CDOIDUtil.createMap(); + } + else + { + newPermissions = null; + } + + PassiveUpdateMode passiveUpdateMode = getPassiveUpdateMode(); + additions = passiveUpdateMode == PassiveUpdateMode.ADDITIONS; + changes = additions || passiveUpdateMode == PassiveUpdateMode.CHANGES; + } + + @Override + protected CDOCommitInfo getDelegate() + { + return delegate; + } + + protected void addNewPermission(CDOID id, CDOPermission permission) + { + newPermissions.put(id, permission); + } + + public Map<CDOID, CDOPermission> getNewPermissions() + { + return newPermissions; + } + + @Override + public List<CDOIDAndVersion> getNewObjects() + { + final List<CDOIDAndVersion> newObjects = super.getNewObjects(); + return new IndexedList<CDOIDAndVersion>() + { + @Override + public CDOIDAndVersion get(int index) + { + CDORevision revision = (CDORevision)newObjects.get(index); + if (additions) + { + if (permissionManager == null) + { + // Return full revision + return revision; + } + + CDOPermission permission = permissionManager.getPermission(revision, delegate, Session.this); + CDOID id = revision.getID(); + addNewPermission(id, permission); + + if (permission != CDOPermission.NONE) + { + // Return full revision + return revision; + } + } + + // Prevent sending full revision by copying the id and version + return CDOIDUtil.createIDAndVersion(revision); + } + + @Override + public int size() + { + return newObjects.size(); + } + }; + } + + @Override + public List<CDORevisionKey> getChangedObjects() + { + final List<CDORevisionKey> changedObjects = super.getChangedObjects(); + return new IndexedList<CDORevisionKey>() + { + @Override + public CDORevisionKey get(int index) + { + CDORevisionDelta revisionDelta = (CDORevisionDelta)changedObjects.get(index); + CDOID id = revisionDelta.getID(); + + if (changes || hasSubscription(id, views)) + { + if (permissionManager == null) + { + // Return full delta + return revisionDelta; + } + + if (revisionProvider == null) + { + // Return full delta + return revisionDelta; + } + + CDORevision newRevision = revisionProvider.getRevision(id); + CDOPermission permission = permissionManager.getPermission(newRevision, delegate, Session.this); + addNewPermission(id, permission); + + if (permission != CDOPermission.NONE) + { + // Return full delta + return revisionDelta; + } + } + + // Prevent sending full delta by copying the id and version + return CDORevisionUtil.copyRevisionKey(revisionDelta); + } + + @Override + public int size() + { + return changedObjects.size(); + } + }; + } + } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java index f4444d53f2..11c168bc33 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java @@ -13,12 +13,13 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.common.CDOCommonRepository; +import org.eclipse.emf.cdo.common.CDOCommonSession; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.common.util.NotAuthenticatedException; import org.eclipse.emf.cdo.internal.server.bundle.OM; import org.eclipse.emf.cdo.server.IPermissionManager; @@ -283,25 +284,25 @@ public class SessionManager extends Container<ISession> implements InternalSessi @Deprecated public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo) { - sendCommitNotification(sender, commitInfo, true); + throw new UnsupportedOperationException(); } @Deprecated public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache) { - sendCommitNotification(sender, commitInfo, true, null); + throw new UnsupportedOperationException(); } - public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider) + public void sendCommitNotification(CommitNotificationInfo info) { + CDOCommonSession sender = info.getSender(); for (InternalSession session : getSessions()) { if (session != sender) { try { - session.sendCommitNotification(commitInfo, clearResourcePathCache, revisionProvider); + session.sendCommitNotification(info); } catch (Exception ex) { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java index 8f2acf818c..d4c16c6af9 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java @@ -28,6 +28,7 @@ import org.eclipse.emf.cdo.common.lock.CDOLockOwner; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.lock.CDOLockUtil; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; @@ -66,7 +67,6 @@ import org.eclipse.emf.cdo.spi.common.revision.StubCDORevision; import org.eclipse.emf.cdo.spi.server.InternalCommitContext; import org.eclipse.emf.cdo.spi.server.InternalLockManager; import org.eclipse.emf.cdo.spi.server.InternalRepository; -import org.eclipse.emf.cdo.spi.server.InternalSession; import org.eclipse.emf.cdo.spi.server.InternalTransaction; import org.eclipse.net4j.util.CheckUtil; @@ -132,8 +132,6 @@ public class TransactionCommitContext implements InternalCommitContext private String commitComment; - private boolean clearResourcePathCache; - private boolean usingEcore; private boolean usingEtypes; @@ -186,6 +184,8 @@ public class TransactionCommitContext implements InternalCommitContext private Map<Object, Object> data; + private CommitNotificationInfo commitNotificationInfo = new CommitNotificationInfo(); + public TransactionCommitContext(InternalTransaction transaction) { this.transaction = transaction; @@ -257,7 +257,12 @@ public class TransactionCommitContext implements InternalCommitContext public boolean isClearResourcePathCache() { - return clearResourcePathCache; + return commitNotificationInfo.isClearResourcePathCache(); + } + + public boolean isClearPermissionCache() + { + return commitNotificationInfo.getSecurityImpact() != CommitNotificationInfo.IMPACT_NONE; } public boolean isUsingEcore() @@ -473,7 +478,13 @@ public class TransactionCommitContext implements InternalCommitContext public void setClearResourcePathCache(boolean clearResourcePathCache) { - this.clearResourcePathCache = clearResourcePathCache; + commitNotificationInfo.setClearResourcePathCache(clearResourcePathCache); + } + + public void setSecurityImpact(byte securityImpact, Set<? extends Object> impactedRules) + { + commitNotificationInfo.setSecurityImpact(securityImpact); + commitNotificationInfo.setImpactedRules(impactedRules); } public void setUsingEcore(boolean usingEcore) @@ -803,10 +814,19 @@ public class TransactionCommitContext implements InternalCommitContext private void sendCommitNotifications(boolean success) { - InternalSession sender = transaction.getSession(); - CDOCommitInfo commitInfo = success ? createCommitInfo() : createFailureCommitInfo(); + commitNotificationInfo.setSender(transaction.getSession()); + commitNotificationInfo.setRevisionProvider(this); + + if (success) + { + commitNotificationInfo.setCommitInfo(createCommitInfo()); + } + else + { + commitNotificationInfo.setCommitInfo(createFailureCommitInfo()); + } - repository.sendCommitNotification(sender, commitInfo, clearResourcePathCache, this); + repository.sendCommitNotification(commitNotificationInfo); } public CDOCommitInfo createCommitInfo() diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java index ea68f0d544..4430eb417f 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java @@ -24,8 +24,6 @@ import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; -import java.util.Set; - /** * @author Eike Stepper * @deprecated Not yet supported. @@ -110,8 +108,7 @@ public class EmbeddedServerSessionProtocol extends Lifecycle implements ISession throw new UnsupportedOperationException(); } - public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly) - throws Exception + public void sendCommitNotification(CommitNotificationInfo info) throws Exception { throw new UnsupportedOperationException(); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java index a2d026950f..240f59b4de 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java @@ -32,6 +32,7 @@ import org.eclipse.emf.cdo.common.lock.CDOLockUtil; import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; @@ -449,9 +450,15 @@ public abstract class SynchronizableRepository extends Repository.Default implem CDOCommitData data = CDOCommitInfoUtil.createCommitData(newPackages, newObjects, changedObjects, detachedObjects); String comment = "<replicate raw commits>"; //$NON-NLS-1$ - CDOCommitInfo commitInfo = manager.createCommitInfo(branch, toCommitTime, previousCommitTime, SYSTEM_USER_ID, - comment, data); - sessionManager.sendCommitNotification(replicatorSession, commitInfo, true, null); + final CDOCommitInfo commitInfo = manager.createCommitInfo( // + branch, toCommitTime, previousCommitTime, SYSTEM_USER_ID, comment, data); + + CommitNotificationInfo info = new CommitNotificationInfo(); + info.setSender(replicatorSession); + info.setCommitInfo(commitInfo); + info.setClearResourcePathCache(true); + + sessionManager.sendCommitNotification(info); } CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IPermissionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IPermissionManager.java index f07e7f3def..f8bf88db81 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IPermissionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IPermissionManager.java @@ -14,6 +14,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.security.CDOPermission; +import java.util.Set; + /** * Provides the protection level of {@link CDORevision revisions} in the context of a specific user. * @@ -34,4 +36,9 @@ public interface IPermissionManager * @since 4.2 */ public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext, ISession session); + + /** + * @since 4.3 + */ + public boolean hasAnyRule(ISession session, Set<? extends Object> rules); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java index e28716723a..11bab73187 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java @@ -329,6 +329,11 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader, Com public boolean isClearResourcePathCache(); /** + * @since 4.3 + */ + public boolean isClearPermissionCache(); + + /** * @since 4.2 */ public boolean isUsingEcore(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java index be490f99e0..6199122f0c 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java @@ -21,8 +21,6 @@ import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; -import java.util.Set; - /** * If the meaning of this type isn't clear, there really should be more of a description here... * @@ -72,7 +70,7 @@ public interface ISessionProtocol extends CDOProtocol /** * @since 4.2 - * @deprecated As of 4.3 use {@link #sendCommitNotification(CDOCommitInfo, boolean, Set)}. + * @deprecated As of 4.3 use {@link #sendCommitNotification(CommitNotificationInfo)}. */ @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) throws Exception; @@ -80,8 +78,7 @@ public interface ISessionProtocol extends CDOProtocol /** * @since 4.3 */ - public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly) - throws Exception; + public void sendCommitNotification(CommitNotificationInfo info) throws Exception; public void sendRemoteSessionNotification(InternalSession sender, byte opcode) throws Exception; diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java index fe37f0445e..15cf8925ab 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java @@ -26,6 +26,7 @@ import org.eclipse.net4j.util.om.monitor.ProgressDistributor; import org.eclipse.emf.ecore.EClass; import java.util.Map; +import java.util.Set; /** * If the meaning of this type isn't clear, there really should be more of a description here... @@ -144,4 +145,9 @@ public interface InternalCommitContext extends IStoreAccessor.CommitContext public void addIDMapping(CDOID oldID, CDOID newID); public void applyIDMappings(OMMonitor monitor); + + /** + * @since 4.3 + */ + public void setSecurityImpact(byte securityImpact, Set<? extends Object> impactedRules); } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java index 4b42ddfabf..91ba787ff7 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java @@ -17,10 +17,10 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lob.CDOLobHandler; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.server.IQueryHandlerProvider; import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IStoreAccessor; @@ -181,7 +181,7 @@ public interface InternalRepository extends IRepository, PackageProcessor, Packa /** * @since 4.2 - * @deprecated As of 4.3 use {@link #sendCommitNotification(InternalSession, CDOCommitInfo, boolean, CDORevisionProvider)}. + * @deprecated As of 4.3 use {@link #sendCommitNotification(ISessionProtocol.CommitNotificationInfo)}. */ @Deprecated public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache); @@ -189,8 +189,7 @@ public interface InternalRepository extends IRepository, PackageProcessor, Packa /** * @since 4.3 */ - public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider); + public void sendCommitNotification(CommitNotificationInfo info); public void setRootResourceID(CDOID rootResourceID); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java index 6063004af6..cb8370f125 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java @@ -17,8 +17,8 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDProvider; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; import org.eclipse.emf.cdo.common.security.CDOPermissionProvider; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage; @@ -90,7 +90,7 @@ public interface InternalSession extends ISession, CDOIDProvider, CDOPermissionP /** * @since 4.2 - * @deprecated As of 4.3 use {@link #sendCommitNotification(CDOCommitInfo, boolean, CDORevisionProvider)}. + * @deprecated As of 4.3 use {@link #sendCommitNotification(CommitNotificationInfo)}. */ @Deprecated public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) throws Exception; @@ -98,8 +98,7 @@ public interface InternalSession extends ISession, CDOIDProvider, CDOPermissionP /** * @since 4.3 */ - public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider) throws Exception; + public void sendCommitNotification(CommitNotificationInfo info) throws Exception; public void sendRemoteSessionNotification(InternalSession sender, byte opcode) throws Exception; diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java index 4d406f04d1..afb5bcdcc9 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java @@ -14,7 +14,7 @@ import org.eclipse.emf.cdo.common.CDOCommonRepository; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.server.IPermissionManager; import org.eclipse.emf.cdo.server.ISessionManager; import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage; @@ -110,7 +110,7 @@ public interface InternalSessionManager extends ISessionManager /** * @since 4.2 - * @deprecated As of 4.3 use {@link #sendCommitNotification(InternalSession, CDOCommitInfo, boolean, CDORevisionProvider)}. + * @deprecated As of 4.3 use {@link #sendCommitNotification(ISessionProtocol.CommitNotificationInfo)}. */ @Deprecated public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache); @@ -118,8 +118,7 @@ public interface InternalSessionManager extends ISessionManager /** * @since 4.3 */ - public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider); + public void sendCommitNotification(CommitNotificationInfo info); /** * @since 4.1 diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java index a169b3e7fe..c48845c14a 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java @@ -24,6 +24,7 @@ import org.eclipse.emf.cdo.security.PermissionFilter; import org.eclipse.emf.cdo.security.ResourceFilter; import org.eclipse.emf.cdo.security.SecurityFactory; import org.eclipse.emf.cdo.security.impl.PermissionFilterImpl; +import org.eclipse.emf.cdo.security.impl.PermissionImpl.CommitImpactContext; import org.eclipse.emf.ecore.EClass; @@ -346,5 +347,10 @@ public class SecurityTest extends AbstractCDOTest { return value; } + + public boolean isImpacted(CommitImpactContext context) + { + return false; + } } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java index 261ed8da52..24c08cb71b 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java @@ -12,11 +12,8 @@ package org.eclipse.emf.cdo.tests; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOState; -import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.eresource.CDOResource; -import org.eclipse.emf.cdo.internal.common.branch.CDOBranchImpl; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.config.ISessionConfig; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires; @@ -32,7 +29,6 @@ import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult; import org.eclipse.emf.spi.cdo.InternalCDOObject; import java.lang.reflect.InvocationTargetException; @@ -44,10 +40,6 @@ import java.lang.reflect.Method; @Requires(ISessionConfig.CAPABILITY_NET4J_JVM) public class StateMachineTest extends AbstractCDOTest { - private static final long TIMESTAMP = 12345678; - - private static final CDOBranch BRANCH = new CDOBranchImpl.Main(null, false, 0L); - // /////////////////////////////////////////////////// public void test_TRANSIENT_with_ATTACH() throws Exception @@ -141,23 +133,6 @@ public class StateMachineTest extends AbstractCDOTest assertTransient(supplier); } - public void test_TRANSIENT_with_COMMIT() throws Exception - { - Supplier supplier = getModel1Factory().createSupplier(); - supplier.setName("Stepper"); - assertTransient(supplier); - try - { - commit(supplier, new CommitTransactionResult(null, BRANCH.getPoint(TIMESTAMP), CDOBranchPoint.UNSPECIFIED_DATE, - false)); - fail("IllegalStateException expected"); - } - catch (IllegalStateException expected) - { - assertFailure(expected); - } - } - public void test_TRANSIENT_with_ROLLBACK() throws Exception { Supplier supplier = getModel1Factory().createSupplier(); @@ -265,24 +240,6 @@ public class StateMachineTest extends AbstractCDOTest } } - public void test_PREPARED_with_COMMIT() throws Exception - { - Supplier supplier = getModel1Factory().createSupplier(); - supplier.setName("Stepper"); - setState(supplier, CDOState.PREPARED); - - try - { - commit(supplier, new CommitTransactionResult(null, BRANCH.getPoint(TIMESTAMP), CDOBranchPoint.UNSPECIFIED_DATE, - false)); - fail("IllegalStateException expected"); - } - catch (IllegalStateException expected) - { - assertFailure(expected); - } - } - public void test_PREPARED_with_ROLLBACK() throws Exception { Supplier supplier = getModel1Factory().createSupplier(); @@ -466,15 +423,6 @@ public class StateMachineTest extends AbstractCDOTest } } - private static void commit(EObject object, CommitTransactionResult result) - { - CDOObject cdoObject = CDOUtil.getCDOObject(object); - if (cdoObject != null) - { - CDOStateMachine.INSTANCE.commit((InternalCDOObject)cdoObject, result); - } - } - private static void rollback(EObject object) { CDOObject cdoObject = CDOUtil.getCDOObject(object); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_343084_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_343084_Test.java index ca7fc73c5b..a18ca4770f 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_343084_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_343084_Test.java @@ -36,6 +36,7 @@ import org.eclipse.emf.ecore.EClass; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * @author Eike Stepper @@ -80,6 +81,11 @@ public class Bugzilla_343084_Test extends AbstractCDOTest { throw new UnsupportedOperationException(); } + + public boolean hasAnyRule(ISession session, Set<? extends Object> permissions) + { + return false; + } }; getTestProperties().put(RepositoryConfig.PROP_TEST_AUTHENTICATOR, userManager); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_418267_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_418267_Test.java new file mode 100644 index 0000000000..341496768a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_418267_Test.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 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.common.security.CDOPermission; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.eresource.CDOResourceFolder; +import org.eclipse.emf.cdo.security.Access; +import org.eclipse.emf.cdo.security.PatternStyle; +import org.eclipse.emf.cdo.security.Realm; +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.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.model1.Company; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; + +import org.eclipse.net4j.util.security.IPasswordCredentials; +import org.eclipse.net4j.util.security.PasswordCredentials; + +/** + * Bug 418267 - [Security] Cached permissions are not always properly updated after commits. + * + * @author Eike Stepper + */ +@CleanRepositoriesBefore(reason = "TEST_SECURITY_MANAGER") +@CleanRepositoriesAfter(reason = "TEST_SECURITY_MANAGER") +public class Bugzilla_418267_Test extends AbstractCDOTest +{ + private static final SecurityFactory SF = SecurityFactory.eINSTANCE; + + private static final IPasswordCredentials CREDENTIALS = new PasswordCredentials("user", "password"); + + private static final IPasswordCredentials CREDENTIALS_WRITER = new PasswordCredentials("writer", "password"); + + public void testMoveFromNoneToNone() throws Exception + { + move(CDOPermission.NONE, CDOPermission.NONE); + } + + public void testMoveFromNoneToRead() throws Exception + { + move(CDOPermission.NONE, CDOPermission.READ); + } + + public void testMoveFromNoneToWrite() throws Exception + { + move(CDOPermission.NONE, CDOPermission.WRITE); + } + + public void testMoveFromReadToNone() throws Exception + { + move(CDOPermission.READ, CDOPermission.NONE); + } + + public void testMoveFromReadToRead() throws Exception + { + move(CDOPermission.READ, CDOPermission.READ); + } + + public void testMoveFromReadToWrite() throws Exception + { + move(CDOPermission.READ, CDOPermission.WRITE); + } + + public void testMoveFromWriteToNone() throws Exception + { + move(CDOPermission.WRITE, CDOPermission.NONE); + } + + public void testMoveFromWriteToRead() throws Exception + { + move(CDOPermission.WRITE, CDOPermission.READ); + } + + public void testMoveFromWriteToWrite() throws Exception + { + move(CDOPermission.WRITE, CDOPermission.WRITE); + } + + private void move(final CDOPermission from, final CDOPermission to) throws Exception + { + final String pathFolder2 = getResourcePath("folder2"); + final String pathFolder1 = getResourcePath("folder1"); + final String pathResource1 = pathFolder1 + "/res"; + + startSecureRepository(new ISecurityManager.RealmOperation() + { + public void execute(Realm realm) + { + CDOTransaction transaction = (CDOTransaction)realm.cdoView(); + transaction.createResourceFolder(pathFolder2); + + CDOResource resource = transaction.createResource(pathResource1); + resource.getContents().add(getModel1Factory().createCompany()); + + Role role = realm.addRole("Test Role"); + + Access accessFrom = getAccess(from); + if (accessFrom != null) + { + role.getPermissions().add(SF.createFilterPermission(accessFrom, // + SF.createResourceFilter(pathFolder1, PatternStyle.TREE, false))); + role.getPermissions().add(SF.createFilterPermission(Access.READ, // + SF.createResourceFilter(pathFolder1, PatternStyle.EXACT, true).setModelObjects(false))); + } + + Access accessTo = getAccess(to); + if (accessTo != null) + { + role.getPermissions().add(SF.createFilterPermission(accessTo, // + SF.createResourceFilter(pathFolder2, PatternStyle.TREE, false))); + role.getPermissions().add(SF.createFilterPermission(Access.READ, // + SF.createResourceFilter(pathFolder2, PatternStyle.EXACT, true).setModelObjects(false))); + } + + User user = realm.addUser(CREDENTIALS); + user.getRoles().add(role); + + User writer = realm.addUser(CREDENTIALS_WRITER); + writer.getRoles().add(realm.getRole(Role.ALL_OBJECTS_WRITER)); + } + + private Access getAccess(CDOPermission permission) + { + switch (permission) + { + case READ: + return Access.READ; + + case WRITE: + return Access.WRITE; + + default: + return null; + } + } + }); + + CDOSession sessionWriter = openSession(CREDENTIALS_WRITER); + CDOTransaction transactionWriter = sessionWriter.openTransaction(); + CDOResource resourceWriter = transactionWriter.getResource(pathResource1); + CDOResourceFolder targetFolderWriter = transactionWriter.getResourceFolder(pathFolder2); + + CDOSession session = openSession(CREDENTIALS); + session.options().setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS); + + CDOTransaction transaction = session.openTransaction(); + assertPermission(from, resourceWriter, transaction); // Pre check + + targetFolderWriter.getNodes().add(resourceWriter); // Move + commitAndSync(transactionWriter, transaction); // Commit + invalidate + assertPermission(to, resourceWriter, transaction); // Post check + } + + private static void assertPermission(CDOPermission expected, CDOResource resourceWriter, CDOTransaction transaction) + { + if (expected == CDOPermission.NONE) + { + try + { + transaction.getObject(resourceWriter); + fail("Exception expected"); + } + catch (Exception ex) + { + // SUCCESS + } + } + else + { + CDOResource resource = transaction.getObject(resourceWriter); + assertEquals(expected, resource.cdoPermission()); + + Company company = (Company)resource.getContents().get(0); + assertEquals(expected, CDOUtil.getCDOObject(company).cdoPermission()); + } + } + + private ISecurityManager startSecureRepository(ISecurityManager.RealmOperation operation) + { + ISecurityManager securityManager = SecurityManagerUtil.createSecurityManager("/security", getServerContainer()); + + // Start repository + getTestProperties().put(RepositoryConfig.PROP_TEST_SECURITY_MANAGER, securityManager); + getRepository(); + + securityManager.modify(operation); + return securityManager; + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java index 5cbafbeb94..e84c8a7f46 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java @@ -16,7 +16,7 @@ import org.eclipse.emf.cdo.common.CDOCommonView; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler; import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager; -import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; import org.eclipse.emf.cdo.internal.common.revision.NOOPRevisionCache; import org.eclipse.emf.cdo.internal.net4j.CDONet4jSessionConfigurationImpl; @@ -905,8 +905,7 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf volatile int counter = 1; @Override - public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, - Set<CDOID> readOnly) + public void handleCommitNotification(CommitNotificationInfo info) { long delay = getTestDelayed2CommitHandling(); if (delay != 0L && counter++ % 2 == 0) @@ -914,7 +913,7 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf AbstractOMTest.sleep(delay); } - super.handleCommitNotification(commitInfo, clearResourcePathCache, readOnly); + super.handleCommitNotification(info); } }; } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java index b635e5a3f1..d3b1370086 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionManager.java @@ -10,10 +10,8 @@ */ package org.eclipse.emf.cdo.tests.util; -import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; -import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.internal.server.SessionManager; -import org.eclipse.emf.cdo.spi.server.InternalSession; import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; @@ -55,8 +53,7 @@ public class TestSessionManager extends SessionManager } @Override - public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache, - CDORevisionProvider revisionProvider) + public void sendCommitNotification(CommitNotificationInfo info) { synchronized (lock) { @@ -68,6 +65,6 @@ public class TestSessionManager extends SessionManager } } - super.sendCommitNotification(sender, commitInfo, clearResourcePathCache, revisionProvider); + super.sendCommitNotification(info); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java index 87ae47be41..7cd74525b4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java @@ -31,6 +31,7 @@ import org.eclipse.emf.cdo.common.lob.CDOLobInfo; import org.eclipse.emf.cdo.common.lob.CDOLobStore; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDOElementProxy; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDOList; @@ -893,32 +894,27 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme @Deprecated public void handleCommitNotification(CDOCommitInfo commitInfo) { - handleCommitNotification(commitInfo, true); + throw new UnsupportedOperationException(); } @Deprecated public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) { - handleCommitNotification(commitInfo, true, null); + throw new UnsupportedOperationException(); } - public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly) + public void handleCommitNotification(CommitNotificationInfo info) { try { + CDOCommitInfo commitInfo = info.getCommitInfo(); registerPackageUnits(commitInfo.getNewPackageUnits()); - Map<CDOID, CDOPermission> permissions = null; - if (readOnly != null) - { - permissions = CDOIDUtil.createMap(); - for (CDOID id : readOnly) - { - permissions.put(id, CDOPermission.READ); - } - } + boolean clearResourcePathCache = info.isClearResourcePathCache(); + boolean clearPermissionCache = info.getSecurityImpact() != CommitNotificationInfo.IMPACT_NONE; + Map<CDOID, CDOPermission> newPermissions = info.getNewPermissions(); - invalidate(commitInfo, null, clearResourcePathCache, permissions); + invalidate(commitInfo, null, clearResourcePathCache, clearPermissionCache, newPermissions); } catch (RuntimeException ex) { @@ -1042,19 +1038,19 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme @Deprecated public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender) { - invalidate(commitInfo, sender, true); + throw new UnsupportedOperationException(); } @Deprecated public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache) { - invalidate(commitInfo, sender, true, null); + throw new UnsupportedOperationException(); } public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache, - Map<CDOID, CDOPermission> permissions) + boolean clearPermissionCache, Map<CDOID, CDOPermission> newPermissions) { - invalidator.reorderInvalidations(commitInfo, sender, clearResourcePathCache, permissions); + invalidator.reorderInvalidations(commitInfo, sender, clearResourcePathCache, clearPermissionCache, newPermissions); } public ILifecycle getInvalidator() @@ -1699,14 +1695,16 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme } public synchronized void reorderInvalidations(CDOCommitInfo commitInfo, InternalCDOTransaction sender, - boolean clearResourcePathCache, Map<CDOID, CDOPermission> permissions) + boolean clearResourcePathCache, boolean clearPermissionCache, Map<CDOID, CDOPermission> newPermissions) { if (!isActive()) { return; } - Invalidation invalidation = new Invalidation(commitInfo, sender, clearResourcePathCache, permissions); + Invalidation invalidation = new Invalidation(commitInfo, sender, clearResourcePathCache, clearPermissionCache, + newPermissions); + reorderQueue.add(invalidation); Collections.sort(reorderQueue); @@ -1776,15 +1774,18 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme private final boolean clearResourcePathCache; - private final Map<CDOID, CDOPermission> permissions; + private final boolean clearPermissionCache; + + private final Map<CDOID, CDOPermission> newPermissions; public Invalidation(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache, - Map<CDOID, CDOPermission> permissions) + boolean clearPermissionCache, Map<CDOID, CDOPermission> newPermissions) { this.commitInfo = commitInfo; this.sender = sender; this.clearResourcePathCache = clearResourcePathCache; - this.permissions = permissions; + this.clearPermissionCache = clearPermissionCache; + this.newPermissions = newPermissions; } public long getTimeStamp() @@ -1944,12 +1945,12 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme private void addNewRevision(InternalCDORevision newRevision) { - if (permissions != null) + if (newPermissions != null) { - CDOPermission permission = permissions.get(newRevision.getID()); - if (permission != null) + CDOPermission newPermission = newPermissions.get(newRevision.getID()); + if (newPermission != null) { - newRevision.setPermission(permission); + newRevision.setPermission(newPermission); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index 31651ba3a3..4ad46970b1 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -2996,7 +2996,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (result.getRollbackMessage() != null) { CDOCommitInfo commitInfo = new FailureCommitInfo(timeStamp, result.getPreviousTimeStamp()); - session.invalidate(commitInfo, transaction, clearResourcePathCache, null); + session.invalidate(commitInfo, transaction, clearResourcePathCache, false, null); return; } @@ -3029,8 +3029,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa CDOCommitInfo commitInfo = makeCommitInfo(timeStamp, result.getPreviousTimeStamp()); if (!commitInfo.isEmpty()) { + boolean clearPermissionCache = result.isClearPermissionCache(); Map<CDOID, CDOPermission> newPermissions = result.getNewPermissions(); - session.invalidate(commitInfo, transaction, clearResourcePathCache, newPermissions); + session.invalidate(commitInfo, transaction, clearResourcePathCache, clearPermissionCache, newPermissions); } // Bug 290032 - Sticky views diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java index 9c39626f1b..9d2ec27a69 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java @@ -29,7 +29,6 @@ import org.eclipse.emf.cdo.common.lob.CDOLobInfo; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.protocol.CDOProtocol; -import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; import org.eclipse.emf.cdo.common.security.CDOPermission; @@ -686,9 +685,18 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo private CDOLockState[] newLockStates; + private boolean clearResourcePathCache; + + private boolean clearPermissionCache; + private Map<CDOID, CDOPermission> newPermissions; - private boolean clearResourcePathCache; + /** + * @since 4.3 + */ + public CommitTransactionResult() + { + } /** * @since 4.0 @@ -698,24 +706,19 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo public CommitTransactionResult(CDOIDProvider idProvider, String rollbackMessage, CDOBranchPoint branchPoint, long previousTimeStamp, List<CDOObjectReference> xRefs) { - this(idProvider, CDOProtocolConstants.ROLLBACK_REASON_UNKNOWN, rollbackMessage, branchPoint, previousTimeStamp, - xRefs, true); + throw new UnsupportedOperationException(); } /** * @since 4.2 + * @deprecated As of 4.3 */ + @Deprecated public CommitTransactionResult(CDOIDProvider idProvider, byte rollbackReason, String rollbackMessage, CDOBranchPoint branchPoint, long previousTimeStamp, List<CDOObjectReference> xRefs, boolean clearResourcePathCache) { - this.idProvider = idProvider; - this.rollbackReason = rollbackReason; - this.rollbackMessage = rollbackMessage; - this.branchPoint = branchPoint; - this.previousTimeStamp = previousTimeStamp; - this.xRefs = xRefs; - this.clearResourcePathCache = clearResourcePathCache; + throw new UnsupportedOperationException(); } /** @@ -725,19 +728,55 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo @Deprecated public CommitTransactionResult(CDOIDProvider idProvider, CDOBranchPoint branchPoint, long previousTimeStamp) { - this(idProvider, branchPoint, previousTimeStamp, false); + throw new UnsupportedOperationException(); } /** * @since 4.2 + * @deprecated As of 4.3 */ + @Deprecated public CommitTransactionResult(CDOIDProvider idProvider, CDOBranchPoint branchPoint, long previousTimeStamp, boolean clearResourcePathCache) { - this.idProvider = idProvider; + throw new UnsupportedOperationException(); + } + + /** + * @since 3.0 + */ + public CDOBranch getBranch() + { + return branchPoint.getBranch(); + } + + public long getTimeStamp() + { + return branchPoint.getTimeStamp(); + } + + /** + * @since 4.3 + */ + public void setBranchPoint(CDOBranchPoint branchPoint) + { this.branchPoint = branchPoint; + } + + /** + * @since 4.0 + */ + public long getPreviousTimeStamp() + { + return previousTimeStamp; + } + + /** + * @since 4.3 + */ + public void setPreviousTimeStamp(long previousTimeStamp) + { this.previousTimeStamp = previousTimeStamp; - this.clearResourcePathCache = clearResourcePathCache; } /** @@ -769,30 +808,25 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo return rollbackReason; } - public String getRollbackMessage() - { - return rollbackMessage; - } - /** - * @since 3.0 + * @since 4.3 */ - public CDOBranch getBranch() + public void setRollbackReason(byte rollbackReason) { - return branchPoint.getBranch(); + this.rollbackReason = rollbackReason; } - public long getTimeStamp() + public String getRollbackMessage() { - return branchPoint.getTimeStamp(); + return rollbackMessage; } /** - * @since 4.0 + * @since 4.3 */ - public long getPreviousTimeStamp() + public void setRollbackMessage(String rollbackMessage) { - return previousTimeStamp; + this.rollbackMessage = rollbackMessage; } /** @@ -804,6 +838,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo } /** + * @since 4.3 + */ + public void setXRefs(List<CDOObjectReference> xRefs) + { + this.xRefs = xRefs; + } + + /** * @since 4.2 */ public boolean isClearResourcePathCache() @@ -811,6 +853,46 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo return clearResourcePathCache; } + /** + * @since 4.3 + */ + public void setClearResourcePathCache(boolean clearResourcePathCache) + { + this.clearResourcePathCache = clearResourcePathCache; + } + + /** + * @since 4.3 + */ + public boolean isClearPermissionCache() + { + return clearPermissionCache; + } + + /** + * @since 4.3 + */ + public void setClearPermissionCache(boolean clearPermissionCache) + { + this.clearPermissionCache = clearPermissionCache; + } + + /** + * @since 4.3 + */ + public CDOIDProvider getIDProvider() + { + return idProvider; + } + + /** + * @since 4.3 + */ + public void setIDProvider(CDOIDProvider idProvider) + { + this.idProvider = idProvider; + } + public Map<CDOID, CDOID> getIDMappings() { return idMappings; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java index f9815bcc33..433122350c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java @@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDGenerator; import org.eclipse.emf.cdo.common.lob.CDOLobStore; import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.security.CDOPermission; import org.eclipse.emf.cdo.session.CDORepositoryInfo; @@ -200,7 +201,7 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag /** * @since 4.2 - * @deprecated As of 4.3 use {@link #handleCommitNotification(CDOCommitInfo, boolean, Set)}. + * @deprecated As of 4.3 use {@link #handleCommitNotification(CommitNotificationInfo)}. */ @Deprecated public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache); @@ -208,7 +209,7 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag /** * @since 4.3 */ - public void handleCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache, Set<CDOID> readOnly); + public void handleCommitNotification(CommitNotificationInfo info); /** * @since 4.1 @@ -234,7 +235,7 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag /** * @since 4.2 - * @deprecated As of 4.3 use {@link #invalidate(CDOCommitInfo, InternalCDOTransaction, boolean, Map)}. + * @deprecated As of 4.3 use {@link #invalidate(CDOCommitInfo, InternalCDOTransaction, boolean, boolean, Map)}. */ @Deprecated public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache); @@ -243,7 +244,7 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag * @since 4.3 */ public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache, - Map<CDOID, CDOPermission> permissions); + boolean clearPermissionCache, Map<CDOID, CDOPermission> permissions); /** * @since 3.0 diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java index 1c6e6cf656..b5b9ce191e 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java @@ -534,7 +534,16 @@ public abstract class AbstractOMTest extends TestCase return; } - Assert.assertEquals(expected, actual); + try + { + Assert.assertEquals(expected, actual); + } + catch (AssertionError ex) + { + AssertionFailedError error = new AssertionFailedError(ex.getMessage()); + error.initCause(ex); + throw error; + } } public static void assertEquals(String message, Object expected, Object actual) |