diff options
author | Sam Davis | 2014-01-30 21:55:41 +0000 |
---|---|---|
committer | Sam Davis | 2014-02-18 22:47:19 +0000 |
commit | bc7ac9f9f49fb5d672ab6845faf1223b8f09eac5 (patch) | |
tree | 97f696bc5205d237213eb57c4584c88ff56702b6 | |
parent | e5b2bc7f021b1195509905f3397bb5086cecb167 (diff) | |
download | org.eclipse.mylyn.tasks-bc7ac9f9f49fb5d672ab6845faf1223b8f09eac5.tar.gz org.eclipse.mylyn.tasks-bc7ac9f9f49fb5d672ab6845faf1223b8f09eac5.tar.xz org.eclipse.mylyn.tasks-bc7ac9f9f49fb5d672ab6845faf1223b8f09eac5.zip |
278474: perform migration of credentials to secure storage
Change-Id: I590cabb6f09c9bdfe28532d47ba5dc04aa15bff2
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=278474
6 files changed, 366 insertions, 32 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/KeyringMigrator.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/KeyringMigrator.java new file mode 100644 index 000000000..5ccd8765e --- /dev/null +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/KeyringMigrator.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2014 Tasktop Technologies 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: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.core.util; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.mylyn.commons.core.StatusHandler; +import org.eclipse.mylyn.commons.repositories.core.ILocationService; +import org.eclipse.mylyn.commons.repositories.core.auth.ICredentialsStore; +import org.eclipse.mylyn.internal.commons.repositories.core.LocationService; +import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; + +/** + * Reads properties from the deprecated Eclipse keyring and writes them to the {@link ICredentialsStore} provided by the + * {@link ILocationService}. + * + * @author Sam Davis + */ +public abstract class KeyringMigrator<T> { + protected final ILocationService service = LocationService.getDefault(); + + protected final String authRealm; + + protected final String authScheme; + + public KeyringMigrator(String authRealm, String authScheme) { + this.authRealm = authRealm; + this.authScheme = authScheme; + } + + /** + * Migrate credentials for the given locations + */ + public void migrateCredentials(Collection<T> locations) { + for (T location : locations) { + migrateCredentials(location); + } + } + + @SuppressWarnings({ "unchecked", "deprecation" }) + protected void migrateCredentials(T location) { + try { + Map<String, String> properties = getAuthorizationInfo(getUrl(location)); + putProperties(properties, location); + } catch (MalformedURLException e) { + StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, + "Error migrating keyring credentials for " + getUrl(location), e)); //$NON-NLS-1$ + } + } + + protected Map<String, String> getAuthorizationInfo(String url) throws MalformedURLException { + return Platform.getAuthorizationInfo(new URL(url), authRealm, authScheme); + } + + protected void putProperties(Map<String, String> properties, T location) { + if (properties != null) { + ICredentialsStore store = service.getCredentialsStore(getUrl(location)); + for (Entry<String, String> entry : properties.entrySet()) { + putKeyValue(location, entry.getKey(), entry.getValue(), store); + } + } + } + + protected void putKeyValue(T location, String key, String value, ICredentialsStore store) { + store.put(key, value, key.endsWith(".password")); //$NON-NLS-1$ + } + + protected abstract String getUrl(T location); +} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositoryKeyringMigrator.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositoryKeyringMigrator.java new file mode 100644 index 000000000..d86d87832 --- /dev/null +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositoryKeyringMigrator.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 Tasktop Technologies 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: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.core.util; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.mylyn.commons.core.StatusHandler; +import org.eclipse.mylyn.commons.repositories.core.auth.ICredentialsStore; +import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +/** + * Extends {@link KeyringMigrator} to migrate TaskRepository credentials, including usernames which are stored in the + * repository properties. + * + * @author Sam Davis + */ +public class TaskRepositoryKeyringMigrator extends KeyringMigrator<TaskRepository> { + private static final String KEY_USERNAME = "org.eclipse.mylyn.tasklist.repositories.username"; //$NON-NLS-1$ + + protected static URL defaultUrl; + static { + try { + defaultUrl = new URL("http://eclipse.org/mylyn"); //$NON-NLS-1$ + } catch (MalformedURLException e) { + StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, e.getMessage(), e)); + } + } + + public TaskRepositoryKeyringMigrator(String authRealm, String authScheme) { + super(authRealm, authScheme); + } + + @Override + public void migrateCredentials(Collection<TaskRepository> locations) { + StatusHandler.log(new Status(IStatus.INFO, ITasksCoreConstants.ID_PLUGIN, + "Migrating task repository credentials from keyring.")); //$NON-NLS-1$ + super.migrateCredentials(locations); + } + + @Override + protected Map<String, String> getAuthorizationInfo(String url) throws MalformedURLException { + try { + return super.getAuthorizationInfo(url); + } catch (MalformedURLException e) { + return Platform.getAuthorizationInfo(defaultUrl, url, authScheme); + } + } + + @Override + protected String getUrl(TaskRepository location) { + return location.getRepositoryUrl(); + } + + @Override + protected void putKeyValue(TaskRepository location, String key, String value, ICredentialsStore store) { + if (KEY_USERNAME.equals(key)) { + location.setProperty(key, value); + } else { + super.putKeyValue(location, key, value, store); + } + } +} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositorySecureStoreMigrator.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositorySecureStoreMigrator.java new file mode 100644 index 000000000..4d43bdee8 --- /dev/null +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/util/TaskRepositorySecureStoreMigrator.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2014 Tasktop Technologies 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: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.core.util; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.security.storage.EncodingUtils; +import org.eclipse.equinox.security.storage.ISecurePreferences; +import org.eclipse.equinox.security.storage.SecurePreferencesFactory; +import org.eclipse.equinox.security.storage.StorageException; +import org.eclipse.mylyn.commons.core.StatusHandler; +import org.eclipse.mylyn.commons.repositories.core.ILocationService; +import org.eclipse.mylyn.commons.repositories.core.auth.ICredentialsStore; +import org.eclipse.mylyn.internal.commons.repositories.core.LocationService; +import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +/** + * Reads all data from the old "org.eclipse.mylyn.tasks.core" secure store node and writes it to the + * {@link ICredentialsStore} provided by the {@link ILocationService}. + * + * @author Sam Davis + */ +public class TaskRepositorySecureStoreMigrator { + private final ILocationService service = LocationService.getDefault(); + + public void migrateCredentials(Collection<TaskRepository> repositories) { + if (!SecurePreferencesFactory.getDefault().nodeExists(ITasksCoreConstants.ID_PLUGIN)) { + // check that the old node exists so that we don't create an empty node + return; + } + StatusHandler.log(new Status(IStatus.INFO, ITasksCoreConstants.ID_PLUGIN, + "Migrating task repository credentials from old secure store node.")); //$NON-NLS-1$ + Set<String> repositoryUrls = getRepositoryUrls(repositories); + ISecurePreferences oldRootNode = SecurePreferencesFactory.getDefault().node(ITasksCoreConstants.ID_PLUGIN); + for (String child : oldRootNode.childrenNames()) { + ISecurePreferences repositoryNode = oldRootNode.node(child); + String repositoryUrl = EncodingUtils.decodeSlashes(repositoryNode.name()); + if (repositoryUrls.contains(repositoryUrl)) { + ICredentialsStore store = service.getCredentialsStore(repositoryUrl); + for (String key : repositoryNode.keys()) { + try { + String value = repositoryNode.get(key, null); + store.put(key, value, repositoryNode.isEncrypted(key)); + } catch (StorageException e) { + StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, + "Error migrating secure store credentials for " + repositoryUrl, e)); //$NON-NLS-1$ + } + } + } + } + } + + private Set<String> getRepositoryUrls(Collection<TaskRepository> repositories) { + Set<String> repositoryUrls = new HashSet<String>(); + for (TaskRepository taskRepository : repositories) { + repositoryUrls.add(taskRepository.getRepositoryUrl()); + } + return repositoryUrls; + } +} diff --git a/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF index b5958b8aa..0c7f82b1f 100644 --- a/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF @@ -30,7 +30,8 @@ Require-Bundle: org.junit;bundle-version="4.8.2", org.eclipse.mylyn.tasks.search, org.eclipse.mylyn.tasks.ui, org.eclipse.mylyn.tests.util, - org.eclipse.mylyn.commons.repositories.core + org.eclipse.mylyn.commons.repositories.core, + org.eclipse.core.runtime.compatibility.auth Export-Package: org.eclipse.mylyn.tasks.tests;x-internal:=true, org.eclipse.mylyn.tasks.tests.bugs;x-internal:=true, org.eclipse.mylyn.tasks.tests.connector;x-friends:="org.eclipse.mylyn.tasks.ui.tests", diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskRepositoryManagerTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskRepositoryManagerTest.java index fa176c870..04e7a5721 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskRepositoryManagerTest.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TaskRepositoryManagerTest.java @@ -12,22 +12,31 @@ package org.eclipse.mylyn.tasks.tests; import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import junit.framework.TestCase; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; import org.eclipse.equinox.security.storage.EncodingUtils; import org.eclipse.equinox.security.storage.ISecurePreferences; import org.eclipse.equinox.security.storage.SecurePreferencesFactory; +import org.eclipse.equinox.security.storage.StorageException; import org.eclipse.mylyn.commons.net.AuthenticationCredentials; import org.eclipse.mylyn.commons.net.AuthenticationType; import org.eclipse.mylyn.internal.tasks.core.AbstractTask; +import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector; import org.eclipse.mylyn.internal.tasks.core.RepositoryTaskHandleUtil; import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager; +import org.eclipse.mylyn.internal.tasks.core.util.TaskRepositoryKeyringMigrator; +import org.eclipse.mylyn.internal.tasks.core.util.TaskRepositorySecureStoreMigrator; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; import org.eclipse.mylyn.tasks.core.ITask; @@ -66,6 +75,12 @@ public class TaskRepositoryManagerTest extends TestCase { private final String AUTH_HTTP_USERNAME = AUTH_HTTP + USERNAME; + private static final String AUTH_PROXY = "org.eclipse.mylyn.tasklist.repositories.proxy"; //$NON-NLS-1$ + + private final String AUTH_PROXY_PASSWORD = AUTH_PROXY + PASSWORD; + + private final String AUTH_PROXY_USERNAME = AUTH_PROXY + USERNAME; + private final String AUTH_SCHEME = "Basic"; //$NON-NLS-1$ private final String AUTH_REALM = ""; //$NON-NLS-1$ @@ -119,37 +134,61 @@ public class TaskRepositoryManagerTest extends TestCase { assertEquals("httpPassword", repository.getCredentials(AuthenticationType.HTTP).getPassword()); } - // FIXME 3.5 re-enable test -// public void testMigrationToSecureStorage() throws Exception { -// TaskRepository repository1 = new TaskRepository("bugzilla", "http://repository1/"); -// -// Map<String, String> map = new HashMap<String, String>(); -// map.put(AUTH_USERNAME, "testuser"); -// map.put(AUTH_PASSWORD, "testpassword"); -// map.put(AUTH_HTTP_USERNAME, "testhttpuser"); -// map.put(AUTH_HTTP_PASSWORD, "testhttppassword"); -// -// Platform.addAuthorizationInfo(new URL(repository1.getUrl()), AUTH_REALM, AUTH_SCHEME, map); -// -// map = Platform.getAuthorizationInfo(new URL(repository1.getUrl()), AUTH_REALM, AUTH_SCHEME); -// -// assertEquals("testuser", map.get(AUTH_USERNAME)); -// assertEquals("testpassword", map.get(AUTH_PASSWORD)); -// assertEquals("testhttpuser", map.get(AUTH_HTTP_USERNAME)); -// assertEquals("testhttppassword", map.get(AUTH_HTTP_PASSWORD)); -// -// assertTrue(manager.migrateToSecureStorage(repository1)); -// -// assertNull(Platform.getAuthorizationInfo(new URL(repository1.getUrl()), AUTH_REALM, AUTH_SCHEME)); -// -// ISecurePreferences securePreferences = SecurePreferencesFactory.getDefault() -// .node(ITasksCoreConstants.ID_PLUGIN); -// securePreferences = securePreferences.node(EncodingUtils.encodeSlashes(repository1.getUrl())); -// assertEquals("testuser", securePreferences.get(AUTH_USERNAME, null)); -// assertEquals("testpassword", securePreferences.get(AUTH_PASSWORD, null)); -// assertEquals("testhttpuser", securePreferences.get(AUTH_HTTP_USERNAME, null)); -// assertEquals("testhttppassword", securePreferences.get(AUTH_HTTP_PASSWORD, null)); -// } + public void testMigrationFromKeyring() throws Exception { + Map<String, String> authInfo = new HashMap<String, String>(); + authInfo.put(AUTH_USERNAME, "testuser"); + authInfo.put(AUTH_PASSWORD, "testpassword"); + authInfo.put(AUTH_HTTP_USERNAME, "testhttpuser"); + authInfo.put(AUTH_HTTP_PASSWORD, "testhttppassword"); + authInfo.put(AUTH_PROXY_USERNAME, "testproxyuser"); + authInfo.put(AUTH_PROXY_PASSWORD, "testproxypassword"); + + TaskRepository repository = new TaskRepository("bugzilla", "http://example.com/"); + repository.flushAuthenticationCredentials(); + Platform.addAuthorizationInfo(new URL(repository.getUrl()), AUTH_REALM, AUTH_SCHEME, authInfo); + new TaskRepositoryKeyringMigrator(AUTH_REALM, AUTH_SCHEME).migrateCredentials(Collections.singleton(repository)); + assertCredentialsMigrated(repository); + + repository = new TaskRepository("bugzilla", "I am not a url."); + repository.flushAuthenticationCredentials(); + Platform.addAuthorizationInfo(new URL("http://eclipse.org/mylyn"), repository.getUrl(), AUTH_SCHEME, authInfo); + new TaskRepositoryKeyringMigrator(AUTH_REALM, AUTH_SCHEME).migrateCredentials(Collections.singleton(repository)); + assertCredentialsMigrated(repository); + } + + public void testMigrationFromOldSecureStoreNode() throws Exception { + TaskRepository repository = new TaskRepository("bugzilla", "http://example.com/"); + repository.flushAuthenticationCredentials(); + repository.setProperty(AUTH_USERNAME, "testuser"); + + ISecurePreferences oldNode = SecurePreferencesFactory.getDefault().node(ITasksCoreConstants.ID_PLUGIN); + oldNode = oldNode.node(EncodingUtils.encodeSlashes(repository.getUrl())); + oldNode.put(AUTH_PASSWORD, "testpassword", true); + oldNode.put(AUTH_HTTP_USERNAME, "testhttpuser", false); + oldNode.put(AUTH_HTTP_PASSWORD, "testhttppassword", true); + oldNode.put(AUTH_PROXY_USERNAME, "testproxyuser", false); + oldNode.put(AUTH_PROXY_PASSWORD, "testproxypassword", true); + + new TaskRepositorySecureStoreMigrator().migrateCredentials(Collections.singleton(repository)); + assertCredentialsMigrated(repository); + } + + private void assertCredentialsMigrated(TaskRepository repository) throws CoreException, MalformedURLException, + StorageException { + assertEquals("testuser", repository.getProperty(AUTH_USERNAME)); + + ISecurePreferences newNode = SecurePreferencesFactory.getDefault().node(SECURE_CREDENTIALS_STORE_NODE_ID); + newNode = newNode.node(EncodingUtils.encodeSlashes(repository.getUrl())); + assertEquals("testpassword", newNode.get(AUTH_PASSWORD, null)); + assertEquals("testhttpuser", newNode.get(AUTH_HTTP_USERNAME, null)); + assertEquals("testhttppassword", newNode.get(AUTH_HTTP_PASSWORD, null)); + assertEquals("testproxyuser", newNode.get(AUTH_PROXY_USERNAME, null)); + assertEquals("testproxypassword", newNode.get(AUTH_PROXY_PASSWORD, null)); + + for (String key : newNode.childrenNames()) { + assertEquals(key.endsWith(PASSWORD), newNode.isEncrypted(key)); + } + } public void testRepositoryWithSlash() throws MalformedURLException { diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java index 1855dabdf..2ebc38160 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java @@ -85,6 +85,8 @@ import org.eclipse.mylyn.internal.tasks.core.externalization.ExternalizationMana import org.eclipse.mylyn.internal.tasks.core.externalization.IExternalizationParticipant; import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizationParticipant; import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer; +import org.eclipse.mylyn.internal.tasks.core.util.TaskRepositoryKeyringMigrator; +import org.eclipse.mylyn.internal.tasks.core.util.TaskRepositorySecureStoreMigrator; import org.eclipse.mylyn.internal.tasks.core.util.TasksCoreExtensionReader; import org.eclipse.mylyn.internal.tasks.ui.actions.ActivateTaskDialogAction; import org.eclipse.mylyn.internal.tasks.ui.actions.NewTaskAction; @@ -144,6 +146,12 @@ public class TasksUiPlugin extends AbstractUIPlugin { private static final int NOTIFICATION_DELAY = 5000; + private static final String PREF_MIGRATED_TASK_REPOSITORIES_FROM_SECURE_STORE = "migrated.task.repositories.secure.store"; //$NON-NLS-1$ + + private static final String PREF_MIGRATED_TASK_REPOSITORIES_FROM_KEYRING = "migrated.task.repositories.keyring"; //$NON-NLS-1$ + + private static final String PROP_FORCE_CREDENTIALS_MIGRATION = "org.eclipse.mylyn.tasks.force.credentials.migration"; //$NON-NLS-1$ + private static TasksUiPlugin INSTANCE; private static ExternalizationManager externalizationManager; @@ -669,6 +677,8 @@ public class TasksUiPlugin extends AbstractUIPlugin { // initialize managers initializeDataSources(); + migrateCredentials(repositoryManager.getAllRepositories()); + // make this available early for clients that are not initialized through tasks ui but need access taskListNotificationManager = new TaskListNotificationManager(); @@ -704,6 +714,47 @@ public class TasksUiPlugin extends AbstractUIPlugin { } } + /** + * Migrate credentials from the old secure store location, and from the deprecated keyring if the compatibility.auth + * bundle is present. + */ + @SuppressWarnings("deprecation") + private void migrateCredentials(final List<TaskRepository> repositories) { + // Use a UI job to ensure the UI has loaded + new UIJob("Credential Migration UI Job") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + // use a Job to ensure we do not access the secure store on the UI thread + new Job("Credential Migration") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + boolean force = Boolean.parseBoolean(System.getProperty(PROP_FORCE_CREDENTIALS_MIGRATION)); + if (force) { + StatusHandler.log(new Status(IStatus.INFO, ITasksCoreConstants.ID_PLUGIN, NLS.bind( + "Forcing task repository credential migration because system property {0} is set.", //$NON-NLS-1$ + PROP_FORCE_CREDENTIALS_MIGRATION))); + } + if (force + || !getPluginPreferences().getBoolean(PREF_MIGRATED_TASK_REPOSITORIES_FROM_SECURE_STORE)) { + new TaskRepositorySecureStoreMigrator().migrateCredentials(repositories); + } + if ((force || !getPluginPreferences().getBoolean(PREF_MIGRATED_TASK_REPOSITORIES_FROM_KEYRING)) + && isKeyringInstalled()) { + new TaskRepositoryKeyringMigrator("", "Basic").migrateCredentials(repositories); //$NON-NLS-1$ //$NON-NLS-2$ + } + return Status.OK_STATUS; + } + + }.schedule(); + return Status.OK_STATUS; + } + }.schedule(); + } + + private boolean isKeyringInstalled() { + return Platform.getBundle("org.eclipse.core.runtime.compatibility.auth") != null; //$NON-NLS-1$ + } + private void initHttpLogging() { System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); //$NON-NLS-1$ //$NON-NLS-2$ System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -821,6 +872,12 @@ public class TasksUiPlugin extends AbstractUIPlugin { identityServiceTracker = null; } + // wait until stop() to set these to reduce chance of crash after setting them but before creds are persisted + getPluginPreferences().setValue(PREF_MIGRATED_TASK_REPOSITORIES_FROM_SECURE_STORE, Boolean.toString(true)); + if (isKeyringInstalled()) { + getPluginPreferences().setValue(PREF_MIGRATED_TASK_REPOSITORIES_FROM_KEYRING, Boolean.toString(true)); + } + if (PlatformUI.isWorkbenchRunning()) { if (taskListNotificationManager != null) { getPreferenceStore().removePropertyChangeListener(taskListNotificationManager); |