/*******************************************************************************
* Copyright (c) 2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.foundation.security;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.PBEKeySpec;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.security.storage.EncodingUtils;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.FormDialog;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
/**
*
*/
public class DescriptiveStorageLoginDialog extends FormDialog {
private static final String HELP_ID = "org.jboss.tools.foundation.security.linux.sec_storage_context"; //$NON-NLS-1$
private static final String DIGEST_ALGORITHM = "MD5"; //$NON-NLS-1$
protected Text password;
protected Text confirm;
private Label statusLabel;
protected Button showPassword;
protected Button okButton;
protected PBEKeySpec generatedPassword;
protected final boolean confirmPassword;
protected final boolean passwordChange;
protected final String location;
/**
* Create new dialog instance
*
* @param confirmPassword
* @param passwordChange
* @param location
*/
public DescriptiveStorageLoginDialog(boolean confirmPassword, boolean passwordChange, String location) {
super(getWorkbenchShell());
this.confirmPassword = confirmPassword;
this.passwordChange = passwordChange;
this.location = location;
}
/**
* Get the shell from an active window. If not found, returns null.
*/
private static Shell getWorkbenchShell() {
if (PlatformUI.isWorkbenchRunning()) {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null)
return window.getShell();
}
return null;
}
/**
* Get the generated password
*
* @return {@link PBEKeySpec} instance of password
*/
public PBEKeySpec getGeneratedPassword() {
return generatedPassword;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
okButton = createButton(parent, IDialogConstants.OK_ID, Messages.ButtonLogin, true);
okButton.setEnabled(false);
createButton(parent, IDialogConstants.CANCEL_ID, Messages.ButtonExit, false);
}
@Override
protected boolean isResizable() {
return false;
}
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(Messages.DialogTitle);
PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, HELP_ID);
shell.setSize(700, 500);
}
@Override
protected void createFormContent(IManagedForm mform) {
final ScrolledForm mainForm = mform.getForm();
FormToolkit toolkit = new FormToolkit(mainForm.getDisplay());
Composite body = mainForm.getBody();
TableWrapLayout layout = new TableWrapLayout();
body.setLayout(layout);
/* description panel */
Section descriptionSection = toolkit.createSection(body, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED );
descriptionSection.setText(Messages.DescriptionTitle);
descriptionSection.setTitleBarForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE));
FormText descriptionText = toolkit.createFormText(descriptionSection, true);
descriptionText.setText(Messages.SecureDescription, true, true);
TableWrapData td = new TableWrapData(TableWrapData.FILL);
td.colspan = 1;
descriptionText.setLayoutData(td);
descriptionSection.setClient(descriptionText);
/* password panel */
String titleMsg;
if (confirmPassword)
titleMsg = Messages.PasswordChangeTitle;
else if (passwordChange)
titleMsg = Messages.MessageLoginChange;
else
titleMsg = Messages.DialogTitle;
/* Separator */
toolkit.createLabel(body, ""); //$NON-NLS-1$
Section passwordSection = toolkit.createSection(body, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED );
passwordSection.setText(titleMsg);
passwordSection.setTitleBarForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE));
passwordSection.setLayoutData(td);
Composite passwordComposite = toolkit.createComposite(passwordSection, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(2).applyTo(passwordComposite);
Label passwordLabel = toolkit.createLabel(passwordComposite, Messages.LabelPassword, SWT.LEFT);
GridDataFactory.swtDefaults().applyTo(passwordLabel);
password = toolkit.createText(passwordComposite, "", SWT.LEFT | SWT.BORDER); //$NON-NLS-1$
GridDataFactory.fillDefaults().grab(true, false).applyTo(password);
password.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
okButton.setEnabled(validatePassword(mainForm));
}
});
/* This textbox has the focus on dialog display */
password.setFocus();
if (confirmPassword) {
Label passwordConfLabel = toolkit.createLabel(passwordComposite, Messages.LabelConfirm, SWT.LEFT);
GridDataFactory.swtDefaults().applyTo(passwordConfLabel);
confirm = toolkit.createText(passwordComposite, "", SWT.LEFT | SWT.BORDER); //$NON-NLS-1$
GridDataFactory.fillDefaults().grab(true, false).applyTo(confirm);
confirm.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
okButton.setEnabled(validatePassword(mainForm));
}
});
} else confirm = null;
Label fillerLabel = toolkit.createLabel(passwordComposite, "", SWT.LEFT);// filler //$NON-NLS-1$
GridDataFactory.swtDefaults().applyTo(fillerLabel);
showPassword = toolkit.createButton(passwordComposite, Messages.ShowPassword, SWT.CHECK | SWT.RIGHT);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(showPassword);
showPassword.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
passwordVisibility();
}
public void widgetDefaultSelected(SelectionEvent e) {
passwordVisibility();
}
});
// by default don't display password as clear text
showPassword.setSelection(false);
passwordVisibility();
if (location != null) {
Group locationGroup = new Group(passwordComposite, SWT.NONE);
locationGroup.setText(Messages.LocationGroup);
toolkit.adapt(locationGroup);
GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(locationGroup);
GridLayoutFactory.fillDefaults().applyTo(locationGroup);
Label locationLabel = toolkit.createLabel(locationGroup, new Path(location).toOSString(), SWT.WRAP);
GridDataFactory.fillDefaults().grab(true, false).applyTo(locationLabel);
}
passwordSection.setClient(passwordComposite);
/* Separator */
toolkit.createLabel(body, ""); //$NON-NLS-1$
/* Status label for any messages */
statusLabel = toolkit.createLabel(body, ""); //$NON-NLS-1$
TableWrapData td2 = new TableWrapData(TableWrapData.FILL);
td2.colspan = 1;
td2.grabHorizontal = true;
statusLabel.setLayoutData(td2);
statusLabel.setForeground(mainForm.getDisplay().getSystemColor(SWT.COLOR_RED));
}
protected void passwordVisibility() {
boolean selected = showPassword.getSelection();
if (selected) {
password.setEchoChar('\0');
if (confirm != null)
confirm.setEchoChar('\0');
} else {
password.setEchoChar('*');
if (confirm != null)
confirm.setEchoChar('*');
}
}
protected boolean validatePassword(ScrolledForm mainForm) {
String password1 = password.getText();
if ((password1 == null) || (password1.length() == 0)) {
statusLabel.setText(Messages.MessageEmptyPassword);
return false;
}
if (confirm != null) {
String password2 = confirm.getText();
if (!password1.equals(password2)) {
statusLabel.setText(Messages.MessageNoMatch);
return false;
}
}
statusLabel.setText(""); //$NON-NLS-1$
return true;
}
@Override
protected void okPressed() {
String internalPassword;
try {
// normally use digest of what was entered
MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM);
byte[] digested = digest.digest(new String(password.getText()).getBytes());
internalPassword = EncodingUtils.encodeBase64(digested);
} catch (NoSuchAlgorithmException e) {
// just use the text as is
internalPassword = password.getText();
}
generatedPassword = new PBEKeySpec(internalPassword.toCharArray());
super.okPressed();
}
}