diff options
author | Eike Stepper | 2021-11-07 16:09:25 +0000 |
---|---|---|
committer | Eike Stepper | 2021-11-07 16:09:25 +0000 |
commit | 4b59aab7dc765abff931aad9be0d9e9af977149b (patch) | |
tree | aaca046f0347072d0a2f225c8c1fe2607d824f78 | |
parent | c8c9b4e7c59e5adb1eb881340e81588ce19a1fb9 (diff) | |
download | cdo-4b59aab7dc765abff931aad9be0d9e9af977149b.tar.gz cdo-4b59aab7dc765abff931aad9be0d9e9af977149b.tar.xz cdo-4b59aab7dc765abff931aad9be0d9e9af977149b.zip |
[577114] Give clients a facility to let the repository authorize arbitrary operations
https://bugs.eclipse.org/bugs/show_bug.cgi?id=577114
66 files changed, 1170 insertions, 163 deletions
diff --git a/features/org.eclipse.emf.cdo.examples-feature/feature.xml b/features/org.eclipse.emf.cdo.examples-feature/feature.xml index 3e0ec7c51c..830104180d 100644 --- a/features/org.eclipse.emf.cdo.examples-feature/feature.xml +++ b/features/org.eclipse.emf.cdo.examples-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.emf.cdo.examples" label="%featureName" - version="4.5.1.qualifier" + version="4.5.2.qualifier" provider-name="%providerName" image="eclipse_update_120.jpg" license-feature="org.eclipse.emf.cdo.license" diff --git a/features/org.eclipse.emf.cdo.examples-feature/pom.xml b/features/org.eclipse.emf.cdo.examples-feature/pom.xml index ed443248f4..2bf09ea131 100644 --- a/features/org.eclipse.emf.cdo.examples-feature/pom.xml +++ b/features/org.eclipse.emf.cdo.examples-feature/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo.features</groupId> <artifactId>org.eclipse.emf.cdo.examples</artifactId> - <version>4.5.1-SNAPSHOT</version> + <version>4.5.2-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/features/org.eclipse.emf.cdo.examples.installer-feature/feature.xml b/features/org.eclipse.emf.cdo.examples.installer-feature/feature.xml index 48067d2d7a..191999807b 100644 --- a/features/org.eclipse.emf.cdo.examples.installer-feature/feature.xml +++ b/features/org.eclipse.emf.cdo.examples.installer-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.emf.cdo.examples.installer" label="%featureName" - version="4.3.6.qualifier" + version="4.3.7.qualifier" provider-name="%providerName" image="eclipse_update_120.jpg" license-feature="org.eclipse.emf.cdo.license" diff --git a/features/org.eclipse.emf.cdo.examples.installer-feature/pom.xml b/features/org.eclipse.emf.cdo.examples.installer-feature/pom.xml index 6b4d9d0d05..18879c8f9d 100644 --- a/features/org.eclipse.emf.cdo.examples.installer-feature/pom.xml +++ b/features/org.eclipse.emf.cdo.examples.installer-feature/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo.features</groupId> <artifactId>org.eclipse.emf.cdo.examples.installer</artifactId> - <version>4.3.6-SNAPSHOT</version> + <version>4.3.7-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.admin/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.admin/META-INF/MANIFEST.MF index 883ce9f117..5771645c90 100644 --- a/plugins/org.eclipse.emf.cdo.admin/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.admin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo.admin; singleton:=true -Bundle-Version: 4.3.1.qualifier +Bundle-Version: 4.3.2.qualifier Bundle-ClassPath: . Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -11,13 +11,13 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.eclipse.emf.cdo;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.emf.cdo.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.admin;version="4.3.1", - org.eclipse.emf.cdo.internal.admin;version="4.3.1"; +Export-Package: org.eclipse.emf.cdo.admin;version="4.3.2", + org.eclipse.emf.cdo.internal.admin;version="4.3.2"; x-friends:="org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.ui.admin, org.eclipse.emf.cdo.examples", - org.eclipse.emf.cdo.internal.admin.bundle;version="4.3.1";x-friends:="org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.internal.admin.protocol;version="4.3.1";x-internal:=true + org.eclipse.emf.cdo.internal.admin.bundle;version="4.3.2";x-friends:="org.eclipse.emf.cdo.tests", + org.eclipse.emf.cdo.internal.admin.protocol;version="4.3.2";x-internal:=true Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.emf.cdo.admin diff --git a/plugins/org.eclipse.emf.cdo.admin/pom.xml b/plugins/org.eclipse.emf.cdo.admin/pom.xml index 14b03185fc..2a9bc6e17d 100644 --- a/plugins/org.eclipse.emf.cdo.admin/pom.xml +++ b/plugins/org.eclipse.emf.cdo.admin/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.admin</artifactId> - <version>4.3.1-SNAPSHOT</version> + <version>4.3.2-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientRepositoryImpl.java b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientRepositoryImpl.java index eb031c08b3..3bb5b967ca 100644 --- a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientRepositoryImpl.java +++ b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientRepositoryImpl.java @@ -70,6 +70,8 @@ public class CDOAdminClientRepositoryImpl extends Notifier implements CDOAdminCl private boolean ensuringReferentialIntegrity; + private boolean authorizingOperations; + private IDGenerationLocation idGenerationLocation; private CommitInfoStorage commitInfoStorage; @@ -107,6 +109,7 @@ public class CDOAdminClientRepositoryImpl extends Notifier implements CDOAdminCl supportingUnits = in.readBoolean(); serializingCommits = in.readBoolean(); ensuringReferentialIntegrity = in.readBoolean(); + authorizingOperations = in.readBoolean(); idGenerationLocation = in.readEnum(IDGenerationLocation.class); commitInfoStorage = in.readEnum(CommitInfoStorage.class); } @@ -209,6 +212,12 @@ public class CDOAdminClientRepositoryImpl extends Notifier implements CDOAdminCl } @Override + public boolean isAuthorizingOperations() + { + return authorizingOperations; + } + + @Override public IDGenerationLocation getIDGenerationLocation() { return idGenerationLocation; diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonRepository.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonRepository.java index 2cd1c6f766..99876d3133 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonRepository.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonRepository.java @@ -135,6 +135,11 @@ public interface CDOCommonRepository extends CDOTimeProvider, IAdaptable public boolean isEnsuringReferentialIntegrity(); /** + * @since 4.15 + */ + public boolean isAuthorizingOperations(); + + /** * @since 4.2 */ public boolean waitWhileInitial(IProgressMonitor monitor); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java index 92f70c19b4..b919de07ab 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java @@ -10,6 +10,11 @@ */ package org.eclipse.emf.cdo.common; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.util.CDOClassNotFoundException; +import org.eclipse.emf.cdo.common.util.CDOPackageNotFoundException; + import org.eclipse.net4j.util.collection.Closeable; import org.eclipse.net4j.util.options.IOptions; import org.eclipse.net4j.util.options.IOptionsContainer; @@ -19,6 +24,12 @@ import org.eclipse.net4j.util.security.IUserAware; import org.eclipse.core.runtime.IAdaptable; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + /** * Abstracts the information about CDO sessions that is common to both client and server side. * @@ -41,6 +52,11 @@ public interface CDOCommonSession extends IAdaptable, IUserAware, IOptionsContai public CDOCommonView getView(int viewID); /** + * @since 4.15 + */ + public String[] authorizeOperations(AuthorizableOperation... operations); + + /** * Returns the {@link Options options} of this session. */ @Override @@ -188,4 +204,78 @@ public interface CDOCommonSession extends IAdaptable, IUserAware, IOptionsContai public LockNotificationMode getNewMode(); } } + + /** + * @author Eike Stepper + * @since 4.15 + */ + public static final class AuthorizableOperation + { + private final String id; + + private final Map<String, Object> parameters = new HashMap<>(); + + public AuthorizableOperation(String id) + { + this.id = id; + } + + public AuthorizableOperation(CDODataInput in) throws IOException + { + id = in.readString(); + + int size = in.readXInt(); + for (int i = 0; i < size; i++) + { + String key = in.readString(); + + try + { + Object object = in.readCDORevisionOrPrimitiveOrClassifier(); + parameters.put(key, object); + } + catch (CDOPackageNotFoundException e) + { + //$FALL-THROUGH$ + } + catch (CDOClassNotFoundException e) + { + //$FALL-THROUGH$ + } + } + } + + public final String getID() + { + return id; + } + + public AuthorizableOperation parameter(String key, Object value) + { + parameters.put(key, value); + return this; + } + + public Object getParameter(String key) + { + return parameters.get(key); + } + + public Map<String, Object> getParameters() + { + return Collections.unmodifiableMap(parameters); + } + + public void write(CDODataOutput out) throws IOException + { + out.writeString(id); + out.writeXInt(parameters.size()); + + for (Entry<String, Object> entry : parameters.entrySet()) + { + out.writeString(entry.getKey()); + out.writeCDORevisionOrPrimitiveOrClassifier(entry.getValue()); + } + } + } } 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 9f10380b1c..0de822d9e4 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 @@ -333,6 +333,11 @@ public interface CDOProtocolConstants */ public static final short SIGNAL_VIEW_CLOSED_NOTIFICATION = 67; + /** + * @since 4.15 + */ + public static final short SIGNAL_AUTHORIZE_OPERATIONS = 68; + // ////////////////////////////////////////////////////////////////////// // Session Refresh diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolVersion.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolVersion.java index 9666d090cb..63bd4b1d6e 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolVersion.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolVersion.java @@ -19,8 +19,9 @@ class CDOProtocolVersion static { - VALUE = 44; // SIGNAL_VIEW_CLOSED_NOTIFICATION + VALUE = 45; // SIGNAL_AUTHORIZE_OPERATIONS + // VALUE = 44; // SIGNAL_VIEW_CLOSED_NOTIFICATION // VALUE = 43; // SIGNAL_DELETE_BRANCH // VALUE = 42; // CDOPrefetcherManager, see bug 576893 // VALUE = 41; // ReconnectionSession mechanism does not update some items after a reconnection diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/AuthorizationException.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/AuthorizationException.java new file mode 100644 index 0000000000..aa508847db --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/util/AuthorizationException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.common.util; + +/** + * @author Eike Stepper + * @since 4.15 + */ +public class AuthorizationException extends CDOException +{ + private static final long serialVersionUID = 1L; + + public AuthorizationException(String message) + { + super(message); + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/AbstractRepositoryProperties.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/AbstractRepositoryProperties.java index a6d2696baa..c224f6a95b 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/AbstractRepositoryProperties.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/AbstractRepositoryProperties.java @@ -97,9 +97,7 @@ public abstract class AbstractRepositoryProperties<RECEIVER> extends Properties< } }); - add(new Property<RECEIVER>("authenticating", Messages.getString("RepositoryPropertyTester_40"), // - Messages.getString("RepositoryPropertyTester_41"), //$NON-NLS-1$ - CATEGORY_REPOSITORY) + add(new Property<RECEIVER>("authenticating") { @Override protected Object eval(RECEIVER receiver) @@ -163,6 +161,17 @@ public abstract class AbstractRepositoryProperties<RECEIVER> extends Properties< } }); + add(new Property<RECEIVER>("authorizingOperations", Messages.getString("RepositoryPropertyTester_44"), // + Messages.getString("RepositoryPropertyTester_45"), //$NON-NLS-1$ + CATEGORY_REPOSITORY) + { + @Override + protected Object eval(RECEIVER receiver) + { + return getRepository(receiver).isAuthorizingOperations(); + } + }); + add(new Property<RECEIVER>("idGenerationLocation", Messages.getString("RepositoryPropertyTester_32"), // Messages.getString("RepositoryPropertyTester_33"), //$NON-NLS-1$ CATEGORY_REPOSITORY) @@ -337,6 +346,12 @@ public abstract class AbstractRepositoryProperties<RECEIVER> extends Properties< } @Override + public boolean isAuthorizingOperations() + { + throw new UnsupportedOperationException(); + } + + @Override public boolean waitWhileInitial(IProgressMonitor monitor) { throw new UnsupportedOperationException(); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOQueryInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOQueryInfoImpl.java index a5ea1de32d..621d6e56e0 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOQueryInfoImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOQueryInfoImpl.java @@ -77,6 +77,7 @@ public class CDOQueryInfoImpl implements CDOQueryInfo for (int i = 0; i < size; i++) { String key = in.readString(); + try { Object object = in.readCDORevisionOrPrimitiveOrClassifier(); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/messages/messages.properties b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/messages/messages.properties index cf58b0d14b..c6d9047e21 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/messages/messages.properties +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/messages/messages.properties @@ -64,7 +64,7 @@ RepositoryPropertyTester_32=ID Generation Location RepositoryPropertyTester_33=One of STORE, CLIENT. RepositoryPropertyTester_38=Serialize Commits RepositoryPropertyTester_39=Whether the repository is serializing commits. -RepositoryPropertyTester_40=Authenticating -RepositoryPropertyTester_41=Whether the repository is authenticating users. RepositoryPropertyTester_42=Commit Info Storage RepositoryPropertyTester_43=One of NO, YES, WITH_MERGE_SOURCE. +RepositoryPropertyTester_44=Authorizing Operations +RepositoryPropertyTester_45=Whether the repository is authorizing operations. diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/util/AuthorizableOperations.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/util/AuthorizableOperations.java new file mode 100644 index 0000000000..b9cdf9ed50 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/util/AuthorizableOperations.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.spi.common.util; + +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; + +/** + * @author Eike Stepper + * @since 4.15 + */ +public final class AuthorizableOperations +{ + public static final String ID_BRANCH_CREATE = "org.eclipse.emf.cdo.branch.Create"; + + public static final String ID_BRANCH_RENAME = "org.eclipse.emf.cdo.branch.Rename"; + + public static final String ID_BRANCH_DELETE = "org.eclipse.emf.cdo.branch.Delete"; + + public static final String ID_TAG_CREATE = "org.eclipse.emf.cdo.tag.Create"; + + public static final String ID_TAG_RENAME = "org.eclipse.emf.cdo.tag.Rename"; + + public static final String ID_TAG_MOVE = "org.eclipse.emf.cdo.tag.Move"; + + public static final String ID_TAG_DELETE = "org.eclipse.emf.cdo.tag.Delete"; + + private AuthorizableOperations() + { + } + + public static AuthorizableOperation createBranch(int branchID, String name, int baseBranchID, long baseTimeStamp) + { + return new AuthorizableOperation(ID_BRANCH_CREATE) // + .parameter("branchID", branchID) // + .parameter("name", name) // + .parameter("baseBranchID", baseBranchID) // + .parameter("baseTimeStamp", baseTimeStamp); + } + + public static AuthorizableOperation renameBranch(int branchID, String newName) + { + return new AuthorizableOperation(ID_BRANCH_RENAME) // + .parameter("branchID", branchID) // + .parameter("newName", newName); + } + + public static AuthorizableOperation deleteBranch(int branchID) + { + return new AuthorizableOperation(ID_BRANCH_DELETE) // + .parameter("branchID", branchID); + } + + public static AuthorizableOperation createTag(String name, int branchID, long timeStamp) + { + return new AuthorizableOperation(ID_TAG_CREATE) // + .parameter("name", name) // + .parameter("branchID", branchID) // + .parameter("timeStamp", timeStamp); + } + + public static AuthorizableOperation renameTag(String oldName, String newName) + { + return new AuthorizableOperation(ID_TAG_RENAME) // + .parameter("oldName", oldName) // + .parameter("newName", newName); + } + + public static AuthorizableOperation moveTag(String name, int branchID, long timeStamp) + { + return new AuthorizableOperation(ID_TAG_MOVE) // + .parameter("name", name) // + .parameter("branchID", branchID) // + .parameter("timeStamp", timeStamp); + } + + public static AuthorizableOperation deleteTag(String name) + { + return new AuthorizableOperation(ID_TAG_DELETE) // + .parameter("name", name); + } +} diff --git a/plugins/org.eclipse.emf.cdo.examples.installer/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.examples.installer/META-INF/MANIFEST.MF index 8b611048be..c7ea55ed38 100644 --- a/plugins/org.eclipse.emf.cdo.examples.installer/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.examples.installer/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.examples.installer;singleton:=true -Bundle-Version: 4.2.6.qualifier +Bundle-Version: 4.2.7.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF index bfeaa6c9d7..94a2e56950 100644 --- a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.examples.master;singleton:=true -Bundle-Version: 4.2.3.qualifier +Bundle-Version: 4.2.4.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml index ae243569f2..c5f8340a21 100644 --- a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml @@ -39,6 +39,10 @@ <authenticator type="file" description="@config/repo1.users"/> --> + <!-- Example http://bugs.eclipse.org/577114 + <operationAuthorizer type="requireGroup" description="org.eclipse.emf.cdo.branch.Delete:Administrators,Operators"/> + --> + <!-- Example http://bugs.eclipse.org/345431 <initialPackage nsURI="http://www.eclipse.org/emf/CDO/examples/company/1.0.0"/> --> diff --git a/plugins/org.eclipse.emf.cdo.examples.installer/pom.xml b/plugins/org.eclipse.emf.cdo.examples.installer/pom.xml index 184f9c2ce3..5862825e6c 100644 --- a/plugins/org.eclipse.emf.cdo.examples.installer/pom.xml +++ b/plugins/org.eclipse.emf.cdo.examples.installer/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.examples.installer</artifactId> - <version>4.2.6-SNAPSHOT</version> + <version>4.2.7-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF index bfeaa6c9d7..94a2e56950 100644 --- a/plugins/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.examples.master/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.examples.master;singleton:=true -Bundle-Version: 4.2.3.qualifier +Bundle-Version: 4.2.4.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml index ae243569f2..c5f8340a21 100644 --- a/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml @@ -39,6 +39,10 @@ <authenticator type="file" description="@config/repo1.users"/> --> + <!-- Example http://bugs.eclipse.org/577114 + <operationAuthorizer type="requireGroup" description="org.eclipse.emf.cdo.branch.Delete:Administrators,Operators"/> + --> + <!-- Example http://bugs.eclipse.org/345431 <initialPackage nsURI="http://www.eclipse.org/emf/CDO/examples/company/1.0.0"/> --> diff --git a/plugins/org.eclipse.emf.cdo.examples.master/pom.xml b/plugins/org.eclipse.emf.cdo.examples.master/pom.xml index 2f7c60aa8e..cc0c4a6276 100644 --- a/plugins/org.eclipse.emf.cdo.examples.master/pom.xml +++ b/plugins/org.eclipse.emf.cdo.examples.master/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.examples.master</artifactId> - <version>4.2.3-SNAPSHOT</version> + <version>4.2.4-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java index f22e22b9c5..49171bf05e 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java @@ -27,7 +27,6 @@ import org.eclipse.emf.cdo.internal.ui.RunnableViewerRefresh; import org.eclipse.emf.cdo.internal.ui.ViewerUtil; import org.eclipse.emf.cdo.ui.CDOItemProvider; -import org.eclipse.net4j.signal.RemoteException; import org.eclipse.net4j.util.container.IContainerEvent; import org.eclipse.net4j.util.event.IEvent; import org.eclipse.net4j.util.event.IListener; @@ -448,15 +447,7 @@ public class CDOCheckoutContentProvider extends CDOContentProvider<CDOCheckout> catch (Exception ex) { OM.LOG.error(ex); - - if (ex instanceof RemoteException) - { - ((AbstractElement)checkout).setError(((RemoteException)ex).getOriginalMessage()); - } - else - { - ((AbstractElement)checkout).setError(ex.getMessage()); - } + ((AbstractElement)checkout).setError(ex.getLocalizedMessage()); } return Status.OK_STATUS; diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/repositories/wizards/MasterRepositoryController.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/repositories/wizards/MasterRepositoryController.java index 894b74928a..9d946fd274 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/repositories/wizards/MasterRepositoryController.java +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/repositories/wizards/MasterRepositoryController.java @@ -368,6 +368,8 @@ public class MasterRepositoryController public void cancelValidation() { + valid = false; + if (validationThread != null) { validationThread.cancel(); diff --git a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/CDORepositoryProperties.java b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/CDORepositoryProperties.java index b9d414d130..010c0c191e 100644 --- a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/CDORepositoryProperties.java +++ b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/repositories/CDORepositoryProperties.java @@ -41,6 +41,7 @@ public class CDORepositoryProperties extends Properties<CDORepository> return repository.getState(); } }); + add(new Property<CDORepository>("error") { @Override @@ -118,8 +119,7 @@ public class CDORepositoryProperties extends Properties<CDORepository> @Override protected Object eval(CDORepository repository) { - IPasswordCredentials credentials = repository.getCredentials(); - return credentials == null ? null : credentials.getUserID(); + return repository.isAuthenticating(); } }); diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java index 51a8fc60d4..ace8e84b36 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java @@ -186,6 +186,8 @@ public class CDONet4jSessionConfigurationImpl extends CDOSessionConfigurationImp private boolean ensuringReferentialIntegrity; + private boolean authorizingOperations; + private IDGenerationLocation idGenerationLocation; private CommitInfoStorage commitInfoStorage; @@ -210,6 +212,7 @@ public class CDONet4jSessionConfigurationImpl extends CDOSessionConfigurationImp supportingUnits = result.isSupportingUnits(); serializingCommits = result.isEnsuringReferentialIntegrity(); ensuringReferentialIntegrity = result.isEnsuringReferentialIntegrity(); + authorizingOperations = result.isAuthorizingOperations(); idGenerationLocation = result.getIDGenerationLocation(); commitInfoStorage = result.getCommitInfoStorage(); } @@ -359,6 +362,12 @@ public class CDONet4jSessionConfigurationImpl extends CDOSessionConfigurationImp } @Override + public boolean isAuthorizingOperations() + { + return authorizingOperations; + } + + @Override public IDGenerationLocation getIDGenerationLocation() { return idGenerationLocation; diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/AuthorizeOperationsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/AuthorizeOperationsRequest.java new file mode 100644 index 0000000000..c33eb499b7 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/AuthorizeOperationsRequest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; + +import java.io.IOException; + +/** + * @author Eike Stepper + */ +public class AuthorizeOperationsRequest extends CDOClientRequest<String[]> +{ + private AuthorizableOperation[] operations; + + public AuthorizeOperationsRequest(CDOClientProtocol protocol, AuthorizableOperation[] operations) + { + super(protocol, CDOProtocolConstants.SIGNAL_AUTHORIZE_OPERATIONS); + this.operations = operations; + } + + @Override + protected void requesting(CDODataOutput out) throws IOException + { + int length = operations.length; + out.writeXInt(length); + + for (int i = 0; i < length; i++) + { + AuthorizableOperation operation = operations[i]; + operation.write(out); + } + } + + @Override + protected String[] confirming(CDODataInput in) throws IOException + { + String[] result = new String[operations.length]; + + for (int i = 0; i < result.length; i++) + { + result[i] = in.readString(); + } + + return result; + } +} 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 dd7109f7e7..78a4066440 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 @@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.internal.net4j.protocol; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode; import org.eclipse.emf.cdo.common.branch.CDOBranch; @@ -620,6 +621,12 @@ public class CDOClientProtocol extends AuthenticatingSignalProtocol<CDOSessionIm } @Override + public String[] authorizeOperations(AuthorizableOperation[] operations) + { + return send(new AuthorizeOperationsRequest(this, operations)); + } + + @Override @Deprecated public void requestChangeCredentials() { diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/DeleteBranchRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/DeleteBranchRequest.java index 517b2d3b76..f953bbf3d9 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/DeleteBranchRequest.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/DeleteBranchRequest.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2013-2015, 2017 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2021 Eike Stepper (Loehne, 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: - * Mathieu Velten - initial API and implementation + * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.internal.net4j.protocol; @@ -21,7 +21,7 @@ import org.eclipse.net4j.util.om.monitor.OMMonitor; import java.io.IOException; /** - * @author Mathieu Velten + * @author Eike Stepper */ public class DeleteBranchRequest extends CDOClientRequestWithMonitoring<CDOBranch[]> { diff --git a/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF index d35f7add96..08221e1883 100644 --- a/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.server.admin;singleton:=true -Bundle-Version: 4.3.3.qualifier +Bundle-Version: 4.3.4.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -17,12 +17,12 @@ Require-Bundle: org.eclipse.core.runtime;resolution:=optional;bundle-version="[3 org.eclipse.emf.cdo.server.security;bundle-version="[4.3.0,5.0.0)", org.eclipse.emf.cdo.security;bundle-version="[4.3.0,5.0.0)", org.eclipse.net4j.jvm;bundle-version="[4.1.100,5.0.0)";resolution:=optional -Export-Package: org.eclipse.emf.cdo.server.admin;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin;x-internal:=true;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin.bundle;x-internal:=true;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin.protocol;x-internal:=true;version="4.3.3", - org.eclipse.emf.cdo.server.spi.admin;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin.catalog;x-internal:=true;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin.catalog.impl;x-internal:=true;version="4.3.3", - org.eclipse.emf.cdo.server.internal.admin.catalog.util;x-internal:=true;version="4.3.3" +Export-Package: org.eclipse.emf.cdo.server.admin;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin;x-internal:=true;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin.bundle;x-internal:=true;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin.protocol;x-internal:=true;version="4.3.4", + org.eclipse.emf.cdo.server.spi.admin;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin.catalog;x-internal:=true;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin.catalog.impl;x-internal:=true;version="4.3.4", + org.eclipse.emf.cdo.server.internal.admin.catalog.util;x-internal:=true;version="4.3.4" Automatic-Module-Name: org.eclipse.emf.cdo.server.admin diff --git a/plugins/org.eclipse.emf.cdo.server.admin/pom.xml b/plugins/org.eclipse.emf.cdo.server.admin/pom.xml index 950c9f5cca..8bac8f3047 100644 --- a/plugins/org.eclipse.emf.cdo.server.admin/pom.xml +++ b/plugins/org.eclipse.emf.cdo.server.admin/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.server.admin</artifactId> - <version>4.3.3-SNAPSHOT</version> + <version>4.3.4-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServerRepository.java b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServerRepository.java index 63adc70f2b..dcd1cc3f9e 100644 --- a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServerRepository.java +++ b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServerRepository.java @@ -209,6 +209,12 @@ public class CDOAdminServerRepository extends Notifier implements CDOAdminReposi } @Override + public boolean isAuthorizingOperations() + { + return delegate.isAuthorizingOperations(); + } + + @Override public boolean waitWhileInitial(IProgressMonitor monitor) { return delegate.waitWhileInitial(monitor); diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/AuthorizeOperationsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/AuthorizeOperationsIndication.java new file mode 100644 index 0000000000..794bdc8231 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/AuthorizeOperationsIndication.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.spi.server.InternalSession; + +import java.io.IOException; + +/** + * @author Eike Stepper + */ +public class AuthorizeOperationsIndication extends CDOServerReadIndication +{ + private AuthorizableOperation[] operations; + + public AuthorizeOperationsIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_AUTHORIZE_OPERATIONS); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + int length = in.readXInt(); + operations = new AuthorizableOperation[length]; + + for (int i = 0; i < length; i++) + { + operations[i] = new AuthorizableOperation(in); + } + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + InternalSession session = getSession(); + String[] result = session.authorizeOperations(operations); + + for (int i = 0; i < result.length; i++) + { + out.writeString(result[i]); + } + } +} 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 ddf9c88ad8..fb3803f916 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 @@ -472,6 +472,9 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement case SIGNAL_DELETE_BRANCH: return new DeleteBranchIndication(this); + case SIGNAL_AUTHORIZE_OPERATIONS: + return new AuthorizeOperationsIndication(this); + default: return super.createSignalReactor(signalID); } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerWriteIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerWriteIndication.java index 798472334f..9769ebfd79 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerWriteIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerWriteIndication.java @@ -47,5 +47,6 @@ public abstract class CDOServerWriteIndication extends CDOServerIndication // Make the store writer available in a ThreadLocal variable StoreThreadLocal.setAccessor(accessor); + StoreThreadLocal.setSession(getSession()); } } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/DeleteBranchIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/DeleteBranchIndication.java index f79f9244fb..8c8a5a163d 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/DeleteBranchIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/DeleteBranchIndication.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2013-2015, 2017 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2021 Eike Stepper (Loehne, 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: - * Mathieu Velten - initial API and implementation + * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.server.internal.net4j.protocol; @@ -23,7 +23,7 @@ import org.eclipse.emf.cdo.spi.server.InternalSessionManager; import org.eclipse.net4j.util.om.monitor.OMMonitor; /** - * @author Mathieu Velten + * @author Eike Stepper */ public class DeleteBranchIndication extends CDOServerReadIndicationWithMonitoring { diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java index ccfe3416ed..a2971517b6 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java @@ -175,6 +175,7 @@ public class OpenSessionIndication extends CDOServerIndicationWithMonitoring out.writeBoolean(repository.isSupportingUnits()); out.writeBoolean(repository.isSerializingCommits()); out.writeBoolean(repository.isEnsuringReferentialIntegrity()); + out.writeBoolean(repository.isAuthorizingOperations()); out.writeEnum(repository.getIDGenerationLocation()); out.writeEnum(repository.getCommitInfoStorage()); diff --git a/plugins/org.eclipse.emf.cdo.server.product/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.product/META-INF/MANIFEST.MF index 26ffcd6720..68f69b1eba 100644 --- a/plugins/org.eclipse.emf.cdo.server.product/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.product/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.server.product;singleton:=true -Bundle-Version: 4.2.3.qualifier +Bundle-Version: 4.2.4.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml index 359ec31ea2..773fddd1af 100644 --- a/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml @@ -39,6 +39,10 @@ <authenticator type="file" description="@config/repo1.users"/> --> + <!-- Example http://bugs.eclipse.org/577114 + <operationAuthorizer type="requireGroup" description="org.eclipse.emf.cdo.branch.Delete:Administrators,Operators"/> + --> + <!-- Example http://bugs.eclipse.org/345431 <initialPackage nsURI="http://www.eclipse.org/emf/CDO/examples/company/1.0.0"/> --> diff --git a/plugins/org.eclipse.emf.cdo.server.product/pom.xml b/plugins/org.eclipse.emf.cdo.server.product/pom.xml index 2cebad8701..876917bdc7 100644 --- a/plugins/org.eclipse.emf.cdo.server.product/pom.xml +++ b/plugins/org.eclipse.emf.cdo.server.product/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.server.product</artifactId> - <version>4.2.3-SNAPSHOT</version> + <version>4.2.4-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.server.security/plugin.xml b/plugins/org.eclipse.emf.cdo.server.security/plugin.xml index 8c2c252f1a..a718e91356 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/plugin.xml +++ b/plugins/org.eclipse.emf.cdo.server.security/plugin.xml @@ -42,6 +42,18 @@ productGroup="org.eclipse.emf.cdo.server.commands" type="setpassword" class="org.eclipse.emf.cdo.server.internal.security.SecurityManagerCommand$SetPassword"/> + <factory + productGroup="org.eclipse.emf.cdo.server.operationAuthorizers" + type="requireUser" + class="org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer$RequireUser$Factory"/> + <factory + productGroup="org.eclipse.emf.cdo.server.operationAuthorizers" + type="requireGroup" + class="org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer$RequireGroup$Factory"/> + <factory + productGroup="org.eclipse.emf.cdo.server.operationAuthorizers" + type="requireRole" + class="org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer$RequireRole$Factory"/> </extension> </plugin> diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/RealmOperationAuthorizer.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/RealmOperationAuthorizer.java new file mode 100644 index 0000000000..2edfa8b9c4 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/RealmOperationAuthorizer.java @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.server.internal.security; + +import org.eclipse.emf.cdo.common.CDOCommonSession; +import org.eclipse.emf.cdo.security.Group; +import org.eclipse.emf.cdo.security.Realm; +import org.eclipse.emf.cdo.security.Role; +import org.eclipse.emf.cdo.security.SecurityItem; +import org.eclipse.emf.cdo.security.User; +import org.eclipse.emf.cdo.server.IRepository; +import org.eclipse.emf.cdo.server.ISession; +import org.eclipse.emf.cdo.server.security.ISecurityManager; +import org.eclipse.emf.cdo.server.security.SecurityManagerUtil; +import org.eclipse.emf.cdo.spi.server.AbstractOperationAuthorizer; +import org.eclipse.emf.cdo.spi.server.IOperationAuthorizer; + +import org.eclipse.net4j.util.factory.ProductCreationException; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public abstract class RealmOperationAuthorizer<T extends SecurityItem> extends AbstractOperationAuthorizer +{ + private final Set<String> itemIDs; + + public RealmOperationAuthorizer(String operationID, Set<String> itemIDs) + { + super(operationID); + this.itemIDs = itemIDs; + } + + public final Set<String> getItemIDs() + { + return itemIDs; + } + + @Override + protected String authorizeOperation(CDOCommonSession session, Map<String, Object> parameters) + { + IRepository repository = ((ISession)session).getManager().getRepository(); + ISecurityManager securityManager = SecurityManagerUtil.getSecurityManager(repository); + if (securityManager == null) + { + return "No security manager"; + } + + Realm realm = securityManager.getRealm(); + if (realm == null) + { + return "No realm"; + } + + String userID = session.getUserID(); + if (userID == null) + { + return "No user ID"; + } + + User user = realm.getUser(userID); + if (user == null) + { + return "User " + userID + " not authenticated"; + } + + Collection<T> items = getItemsOfUser(user); + for (T item : items) + { + if (itemIDs.contains(getID(item))) + { + return null; + } + } + + return "User " + userID + " is not authorized"; + } + + protected abstract Collection<T> getItemsOfUser(User user); + + protected abstract String getID(T item); + + /** + * @author Eike Stepper + */ + public static abstract class Factory extends org.eclipse.emf.cdo.spi.server.AbstractOperationAuthorizer.Factory + { + public Factory(String type) + { + super(type); + } + + @Override + protected IOperationAuthorizer create(String operationID, String description) throws ProductCreationException + { + Set<String> itemIDs = new HashSet<>(); + + if (description != null) + { + for (String itemID : description.split(",")) + { + itemID = itemID.trim(); + if (itemID.length() != 0) + { + itemIDs.add(itemID); + } + } + } + + return create(operationID, itemIDs); + } + + protected abstract IOperationAuthorizer create(String operationID, Set<String> itemIDs) throws ProductCreationException; + } + + /** + * @author Eike Stepper + */ + public static final class RequireUser extends RealmOperationAuthorizer<User> + { + public RequireUser(String operationID, Set<String> itemIDs) + { + super(operationID, itemIDs); + } + + @Override + protected Collection<User> getItemsOfUser(User user) + { + return Collections.singleton(user); + } + + @Override + protected String getID(User user) + { + return user.getId(); + } + + /** + * @author Eike Stepper + */ + public static final class Factory extends org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer.Factory + { + public static final String TYPE = "requireUser"; + + public Factory() + { + super(TYPE); + } + + @Override + protected IOperationAuthorizer create(String operationID, Set<String> itemIDs) throws ProductCreationException + { + return new RequireUser(operationID, itemIDs); + } + } + } + + /** + * @author Eike Stepper + */ + public static final class RequireGroup extends RealmOperationAuthorizer<Group> + { + public RequireGroup(String operationID, Set<String> itemIDs) + { + super(operationID, itemIDs); + } + + @Override + protected Collection<Group> getItemsOfUser(User user) + { + return user.getAllGroups(); + } + + @Override + protected String getID(Group group) + { + return group.getId(); + } + + /** + * @author Eike Stepper + */ + public static final class Factory extends org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer.Factory + { + public static final String TYPE = "requireGroup"; + + public Factory() + { + super(TYPE); + } + + @Override + protected IOperationAuthorizer create(String operationID, Set<String> itemIDs) throws ProductCreationException + { + return new RequireGroup(operationID, itemIDs); + } + } + } + + /** + * @author Eike Stepper + */ + public static final class RequireRole extends RealmOperationAuthorizer<Role> + { + public RequireRole(String operationID, Set<String> itemIDs) + { + super(operationID, itemIDs); + } + + @Override + protected Collection<Role> getItemsOfUser(User user) + { + return user.getAllRoles(); + } + + @Override + protected String getID(Role role) + { + return role.getId(); + } + + /** + * @author Eike Stepper + */ + public static final class Factory extends org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer.Factory + { + public static final String TYPE = "requireRole"; + + public Factory() + { + super(TYPE); + } + + @Override + protected IOperationAuthorizer create(String operationID, Set<String> itemIDs) throws ProductCreationException + { + return new RequireRole(operationID, itemIDs); + } + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/SecurityManagerUtil.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/SecurityManagerUtil.java index f6f46d4aae..fc8ee17a07 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/SecurityManagerUtil.java +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/security/SecurityManagerUtil.java @@ -11,6 +11,7 @@ package org.eclipse.emf.cdo.server.security; import org.eclipse.emf.cdo.server.IRepository; +import org.eclipse.emf.cdo.server.internal.security.RealmOperationAuthorizer; import org.eclipse.emf.cdo.server.internal.security.SecurityManager; import org.eclipse.emf.cdo.server.spi.security.AnnotationHandler; import org.eclipse.emf.cdo.server.spi.security.HomeFolderHandler; @@ -55,5 +56,8 @@ public final class SecurityManagerUtil container.registerFactory(new SecurityManagerFactory.Annotation()); container.registerFactory(new AnnotationHandler.Factory()); container.registerFactory(new HomeFolderHandler.Factory()); + container.registerFactory(new RealmOperationAuthorizer.RequireUser.Factory()); + container.registerFactory(new RealmOperationAuthorizer.RequireGroup.Factory()); + container.registerFactory(new RealmOperationAuthorizer.RequireRole.Factory()); } } 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 3b7044aee7..bd363ce6cf 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 @@ -15,6 +15,8 @@ */ package org.eclipse.emf.cdo.internal.server; +import org.eclipse.emf.cdo.common.CDOCommonSession; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; import org.eclipse.emf.cdo.common.CDOCommonView; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchHandler; @@ -45,6 +47,7 @@ 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.CDORevisionUtil; +import org.eclipse.emf.cdo.common.util.AuthorizationException; import org.eclipse.emf.cdo.common.util.CDOCommonUtil; import org.eclipse.emf.cdo.common.util.CDOException; import org.eclipse.emf.cdo.common.util.CDOQueryInfo; @@ -89,8 +92,10 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager; import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision; import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo; +import org.eclipse.emf.cdo.spi.common.util.AuthorizableOperations; import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider; import org.eclipse.emf.cdo.spi.server.ICommitConflictResolver; +import org.eclipse.emf.cdo.spi.server.IOperationAuthorizer; import org.eclipse.emf.cdo.spi.server.InternalCommitContext; import org.eclipse.emf.cdo.spi.server.InternalCommitManager; import org.eclipse.emf.cdo.spi.server.InternalLockManager; @@ -231,6 +236,8 @@ public class Repository extends Container<Object> implements InternalRepository private IQueryHandlerProvider queryHandlerProvider; + private List<IOperationAuthorizer> operationAuthorizers = new ArrayList<>(); + private IManagedContainer container; private final List<ReadAccessHandler> readAccessHandlers = new ArrayList<>(); @@ -501,6 +508,8 @@ public class Repository extends Container<Object> implements InternalRepository branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp); } + authorizeOperation(AuthorizableOperations.createBranch(branchID, branchInfo.getName(), branchInfo.getBaseBranchID(), branchInfo.getBaseTimeStamp())); + synchronized (createBranchLock) { IStoreAccessor accessor = StoreThreadLocal.getAccessor(); @@ -548,6 +557,8 @@ public class Repository extends Container<Object> implements InternalRepository throw new UnsupportedOperationException("Branch deletion is not supported by " + this); } + authorizeOperation(AuthorizableOperations.deleteBranch(branchID)); + synchronized (createBranchLock) { CDOBranch[] branches = ((BranchLoader5)accessor).deleteBranches(branchID, monitor); @@ -568,8 +579,8 @@ public class Repository extends Container<Object> implements InternalRepository } } - InternalCDORevisionCache cache = getRevisionManager().getCache(); - cache.removeRevisions(branches); + InternalCDORevisionCache revisionCache = getRevisionManager().getCache(); + revisionCache.removeRevisions(branches); return branches; } @@ -608,6 +619,8 @@ public class Repository extends Container<Object> implements InternalRepository throw new UnsupportedOperationException("Branch renaming is not supported by " + this); } + authorizeOperation(AuthorizableOperations.renameBranch(branchID, newName)); + synchronized (createBranchLock) { ((BranchLoader3)accessor).renameBranch(branchID, oldName, newName); @@ -636,6 +649,26 @@ public class Repository extends Container<Object> implements InternalRepository branchPoint = branchPoint.getBranch().getPoint(getTimeStamp()); } + switch (InternalCDOBranchManager.getTagChangeKind(oldName, newName, branchPoint)) + { + case CREATED: + authorizeOperation(AuthorizableOperations.createTag(newName, branchPoint.getBranch().getID(), branchPoint.getTimeStamp())); + break; + + case RENAMED: + authorizeOperation(AuthorizableOperations.renameTag(oldName, newName)); + break; + + case MOVED: + authorizeOperation(AuthorizableOperations.moveTag(oldName, branchPoint.getBranch().getID(), branchPoint.getTimeStamp())); + break; + + case DELETED: + authorizeOperation(AuthorizableOperations.deleteTag(oldName)); + break; + + } + ((BranchLoader4)accessor).changeTag(modCount, oldName, newName, branchPoint); InternalSession sender = null; @@ -1545,6 +1578,65 @@ public class Repository extends Container<Object> implements InternalRepository } @Override + public void addOperationAuthorizer(IOperationAuthorizer operationAuthorizer) + { + checkInactive(); + operationAuthorizers.add(operationAuthorizer); + } + + @Override + public boolean isAuthorizingOperations() + { + return !operationAuthorizers.isEmpty(); + } + + @Override + public String authorizeOperation(CDOCommonSession session, AuthorizableOperation operation) + { + if (session == null) + { + return "No session"; + } + + for (IOperationAuthorizer authorizer : operationAuthorizers) + { + try + { + String result = authorizer.authorizeOperation(session, operation); + if (result != null) + { + return result; + } + } + catch (Error ex) + { + throw ex; + } + catch (Throwable t) + { + OM.LOG.error(t); + } + } + + // No veto -> authorized. + return null; + } + + protected final void authorizeOperation(AuthorizableOperation operation) throws AuthorizationException + { + if (isAuthorizingOperations()) + { + InternalSession session = StoreThreadLocal.getSession(); + + String denial = authorizeOperation(session, operation); + if (denial != null) + { + throw new AuthorizationException(denial); + } + } + } + + @Override public IManagedContainer getContainer() { if (container == null) 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 d4c871e5f9..5fdfff550c 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 @@ -1004,6 +1004,18 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd } @Override + public boolean isAuthorizingOperations() + { + return repository.isAuthorizingOperations(); + } + + @Override + public String[] authorizeOperations(AuthorizableOperation... operations) + { + return internalSession.authorizeOperations(operations); + } + + @Override public void handleRepositoryTypeChanged(Type oldType, Type newType) { } 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 e3f8cca5cd..fd0d918a3d 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 @@ -44,6 +44,7 @@ import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage; import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager; +import org.eclipse.emf.cdo.spi.server.IOperationAuthorizer; import org.eclipse.emf.cdo.spi.server.ISessionProtocol; import org.eclipse.emf.cdo.spi.server.InternalLockManager; import org.eclipse.emf.cdo.spi.server.InternalRepository; @@ -508,6 +509,21 @@ public class Session extends Container<IView> implements InternalSession } @Override + public String[] authorizeOperations(AuthorizableOperation... operations) + { + String[] result = new String[operations.length]; + IOperationAuthorizer authorizer = getRepository(); + + for (int i = 0; i < operations.length; i++) + { + AuthorizableOperation operation = operations[i]; + result[i] = authorizer.authorizeOperation(this, operation); + } + + return result; + } + + @Override public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext) { IPermissionManager permissionManager = manager.getPermissionManager(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/AbstractOperationAuthorizer.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/AbstractOperationAuthorizer.java new file mode 100644 index 0000000000..49e5f96e67 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/AbstractOperationAuthorizer.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.spi.server; + +import org.eclipse.emf.cdo.common.CDOCommonSession; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; + +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.factory.ProductCreationException; + +import java.util.Map; +import java.util.Objects; + +/** + * @author Eike Stepper + * @since 4.15 + */ +public abstract class AbstractOperationAuthorizer implements IOperationAuthorizer +{ + private final String operationID; + + public AbstractOperationAuthorizer(String operationID) + { + this.operationID = operationID; + } + + public final String getOperationID() + { + return operationID; + } + + @Override + public String authorizeOperation(CDOCommonSession session, AuthorizableOperation operation) + { + if (!Objects.equals(operationID, operation.getID())) + { + return null; + } + + Map<String, Object> parameters = operation.getParameters(); + return authorizeOperation(session, parameters); + } + + protected abstract String authorizeOperation(CDOCommonSession session, Map<String, Object> parameters); + + /** + * @author Eike Stepper + */ + public static abstract class Factory extends OperationAuthorizerFactory + { + public Factory(String type) + { + super(type); + } + + @Override + public IOperationAuthorizer create(String description) throws ProductCreationException + { + if (StringUtil.isEmpty(description)) + { + throw new ProductCreationException("No description: " + this); + } + + int colon = description.indexOf(':'); + String operationID = colon == -1 ? description : description.substring(0, colon); + description = colon == -1 ? null : description.substring(colon + 1); + return create(operationID, description); + } + + protected abstract IOperationAuthorizer create(String operationID, String description) throws ProductCreationException; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/IOperationAuthorizer.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/IOperationAuthorizer.java new file mode 100644 index 0000000000..a59a3b4a1c --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/IOperationAuthorizer.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.spi.server; + +import org.eclipse.emf.cdo.common.CDOCommonSession; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; + +/** + * @author Eike Stepper + * @since 4.15 + */ +public interface IOperationAuthorizer +{ + public String authorizeOperation(CDOCommonSession session, AuthorizableOperation operation); +} 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 80a2789c58..7467ae9a74 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 @@ -79,6 +79,7 @@ public interface InternalRepository extends IRepository, // RevisionLoader2, // CommitInfoLoader, // CDORevisionUnchunker, // + IOperationAuthorizer, // IExecutorServiceProvider, // IManagedContainerProvider { @@ -170,6 +171,11 @@ public interface InternalRepository extends IRepository, // public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider); /** + * @since 4.15 + */ + public void addOperationAuthorizer(IOperationAuthorizer operationAuthorizer); + + /** * @since 4.3 */ public void setContainer(IManagedContainer container); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/OperationAuthorizerFactory.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/OperationAuthorizerFactory.java new file mode 100644 index 0000000000..2677118e1a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/OperationAuthorizerFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.spi.server; + +import org.eclipse.net4j.util.factory.Factory; +import org.eclipse.net4j.util.factory.ProductCreationException; + +/** + * If the meaning of this type isn't clear, there really should be more of a description here... + * + * @author Eike Stepper + * @since 4.15 + */ +public abstract class OperationAuthorizerFactory extends Factory +{ + public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.operationAuthorizers"; //$NON-NLS-1$ + + public OperationAuthorizerFactory(String type) + { + super(PRODUCT_GROUP, type); + } + + /** + * @since 3.0 + */ + @Override + public abstract IOperationAuthorizer create(String description) throws ProductCreationException; +} diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/RepositoryConfigurator.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/RepositoryConfigurator.java index b51727b7f0..4e9a342d4f 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/RepositoryConfigurator.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/RepositoryConfigurator.java @@ -242,6 +242,7 @@ public class RepositoryConfigurator implements IManagedContainerProvider setUserManager(repository, repositoryConfig); setAuthenticator(repository, repositoryConfig); + addOperationAuthorizers(repository, repositoryConfig); setActivityLog(repository, repositoryConfig); EPackage[] initialPackages = getInitialPackages(repositoryConfig); @@ -362,6 +363,49 @@ public class RepositoryConfigurator implements IManagedContainerProvider } /** + * @since 4.15 + */ + protected void addOperationAuthorizers(InternalRepository repository, Element repositoryConfig) throws CoreException + { + NodeList children = repositoryConfig.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) + { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) + { + Element childElement = (Element)child; + if (childElement.getNodeName().equalsIgnoreCase("operationAuthorizer"))//$NON-NLS-1$ + { + String type = getAttribute(childElement, "type"); //$NON-NLS-1$ + if (type == null) + { + throw new IllegalStateException("type missing for operationAuthorizer element"); //$NON-NLS-1$ + } + + String description = getAttribute(childElement, "description"); //$NON-NLS-1$ + + IOperationAuthorizer authorizer = getOperationAuthorizer(type, description); + repository.addOperationAuthorizer(authorizer); + } + } + } + } + + /** + * @since 4.15 + */ + protected IOperationAuthorizer getOperationAuthorizer(String type, String description) throws CoreException + { + IOperationAuthorizer authorizer = (IOperationAuthorizer)container.getElement(OperationAuthorizerFactory.PRODUCT_GROUP, type, description); + if (authorizer == null) + { + throw new IllegalStateException("Operation authorizer factory not found: " + type); //$NON-NLS-1$ + } + + return authorizer; + } + + /** * @since 4.7 */ protected void setActivityLog(InternalRepository repository, Element repositoryConfig) diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/CreateBranchHandler.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/CreateBranchHandler.java index 65ddb959b0..f9d2646100 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/CreateBranchHandler.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/CreateBranchHandler.java @@ -78,6 +78,12 @@ public class CreateBranchHandler extends AbstractBaseHandler<CDOBranchCreationCo } } + @Override + protected String getErrorMessage(Exception ex) + { + return "Branch " + name + " could not be created."; + } + public static String getValidChildName(CDOBranch branch) { Set<String> names = new HashSet<>(); diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/DeleteBranchHandler.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/DeleteBranchHandler.java index 7e74167dda..17d89d89f0 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/DeleteBranchHandler.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/handlers/DeleteBranchHandler.java @@ -46,13 +46,12 @@ public class DeleteBranchHandler extends AbstractBaseHandler<CDOBranch> @Override protected void doExecute(IProgressMonitor monitor) throws Exception { - try - { - branch.delete(new EclipseMonitor(monitor)); - } - finally - { - branch = null; - } + branch.delete(new EclipseMonitor(monitor)); + } + + @Override + protected String getErrorMessage(Exception ex) + { + return "Branch " + branch.getName() + " could not be deleted."; } } 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 a7df7aa22a..30e5f0c13d 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 @@ -710,6 +710,18 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme return null; } + @Override + public String[] authorizeOperations(AuthorizableOperation... operations) + { + if (repositoryInfo.isAuthorizingOperations()) + { + return sessionProtocol.authorizeOperations(operations); + } + + // No vetoes -> authorized. + return new String[operations.length]; + } + /** * @since 2.0 */ diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java index 4e70e032ab..875cbb1075 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java @@ -12,6 +12,7 @@ package org.eclipse.emf.internal.cdo.session; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode; import org.eclipse.emf.cdo.common.branch.CDOBranch; @@ -1144,6 +1145,23 @@ public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionPr } @Override + public String[] authorizeOperations(AuthorizableOperation[] operations) + { + int attempt = 0; + for (;;) + { + try + { + return delegate.authorizeOperations(operations); + } + catch (Exception ex) + { + handleException(++attempt, ex); + } + } + } + + @Override @Deprecated public void requestChangeCredentials() { 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 ba9f735e65..b97e6b8c7c 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 @@ -14,6 +14,7 @@ package org.eclipse.emf.spi.cdo; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.common.CDOCommonRepository; +import org.eclipse.emf.cdo.common.CDOCommonSession.AuthorizableOperation; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode; import org.eclipse.emf.cdo.common.branch.CDOBranch; @@ -327,6 +328,11 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo public Map<CDORevision, CDOPermission> loadPermissions(InternalCDORevision[] revisions); /** + * @since 4.15 + */ + public String[] authorizeOperations(AuthorizableOperation[] operations); + + /** * Requests that the server initiate the change-credentials protocol. * This is an optional session protocol operation. * @@ -417,6 +423,8 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo private boolean ensuringReferentialIntegrity; + private boolean authorizingOperations; + private final List<InternalCDOPackageUnit> packageUnits = new ArrayList<>(); private IDGenerationLocation idGenerationLocation; @@ -455,6 +463,7 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo supportingUnits = in.readBoolean(); serializingCommits = in.readBoolean(); ensuringReferentialIntegrity = in.readBoolean(); + authorizingOperations = in.readBoolean(); idGenerationLocation = in.readEnum(IDGenerationLocation.class); commitInfoStorage = in.readEnum(CommitInfoStorage.class); @@ -629,6 +638,15 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo } /** + * @since 4.15 + */ + @Override + public boolean isAuthorizingOperations() + { + return authorizingOperations; + } + + /** * @since 4.5 */ @Override diff --git a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF index 9e760400d8..c05b81e68f 100644 --- a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.net4j.util.ui;singleton:=true -Bundle-Version: 3.11.2.qualifier +Bundle-Version: 3.12.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-ActivationPolicy: lazy @@ -15,20 +15,20 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport, org.eclipse.net4j.ui.shared;bundle-version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.net4j.util.internal.ui;version="3.11.2";x-internal:=true, - org.eclipse.net4j.util.internal.ui.actions;version="3.11.2";x-internal:=true, - org.eclipse.net4j.util.internal.ui.bundle;version="3.11.2";x-internal:=true, - org.eclipse.net4j.util.internal.ui.messages;version="3.11.2";x-internal:=true, - org.eclipse.net4j.util.internal.ui.views;version="3.11.2";x-internal:=true, - org.eclipse.net4j.util.ui;version="3.11.2", - org.eclipse.net4j.util.ui.actions;version="3.11.2", - org.eclipse.net4j.util.ui.confirmation;version="3.11.2", - org.eclipse.net4j.util.ui.container;version="3.11.2", - org.eclipse.net4j.util.ui.dnd;version="3.11.2", - org.eclipse.net4j.util.ui.handlers;version="3.11.2", - org.eclipse.net4j.util.ui.prefs;version="3.11.2", - org.eclipse.net4j.util.ui.proposals;version="3.11.2", - org.eclipse.net4j.util.ui.security;version="3.11.2", - org.eclipse.net4j.util.ui.views;version="3.11.2", - org.eclipse.net4j.util.ui.widgets;version="3.11.2" +Export-Package: org.eclipse.net4j.util.internal.ui;version="3.12.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.actions;version="3.12.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.bundle;version="3.12.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.messages;version="3.12.0";x-internal:=true, + org.eclipse.net4j.util.internal.ui.views;version="3.12.0";x-internal:=true, + org.eclipse.net4j.util.ui;version="3.12.0", + org.eclipse.net4j.util.ui.actions;version="3.12.0", + org.eclipse.net4j.util.ui.confirmation;version="3.12.0", + org.eclipse.net4j.util.ui.container;version="3.12.0", + org.eclipse.net4j.util.ui.dnd;version="3.12.0", + org.eclipse.net4j.util.ui.handlers;version="3.12.0", + org.eclipse.net4j.util.ui.prefs;version="3.12.0", + org.eclipse.net4j.util.ui.proposals;version="3.12.0", + org.eclipse.net4j.util.ui.security;version="3.12.0", + org.eclipse.net4j.util.ui.views;version="3.12.0", + org.eclipse.net4j.util.ui.widgets;version="3.12.0" Automatic-Module-Name: org.eclipse.net4j.util.ui diff --git a/plugins/org.eclipse.net4j.util.ui/pom.xml b/plugins/org.eclipse.net4j.util.ui/pom.xml index fdf89e1beb..95019cc774 100644 --- a/plugins/org.eclipse.net4j.util.ui/pom.xml +++ b/plugins/org.eclipse.net4j.util.ui/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.net4j.util.ui</artifactId> - <version>3.11.2-SNAPSHOT</version> + <version>3.12.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningAction.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningAction.java index 9554d17c2c..76d33002d2 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningAction.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningAction.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; @@ -195,12 +196,15 @@ public abstract class LongRunningAction extends SafeAction try { doRun(progressMonitor); - return Status.OK_STATUS; } catch (Exception ex) { - return new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex); + OM.LOG.error(ex); + UIUtil.asyncExec(() -> ErrorDialog.openError(getShell(), getErrorTitle(ex), getErrorMessage(ex), + new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex))); } + + return Status.OK_STATUS; } }.schedule(); } @@ -222,6 +226,22 @@ public abstract class LongRunningAction extends SafeAction } /** + * @since 3.12 + */ + protected String getErrorTitle(Exception ex) + { + return "Problem Occurred"; + } + + /** + * @since 3.12 + */ + protected String getErrorMessage(Exception ex) + { + return ex.getLocalizedMessage(); + } + + /** * @since 2.0 */ protected abstract void doRun(IProgressMonitor progressMonitor) throws Exception; diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningActionDelegate.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningActionDelegate.java index d9ddca746a..6bf9a3649a 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningActionDelegate.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/actions/LongRunningActionDelegate.java @@ -12,11 +12,13 @@ package org.eclipse.net4j.util.ui.actions; import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; import org.eclipse.net4j.util.internal.ui.bundle.OM; +import org.eclipse.net4j.util.ui.UIUtil; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.ErrorDialog; /** * @author Eike Stepper @@ -69,13 +71,15 @@ public abstract class LongRunningActionDelegate extends SafeActionDelegate try { doRun(progressMonitor); - return Status.OK_STATUS; } catch (Exception ex) { OM.LOG.error(ex); - return new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex); + UIUtil.asyncExec(() -> ErrorDialog.openError(getShell(), getErrorTitle(ex), getErrorMessage(ex), + new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex))); } + + return Status.OK_STATUS; } }.schedule(); } @@ -96,6 +100,22 @@ public abstract class LongRunningActionDelegate extends SafeActionDelegate } /** + * @since 3.12 + */ + protected String getErrorTitle(Exception ex) + { + return "Problem Occurred"; + } + + /** + * @since 3.12 + */ + protected String getErrorMessage(Exception ex) + { + return ex.getLocalizedMessage(); + } + + /** * @since 2.0 */ protected abstract void doRun(IProgressMonitor progressMonitor) throws Exception; diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/handlers/LongRunningHandler.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/handlers/LongRunningHandler.java index b906d2fd4e..85caed7d1c 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/handlers/LongRunningHandler.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/handlers/LongRunningHandler.java @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.ui.handlers; import org.eclipse.net4j.util.internal.ui.bundle.OM; +import org.eclipse.net4j.util.ui.UIUtil; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.runtime.IProgressMonitor; @@ -19,6 +20,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.ui.handlers.HandlerUtil; /** * @author Eike Stepper @@ -74,13 +77,15 @@ public abstract class LongRunningHandler extends SafeHandler try { doExecute(event, progressMonitor); - return Status.OK_STATUS; } catch (Exception ex) { OM.LOG.error(ex); - return new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex); + UIUtil.asyncExec(() -> ErrorDialog.openError(HandlerUtil.getActiveShell(event), getErrorTitle(ex), getErrorMessage(ex), + new Status(IStatus.ERROR, getBundleID(), ex.getMessage(), ex))); } + + return Status.OK_STATUS; } }.schedule(); } @@ -95,6 +100,22 @@ public abstract class LongRunningHandler extends SafeHandler } /** + * @since 3.12 + */ + protected String getErrorTitle(Exception ex) + { + return "Problem Occurred"; + } + + /** + * @since 3.12 + */ + protected String getErrorMessage(Exception ex) + { + return ex.getLocalizedMessage(); + } + + /** * @since 3.5 */ protected void preRun(ExecutionEvent event) throws Exception diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/IndicationWithResponse.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/IndicationWithResponse.java index 3d8e7c4860..edef96fa42 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/IndicationWithResponse.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/IndicationWithResponse.java @@ -12,7 +12,6 @@ package org.eclipse.net4j.signal; import org.eclipse.net4j.buffer.BufferInputStream; import org.eclipse.net4j.buffer.BufferOutputStream; -import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; @@ -60,7 +59,7 @@ public abstract class IndicationWithResponse extends SignalReactor */ protected String getExceptionMessage(Throwable t) { - return StringUtil.formatException(t); + return t.getLocalizedMessage(); } @Override @@ -111,10 +110,9 @@ public abstract class IndicationWithResponse extends SignalReactor SignalProtocol<?> protocol = getProtocol(); int correlationID = -getCorrelationID(); String message = getExceptionMessage(t); - String originalMessage = t.getMessage(); - final boolean closeChannel = closeChannelAfterException(); + boolean closeChannel = closeChannelAfterException(); - RemoteExceptionRequest request = new RemoteExceptionRequest(protocol, correlationID, responding, message, originalMessage, t) + RemoteExceptionRequest request = new RemoteExceptionRequest(protocol, correlationID, responding, message, t) { @Override protected boolean closeChannelAfterMe() diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java index 3b209aaf61..0f0be3b5c7 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java @@ -26,49 +26,29 @@ public class RemoteException extends RuntimeException private StackTraceElement[] localStackTrace; - private final String originalMessage; - /** * @since 4.0 */ public RemoteException(Throwable remoteCause, RequestWithConfirmation<?> localRequest, boolean whileResponding) { - super(remoteCause); + super(remoteCause.getMessage(), remoteCause); this.localRequest = localRequest; this.whileResponding = whileResponding; - originalMessage = remoteCause.getMessage(); } - /** - * @since 4.13 - */ - public RemoteException(String message, String originalMessage, boolean whileResponding) + public RemoteException(String message, boolean whileResponding) { super(message); - this.originalMessage = originalMessage; this.whileResponding = whileResponding; localRequest = null; } - public RemoteException(String message, boolean whileResponding) - { - this(message, getFirstLine(message), whileResponding); - } - public boolean whileResponding() { return whileResponding; } /** - * @since 4.13 - */ - public final String getOriginalMessage() - { - return originalMessage; - } - - /** * @since 4.0 */ public RequestWithConfirmation<?> getLocalRequest() @@ -94,25 +74,4 @@ public class RemoteException extends RuntimeException { return localStackTrace; } - - static String getFirstLine(String message) - { - if (message == null) - { - return null; - } - - int nl = message.indexOf('\n'); - if (nl == -1) - { - nl = message.length(); - } - - if (nl > 100) - { - nl = 100; - } - - return message.substring(0, nl); - } } diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java index 9ef0667d92..23a32d2672 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionIndication.java @@ -12,17 +12,12 @@ package org.eclipse.net4j.signal; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedIOUtil; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.internal.net4j.bundle.OM; /** * @author Eike Stepper */ class RemoteExceptionIndication extends Indication { - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SIGNAL, RemoteExceptionIndication.class); - private Throwable t; public RemoteExceptionIndication(SignalProtocol<?> protocol) @@ -36,11 +31,6 @@ class RemoteExceptionIndication extends Indication int correlationID = in.readInt(); boolean responding = in.readBoolean(); String message = in.readString(); - String originalMessage = in.readString(); - if (TRACER.isEnabled()) - { - TRACER.format("Reading remote exception for signal {0}: {1}", correlationID, originalMessage); //$NON-NLS-1$ - } try { @@ -53,7 +43,7 @@ class RemoteExceptionIndication extends Indication if (t == null) { - t = new RemoteException(message, originalMessage, responding); + t = new RemoteException(message, responding); } SignalProtocol<?> protocol = getProtocol(); diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java index 415fc680da..f9d8f9bba8 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteExceptionRequest.java @@ -12,38 +12,25 @@ package org.eclipse.net4j.signal; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; import org.eclipse.net4j.util.io.ExtendedIOUtil; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.internal.net4j.bundle.OM; /** * @author Eike Stepper */ class RemoteExceptionRequest extends Request { - public static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SIGNAL, RemoteExceptionRequest.class); - private final int correlationID; private final boolean responding; private final String message; - private final String originalMessage; - private final Throwable t; public RemoteExceptionRequest(SignalProtocol<?> protocol, int correlationID, boolean responding, String message, Throwable t) { - this(protocol, correlationID, responding, message, RemoteException.getFirstLine(message), t); - } - - public RemoteExceptionRequest(SignalProtocol<?> protocol, int correlationID, boolean responding, String message, String originalMessage, Throwable t) - { super(protocol, SignalProtocol.SIGNAL_REMOTE_EXCEPTION); this.correlationID = correlationID; this.message = message; - this.originalMessage = originalMessage; this.t = t; this.responding = responding; } @@ -51,15 +38,9 @@ class RemoteExceptionRequest extends Request @Override protected void requesting(ExtendedDataOutputStream out) throws Exception { - if (TRACER.isEnabled()) - { - TRACER.format("Writing remote exception for signal {0}: {1}", correlationID, originalMessage); //$NON-NLS-1$ - } - out.writeInt(correlationID); out.writeBoolean(responding); out.writeString(message); - out.writeString(originalMessage); out.writeByteArray(ExtendedIOUtil.serializeThrowable(t)); } } |