blob: 31433f1052a258b76d9316dadd25e82efc0292d9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.security.ui.storage;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.*;
import org.eclipse.equinox.internal.security.storage.friends.*;
import org.eclipse.equinox.internal.security.ui.nls.SecUIMessages;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.*;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class TabPassword {
private static final String PREFERENCES_PLUGIN = "org.eclipse.equinox.security"; //$NON-NLS-1$
private final static String PASSWORD_RECOVERY_NODE = "/org.eclipse.equinox.secure.storage/recovery/"; //$NON-NLS-1$
protected Table providerTable;
protected Button buttonClearPassword;
protected Button buttonChangePassword;
protected Button buttonRecoverPassword;
protected Text detailsText;
protected boolean providerModified = false;
public TabPassword(TabFolder folder, int index, final Shell shell) {
TabItem tab = new TabItem(folder, SWT.NONE, index);
tab.setText(SecUIMessages.tabPassword);
Composite page = new Composite(folder, SWT.NONE);
page.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
tab.setControl(page);
Group passwordGroup = new Group(page, SWT.NONE);
passwordGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
passwordGroup.setLayout(new GridLayout(2, false));
passwordGroup.setText(SecUIMessages.passwordCacheGroup);
buttonClearPassword = new Button(passwordGroup, SWT.PUSH);
buttonClearPassword.setText(SecUIMessages.logoutButton);
buttonClearPassword.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
buttonClearPassword.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
InternalExchangeUtils.passwordProvidersReset();
enableLogout();
}
});
setButtonSize(buttonClearPassword);
Label passwordNote = new Label(passwordGroup, SWT.WRAP);
GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
labelData.widthHint = 340;
passwordNote.setLayoutData(labelData);
passwordNote.setText(SecUIMessages.passwordCacheNote);
Group providersGroup = new Group(page, SWT.NONE);
providersGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
providersGroup.setLayout(new GridLayout());
providersGroup.setText(SecUIMessages.providerGroup);
Label providersNote = new Label(providersGroup, SWT.WRAP);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.widthHint = 500;
providersNote.setLayoutData(gridData);
providersNote.setText(SecUIMessages.providerDescription);
Composite providersComp = new Composite(providersGroup, SWT.NONE);
providersComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GridLayout gridLayout = new GridLayout(2, false);
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
providersComp.setLayout(gridLayout);
providerTable = new Table(providersComp, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION | SWT.CHECK);
GridData tableData = new GridData(GridData.FILL, GridData.FILL, true, true);
providerTable.setLayoutData(tableData);
providerTable.setLinesVisible(true);
providerTable.setHeaderVisible(true);
fillProviderTable();
providerTable.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
public void widgetSelected(SelectionEvent e) {
if ((e.detail & SWT.CHECK) != 0)
providerModified = true;
enableButtons();
updateDescription();
}
});
GridDataFactory.defaultsFor(providerTable).span(1, 2).applyTo(providerTable);
buttonChangePassword = new Button(providersComp, SWT.PUSH);
buttonChangePassword.setText(SecUIMessages.changePasswordButton);
buttonChangePassword.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false));
buttonChangePassword.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
public void widgetSelected(SelectionEvent e) {
PasswordProviderDescription selectedModule = getSelectedModule();
if (selectedModule == null)
return;
String moduleID = getSelectedModuleID();
ISecurePreferences rootNode = SecurePreferencesFactory.getDefault();
if (selectedModule.hasHint(InternalExchangeUtils.HINT_PASSWORD_AUTOGEN)) {
// do replacement behind the scene without showing the wizard
changePassword(rootNode, moduleID, selectedModule.getName(), shell);
} else {
// show the wizard to provide separate "old" and "new" password entries
ChangePasswordWizardDialog dialog = new ChangePasswordWizardDialog(shell, rootNode, moduleID);
dialog.open();
}
enableLogout();
}
});
setButtonSize(buttonChangePassword);
buttonRecoverPassword = new Button(providersComp, SWT.PUSH);
buttonRecoverPassword.setText(SecUIMessages.recoverPasswordButton);
buttonRecoverPassword.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false));
buttonRecoverPassword.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
public void widgetSelected(SelectionEvent e) {
String moduleID = getSelectedModuleID();
ISecurePreferences rootNode = SecurePreferencesFactory.getDefault();
String[] questions = InternalExchangeUtils.getPasswordRecoveryQuestions(rootNode, moduleID);
if (questions.length == 0)
return; // no password recovery questions were setup
PasswordRecoveryDialog dialog = new PasswordRecoveryDialog(questions, shell, moduleID);
dialog.open();
enableLogout();
}
});
setButtonSize(buttonRecoverPassword);
enableButtons();
Label descriptionLabel = new Label(providersComp, SWT.NONE);
descriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
descriptionLabel.setText(SecUIMessages.providerDetails);
detailsText = new Text(providersComp, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.READ_ONLY | SWT.WRAP);
detailsText.setBackground(detailsText.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
gridData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
gridData.widthHint = 300;
gridData.heightHint = 65;
detailsText.setLayoutData(gridData);
updateDescription();
GridLayoutFactory.fillDefaults().margins(LayoutConstants.getSpacing()).generateLayout(page);
}
private void fillProviderTable() {
TableColumn idColumn = new TableColumn(providerTable, SWT.LEAD);
idColumn.setText(SecUIMessages.idColumn);
TableColumn priorityColumn = new TableColumn(providerTable, SWT.CENTER);
priorityColumn.setText(SecUIMessages.priorityColumn);
HashSet<String> disabledModules = getDisabledModules();
for (PasswordProviderDescription module : InternalExchangeUtils.passwordProvidersFind()) {
TableItem item = new TableItem(providerTable, SWT.NONE);
item.setText(new String[] {module.getName(), Integer.toString(module.getPriority())});
item.setData(module);
if (disabledModules == null)
item.setChecked(true);
else
item.setChecked(!disabledModules.contains(module.getId()));
}
TableLayout layout = new TableLayout();
layout.addColumnData(new ColumnWeightData(5));
layout.addColumnData(new ColumnWeightData(1));
providerTable.setLayout(layout);
if (providerTable.getItemCount() > 0)
providerTable.select(0);
}
protected PasswordProviderDescription getSelectedModule() {
if (providerTable == null)
return null;
TableItem[] items = providerTable.getSelection();
if (items.length == 0)
return null;
return ((PasswordProviderDescription) items[0].getData());
}
protected String getSelectedModuleID() {
PasswordProviderDescription selectedModule = getSelectedModule();
if (selectedModule == null)
return null;
return selectedModule.getId();
}
protected void enableButtons() {
String moduleID = getSelectedModuleID();
if (moduleID == null) { // nothing selected
buttonChangePassword.setEnabled(false);
buttonRecoverPassword.setEnabled(false);
} else {
buttonChangePassword.setEnabled(true);
ISecurePreferences rootNode = SecurePreferencesFactory.getDefault();
String path = PASSWORD_RECOVERY_NODE + moduleID;
boolean recoveryAvailable = rootNode.nodeExists(path);
buttonRecoverPassword.setEnabled(recoveryAvailable);
}
enableLogout();
}
protected HashSet<String> getDisabledModules() {
IScopeContext[] scopes = {ConfigurationScope.INSTANCE, DefaultScope.INSTANCE};
IPreferencesService preferencesService = Platform.getPreferencesService();
String defaultPreferenceValue = ""; //$NON-NLS-1$
String tmp = preferencesService.getString(PREFERENCES_PLUGIN, IStorageConstants.DISABLED_PROVIDERS_KEY, defaultPreferenceValue, scopes);
HashSet<String> disabledModules = splitModuleIds(tmp);
return disabledModules;
}
public void performDefaults() {
if (providerTable == null)
return;
Set<String> defaultDisabledModules = getDefaultDisabledModules();
TableItem[] items = providerTable.getItems();
for (TableItem item : items) {
String moduleId = getModuleId(item);
boolean enabled = defaultDisabledModules == null || moduleId == null || !defaultDisabledModules.contains(moduleId);
if (item.getChecked() != enabled) {
item.setChecked(enabled);
providerModified = true;
}
}
}
public void performOk() {
if (!providerModified)
return;
// save current selection
StringBuilder tmp = new StringBuilder();
boolean first = true;
TableItem[] items = providerTable.getItems();
for (TableItem item : items) {
if (item.getChecked()) {
continue;
}
if (!first)
tmp.append(',');
else
first = false;
tmp.append(((PasswordProviderDescription) item.getData()).getId());
}
IEclipsePreferences node = ConfigurationScope.INSTANCE.getNode(PREFERENCES_PLUGIN);
node.put(IStorageConstants.DISABLED_PROVIDERS_KEY, tmp.toString());
try {
node.flush();
} catch (BackingStoreException e) {
// nothing can be done
}
// logout so that previously selected default provider is not reused
InternalExchangeUtils.passwordProvidersReset();
}
public void onActivated() {
enableLogout();
}
protected void enableLogout() {
buttonClearPassword.setEnabled(InternalExchangeUtils.isLoggedIn());
}
protected void setButtonSize(Button button) {
GridDataFactory.defaultsFor(button).align(SWT.FILL, SWT.BEGINNING).grab(false, false).applyTo(button);
}
protected boolean changePassword(ISecurePreferences node, String moduleID, String name, Shell shell) {
ReEncrypter reEncrypter = new ReEncrypter(node, moduleID);
if (!reEncrypter.decrypt()) {
MessageBox messageBox = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_WARNING);
messageBox.setText(SecUIMessages.changePasswordWizardTitle);
messageBox.setMessage(SecUIMessages.wizardDecodeWarning);
if (messageBox.open() == SWT.YES)
return false;
}
if (!reEncrypter.switchToNewPassword()) {
MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
messageBox.setText(SecUIMessages.changePasswordWizardTitle);
messageBox.setMessage(SecUIMessages.wizardSwitchError);
messageBox.open();
return false;
}
reEncrypter.encrypt();
// all good
String msg = NLS.bind(SecUIMessages.passwordChangeDone, name);
MessageDialog.openInformation(StorageUtils.getShell(), SecUIMessages.generalDialogTitle, msg);
return true;
}
protected void updateDescription() {
PasswordProviderDescription selectedModule = getSelectedModule();
if (selectedModule != null && detailsText != null)
detailsText.setText(selectedModule.getDescription());
}
private HashSet<String> getDefaultDisabledModules() {
String defaultPreferenceValue = ""; //$NON-NLS-1$
Preferences pluginNode = DefaultScope.INSTANCE.getNode(PREFERENCES_PLUGIN);
String tmp = pluginNode.get(IStorageConstants.DISABLED_PROVIDERS_KEY, defaultPreferenceValue);
HashSet<String> defaultDisabledModules = splitModuleIds(tmp);
return defaultDisabledModules;
}
private String getModuleId(TableItem item) {
String moduleId = null;
Object itemData = item.getData();
if (itemData instanceof PasswordProviderDescription) {
PasswordProviderDescription module = (PasswordProviderDescription) itemData;
moduleId = module.getId();
}
return moduleId;
}
private static HashSet<String> splitModuleIds(String joinedModuleIds) {
if (joinedModuleIds == null || joinedModuleIds.isEmpty())
return null;
HashSet<String> modules = new HashSet<>();
String[] disabledProviders = joinedModuleIds.split(","); //$NON-NLS-1$
for (String disabledProvider : disabledProviders) {
modules.add(disabledProvider);
}
return modules;
}
}