diff options
Diffstat (limited to 'src')
10 files changed, 378 insertions, 40 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java index 3a2592f0..8898cf92 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java @@ -9,6 +9,7 @@ import static com.gluster.storage.management.client.constants.ClientConstants.TR import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.ConnectException;
import java.net.URI;
import java.security.KeyStore;
@@ -19,6 +20,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
import com.gluster.storage.management.client.utils.ClientUtil;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
@@ -130,10 +132,35 @@ public abstract class AbstractClient { */
private <T> T fetchResource(WebResource res, MultivaluedMap<String, String> queryParams, Class<T> responseClass) {
try {
- return res.queryParams(queryParams)
- .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).get(responseClass);
- } catch(UniformInterfaceException e) {
- throw new GlusterRuntimeException(e.getResponse().getEntity(String.class), e);
+ return res.queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML)
+ .get(responseClass);
+ } catch (Exception e1) {
+ throw createGlusterException(e1);
+ }
+ }
+
+ private GlusterRuntimeException createGlusterException(Exception e) {
+ if(e instanceof GlusterRuntimeException) {
+ return (GlusterRuntimeException)e;
+ }
+
+ if (e instanceof UniformInterfaceException) {
+ UniformInterfaceException uie = (UniformInterfaceException) e;
+ if ((uie.getResponse().getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) {
+ // authentication failed. clear security token.
+ setSecurityToken(null);
+ return new GlusterRuntimeException("Invalid credentials!");
+ } else {
+ return new GlusterRuntimeException("[" + uie.getResponse().getStatus() + "]["
+ + uie.getResponse().getEntity(String.class) + "]");
+ }
+ } else {
+ Throwable cause = e.getCause();
+ if (cause != null && cause instanceof ConnectException) {
+ return new GlusterRuntimeException("Couldn't connect to Gluster Management Gateway!");
+ }
+
+ return new GlusterRuntimeException("Exception in REST communication!", e);
}
}
@@ -273,12 +300,17 @@ public abstract class AbstractClient { private ClientResponse putRequest(WebResource resource, Form form) {
try {
ClientResponse response = prepareFormRequestBuilder(resource).put(ClientResponse.class, form);
+ if ((response.getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) {
+ // authentication failed. clear security token.
+ setSecurityToken(null);
+ throw new GlusterRuntimeException("Invalid credentials!");
+ }
if(response.getStatus() >= 300) {
throw new GlusterRuntimeException(response.getEntity(String.class));
}
return response;
- } catch (UniformInterfaceException e) {
- throw new GlusterRuntimeException(e.getResponse().getEntity(String.class));
+ } catch (Exception e) {
+ throw createGlusterException(e);
}
}
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 6c2fbdb3..ba5ce336 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -86,8 +86,7 @@ public class GlusterDataModelManager { return instance; } - public void initializeModel(String securityToken, String clusterName) { - setSecurityToken(securityToken); + public void initializeModel(String clusterName) { setClusterName(clusterName); model = fetchData(clusterName); diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java index 6dc251dc..45dcf27f 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java @@ -46,33 +46,9 @@ public class UsersClient extends AbstractClient { public void authenticate(String user, String password) { setSecurityToken(generateSecurityToken(user, password)); - try { - fetchSubResource(user, Status.class); - } catch (RuntimeException e) { - Throwable cause = e.getCause(); - if(cause == null) { - throw e; - } - - if (cause instanceof UniformInterfaceException) { - UniformInterfaceException e1 = (UniformInterfaceException) cause; - if ((e1.getResponse().getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) { - // authentication failed. clear security token. - setSecurityToken(null); - throw new GlusterRuntimeException("Invalid user id or password!"); - } else { - String errMsg = "Exception during authentication: [" + e1.getResponse().getStatus() + "]"; - logger.error(errMsg); - throw new GlusterRuntimeException(errMsg); - } - } else if(cause instanceof ConnectException) { - throw new GlusterRuntimeException("Couldn't connect to Gluster Management Gateway!"); - } else { - String errMsg = "Exception during authentication: [" + e.getMessage() + "]"; - logger.error(errMsg); - throw new GlusterRuntimeException(errMsg); - } - } + fetchSubResource(user, Status.class); + // authentication successful. update security token in the data model manager + GlusterDataModelManager.getInstance().setSecurityToken(getSecurityToken()); } public void changePassword(String user, String oldPassword, String newPassword) { @@ -82,6 +58,10 @@ public class UsersClient extends AbstractClient { form.add(FORM_PARAM_OLD_PASSWORD, oldPassword); form.add(FORM_PARAM_NEW_PASSWORD, newPassword); putRequest(user, form); + + // password changed. set the new security token + setSecurityToken(generateSecurityToken(user, newPassword)); + GlusterDataModelManager.getInstance().setSecurityToken(getSecurityToken()); } public static void main(String[] args) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ConnectionDetails.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ConnectionDetails.java index ccf8fecf..9f66ba5b 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ConnectionDetails.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ConnectionDetails.java @@ -18,8 +18,11 @@ *******************************************************************************/ package com.gluster.storage.management.core.model; +/** + * Class used for binding UI fields on login / password-change dialog boxes + */ public class ConnectionDetails { - private String userId, password; + private String userId, password, newPassword, confirmNewPassword; public ConnectionDetails() { @@ -28,6 +31,7 @@ public class ConnectionDetails { public ConnectionDetails(String userId, String password) { this.userId = userId; this.password = password; + this.confirmNewPassword = ""; } public String getUserId() { @@ -41,4 +45,20 @@ public class ConnectionDetails { public void setPassword(String password) { this.password = password; } + + public void setNewPassword(String newPassword) { + this.newPassword = newPassword; + } + + public String getNewPassword() { + return newPassword; + } + + public void setConfirmNewPassword(String confirmNewPassword) { + this.confirmNewPassword = confirmNewPassword; + } + + public String getConfirmNewPassword() { + return confirmNewPassword; + } } diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/change-password.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/change-password.png Binary files differnew file mode 100644 index 00000000..ea8f97ae --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/change-password.png diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index 0a4c068d..f67bb454 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -279,6 +279,12 @@ id="com.gluster.storage.management.gui.commands.Delete" name="Delete"> </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Change Password" + id="com.gluster.storage.management.gui.commands.ChangePassword" + name="Change Password"> + </command> </extension> <extension point="org.eclipse.ui.bindings"> @@ -981,7 +987,7 @@ class="com.gluster.storage.management.gui.actions.RefreshDataAction" definitionId="org.eclipse.ui.window.preferences" icon="icons/tango/32x32/view-refresh.png" - id="com.gluster.storage.management.gui.actions.AddServerAction" + id="com.gluster.storage.management.gui.actions.RefreshDataAction" label="&Refresh" menubarPath="com.gluster.storage.management.gui.menu.edit/edit" mode="FORCE_TEXT" @@ -997,7 +1003,7 @@ class="com.gluster.storage.management.gui.actions.PreferencesAction" definitionId="org.eclipse.ui.window.preferences" icon="icons/tango/32x32/settings.png" - id="com.gluster.storage.management.gui.actions.AddServerAction" + id="com.gluster.storage.management.gui.actions.PreferencesAction" label="&Settings" menubarPath="com.gluster.storage.management.gui.menu.edit/edit" mode="FORCE_TEXT" @@ -1008,6 +1014,21 @@ toolbarPath="Normal" tooltip="Settings"> </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.ChangePasswordAction" + definitionId="com.gluster.storage.management.gui.commands.ChangePassword" + icon="icons/tango/32x32/change-password.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Change Password" + menubarPath="com.gluster.storage.management.gui.menu.edit/edit" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + tooltip="Change password"> + </action> <menu id="com.gluster.storage.management.gui.menu.edit" label="&Edit" diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ChangePasswordAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ChangePasswordAction.java new file mode 100644 index 00000000..fedbc893 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ChangePasswordAction.java @@ -0,0 +1,25 @@ +package com.gluster.storage.management.gui.actions; + +import java.awt.Window; + +import org.eclipse.jface.action.IAction; + +import com.gluster.storage.management.gui.dialogs.ChangePasswordDialog; + +public class ChangePasswordAction extends AbstractActionDelegate { + + @Override + protected void performAction(IAction action) { + try { + // To open a dialog for change password + ChangePasswordDialog dialog = new ChangePasswordDialog(getShell()); + dialog.open(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void dispose() { + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java new file mode 100644 index 00000000..df4e7be9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java @@ -0,0 +1,259 @@ +/** + * ChangePasswordDialog.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.dialogs; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; +import org.eclipse.core.databinding.beans.PojoProperties; +import org.eclipse.core.databinding.validation.ValidationStatus; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.swt.WidgetProperties; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.UsersClient; +import com.gluster.storage.management.core.model.ConnectionDetails; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.validators.StringRequiredValidator; + +public class ChangePasswordDialog extends Dialog { + public static final int RETURN_CODE_ERROR = 2; + private Text oldPassword; + private Text newPassword; + private Text confirmPassword; + private Button okButton; + + private final GUIHelper guiHelper = GUIHelper.getInstance(); + private Composite composite; + + private final ConnectionDetails connectionDetails = new ConnectionDetails("gluster", ""); + + public ChangePasswordDialog(Shell shell) { + super(shell); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + + newShell.setText("Gluster Management Console"); + addEscapeListener(newShell); + } + + private void addEscapeListener(Shell shell) { + shell.addTraverseListener(new TraverseListener() { + + @Override + public void keyTraversed(TraverseEvent e) { + if (e.keyCode == SWT.ESC) { + cancelPressed(); + } + } + }); + } + + /** + * Overriding to make sure that the dialog is centered in screen + */ + @Override + protected void initializeBounds() { + super.initializeBounds(); + + guiHelper.centerShellInScreen(getShell()); + } + + private void configureDialogLayout(Composite composite) { + GridLayout layout = (GridLayout) composite.getLayout(); + layout.numColumns = 2; + layout.marginLeft = 20; + layout.marginRight = 20; + layout.marginTop = 20; + layout.horizontalSpacing = 20; + layout.verticalSpacing = 20; + } + + // ------------------------------------------ + + private void createLabel(Composite composite, String label) { + Label passwordLabel = new Label(composite, SWT.NONE); + passwordLabel.setText(label); + passwordLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private Text createPasswordText(Composite composite) { + Text field = new Text(composite, SWT.BORDER | SWT.PASSWORD); + GridData layoutData = new GridData(SWT.FILL, GridData.FILL, true, false); + layoutData.widthHint = convertWidthInCharsToPixels(32); + field.setLayoutData(layoutData); + return field; + } + + @Override + protected Control createDialogArea(Composite parent) { + parent.setBackgroundImage(guiHelper.getImage(IImageKeys.DIALOG_SPLASH_IMAGE)); + parent.setBackgroundMode(SWT.INHERIT_FORCE); + + composite = (Composite) super.createDialogArea(parent); + configureDialogLayout(composite); + + createLabel(composite, "Old Password:"); + oldPassword = createPasswordText(composite); + + createLabel(composite, "New Password:"); + newPassword = createPasswordText(composite); + + createLabel(composite, "Confirm Password:"); + confirmPassword = createPasswordText(composite); + + createListeners(); + + return composite; + } + + /** + * + */ + private void createListeners() { + ModifyListener listener = new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateButtonStatus(); + } + }; + + oldPassword.addModifyListener(listener); + newPassword.addModifyListener(listener); + confirmPassword.addModifyListener(listener); + } + + private void updateButtonStatus() { + String oldPwd = oldPassword.getText(); + String newPwd = newPassword.getText(); + String confirmPwd = confirmPassword.getText(); + if(oldPwd.isEmpty() || newPwd.isEmpty() || confirmPwd.isEmpty()) { + okButton.setEnabled(false); + return; + } + + if(!newPwd.equals(confirmPwd)) { + okButton.setEnabled(false); + return; + } + + if (newPwd.length() < 4 ) { // Minimum password length is 4 + okButton.setEnabled(false); + return; + } + okButton.setEnabled(true); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + okButton = createButton(parent, IDialogConstants.OK_ID, "&Change", true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + + setupDataBinding(); + } + + public class ConfirmPasswordValidator extends StringRequiredValidator { + public ConfirmPasswordValidator(String errorText, ControlDecoration controlDecoration, Control linkedControl) { + super(errorText, controlDecoration, linkedControl); + } + + @Override + public IStatus validate(Object value) { + + IStatus status = super.validate(value); + if (status.isOK()) { + if (!value.equals(newPassword.getText())) { + return ValidationStatus.error("Passwords do not match"); + } + } + return status; + } + }; + + private void setupDataBinding() { + DataBindingContext dataBindingContext = new DataBindingContext(SWTObservables.getRealm(Display.getCurrent())); + UpdateValueStrategy passwordBindingStrategy = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); + UpdateValueStrategy newPwdBindingStrategy = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); + UpdateValueStrategy confirmPwdBindingStrategy = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); + + // The Validator shows error decoration and disables OK button on + // validation failure + passwordBindingStrategy.setBeforeSetValidator(new StringRequiredValidator("Please enter old password!", + guiHelper.createErrorDecoration(oldPassword), null)); + + dataBindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(oldPassword), + PojoProperties.value("password").observe(connectionDetails), passwordBindingStrategy, + passwordBindingStrategy); + + newPwdBindingStrategy.setBeforeSetValidator(new StringRequiredValidator("Please enter new password!", guiHelper + .createErrorDecoration(newPassword), null)); + + dataBindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(newPassword), + PojoProperties.value("newPassword").observe(connectionDetails), newPwdBindingStrategy, + newPwdBindingStrategy); + + confirmPwdBindingStrategy.setBeforeSetValidator(new ConfirmPasswordValidator("Please enter confirm password!", + guiHelper.createErrorDecoration(confirmPassword), null)); + + dataBindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(confirmPassword), + PojoProperties.value("confirmNewPassword").observe(connectionDetails), confirmPwdBindingStrategy, + confirmPwdBindingStrategy); + } + + protected void okPressed() { + String user = connectionDetails.getUserId(); + String oldPassword = connectionDetails.getPassword(); + String newPassword = connectionDetails.getNewPassword(); + + UsersClient usersClient = new UsersClient(); + try { + usersClient.changePassword(user, oldPassword, newPassword); + MessageDialog.openInformation(getShell(), "Change password", "Password changed successfully!"); + } catch (Exception e) { + MessageDialog.openError(getShell(), "Change password Failed", e.getMessage()); + setReturnCode(RETURN_CODE_ERROR); + } + this.close(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 487a03c4..e46cd397 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -250,7 +250,7 @@ public class LoginDialog extends Dialog { try { createOrRegisterCluster(clustersClient, clusterName, serverName, mode); - GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken(), clusterName); + GlusterDataModelManager.getInstance().initializeModel(clusterName); super.okPressed(); } catch (Exception e) { setReturnCode(RETURN_CODE_ERROR); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java index fd76c6e5..d4dd489c 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java @@ -52,7 +52,9 @@ public class StringRequiredValidator implements IValidator { return ValidationStatus.error(errorText); } } - linkedControl.setEnabled(true); + if(linkedControl != null) { + linkedControl.setEnabled(true); + } controlDecoration.hide(); return Status.OK_STATUS; } |
