diff options
30 files changed, 977 insertions, 31 deletions
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 2b2dd3bc92..7a23108916 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -10,6 +10,7 @@ * Simon McDuff - bug 230832 * Simon McDuff - bug 233490 * Simon McDuff - bug 213402 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.common.protocol; @@ -28,9 +29,9 @@ public interface CDOProtocolConstants /** * @since 4.2 */ - public static final int PROTOCOL_VERSION = 17; // Make query fail in sequence + public static final int PROTOCOL_VERSION = 18; // Password change protocol - // public static final int PROTOCOL_VERSION = 16; // Last update for permission transfers + // public static final int PROTOCOL_VERSION = 17; // Last update for make query fail in sequence // ////////////////////////////////////////////////////////////////////// // Signal IDs @@ -259,6 +260,24 @@ public interface CDOProtocolConstants */ public static final short SIGNAL_LOAD_PERMISSIONS = 55; + /** + * Server's request to the client for new credentials. + * + * @since 4.3 + * + * @see #SIGNAL_REQUEST_CHANGE_CREDENTIALS + */ + public static final short SIGNAL_CHANGE_CREDENTIALS = 56; + + /** + * Client's request to the server to initiate a change-credentials operation. + * + * @since 4.3 + * + * @see #SIGNAL_CHANGE_CREDENTIALS + */ + public static final short SIGNAL_REQUEST_CHANGE_CREDENTIALS = 57; + // ////////////////////////////////////////////////////////////////////// // Session Refresh diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java index 59e503531a..a485c942f9 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -13,6 +13,7 @@ * Simon McDuff - bug 213402 * Victor Roldan Betancort - maintenance * Andre Dietisheim - bug 256649 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.net4j; @@ -294,6 +295,14 @@ public class CDONet4jSessionImpl extends CDOSessionImpl implements org.eclipse.e getPackageRegistry().deactivate(); } + public void changeCredentials() + { + // send a request to the server to initiate (from the server) the password change protocol + CDOSessionProtocol sessionProtocol = getSessionProtocol(); + + sessionProtocol.requestChangeCredentials(); + } + /** * @author Eike Stepper */ 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 3d212f0f8a..d955f4364c 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.net4j.protocol; @@ -491,6 +492,9 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO case SIGNAL_LOCK_NOTIFICATION: return new LockNotificationIndication(this); + case SIGNAL_CHANGE_CREDENTIALS: + return new ChangeCredentialsIndication(this); + default: return super.createSignalReactor(signalID); } @@ -560,4 +564,9 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO { return send(new LoadPermissionsRequest(this, revisions)); } + + public void requestChangeCredentials() + { + send(new RequestChangeCredentialsRequest(this)); + } } diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ChangeCredentialsIndication.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ChangeCredentialsIndication.java new file mode 100644 index 0000000000..a42a7bccce --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ChangeCredentialsIndication.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 + * Christian W. Damus (CEA LIST) - Adapted from AuthenticationIndication for 399306 + */ +package org.eclipse.emf.cdo.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.internal.net4j.bundle.OM; + +import org.eclipse.net4j.signal.IndicationWithMonitoring; +import org.eclipse.net4j.signal.SignalProtocol; +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.io.ExtendedDataInputStream; +import org.eclipse.net4j.util.io.ExtendedDataOutputStream; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; +import org.eclipse.net4j.util.security.DiffieHellman; +import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; +import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; +import org.eclipse.net4j.util.security.IPasswordCredentialsProvider; +import org.eclipse.net4j.util.security.IPasswordCredentialsUpdate; +import org.eclipse.net4j.util.security.IPasswordCredentialsUpdateProvider; + +import org.eclipse.emf.spi.cdo.InternalCDOSession; + +import java.io.ByteArrayOutputStream; + +/** + * Implementation of the CDO client handler for the server-initiated change-credentials protocol. + */ +public class ChangeCredentialsIndication extends IndicationWithMonitoring +{ + private Challenge challenge; + + public ChangeCredentialsIndication(SignalProtocol<?> protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_CHANGE_CREDENTIALS); + } + + @Override + public CDOClientProtocol getProtocol() + { + return (CDOClientProtocol)super.getProtocol(); + } + + protected InternalCDOSession getSession() + { + return (InternalCDOSession)getProtocol().getSession(); + } + + @Override + protected void indicating(ExtendedDataInputStream in, OMMonitor monitor) throws Exception + { + challenge = new Challenge(in); + } + + @Override + protected void responding(ExtendedDataOutputStream out, OMMonitor monitor) throws Exception + { + monitor.begin(); + Async async = monitor.forkAsync(); + + try + { + IPasswordCredentialsProvider credentialsProvider = getSession().getCredentialsProvider(); + if (!(credentialsProvider instanceof IPasswordCredentialsUpdateProvider)) + { + throw new IllegalStateException("No credentials update provider configured"); //$NON-NLS-1$ + } + + IPasswordCredentialsUpdate credentials = ((IPasswordCredentialsUpdateProvider)credentialsProvider) + .getCredentialsUpdate(); + if (credentials == null) + { + // user canceled. Fine + out.writeBoolean(false); + return; + } + + String userID = credentials.getUserID(); + if (StringUtil.isEmpty(userID)) + { + throw new IllegalStateException("No userID provided"); //$NON-NLS-1$ + } + + String password = new String(credentials.getPassword()); + if (StringUtil.isEmpty(password)) + { + throw new IllegalStateException("No password provided"); //$NON-NLS-1$ + } + + String newPassword = new String(credentials.getNewPassword()); + if (StringUtil.isEmpty(newPassword)) + { + throw new IllegalStateException("No new password provided"); //$NON-NLS-1$ + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + @SuppressWarnings("resource") + ExtendedDataOutputStream stream = new ExtendedDataOutputStream(baos); + stream.writeString(userID); + stream.writeString(password); + stream.writeString(newPassword); + stream.flush(); + byte[] clearText = baos.toByteArray(); + + DiffieHellman.Client client = new DiffieHellman.Client(); + Response response = client.handleChallenge(challenge, clearText); + out.writeBoolean(true); + response.write(out); + } + catch (Throwable ex) + { + out.writeBoolean(false); + OM.LOG.error(ex); + } + finally + { + async.stop(); + monitor.done(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RequestChangeCredentialsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RequestChangeCredentialsRequest.java new file mode 100644 index 0000000000..b79593c2a0 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RequestChangeCredentialsRequest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.net4j.protocol; + +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.internal.net4j.bundle.OM; + +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import java.io.IOException; + +/** + * Request from the client to the server to initiate (from the server) the change-credentials protocol. + */ +public class RequestChangeCredentialsRequest extends CDOClientRequestWithMonitoring<Boolean> +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, + RequestChangeCredentialsRequest.class); + + public RequestChangeCredentialsRequest(CDOClientProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_REQUEST_CHANGE_CREDENTIALS); + } + + @Override + protected void requesting(CDODataOutput out, OMMonitor monitor) throws IOException + { + // nothing to communicate + if (TRACER.isEnabled()) + { + TRACER.trace("Requesting change of user credentials"); //$NON-NLS-1$ + } + } + + @Override + protected Boolean confirming(CDODataInput in, OMMonitor monitor) throws IOException + { + return in.readBoolean(); + } +} 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 6708c5e9ce..40b226b847 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -11,6 +11,7 @@ * Simon McDuff - bug 230832 * Simon McDuff - bug 233490 * Simon McDuff - bug 213402 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.server.internal.net4j.protocol; @@ -95,6 +96,11 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement return new AuthenticationRequest(this, challenge).send(negotiationTimeout); } + public Response sendChangeCredentialsChallenge(Challenge challenge) throws Exception + { + return new ChangeCredentialsRequest(this, challenge).send(negotiationTimeout); + } + public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType) throws Exception { @@ -351,6 +357,9 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement case SIGNAL_LOAD_PERMISSIONS: return new LoadPermissionsIndication(this); + case SIGNAL_REQUEST_CHANGE_CREDENTIALS: + return new RequestChangeCredentialsIndication(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/ChangeCredentialsRequest.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ChangeCredentialsRequest.java new file mode 100644 index 0000000000..b4e0d7645a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ChangeCredentialsRequest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.common.util.NotAuthenticatedException; + +import org.eclipse.net4j.signal.RemoteException; +import org.eclipse.net4j.signal.RequestWithMonitoring; +import org.eclipse.net4j.util.io.ExtendedDataInputStream; +import org.eclipse.net4j.util.io.ExtendedDataOutputStream; +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; +import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; + +/** + * Server-initiated request to change the user's password. It incorporates and extends the + * authentication challenge (the current credentials must be verified in the same operation). + * + * @since 4.3 + */ +public class ChangeCredentialsRequest extends RequestWithMonitoring<Response> +{ + private Challenge challenge; + + public ChangeCredentialsRequest(CDOServerProtocol protocol, Challenge challenge) + { + super(protocol, CDOProtocolConstants.SIGNAL_CHANGE_CREDENTIALS); + this.challenge = challenge; + } + + @Override + protected void requesting(ExtendedDataOutputStream out, OMMonitor monitor) throws Exception + { + challenge.write(out); + } + + @Override + protected Response confirming(ExtendedDataInputStream in, OMMonitor monitor) throws Exception + { + Response result = null; + + try + { + if (in.readBoolean()) + { + result = new Response(in); + } + } + catch (RemoteException e) + { + // user may have cancelled the change-password operation + if (!(e.getCause() instanceof NotAuthenticatedException)) + { + throw e; + } + } + catch (Exception e) + { + // user may have cancelled the change-password operation + if (!(e instanceof NotAuthenticatedException)) + { + throw e; + } + } + + return result; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RequestChangeCredentialsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RequestChangeCredentialsIndication.java new file mode 100644 index 0000000000..726370199f --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RequestChangeCredentialsIndication.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.server.internal.net4j.protocol; + +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.common.util.NotAuthenticatedException; +import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; +import org.eclipse.emf.cdo.spi.server.InternalSessionManager; + +import org.eclipse.net4j.util.om.monitor.OMMonitor; +import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +/** + * Handles the request from a client to initiate the change-credentials protocol. + */ +public class RequestChangeCredentialsIndication extends CDOServerIndicationWithMonitoring +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, + RequestChangeCredentialsIndication.class); + + public RequestChangeCredentialsIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_REQUEST_CHANGE_CREDENTIALS); + } + + @Override + protected void indicating(CDODataInput in, OMMonitor monitor) throws Exception + { + // nothing to read from the client + + if (TRACER.isEnabled()) + { + TRACER.trace("Initiating change of user credentials"); //$NON-NLS-1$ + } + } + + @Override + protected void responding(CDODataOutput out, OMMonitor monitor) throws Exception + { + monitor.begin(); + Async async = monitor.forkAsync(); + + try + { + try + { + InternalSessionManager sessionManager = getRepository().getSessionManager(); + sessionManager.changeUserCredentials(getProtocol()); + + if (TRACER.isEnabled()) + { + TRACER.format("Credentials change processed."); //$NON-NLS-1$ + } + out.writeBoolean(true); + } + catch (NotAuthenticatedException ex) + { + // user has cancelled the authentication + out.writeBoolean(false); + return; + } + } + finally + { + async.stop(); + monitor.done(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java index fc4e8d5595..5739d36208 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2012, 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.server.internal.security; @@ -76,6 +77,7 @@ import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.net4j.util.security.IAuthenticator; +import org.eclipse.net4j.util.security.IAuthenticator2; import org.eclipse.net4j.util.security.IPasswordCredentials; import org.eclipse.emf.common.util.EList; @@ -856,7 +858,7 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage /** * @author Eike Stepper */ - private final class Authenticator implements IAuthenticator + private final class Authenticator implements IAuthenticator2 { public void authenticate(String userID, char[] password) throws SecurityException { @@ -872,6 +874,12 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage } } } + + public void updatePassword(String userID, char[] oldPassword, char[] newPassword) + { + authenticate(userID, oldPassword); + setPassword(userID, new String(newPassword)); + } } /** 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 4a52229b93..8542d7b518 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2010-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.server; @@ -517,6 +518,17 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd throw new UnsupportedOperationException(); } + /** + * Server sessions may not be used to change the user's credentials: it must + * be done client-side by interaction with the user. + * + * @since 4.3 + */ + public void changeCredentials() + { + throw new UnsupportedOperationException(); + } + public InternalCDORevisionManager getRevisionManager() { return repository.getRevisionManager(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java index 11c168bc33..5a4797a54b 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -9,6 +9,7 @@ * Eike Stepper - initial API and implementation * Simon McDuff - bug 201266 * Simon McDuff - bug 202725 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.server; @@ -39,6 +40,7 @@ import org.eclipse.net4j.util.security.DiffieHellman; import org.eclipse.net4j.util.security.DiffieHellman.Client.Response; import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge; import org.eclipse.net4j.util.security.IAuthenticator; +import org.eclipse.net4j.util.security.IAuthenticator2; import org.eclipse.net4j.util.security.IUserManager; import org.eclipse.net4j.util.security.UserManagerAuthenticator; @@ -436,6 +438,59 @@ public class SessionManager extends Container<ISession> implements InternalSessi } } + public void changeUserCredentials(ISessionProtocol sessionProtocol) + { + + if (sessionProtocol == null) + { + return; + } + + if (authenticationServer == null || authenticator == null) + { + return; + } + + if (!(authenticator instanceof IAuthenticator2)) + { + throw new SecurityException("Current authenticator does not permit password updates"); //$NON-NLS-1$ + } + + try + { + Challenge challenge = authenticationServer.getChallenge(); + Response response = sessionProtocol.sendChangeCredentialsChallenge(challenge); + if (response == null) + { + throw new NotAuthenticatedException(); + } + + ByteArrayInputStream baos = new ByteArrayInputStream(authenticationServer.handleResponse(response)); + @SuppressWarnings("resource") + ExtendedDataInputStream stream = new ExtendedDataInputStream(baos); + String userID = stream.readString(); + char[] password = stream.readString().toCharArray(); + char[] newPassword = stream.readString().toCharArray(); + + // this will throw if the "old password" provided by the user is not correct + ((IAuthenticator2)authenticator).updatePassword(userID, password, newPassword); + } + catch (SecurityException ex) + { + throw ex; + } + catch (Exception ex) + { + Throwable cause = ex.getCause(); + if (cause instanceof SecurityException) + { + throw (SecurityException)cause; + } + + throw new SecurityException(ex); + } + } + @Override protected void doActivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSession.java index b2e1abda80..a7ef38f499 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSession.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Andre Dietisheim - bug 256649 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.server.embedded; @@ -66,6 +67,17 @@ public class EmbeddedClientSession extends CDOSessionImpl implements CDOSession throw new UnsupportedOperationException(); } + /** + * Changing the user's password in an embedded client session is not supported: + * it must be done interactively with the user in a client session. + * + * @since 4.3 + */ + public void changeCredentials() + { + throw new UnsupportedOperationException(); + } + @Override protected void doActivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java index e9754677a5..27b84ccf02 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.server.embedded; @@ -595,6 +596,15 @@ public class EmbeddedClientSessionProtocol extends Lifecycle implements CDOSessi return result; } + /** + * Change of credentials may not be requested by embedded client sessions, only by + * interactive user client sessions. + */ + public void requestChangeCredentials() + { + throw new UnsupportedOperationException(); + } + @Override protected void doActivate() throws Exception { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java index 4430eb417f..77afa07be9 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.internal.server.embedded; @@ -70,6 +71,11 @@ public class EmbeddedServerSessionProtocol extends Lifecycle implements ISession throw new UnsupportedOperationException(); } + public Response sendChangeCredentialsChallenge(Challenge challenge) throws Exception + { + throw new UnsupportedOperationException(); + } + public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType) { EmbeddedClientSession clientSession = clientSessionProtocol.getSession(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java index 6199122f0c..65a4bf9e3c 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.spi.server; @@ -44,6 +45,11 @@ public interface ISessionProtocol extends CDOProtocol */ public Response sendAuthenticationChallenge(Challenge challenge) throws Exception; + /** + * @since 4.3 + */ + public Response sendChangeCredentialsChallenge(Challenge challenge) throws Exception; + public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType) throws Exception; diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java index afb5bcdcc9..4feff228fa 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.spi.server; @@ -64,6 +65,14 @@ public interface InternalSessionManager extends ISessionManager public void setAuthenticationServer(DiffieHellman.Server authenticationServer); /** + * Initiates the change-credentials protocol with the client and processes the + * client response to update the user's credentials. + * + * @since 4.3 + */ + public void changeUserCredentials(ISessionProtocol sessionProtocol); + + /** * @since 4.1 */ public IPermissionManager getPermissionManager(); diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ChangePasswordAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ChangePasswordAction.java new file mode 100644 index 0000000000..18bbfc0226 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ChangePasswordAction.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.ui.actions; + +import org.eclipse.emf.cdo.internal.ui.messages.Messages; +import org.eclipse.emf.cdo.session.CDOSession; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IWorkbenchPage; + +/** + * The "change password" action. + */ +public final class ChangePasswordAction extends SessionAction +{ + private static final String TITLE = Messages.getString("ChangePasswordAction_0"); //$NON-NLS-1$ + + private static final String TOOL_TIP = Messages.getString("ChangePasswordAction_1"); //$NON-NLS-1$ + + public ChangePasswordAction(IWorkbenchPage page, CDOSession session) + { + super(page, TITLE, TOOL_TIP, null, session); + } + + @Override + protected void doRun(IProgressMonitor progressMonitor) throws Exception + { + getSession().changeCredentials(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties index ae5d54c223..6a6645083a 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties @@ -1,5 +1,5 @@ # ============================================================================== -# Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. +# Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -8,6 +8,7 @@ # Contributors: # Victor Roldan Betancort - initial API and implementation # Eike Stepper - maintenance +# Christian W. Damus (CEA LIST) - 399306 # ============================================================================== # ============================================================================== @@ -88,6 +89,8 @@ CDOWatchListView.7=Remove all subscriptions CDOWatchListView.8=Reset Changes CDOWatchListView.9=Reset all change notifications from the selected subscriptions ChangePassiveUpdateAction.1=Passive Updates +ChangePasswordAction_0=Change Password... +ChangePasswordAction_1=Change the connected user's password CloseSessionAction.0=Close CloseSessionAction.1=Close the CDO session CloseSessionAction.2=You have uncommitted changes. Do you want to discard them? diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java index 48527278e6..7d832732a2 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Victor Roldan Betancort - maintenance + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.ui; @@ -25,6 +26,7 @@ import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOResourceLeaf; import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.eresource.CDOTextResource; +import org.eclipse.emf.cdo.internal.ui.actions.ChangePasswordAction; import org.eclipse.emf.cdo.internal.ui.actions.CloseSessionAction; import org.eclipse.emf.cdo.internal.ui.actions.CloseViewAction; import org.eclipse.emf.cdo.internal.ui.actions.CommitTransactionAction; @@ -518,6 +520,7 @@ public class CDOItemProvider extends ContainerItemProvider<IContainer<Object>> } manager.add(new Separator()); + manager.add(new ChangePasswordAction(page, session)); manager.add(new CloseSessionAction(page, session)); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java index 33f6081e6c..1d8b4897e4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -10,6 +10,7 @@ * Simon McDuff - maintenance * Victor Roldan Betancort - maintenance * Andre Dietisheim - bug 256649 + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.cdo.session; @@ -139,6 +140,16 @@ public interface CDOSession extends CDOCommonSession, CDOUpdatable, CDOTransacti public IPasswordCredentialsProvider getCredentialsProvider(); /** + * Initiates interactive changing of credentials for the user logged in in this session. + * This is an optional operation of the session. + * + * @since 4.3 + * + * @throws UnsupportedOperationException if the session implementation does not permit changing credentials + */ + public void changeCredentials(); + + /** * Returns the CDO {@link CDORemoteSessionManager remote session manager} that keeps track of the other remote * sessions served by the repository of this local session. */ 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 af0b18fc1d..025d4f2e26 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2010-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.internal.cdo.session; @@ -933,6 +934,23 @@ public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionPr } } + public void requestChangeCredentials() + { + int attempt = 0; + for (;;) + { + try + { + delegate.requestChangeCredentials(); + return; + } + catch (Exception ex) + { + handleException(++attempt, ex); + } + } + } + @Override protected void doActivate() throws Exception { 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 c655a31c50..49bf99dd3c 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2009-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.emf.spi.cdo; @@ -297,6 +298,17 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo public Map<CDORevision, CDOPermission> loadPermissions(InternalCDORevision[] revisions); /** + * Requests that the server initiate the change-credentials protocol. + * This is an optional session protocol operation. + * + * @since 4.3 + * + * @throws UnsupportedOperationException if the session protocol implementation does + * not support requesting change of credentials + */ + public void requestChangeCredentials(); + + /** * If the meaning of this type isn't clear, there really should be more of a description here... * * @author Eike Stepper diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/internal/ui/messages/messages.properties b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/internal/ui/messages/messages.properties index ba8ca548ef..d4043eaa30 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/internal/ui/messages/messages.properties +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/internal/ui/messages/messages.properties @@ -1,5 +1,5 @@ # ============================================================================== -# Copyright (c) 2009, 2012 Eike Stepper (Berlin, Germany) and others. +# Copyright (c) 2009, 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -8,6 +8,7 @@ # Contributors: # Victor Roldan Betancort - initial API and implementation # Eike Stepper - maintenance +# Christian W. Damus (CEA LIST) - 399306 # ============================================================================== # ============================================================================== @@ -22,6 +23,12 @@ CredentialsDialog_1=Enter your user ID and password. CredentialsDialog_2=User ID: CredentialsDialog_3=Password: CredentialsDialog_0=Login +CredentialsUpdateDialog_0=Change Password +CredentialsUpdateDialog_1=Authenticate and enter your new password. +CredentialsUpdateDialog_2=New Password: +CredentialsUpdateDialog_3=Repeat Password: +CredentialsUpdateDialog_4=New password is required. +CredentialsUpdateDialog_5=Repeated password does not match the new password. IntrospectAction_0=Introspect MasterDetailsView_2=Refresh MasterDetailsView_3=Refresh diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsDialog.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsDialog.java index 5ca332b2f7..fbf94de77e 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsDialog.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2011-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2008, 2009, 2011-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.net4j.util.ui.security; @@ -67,8 +68,16 @@ public class CredentialsDialog extends BaseDialog<Viewer> */ public CredentialsDialog(Shell shell, String realm) { - super(shell, DEFAULT_SHELL_STYLE | SWT.APPLICATION_MODAL, TITLE, MESSAGE, OM.Activator.INSTANCE.getDialogSettings(), OM - .getImageDescriptor("icons/credentials_wiz.gif")); + this(shell, realm, TITLE, MESSAGE); + } + + /** + * @since 3.4 + */ + public CredentialsDialog(Shell shell, String realm, String title, String message) + { + super(shell, DEFAULT_SHELL_STYLE | SWT.APPLICATION_MODAL, title, message, + OM.Activator.INSTANCE.getDialogSettings(), OM.getImageDescriptor("icons/credentials_wiz.gif")); //$NON-NLS-1$ this.realm = realm; users = loadUsers(); } @@ -91,25 +100,41 @@ public class CredentialsDialog extends BaseDialog<Viewer> { super.configureShell(newShell); + configureShell(newShell, WIDTH, HEIGHT); + } + + /** + * @since 3.4 + */ + protected void configureShell(Shell newShell, int width, int height) + { Composite parent = newShell.getParent(); if (parent != null) { Rectangle bounds = parent.getBounds(); - int x = bounds.x + (bounds.width >> 1) - (WIDTH >> 1); - int y = bounds.y + (bounds.height >> 1) - (HEIGHT >> 1); + int x = bounds.x + (bounds.width >> 1) - (width >> 1); + int y = bounds.y + (bounds.height >> 1) - (height >> 1); - newShell.setBounds(x, y, WIDTH, HEIGHT); + newShell.setBounds(x, y, width, height); } else { - newShell.setSize(WIDTH, HEIGHT); + newShell.setSize(width, height); } } @Override protected void createUI(Composite parent) { + createCredentialsArea(parent); + } + + /** + * @since 3.4 + */ + protected Composite createCredentialsArea(Composite parent) + { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(UIUtil.createGridData()); composite.setLayout(new GridLayout(2, false)); @@ -138,6 +163,8 @@ public class CredentialsDialog extends BaseDialog<Viewer> { passwordControl.setFocus(); } + + return composite; } @Override @@ -154,7 +181,7 @@ public class CredentialsDialog extends BaseDialog<Viewer> } String password = passwordControl.getText(); - credentials = new PasswordCredentials(userID, password.toCharArray()); + credentials = createCredentials(userID, password.toCharArray()); users.remove(userID); users.add(0, userID); @@ -166,6 +193,14 @@ public class CredentialsDialog extends BaseDialog<Viewer> /** * @since 3.4 */ + protected IPasswordCredentials createCredentials(String userID, char[] password) + { + return new PasswordCredentials(userID, password); + } + + /** + * @since 3.4 + */ protected List<String> loadUsers() { List<String> result = new ArrayList<String>(); diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsUpdateDialog.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsUpdateDialog.java new file mode 100644 index 0000000000..052ef25f03 --- /dev/null +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/CredentialsUpdateDialog.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.net4j.util.ui.security; + +import org.eclipse.net4j.util.internal.ui.messages.Messages; +import org.eclipse.net4j.util.security.IPasswordCredentials; +import org.eclipse.net4j.util.security.IPasswordCredentialsUpdate; +import org.eclipse.net4j.util.security.PasswordCredentialsUpdate; +import org.eclipse.net4j.util.ui.UIUtil; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * @since 3.4 + */ +public class CredentialsUpdateDialog extends CredentialsDialog +{ + private static final String TITLE = Messages.getString("CredentialsUpdateDialog_0"); //$NON-NLS-1$ + + private static final String MESSAGE = Messages.getString("CredentialsUpdateDialog_1"); //$NON-NLS-1$ + + private static final int HEIGHT = 275; + + private Text newPasswordControl; + + private Text repeatNewPasswordControl; + + public CredentialsUpdateDialog(Shell shell) + { + this(shell, null); + } + + public CredentialsUpdateDialog(Shell shell, String realm) + { + super(shell, realm, TITLE, MESSAGE); + } + + @Override + protected void configureShell(Shell newShell, int width, int height) + { + super.configureShell(newShell, width, HEIGHT); + } + + @Override + public IPasswordCredentialsUpdate getCredentials() + { + return (IPasswordCredentialsUpdate)super.getCredentials(); + } + + @Override + protected IPasswordCredentials createCredentials(String userID, char[] password) + { + String newPassword = newPasswordControl.getText(); + return new PasswordCredentialsUpdate(userID, password, newPassword.toCharArray()); + } + + @Override + protected Composite createCredentialsArea(Composite parent) + { + Composite result = super.createCredentialsArea(parent); + + ModifyListener newPasswordListener = new ModifyListener() + { + + public void modifyText(ModifyEvent e) + { + validateNewPassword(); + } + }; + + new Label(result, SWT.NONE).setText(Messages.getString("CredentialsUpdateDialog_2")); //$NON-NLS-1$ + newPasswordControl = new Text(result, SWT.BORDER | SWT.PASSWORD); + newPasswordControl.setLayoutData(UIUtil.createGridData(true, false)); + newPasswordControl.addModifyListener(newPasswordListener); + + new Label(result, SWT.NONE).setText(Messages.getString("CredentialsUpdateDialog_3")); //$NON-NLS-1$ + repeatNewPasswordControl = new Text(result, SWT.BORDER | SWT.PASSWORD); + repeatNewPasswordControl.setLayoutData(UIUtil.createGridData(true, false)); + repeatNewPasswordControl.addModifyListener(newPasswordListener); + + return result; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) + { + super.createButtonsForButtonBar(parent); + + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + void validateNewPassword() + { + String newPassword = newPasswordControl.getText().trim(); + if (newPassword.length() == 0) + { + error(Messages.getString("CredentialsUpdateDialog_4")); //$NON-NLS-1$ + return; + } + + String verify = repeatNewPasswordControl.getText().trim(); + if (verify.length() == 0) + { + error(null); + getButton(IDialogConstants.OK_ID).setEnabled(false); + return; + } + + if (!verify.equals(newPassword)) + { + error(Messages.getString("CredentialsUpdateDialog_5")); //$NON-NLS-1$ + return; + } + + error(null); + } + + void error(String message) + { + setErrorMessage(message); + getButton(IDialogConstants.OK_ID).setEnabled(message == null); + } + +} diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/InteractiveCredentialsProvider.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/InteractiveCredentialsProvider.java index 9f5da6a175..50cbb76f75 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/InteractiveCredentialsProvider.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/security/InteractiveCredentialsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011-2013 Eike Stepper (Berlin, Germany) and others. + * Copyright (c) 2008, 2011-2013 Eike Stepper (Berlin, Germany), CEA LIST, 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 @@ -7,13 +7,17 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - 399306 */ package org.eclipse.net4j.util.ui.security; import org.eclipse.net4j.util.security.IPasswordCredentials; import org.eclipse.net4j.util.security.IPasswordCredentialsProvider2; +import org.eclipse.net4j.util.security.IPasswordCredentialsUpdate; +import org.eclipse.net4j.util.security.IPasswordCredentialsUpdateProvider; import org.eclipse.net4j.util.ui.UIUtil; +import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; @@ -22,7 +26,8 @@ import org.eclipse.ui.IWorkbenchWindow; * @author Eike Stepper * @since 2.0 */ -public class InteractiveCredentialsProvider implements IPasswordCredentialsProvider2 +public class InteractiveCredentialsProvider implements IPasswordCredentialsProvider2, + IPasswordCredentialsUpdateProvider { public InteractiveCredentialsProvider() { @@ -71,4 +76,46 @@ public class InteractiveCredentialsProvider implements IPasswordCredentialsProvi return credentials[0]; } + + /** + * @since 3.4 + */ + public IPasswordCredentialsUpdate getCredentialsUpdate() + { + return getCredentialsUpdate(null); + } + + /** + * @since 3.4 + */ + public IPasswordCredentialsUpdate getCredentialsUpdate(final String realm) + { + final IPasswordCredentialsUpdate[] update = { null }; + final Display display = UIUtil.getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + Shell shell; + + try + { + IWorkbenchWindow window = UIUtil.getActiveWorkbenchWindow(); + shell = window.getShell(); + } + catch (Exception ex) + { + shell = new Shell(display); + } + + CredentialsUpdateDialog dialog = new CredentialsUpdateDialog(shell, realm); + if (dialog.open() == Window.OK) + { + update[0] = dialog.getCredentials(); + } + } + }); + + return update[0]; + } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IAuthenticator2.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IAuthenticator2.java new file mode 100644 index 0000000000..f824fbf7f0 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IAuthenticator2.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.net4j.util.security; + +/** + * Extension interface for authenticators that can update user credentials in addition to authenticating them. + * + * @since 3.4 + */ +public interface IAuthenticator2 extends IAuthenticator +{ + + /** + * Updates the password <em>stored</em> for the user identified by {@code userID}. The {@code oldPassword} is authenticated + * {@linkplain IAuthenticator#authenticate(String, char[]) as per usual} and is replaced by the {@code newPassword} only + * (and atomically) on success. + * + * @param userID the ID of the user whose password is to be updated + * @param oldPassword the user's current password attempt to verify against the <em>stored</em> password + * @param newPassword the new password to replace the {@code oldPassword} + * + * @throws SecurityException on any failure to authenticate the {@code oldPassword} or validate and/or set the {@code newPassword} + */ + void updatePassword(String userID, char[] oldPassword, char[] newPassword); +} diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdate.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdate.java new file mode 100644 index 0000000000..54f53c72b7 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdate.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.net4j.util.security; + +/** + * Password credentials with an update (new password) in addition to the usual + * user ID and password for authentication of the password change. + * + * @since 3.4 + */ +public interface IPasswordCredentialsUpdate extends IPasswordCredentials +{ + /** + * Queries the new password to be set for the {@linkplain IUserAware#getUserID() user}. + * It is the responsibility of the provider of an update to verify that this is actually + * the new password intended by the user. + */ + public char[] getNewPassword(); +} diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdateProvider.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdateProvider.java new file mode 100644 index 0000000000..6745ae2197 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/IPasswordCredentialsUpdateProvider.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.net4j.util.security; + +/** + * Interface for providers of password credentials updates. + * + * @since 3.4 + */ +public interface IPasswordCredentialsUpdateProvider +{ + public IPasswordCredentialsUpdate getCredentialsUpdate(); + + public IPasswordCredentialsUpdate getCredentialsUpdate(String realm); +} diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/PasswordCredentialsUpdate.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/PasswordCredentialsUpdate.java new file mode 100644 index 0000000000..22854002c1 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/security/PasswordCredentialsUpdate.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany), CEA LIST, 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: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.net4j.util.security; + +/** + * Default implementation of the {@link IPasswordCredentialsUpdate} interface. + * + * @since 3.4 + */ +public class PasswordCredentialsUpdate extends PasswordCredentials implements IPasswordCredentialsUpdate +{ + + private char[] newPassword; + + public PasswordCredentialsUpdate(String userID, char[] oldPassword, char[] newPassword) + { + super(userID, oldPassword); + this.newPassword = newPassword; + } + + public PasswordCredentialsUpdate(String userID, String password, String newPassword) + { + this(userID, password.toCharArray(), newPassword.toCharArray()); + } + + public PasswordCredentialsUpdate(String userID) + { + super(userID); + } + + public char[] getNewPassword() + { + return newPassword; + } + + public void setNewPassword(char[] newPassword) + { + this.newPassword = newPassword; + } +} |