From c58cb2bc0ee0ea8eda1def8c5d003793ff34152e Mon Sep 17 00:00:00 2001 From: arukhlin Date: Sat, 29 Apr 2017 10:34:11 -0400 Subject: [PATCH 1/8] Update targets Use EGit 4.6 Remove not supported targets 3.5, 3.7 --- .../3.5.target | 17 ----------------- .../3.7.target | 17 ----------------- .../4.6.target | 16 ++++++++-------- 3 files changed, 8 insertions(+), 42 deletions(-) delete mode 100644 source/com.microsoft.tfs.client.eclipse.target/3.5.target delete mode 100644 source/com.microsoft.tfs.client.eclipse.target/3.7.target diff --git a/source/com.microsoft.tfs.client.eclipse.target/3.5.target b/source/com.microsoft.tfs.client.eclipse.target/3.5.target deleted file mode 100644 index 2f1d875ce..000000000 --- a/source/com.microsoft.tfs.client.eclipse.target/3.5.target +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/source/com.microsoft.tfs.client.eclipse.target/3.7.target b/source/com.microsoft.tfs.client.eclipse.target/3.7.target deleted file mode 100644 index d6c53d948..000000000 --- a/source/com.microsoft.tfs.client.eclipse.target/3.7.target +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/source/com.microsoft.tfs.client.eclipse.target/4.6.target b/source/com.microsoft.tfs.client.eclipse.target/4.6.target index e1a484f50..0ee2b840a 100644 --- a/source/com.microsoft.tfs.client.eclipse.target/4.6.target +++ b/source/com.microsoft.tfs.client.eclipse.target/4.6.target @@ -1,16 +1,16 @@ - + - - + + + + + - - - - - + + From acb6182316fbf7a8b602471e0f09324cc3ce5974 Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Fri, 28 Apr 2017 17:37:32 -0400 Subject: [PATCH 2/8] Story #985181 - Allow specifying PAT credentials for a TFS server --- .../ui/config/UITransportRequestHandler.java | 2 +- .../controls/connect/ServerListControl.java | 46 ++++- .../ui/dialogs/connect/AddServerDialog.java | 51 +++++ .../ui/dialogs/connect/ServerAuthDialog.java | 161 ++++++++++++++++ .../common/ui/helpers/CredentialsHelper.java | 2 +- .../tfs/client/common/ui/messages.properties | 8 + .../EclipseCredentialsManagerFactory.java | 25 +-- .../internal/EclipseCredentialsManager.java | 178 ++++-------------- ...izardCrossCollectionRepoSelectionPage.java | 2 +- .../core/httpclient/HttpMethodDirector.java | 16 +- .../methods/EntityEnclosingMethod.java | 2 +- .../httpclient/DefaultHTTPClientFactory.java | 2 + 12 files changed, 324 insertions(+), 171 deletions(-) create mode 100644 source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java index 3b9c2670d..a660d3caa 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java @@ -283,7 +283,7 @@ && isPatCredentials(connectionInstanceData.getCredentials())) { // PAT token is probably expired. Remove it from the Eclipse // secure storage and retry. final CredentialsManager credentialsManager = - EclipseCredentialsManagerFactory.getGitCredentialsManager(); + EclipseCredentialsManagerFactory.getCredentialsManager(); credentialsManager.removeCredentials(connectionInstanceData.getServerURI()); dialogRunnable = new UITransportOAuthRunnable(connectionInstanceData.getServerURI()); } else { diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java index 3eb3e10cd..6f92198c8 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java @@ -23,6 +23,7 @@ import com.microsoft.tfs.client.common.ui.Messages; import com.microsoft.tfs.client.common.ui.controls.generic.BaseControl; import com.microsoft.tfs.client.common.ui.dialogs.connect.AddServerDialog; +import com.microsoft.tfs.client.common.ui.dialogs.connect.ServerAuthDialog; import com.microsoft.tfs.client.common.ui.framework.helper.SWTUtil; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; import com.microsoft.tfs.client.common.ui.framework.validation.ButtonValidatorBinding; @@ -31,7 +32,10 @@ import com.microsoft.tfs.client.common.ui.helpers.UIConnectionPersistence; import com.microsoft.tfs.core.TFSConnection; import com.microsoft.tfs.core.config.persistence.DefaultPersistenceStoreProvider; +import com.microsoft.tfs.core.credentials.CachedCredentials; import com.microsoft.tfs.core.credentials.CredentialsManager; +import com.microsoft.tfs.core.httpclient.CookieCredentials; +import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.util.ServerURIUtils; import com.microsoft.tfs.core.util.serverlist.ServerList; import com.microsoft.tfs.core.util.serverlist.ServerListConfigurationEntry; @@ -40,6 +44,7 @@ public class ServerListControl extends BaseControl { public static final String SERVERS_TABLE_ID = "ServerListControl.profilesTable"; //$NON-NLS-1$ public static final String ADD_BUTTON_ID = "ServerListControl.addButton"; //$NON-NLS-1$ + public static final String AUTH_BUTTON_ID = "ServerListControl.authButton"; //$NON-NLS-1$ public static final String DELETE_BUTTON_ID = "ServerListControl.deleteButton"; //$NON-NLS-1$ public static final String CLEAR_BUTTON_ID = "ServerListControl.clearButton"; //$NON-NLS-1$ @@ -83,6 +88,17 @@ public void widgetSelected(final SelectionEvent e) { } }); + final Button authButton = SWTUtil.createButton(this, Messages.getString("ServerListControl.AuthButtonText")); //$NON-NLS-1$ + AutomationIDHelper.setWidgetID(authButton, AUTH_BUTTON_ID); + GridDataBuilder.newInstance().hFill().wButtonHint(authButton).applyTo(authButton); + authButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + ServerListControl.this.onAuthButtonSelected(e); + } + }); + new ButtonValidatorBinding(authButton).bind(serverListTable.getSelectionValidator()); + final Button deleteButton = SWTUtil.createButton(this, Messages.getString("ServerListControl.DeleteButtonText")); //$NON-NLS-1$ AutomationIDHelper.setWidgetID(deleteButton, DELETE_BUTTON_ID); @@ -123,6 +139,9 @@ public void selectionChanged(final SelectionChangedEvent event) { // is selected deleteButton.setEnabled(!currentServerSelected); + // Enable authentication button if one and only one server is + // selected + authButton.setEnabled(selectedEntries.length == 1); } }); } @@ -164,6 +183,31 @@ private void onAddButtonSelected(final SelectionEvent e) { } } + private void onAuthButtonSelected(SelectionEvent e) { + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); + + final ServerListConfigurationEntry[] serverListEntries = serverListTable.getSelectedServerListEntries(); + final ServerListConfigurationEntry selectedEntry = serverListEntries[0]; + final URI serverUrl = selectedEntry.getURI(); + + final ServerAuthDialog credentialsDialog = new ServerAuthDialog(getShell(), serverUrl); + + final CachedCredentials oldCachedCredentials = credentialsManager.getCredentials(serverUrl); + if (oldCachedCredentials != null) { + final Credentials savedCredentials = oldCachedCredentials.toCredentials(); + if (savedCredentials == null || !(savedCredentials instanceof CookieCredentials)) { + credentialsDialog.setCredentials(savedCredentials); + } + } + + if (credentialsDialog.open() == IDialogConstants.OK_ID) { + final Credentials credentials = credentialsDialog.getCredentials(); + + final CachedCredentials newCachedCredentials = new CachedCredentials(serverUrl, credentials); + credentialsManager.setCredentials(newCachedCredentials); + } + } + private void onDeleteButtonSelected(final SelectionEvent e) { final ServerListConfigurationEntry[] serverListEntries = serverListTable.getSelectedServerListEntries(); @@ -231,7 +275,7 @@ private void removeCredentials(final ServerListConfigurationEntry[] serverListEn final CredentialsManager teeCredentialsProvider = EclipseCredentialsManagerFactory.getCredentialsManager(DefaultPersistenceStoreProvider.INSTANCE); - final CredentialsManager gitCredentialsProvider = EclipseCredentialsManagerFactory.getGitCredentialsManager(); + final CredentialsManager gitCredentialsProvider = EclipseCredentialsManagerFactory.getCredentialsManager(); boolean removeOAuth2Token = false; for (int i = 0; i < serverListEntries.length; i++) { diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java index 418b5a481..c91ffdc1d 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java @@ -15,6 +15,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; +import com.microsoft.tfs.client.common.credentials.EclipseCredentialsManagerFactory; import com.microsoft.tfs.client.common.ui.Messages; import com.microsoft.tfs.client.common.ui.controls.connect.AddServerControl; import com.microsoft.tfs.client.common.ui.framework.dialog.BaseDialog; @@ -23,6 +24,10 @@ import com.microsoft.tfs.client.common.ui.tasks.ConnectToConfigurationServerTask; import com.microsoft.tfs.core.TFSConfigurationServer; import com.microsoft.tfs.core.TFSConnection; +import com.microsoft.tfs.core.credentials.CachedCredentials; +import com.microsoft.tfs.core.credentials.CredentialsManager; +import com.microsoft.tfs.core.httpclient.CookieCredentials; +import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.util.serverlist.ServerList; import com.microsoft.tfs.core.util.serverlist.ServerListConfigurationEntry; import com.microsoft.tfs.core.util.serverlist.ServerListEntryType; @@ -33,6 +38,9 @@ * @threadsafety unknown */ public class AddServerDialog extends BaseDialog { + + private static final int AUTH_BUTTON_ID = 3; + private AddServerControl addServerControl; private ServerList serverList; @@ -56,6 +64,8 @@ protected void hookAddToDialogArea(final Composite dialogArea) { addServerControl = new AddServerControl(dialogArea, SWT.NONE); GridDataBuilder.newInstance().grab().fill().applyTo(addServerControl); + this.addButtonDescription(AUTH_BUTTON_ID, "Authentication...", false); //$NON-NLS-1$ + setOptionResizableDirections(SWT.HORIZONTAL); } @@ -68,6 +78,24 @@ protected void createButtonsForButtonBar(final Composite parent) { super.createButtonsForButtonBar(parent); final Button okButton = getButton(IDialogConstants.OK_ID); new ButtonValidatorBinding(okButton).bind(addServerControl); + + final Button authButton = getButton(AUTH_BUTTON_ID); + new ButtonValidatorBinding(authButton).bind(addServerControl); + + // final Button authButton = getButton(AUTH_BUTTON_ID); + // authButton.addSelectionListener(new SelectionAdapter() { + // @Override + // public void widgetSelected(SelectionEvent event) { + // buttonPressed(((Integer) event.widget.getData()).intValue()); + // } + // }); + } + + @Override + protected void hookCustomButtonPressed(final int buttonId) { + if (buttonId == AUTH_BUTTON_ID) { + onAuthButtonSelected(); + } } @Override @@ -109,6 +137,29 @@ protected void okPressed() { super.okPressed(); } + private void onAuthButtonSelected() { + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); + + final URI serverUrl = addServerControl.getServerURI(); + + final ServerAuthDialog credentialsDialog = new ServerAuthDialog(getShell(), serverUrl); + + final CachedCredentials oldCachedCredentials = credentialsManager.getCredentials(serverUrl); + if (oldCachedCredentials != null) { + final Credentials savedCredentials = oldCachedCredentials.toCredentials(); + if (savedCredentials == null || !(savedCredentials instanceof CookieCredentials)) { + credentialsDialog.setCredentials(savedCredentials); + } + } + + if (credentialsDialog.open() == IDialogConstants.OK_ID) { + final Credentials credentials = credentialsDialog.getCredentials(); + + final CachedCredentials newCachedCredentials = new CachedCredentials(serverUrl, credentials); + credentialsManager.setCredentials(newCachedCredentials); + } + } + public TFSConnection getConnection() { return connection; } diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java new file mode 100644 index 000000000..3924b8763 --- /dev/null +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See License.txt in the repository root. + +package com.microsoft.tfs.client.common.ui.dialogs.connect; + +import java.net.URI; +import java.text.MessageFormat; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.microsoft.tfs.client.common.ui.Messages; +import com.microsoft.tfs.client.common.ui.framework.dialog.BaseDialog; +import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; +import com.microsoft.tfs.core.httpclient.Credentials; +import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; +import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials.PatCredentials; +import com.microsoft.tfs.util.Check; +import com.microsoft.tfs.util.StringUtil; + +public class ServerAuthDialog extends BaseDialog { + + private final URI serverURI; + private Credentials credentials; + private String savedUserName = StringUtil.EMPTY; + + private Text usernameText; + private Text passwordText; + private Button userpasswordButton; + private Button patButton; + + public ServerAuthDialog(final Shell parent, final URI serverURI) { + super(parent); + + Check.notNull(serverURI, "serverURI"); //$NON-NLS-1$ + this.serverURI = serverURI; + + setOptionPersistGeometry(false); + } + + public void setCredentials(final Credentials credentials) { + this.credentials = credentials; + } + + public Credentials getCredentials() { + return credentials; + } + + @Override + protected String provideDialogTitle() { + return Messages.getString("ServerAuthDialog.DialogTitleText"); //$NON-NLS-1$ + } + + @Override + protected void hookAddToDialogArea(final Composite dialogArea) { + final GridLayout layout = new GridLayout(2, false); + layout.marginWidth = getHorizontalMargin(); + layout.marginHeight = getVerticalMargin(); + layout.horizontalSpacing = getHorizontalSpacing(); + layout.verticalSpacing = getVerticalSpacing(); + dialogArea.setLayout(layout); + + final String messageFormat = Messages.getString("ServerAuthDialog.PromptMessageFormat"); //$NON-NLS-1$ + final String message = MessageFormat.format(messageFormat, serverURI.toString()); + + final Label promptLabel = new Label(dialogArea, SWT.NONE); + promptLabel.setText(message); + GridDataBuilder.newInstance().hSpan(2).hGrab().hFill().wHint( + convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH)).applyTo(promptLabel); + + final Label credentialsTypeLabel = new Label(dialogArea, SWT.NONE); + credentialsTypeLabel.setText(Messages.getString("ServerAuthDialog.CredentialsTypeLabel")); //$NON-NLS-1$ + + final Composite buttonComposite = new Composite(dialogArea, SWT.NONE); + final GridLayout buttonCompositeLayout = new GridLayout(2, false); + buttonCompositeLayout.horizontalSpacing = getHorizontalSpacing(); + buttonCompositeLayout.verticalSpacing = getVerticalSpacing(); + buttonCompositeLayout.marginWidth = 0; + buttonCompositeLayout.marginHeight = 0; + buttonComposite.setLayout(buttonCompositeLayout); + + userpasswordButton = new Button(buttonComposite, SWT.RADIO); + userpasswordButton.setText(Messages.getString("ServerAuthDialog.UserPasswordTypeLabel")); //$NON-NLS-1$ + userpasswordButton.setSelection(true); + // userpasswordButton.addSelectionListener(new SelectionAdapter() { + // @Override + // public void widgetSelected(final SelectionEvent e) { + // onCredentialTypeSelected(); + // } + // }); + + patButton = new Button(buttonComposite, SWT.RADIO); + patButton.setText(Messages.getString("ServerAuthDialog.PatTypeLabel")); //$NON-NLS-1$ + patButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + onCredentialTypeSelected(); + } + }); + + final Label usernameLabel = new Label(dialogArea, SWT.NONE); + usernameLabel.setText(Messages.getString("ServerAuthDialog.UsernameLabel")); //$NON-NLS-1$ + + usernameText = new Text(dialogArea, SWT.BORDER); + GridDataBuilder.newInstance().hGrab().hFill().applyTo(usernameText); + + final Label passwordLabel = new Label(dialogArea, SWT.NONE); + passwordLabel.setText(Messages.getString("ServerAuthDialog.PasswordTokenLabel")); //$NON-NLS-1$ + + passwordText = new Text(dialogArea, SWT.PASSWORD | SWT.BORDER); + GridDataBuilder.newInstance().hGrab().hFill().wCHint(passwordText, 16).applyTo(passwordText); + + if (credentials == null || credentials instanceof PatCredentials) { + patButton.setSelection(true); + userpasswordButton.setSelection(false); + } else if (credentials instanceof UsernamePasswordCredentials) { + savedUserName = ((UsernamePasswordCredentials) credentials).getUsername(); + usernameText.setText(savedUserName); + patButton.setSelection(false); + userpasswordButton.setSelection(true); + } + + if (usernameText.getText().length() > 0) { + passwordText.setFocus(); + } + + onCredentialTypeSelected(); + } + + private void onCredentialTypeSelected() { + if (patButton.getSelection()) { + savedUserName = usernameText.getText(); + usernameText.setText(StringUtil.EMPTY); + } else { + usernameText.setText(savedUserName); + } + usernameText.setEnabled(userpasswordButton.getSelection()); + } + + @Override + protected void okPressed() { + final String username = usernameText.getText(); + final String password = passwordText.getText(); + + if (userpasswordButton.getSelection()) { + credentials = new UsernamePasswordCredentials(username, password); + } else if (patButton.getSelection()) { + credentials = new PatCredentials(password); + } + + super.okPressed(); + } +} diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java index 6c7a10e0c..9422ae139 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java @@ -57,7 +57,7 @@ public abstract class CredentialsHelper { private final static String REDIRECT_URL = "https://java.visualstudio.com"; //$NON-NLS-1$ private final static CredentialsManager gitCredentialsManager = - EclipseCredentialsManagerFactory.getGitCredentialsManager(); + EclipseCredentialsManagerFactory.getCredentialsManager(); private final static SecretStore accessTokenStore = new InsecureInMemoryStore(); private final static SecretStore tokenStore = new EclipseTokenStore(); diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties index ae4e86de5..d47f539fc 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties @@ -1503,6 +1503,13 @@ SelectMergeVersionWizardPage.VersionTypeLabelText=&Version type: SelectQueryItemDialog.PromptLabelTextFormat={0}: SelectQueryItemDialog.SelectQueryDialogTitle=Select Query SelectQueryItemDialog.SelectQueryFolderDialogTitle=Select Query Folder +ServerAuthDialog.CredentialsTypeLabel=Credentials type: +ServerAuthDialog.DialogTitleText=Server authentication +ServerAuthDialog.PasswordTokenLabel=Password/Token +ServerAuthDialog.PatTypeLabel=Personal access token +ServerAuthDialog.PromptMessageFormat=Enter credentials for {0} +ServerAuthDialog.UsernameLabel=Username: +ServerAuthDialog.UserPasswordTypeLabel=Username and password ServerFolderPathCellEditor.BrowseForFolderDialogTitle=Browse for Folder ServerItemByItemSpecGenerator.NoServerItemFormat=No server item exists at path "{0}" in {1} ServerItemByItemSpecGenerator.ProgressQueryingServerFormat=Querying server items: {0} @@ -1524,6 +1531,7 @@ ServerItemTreeDialog.ItemPathLabelText=Item path: ServerItemTreeDialog.ItemsLabelText=Items: ServerItemTreeDialog.TfsLabelText=Team Project Collection: ServerListControl.AddButtonText=Add... +ServerListControl.AuthButtonText=Authentication... ServerListControl.ClearButtonText=Clear ServerListControl.ClearServerPromptFormat=Do you want to clear saved credentials for Team Foundation Server {0}? ServerListControl.ClearServersPrompt=Do you want to clear saved credentials for the selected Team Foundation Servers? diff --git a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/EclipseCredentialsManagerFactory.java b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/EclipseCredentialsManagerFactory.java index dd36cd863..06d0fbb8b 100644 --- a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/EclipseCredentialsManagerFactory.java +++ b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/EclipseCredentialsManagerFactory.java @@ -3,9 +3,9 @@ package com.microsoft.tfs.client.common.credentials; -import com.microsoft.tfs.client.common.credentials.internal.EclipseCredentialsManager.EclipseGitCredentialsManager; -import com.microsoft.tfs.client.common.credentials.internal.EclipseCredentialsManager.EclipseTeeCredentialsManager; +import com.microsoft.tfs.client.common.credentials.internal.EclipseCredentialsManager; import com.microsoft.tfs.core.config.ConnectionAdvisor; +import com.microsoft.tfs.core.config.persistence.DefaultPersistenceStoreProvider; import com.microsoft.tfs.core.config.persistence.PersistenceStoreProvider; import com.microsoft.tfs.core.credentials.CredentialsManager; import com.microsoft.tfs.util.Check; @@ -24,9 +24,9 @@ public class EclipseCredentialsManagerFactory { /** * Gets the best {@link CredentialsManager} for this platform. If the * platform provides credential management services (Windows CredMan, Mac OS - * X Keychain), an implementation that uses that service is returned, - * otherwise the given {@link PersistenceStoreProvider} may be used for - * storage. Test the returned {@link CredentialsManager} for its + * X Keychain, Gnome KeyRing), an implementation that uses that service is + * returned, otherwise the given {@link PersistenceStoreProvider} may be + * used for storage. Test the returned {@link CredentialsManager} for its * capabilities (whether it is secure, is read-only, etc.). * * @param persistenceProvider @@ -39,18 +39,13 @@ public static CredentialsManager getCredentialsManager(final PersistenceStorePro Check.notNull(persistenceProvider, "persistenceProvider"); //$NON-NLS-1$ /* - * EclipseCredentialsManager uses platformCredentialsManager for - * Username/Password credentials and Eclipse secure storage for - * CookieCredentials + * EclipseCredentialsManager uses platformCredentialsManager and Eclipse + * secure storage for Username/Password and PAT credentials. */ - return new EclipseTeeCredentialsManager(persistenceProvider); + return new EclipseCredentialsManager(persistenceProvider); } - public static CredentialsManager getGitCredentialsManager() { - /* - * EGit uses Eclipse secure storage only, i.e. - * platformCredentialsManager is null - */ - return new EclipseGitCredentialsManager(); + public static CredentialsManager getCredentialsManager() { + return new EclipseCredentialsManager(DefaultPersistenceStoreProvider.INSTANCE); } } diff --git a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java index c31f48281..85866e1b7 100644 --- a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java +++ b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java @@ -4,9 +4,6 @@ package com.microsoft.tfs.client.common.credentials.internal; import java.net.URI; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -19,18 +16,13 @@ import com.microsoft.tfs.core.credentials.CachedCredentials; import com.microsoft.tfs.core.credentials.CredentialsManager; import com.microsoft.tfs.core.credentials.CredentialsManagerFactory; -import com.microsoft.tfs.core.httpclient.Cookie; -import com.microsoft.tfs.core.httpclient.CookieCredentials; import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; -import com.microsoft.tfs.core.httpclient.cookie.CookiePolicy; -import com.microsoft.tfs.core.httpclient.cookie.CookieSpec; import com.microsoft.tfs.util.Check; import com.microsoft.tfs.util.StringUtil; public class EclipseCredentialsManager implements CredentialsManager { public static final String GIT_PATH_PREFIX = "/GIT/"; //$NON-NLS-1$ - public static final String TEE_PATH_PREFIX = "/TEE/"; //$NON-NLS-1$ private static final String USER_NAME = "user"; //$NON-NLS-1$ private static final String PASSWORD = "password"; //$NON-NLS-1$ @@ -47,17 +39,14 @@ public class EclipseCredentialsManager implements CredentialsManager { /* * The platform specific credentials manager is used for user name/password - * credentials only. The Eclipse secure storage is used for Federated cookie - * credentials + * credentials only. */ CredentialsManager platformCredentialsManager = null; - public EclipseCredentialsManager(final String rootPathPrefix) { - this(rootPathPrefix, null); - } + public EclipseCredentialsManager(final PersistenceStoreProvider persistenceProvider) { + Check.notNull(persistenceProvider, "persistenceProvider"); //$NON-NLS-1$ - public EclipseCredentialsManager(final String rootPathPrefix, final PersistenceStoreProvider persistenceProvider) { - this.rootPathPrefix = rootPathPrefix; + this.rootPathPrefix = GIT_PATH_PREFIX; this.preferences = SecurePreferencesFactory.getDefault(); this.persistenceProvider = persistenceProvider; } @@ -88,7 +77,6 @@ public CachedCredentials getCredentials(final URI serverURI) { final ISecurePreferences node = getSecureStorageNode(serverURI); if (node != null) { - try { final String storedUserName = node.get(USER_NAME, ""); //$NON-NLS-1$ final String password = node.get(PASSWORD, ""); //$NON-NLS-1$ @@ -96,81 +84,19 @@ public CachedCredentials getCredentials(final URI serverURI) { log.debug("User name & password credentials created"); //$NON-NLS-1$ return new CachedCredentials(serverURI, storedUserName, password); } - - /* Parse cookies according to RFC2109 */ - final CookieSpec cookieParser = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109); - - final String domain = serverURI.getHost(); - int port = serverURI.getPort(); - if (port < 0) { - if ("https".equalsIgnoreCase(serverURI.getScheme())) //$NON-NLS-1$ - { - port = 443; - } else { - port = 80; - } - } - - final String[] keys = node.keys(); - final List fedAuthCookies = new ArrayList(); - - for (int k = 0; k < keys.length; k++) { - if (keys[k].startsWith(COOKIE_PREFIX)) { - final String cookieValue = node.get(keys[k], ""); //$NON-NLS-1$ - - try { - final Cookie[] cookies = cookieParser.parse(domain, port, "/", true, cookieValue); //$NON-NLS-1$ - - for (final Cookie cookie : cookies) { - if (cookie.getName().startsWith(COOKIE_PREFIX)) { - /* - * Setting the following property to true - * makes cookies added to the HTTP headers - * contain the attribute $Path=/ and thus a - * semicolon between the cookie value and - * this attribute. - * - * This is a workaround for a bug in cookie - * processing on the server side: the cookie - * values has to be appended with a - * semicolon otherwise an error is reported - * either by .NET or TFS (not clear yet by - * which one exactly): - * - * "The input is not a valid Base-64 string - * as it contains a non-base 64 character, - * more than two padding characters, or an - * illegal character among the padding - * characters." - */ - cookie.setPathAttributeSpecified(true); - - fedAuthCookies.add(cookie); - } - } - } catch (final Exception e) { - log.warn(MessageFormat.format("Could not parse authentication cookie {0}", cookieValue), e); //$NON-NLS-1$ - } - } - } - - if (fedAuthCookies.size() > 0) { - final Credentials credentials = - new CookieCredentials(fedAuthCookies.toArray(new Cookie[fedAuthCookies.size()])); - - log.debug("Cookie credentials created"); //$NON-NLS-1$ - return new CachedCredentials(serverURI, credentials); - } } catch (final StorageException e) { log.error("Error reading credentials from the Eclipse secure store", e); //$NON-NLS-1$ } } - if (persistenceProvider == null) { - return null; - } else { - return getPlatformCredentialsManager().getCredentials(serverURI); + final CachedCredentials credentials = getPlatformCredentialsManager().getCredentials(serverURI); + if (credentials != null) { + final String credentialsType = credentials.isPatCredentials() ? "PAT" //$NON-NLS-1$ + : credentials.isUsernamePasswordCredentials() ? "User name & password" : "Unexpected"; //$NON-NLS-1$ //$NON-NLS-2$ + log.debug(credentialsType + " credentials created found in the platform credentials manager."); //$NON-NLS-1$ } + + return credentials; } private ISecurePreferences getSecureStorageNode(final URI serverURI) { @@ -191,51 +117,32 @@ private ISecurePreferences getSecureStorageNode(final URI serverURI) { public boolean setCredentials(final CachedCredentials cachedCredentials) { final Credentials credentials = cachedCredentials.toCredentials(); Check.isTrue( - credentials instanceof UsernamePasswordCredentials || credentials instanceof CookieCredentials, - "credentials must be UsernamePasswordCredentials or CookieCredentials"); //$NON-NLS-1$ + credentials instanceof UsernamePasswordCredentials, + "credentials must be UsernamePasswordCredentials"); //$NON-NLS-1$ - if (credentials instanceof CookieCredentials || persistenceProvider == null) { - try { - final String nodePath = getNodePath(cachedCredentials.getURI()); - final ISecurePreferences node = preferences.node(nodePath); - node.clear(); - - if (credentials instanceof UsernamePasswordCredentials) { - node.put(USER_NAME, ((UsernamePasswordCredentials) credentials).getUsername(), false); - node.put(PASSWORD, ((UsernamePasswordCredentials) credentials).getPassword(), true); - } else if (credentials instanceof CookieCredentials) { - final Cookie[] cookies = ((CookieCredentials) credentials).getCookies(); - Check.notNullOrEmpty(cookies, "cookies"); //$NON-NLS-1$ - - for (int k = 0; k < cookies.length; k++) { - if (cookies[k].getName().startsWith(COOKIE_PREFIX)) { - node.put( - COOKIE_PREFIX + (k == 0 ? StringUtil.EMPTY : String.valueOf(k)), - cookies[k].toString(), - true); - } - } - } + try { + final String nodePath = getNodePath(cachedCredentials.getURI()); + final ISecurePreferences node = preferences.node(nodePath); + node.clear(); + + node.put(USER_NAME, ((UsernamePasswordCredentials) credentials).getUsername(), false); + node.put(PASSWORD, ((UsernamePasswordCredentials) credentials).getPassword(), true); - node.flush(); - - return true; - } catch (final Exception e) { - log.error("Error writing credentials to the Eclipse secure store", e); //$NON-NLS-1$ - final String nodePath = getNodePath(cachedCredentials.getURI()); - try { - if (preferences.nodeExists(nodePath)) { - log.error("We'll remove the node " + nodePath + " in the credentials storage"); //$NON-NLS-1$ //$NON-NLS-2$ - preferences.remove(nodePath); - } - } catch (final Exception ex) { - log.error("Failed to remove the node", ex); //$NON-NLS-1$ + node.flush(); + } catch (final Exception e) { + log.error("Error writing credentials to the Eclipse secure store", e); //$NON-NLS-1$ + final String nodePath = getNodePath(cachedCredentials.getURI()); + try { + if (preferences.nodeExists(nodePath)) { + log.error("We'll remove the node " + nodePath + " in the credentials storage"); //$NON-NLS-1$ //$NON-NLS-2$ + preferences.remove(nodePath); } - return false; + } catch (final Exception ex) { + log.error("Failed to remove the node", ex); //$NON-NLS-1$ } - } else { - return getPlatformCredentialsManager().setCredentials(cachedCredentials); } + + return getPlatformCredentialsManager().setCredentials(cachedCredentials); } @Override @@ -247,12 +154,9 @@ public boolean removeCredentials(final URI uri) { final ISecurePreferences node = preferences.node(nodePath); node.clear(); node.removeNode(); - return true; - } else if (persistenceProvider != null) { - return getPlatformCredentialsManager().removeCredentials(uri); - } else { - return true; } + + return getPlatformCredentialsManager().removeCredentials(uri); } @Override @@ -311,18 +215,4 @@ private CredentialsManager getPlatformCredentialsManager() { return platformCredentialsManager; } - - public static class EclipseGitCredentialsManager extends EclipseCredentialsManager { - - public EclipseGitCredentialsManager() { - super(GIT_PATH_PREFIX, null); - } - } - - public static class EclipseTeeCredentialsManager extends EclipseCredentialsManager { - - public EclipseTeeCredentialsManager(final PersistenceStoreProvider persistenceProvider) { - super(TEE_PATH_PREFIX, persistenceProvider); - } - } } diff --git a/source/com.microsoft.tfs.client.eclipse.ui.egit/src/com/microsoft/tfs/client/eclipse/ui/egit/importwizard/WizardCrossCollectionRepoSelectionPage.java b/source/com.microsoft.tfs.client.eclipse.ui.egit/src/com/microsoft/tfs/client/eclipse/ui/egit/importwizard/WizardCrossCollectionRepoSelectionPage.java index 0f1b03501..c48d7f185 100644 --- a/source/com.microsoft.tfs.client.eclipse.ui.egit/src/com/microsoft/tfs/client/eclipse/ui/egit/importwizard/WizardCrossCollectionRepoSelectionPage.java +++ b/source/com.microsoft.tfs.client.eclipse.ui.egit/src/com/microsoft/tfs/client/eclipse/ui/egit/importwizard/WizardCrossCollectionRepoSelectionPage.java @@ -328,7 +328,7 @@ private CloneGitRepositoryCommand createCloneCommand( } private UsernamePasswordCredentials getCredentials(final TFSConnection connection) { - final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getGitCredentialsManager(); + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); Credentials savedCredentials = null; CachedCredentials cachedCredentials = credentialsManager.getCredentials(connection.getBaseURI()); diff --git a/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/HttpMethodDirector.java b/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/HttpMethodDirector.java index bfc19c687..63c920210 100644 --- a/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/HttpMethodDirector.java +++ b/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/HttpMethodDirector.java @@ -48,6 +48,7 @@ import com.microsoft.tfs.core.httpclient.auth.AuthState; import com.microsoft.tfs.core.httpclient.auth.AuthenticationException; import com.microsoft.tfs.core.httpclient.auth.AuthorizationHeaderScheme; +import com.microsoft.tfs.core.httpclient.auth.BasicScheme; import com.microsoft.tfs.core.httpclient.auth.CredentialsNotAvailableException; import com.microsoft.tfs.core.httpclient.auth.CredentialsProvider; import com.microsoft.tfs.core.httpclient.auth.MalformedChallengeException; @@ -150,15 +151,16 @@ public void executeMethod(final HttpMethod method) throws IOException, HttpExcep if (preemptiveCredentials != null && method.getDoAuthentication()) { method.getHostAuthState().setPreemptive(preemptiveCredentials); method.getHostAuthState().setAuthAttempted(true); + method.getHostAuthState().setAuthScheme(new BasicScheme()); /* - * Disabled. HttpClient used to force - * pre-emptive auth to the proxy if it was enabled for - * the host, but this doesn't work when the pre-emptive - * auth uses the Authorization header. Disabling will - * prevent Basic auth to proxies, which TEE never - * supported in the past because we never enabled - * pre-emptive authentication before Dev11. + * Disabled. HttpClient used to force pre-emptive auth + * to the proxy if it was enabled for the host, but this + * doesn't work when the pre-emptive auth uses the + * Authorization header. Disabling will prevent Basic + * auth to proxies, which TEE never supported in the + * past because we never enabled pre-emptive + * authentication before Dev11. */ // if (conn.isProxied() && !conn.isSecure()) // { diff --git a/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/methods/EntityEnclosingMethod.java b/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/methods/EntityEnclosingMethod.java index b6b694e28..2d4fc9e1e 100644 --- a/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/methods/EntityEnclosingMethod.java +++ b/source/com.microsoft.tfs.core.httpclient/src/com/microsoft/tfs/core/httpclient/methods/EntityEnclosingMethod.java @@ -178,7 +178,7 @@ protected void clearRequestBody() { * @since 2.0beta1 */ protected byte[] generateRequestBody() { - LOG.trace("enter EntityEnclosingMethod.renerateRequestBody()"); + LOG.trace("enter EntityEnclosingMethod.generateRequestBody()"); return null; } diff --git a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/config/httpclient/DefaultHTTPClientFactory.java b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/config/httpclient/DefaultHTTPClientFactory.java index 457b2c51e..4e8cd583c 100644 --- a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/config/httpclient/DefaultHTTPClientFactory.java +++ b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/config/httpclient/DefaultHTTPClientFactory.java @@ -27,6 +27,7 @@ import com.microsoft.tfs.core.httpclient.MultiThreadedHttpConnectionManager; import com.microsoft.tfs.core.httpclient.PreemptiveUsernamePasswordCredentials; import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; +import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials.PatCredentials; import com.microsoft.tfs.core.httpclient.auth.AuthScope; import com.microsoft.tfs.core.httpclient.params.HttpClientParams; import com.microsoft.tfs.core.httpclient.params.HttpConnectionManagerParams; @@ -474,6 +475,7 @@ public void configureClientCredentials( httpClient.getParams().setPreemptiveAuthenticationTypes(new Class[] { CookieCredentials.class, JwtCredentials.class, + PatCredentials.class, PreemptiveUsernamePasswordCredentials.class }); } From 12f886214f895d36a8f46401a84e91f8a5d3ab8c Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Wed, 7 Jun 2017 18:51:09 -0400 Subject: [PATCH 3/8] Change the credentials dialog --- .../ui/config/UITransportRequestHandler.java | 45 ++--- .../controls/connect/ServerListControl.java | 42 ++--- .../ui/dialogs/connect/AddServerDialog.java | 51 ++++-- .../ui/dialogs/connect/CredentialsDialog.java | 71 +++++++- .../ui/dialogs/connect/ServerAuthDialog.java | 161 ------------------ .../tfs/client/common/ui/messages.properties | 30 ++-- .../ui/prefs/CredentialsPreferencePage.java | 50 +++--- .../internal/EclipseCredentialsManager.java | 30 +++- .../core/credentials/CachedCredentials.java | 5 +- 9 files changed, 223 insertions(+), 262 deletions(-) delete mode 100644 source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java index a660d3caa..089d1ee06 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java @@ -31,7 +31,6 @@ import com.microsoft.tfs.core.httpclient.URI; import com.microsoft.tfs.core.httpclient.URIException; import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; -import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials.PatCredentials; import com.microsoft.tfs.core.httpclient.cookie.CookiePolicy; import com.microsoft.tfs.core.httpclient.cookie.CookieSpec; import com.microsoft.tfs.core.ws.runtime.client.SOAPRequest; @@ -278,18 +277,37 @@ public Status handleException( else if (exception instanceof UnauthorizedException && service.isPromptForCredentials()) { log.debug(" UnauthorizedException has been raised."); //$NON-NLS-1$ + final Credentials usedCredentials = connectionInstanceData.getCredentials(); + final java.net.URI serverUrl = connectionInstanceData.getServerURI(); + final Header[] authHeaders = request.getPostMethod().getResponseHeaders("WWW-Authenticate"); //$NON-NLS-1$ + boolean isHosted = true; + for (final Header header : authHeaders) { + if (header.getValue().equals("NTLM")) { //$NON-NLS-1$ + isHosted = false; + break; + } + if (header.getValue().equals("Negotiate")) { //$NON-NLS-1$ + isHosted = false; + break; + } + if (header.getValue().equals("Federated")) { //$NON-NLS-1$ + break; + } + } + if (EnvironmentVariables.getBoolean(EnvironmentVariables.USE_OAUTH_LIBRARY, true) - && isPatCredentials(connectionInstanceData.getCredentials())) { + && usedCredentials != null + && new CachedCredentials(serverUrl, usedCredentials).isPatCredentials() + && isHosted) { // PAT token is probably expired. Remove it from the Eclipse // secure storage and retry. - final CredentialsManager credentialsManager = - EclipseCredentialsManagerFactory.getCredentialsManager(); - credentialsManager.removeCredentials(connectionInstanceData.getServerURI()); - dialogRunnable = new UITransportOAuthRunnable(connectionInstanceData.getServerURI()); + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); + credentialsManager.removeCredentials(serverUrl); + dialogRunnable = new UITransportOAuthRunnable(serverUrl); } else { dialogRunnable = new UITransportUsernamePasswordAuthRunnable( - connectionInstanceData.getServerURI(), - connectionInstanceData.getCredentials(), + serverUrl, + usedCredentials, (UnauthorizedException) exception); } } @@ -331,17 +349,6 @@ else if (exception instanceof FederatedAuthFailedException) { return Status.COMPLETE; } - private boolean isPatCredentials(Credentials credentials) { - if (credentials == null) { - return false; - } else if (!(credentials instanceof UsernamePasswordCredentials)) { - return false; - } else { - final String userName = ((UsernamePasswordCredentials) credentials).getUsername(); - return PatCredentials.USERNAME_FOR_CODE_ACCESS_PAT.equals(userName); - } - } - private void cleanupSavedCredentials(final HttpClient client) { log.debug(" If any credentials were used they failed. Clean up saved credentials for the host"); //$NON-NLS-1$ diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java index 6f92198c8..6fc1d2557 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/connect/ServerListControl.java @@ -23,7 +23,7 @@ import com.microsoft.tfs.client.common.ui.Messages; import com.microsoft.tfs.client.common.ui.controls.generic.BaseControl; import com.microsoft.tfs.client.common.ui.dialogs.connect.AddServerDialog; -import com.microsoft.tfs.client.common.ui.dialogs.connect.ServerAuthDialog; +import com.microsoft.tfs.client.common.ui.dialogs.connect.CredentialsDialog; import com.microsoft.tfs.client.common.ui.framework.helper.SWTUtil; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; import com.microsoft.tfs.client.common.ui.framework.validation.ButtonValidatorBinding; @@ -31,10 +31,8 @@ import com.microsoft.tfs.client.common.ui.helpers.CredentialsHelper; import com.microsoft.tfs.client.common.ui.helpers.UIConnectionPersistence; import com.microsoft.tfs.core.TFSConnection; -import com.microsoft.tfs.core.config.persistence.DefaultPersistenceStoreProvider; import com.microsoft.tfs.core.credentials.CachedCredentials; import com.microsoft.tfs.core.credentials.CredentialsManager; -import com.microsoft.tfs.core.httpclient.CookieCredentials; import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.util.ServerURIUtils; import com.microsoft.tfs.core.util.serverlist.ServerList; @@ -99,6 +97,17 @@ public void widgetSelected(final SelectionEvent e) { }); new ButtonValidatorBinding(authButton).bind(serverListTable.getSelectionValidator()); + final Button clearButton = SWTUtil.createButton(this, Messages.getString("ServerListControl.ClearButtonText")); //$NON-NLS-1$ + AutomationIDHelper.setWidgetID(clearButton, CLEAR_BUTTON_ID); + GridDataBuilder.newInstance().hFill().wButtonHint(clearButton).applyTo(clearButton); + clearButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + ServerListControl.this.onClearButtonSelected(e); + } + }); + new ButtonValidatorBinding(clearButton).bind(serverListTable.getSelectionValidator()); + final Button deleteButton = SWTUtil.createButton(this, Messages.getString("ServerListControl.DeleteButtonText")); //$NON-NLS-1$ AutomationIDHelper.setWidgetID(deleteButton, DELETE_BUTTON_ID); @@ -111,17 +120,6 @@ public void widgetSelected(final SelectionEvent e) { }); new ButtonValidatorBinding(deleteButton).bind(serverListTable.getSelectionValidator()); - final Button clearButton = SWTUtil.createButton(this, Messages.getString("ServerListControl.ClearButtonText")); //$NON-NLS-1$ - AutomationIDHelper.setWidgetID(deleteButton, CLEAR_BUTTON_ID); - GridDataBuilder.newInstance().hFill().wButtonHint(clearButton).applyTo(clearButton); - clearButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - ServerListControl.this.onClearButtonSelected(e); - } - }); - new ButtonValidatorBinding(clearButton).bind(serverListTable.getSelectionValidator()); - serverListTable.addSelectionChangedListener(new ISelectionChangedListener() { @Override @@ -190,14 +188,11 @@ private void onAuthButtonSelected(SelectionEvent e) { final ServerListConfigurationEntry selectedEntry = serverListEntries[0]; final URI serverUrl = selectedEntry.getURI(); - final ServerAuthDialog credentialsDialog = new ServerAuthDialog(getShell(), serverUrl); + final CredentialsDialog credentialsDialog = new CredentialsDialog(getShell(), serverUrl); final CachedCredentials oldCachedCredentials = credentialsManager.getCredentials(serverUrl); - if (oldCachedCredentials != null) { - final Credentials savedCredentials = oldCachedCredentials.toCredentials(); - if (savedCredentials == null || !(savedCredentials instanceof CookieCredentials)) { - credentialsDialog.setCredentials(savedCredentials); - } + if (oldCachedCredentials != null && !oldCachedCredentials.isCookieCredentials()) { + credentialsDialog.setCredentials(oldCachedCredentials.toCredentials()); } if (credentialsDialog.open() == IDialogConstants.OK_ID) { @@ -273,17 +268,14 @@ private void onClearButtonSelected(final SelectionEvent e) { private void removeCredentials(final ServerListConfigurationEntry[] serverListEntries) { - final CredentialsManager teeCredentialsProvider = - EclipseCredentialsManagerFactory.getCredentialsManager(DefaultPersistenceStoreProvider.INSTANCE); - final CredentialsManager gitCredentialsProvider = EclipseCredentialsManagerFactory.getCredentialsManager(); + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); boolean removeOAuth2Token = false; for (int i = 0; i < serverListEntries.length; i++) { final ServerListConfigurationEntry serverListEntry = serverListEntries[i]; final URI url = serverListEntry.getURI(); - teeCredentialsProvider.removeCredentials(url); - gitCredentialsProvider.removeCredentials(url); + credentialsManager.removeCredentials(url); // Remove from OAuth2 access token from the internal store removeOAuth2Token = removeOAuth2Token || ServerURIUtils.isHosted(url); diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java index c91ffdc1d..5e0a0b9ec 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/AddServerDialog.java @@ -21,6 +21,7 @@ import com.microsoft.tfs.client.common.ui.framework.dialog.BaseDialog; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; import com.microsoft.tfs.client.common.ui.framework.validation.ButtonValidatorBinding; +import com.microsoft.tfs.client.common.ui.helpers.CredentialsHelper; import com.microsoft.tfs.client.common.ui.tasks.ConnectToConfigurationServerTask; import com.microsoft.tfs.core.TFSConfigurationServer; import com.microsoft.tfs.core.TFSConnection; @@ -28,6 +29,7 @@ import com.microsoft.tfs.core.credentials.CredentialsManager; import com.microsoft.tfs.core.httpclient.CookieCredentials; import com.microsoft.tfs.core.httpclient.Credentials; +import com.microsoft.tfs.core.util.ServerURIUtils; import com.microsoft.tfs.core.util.serverlist.ServerList; import com.microsoft.tfs.core.util.serverlist.ServerListConfigurationEntry; import com.microsoft.tfs.core.util.serverlist.ServerListEntryType; @@ -40,6 +42,7 @@ public class AddServerDialog extends BaseDialog { private static final int AUTH_BUTTON_ID = 3; + private static final int CLEAR_BUTTON_ID = 4; private AddServerControl addServerControl; @@ -64,7 +67,8 @@ protected void hookAddToDialogArea(final Composite dialogArea) { addServerControl = new AddServerControl(dialogArea, SWT.NONE); GridDataBuilder.newInstance().grab().fill().applyTo(addServerControl); - this.addButtonDescription(AUTH_BUTTON_ID, "Authentication...", false); //$NON-NLS-1$ + this.addButtonDescription(AUTH_BUTTON_ID, Messages.getString("AddServerDialog.AuthButtonText"), false); //$NON-NLS-1$ + this.addButtonDescription(CLEAR_BUTTON_ID, Messages.getString("AddServerDialog.ClearButtonText"), false); //$NON-NLS-1$ setOptionResizableDirections(SWT.HORIZONTAL); } @@ -82,19 +86,16 @@ protected void createButtonsForButtonBar(final Composite parent) { final Button authButton = getButton(AUTH_BUTTON_ID); new ButtonValidatorBinding(authButton).bind(addServerControl); - // final Button authButton = getButton(AUTH_BUTTON_ID); - // authButton.addSelectionListener(new SelectionAdapter() { - // @Override - // public void widgetSelected(SelectionEvent event) { - // buttonPressed(((Integer) event.widget.getData()).intValue()); - // } - // }); + final Button clearButton = getButton(CLEAR_BUTTON_ID); + new ButtonValidatorBinding(clearButton).bind(addServerControl); } @Override protected void hookCustomButtonPressed(final int buttonId) { if (buttonId == AUTH_BUTTON_ID) { onAuthButtonSelected(); + } else if (buttonId == CLEAR_BUTTON_ID) { + onClearButtonSelected(); } } @@ -139,12 +140,11 @@ protected void okPressed() { private void onAuthButtonSelected() { final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); - final URI serverUrl = addServerControl.getServerURI(); + final CachedCredentials oldCachedCredentials = credentialsManager.getCredentials(serverUrl); - final ServerAuthDialog credentialsDialog = new ServerAuthDialog(getShell(), serverUrl); + final CredentialsDialog credentialsDialog = new CredentialsDialog(getShell(), serverUrl); - final CachedCredentials oldCachedCredentials = credentialsManager.getCredentials(serverUrl); if (oldCachedCredentials != null) { final Credentials savedCredentials = oldCachedCredentials.toCredentials(); if (savedCredentials == null || !(savedCredentials instanceof CookieCredentials)) { @@ -160,6 +160,35 @@ private void onAuthButtonSelected() { } } + private void onClearButtonSelected() { + + final URI serverUrl = addServerControl.getServerURI(); + final String title; + final String message; + + title = Messages.getString(Messages.getString("AddServerDialog.ClearCredentialsTitleText")); //$NON-NLS-1$ + message = MessageFormat.format( + Messages.getString(Messages.getString("AddServerDialog.ClearCredentialsMessageFormat")), //$NON-NLS-1$ + serverUrl); + + if (!MessageDialog.openQuestion(getShell(), title, message)) { + return; + } + + final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); + + credentialsManager.removeCredentials(serverUrl); + + if (ServerURIUtils.isHosted(serverUrl)) { + /* + * Removing the token pair from the internal store. Next time we + * connect to a VSTS account that does not have saved PAT, the user + * will be prompted for credentials. + */ + CredentialsHelper.removeOAuth2Token(true); + } + } + public TFSConnection getConnection() { return connection; } diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/CredentialsDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/CredentialsDialog.java index 8199f2c78..9c65f0f2c 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/CredentialsDialog.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/CredentialsDialog.java @@ -28,13 +28,17 @@ import com.microsoft.tfs.client.common.ui.framework.helper.SWTUtil; import com.microsoft.tfs.client.common.ui.framework.helper.ShellUtils; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; +import com.microsoft.tfs.client.common.ui.framework.validation.ButtonValidatorBinding; +import com.microsoft.tfs.client.common.ui.framework.validation.TextControlValidator; import com.microsoft.tfs.client.common.ui.helpers.AutomationIDHelper; import com.microsoft.tfs.core.config.persistence.DefaultPersistenceStoreProvider; import com.microsoft.tfs.core.credentials.CachedCredentials; import com.microsoft.tfs.core.credentials.CredentialsManagerFactory; import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; +import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials.PatCredentials; import com.microsoft.tfs.util.Check; +import com.microsoft.tfs.util.StringUtil; import com.microsoft.tfs.util.listeners.SingleListenerFacade; public class CredentialsDialog extends CredentialsCompleteDialog { @@ -45,12 +49,15 @@ public class CredentialsDialog extends CredentialsCompleteDialog { private static final Log log = LogFactory.getLog(CredentialsDialog.class); private final URI serverURI; + private String savedUserName = StringUtil.EMPTY; private Credentials credentials; private String errorMessage; private Text usernameText; private Text passwordText; private Button savePasswordButton; + private Button userpasswordButton; + private Button patButton; private Composite insecureComposite; private Label insecureSaveSpacer; @@ -147,6 +154,30 @@ protected void hookAddToDialogArea(final Composite dialogArea) { GridDataBuilder.newInstance().hSpan(2).applyTo(spacerLabel); } + final Label credentialsTypeLabel = new Label(dialogArea, SWT.NONE); + credentialsTypeLabel.setText(Messages.getString("CredentialsDialog.CredentialsTypeLabel")); //$NON-NLS-1$ + + final Composite buttonComposite = new Composite(dialogArea, SWT.NONE); + final GridLayout buttonCompositeLayout = new GridLayout(2, false); + buttonCompositeLayout.horizontalSpacing = getHorizontalSpacing(); + buttonCompositeLayout.verticalSpacing = getVerticalSpacing(); + buttonCompositeLayout.marginWidth = 0; + buttonCompositeLayout.marginHeight = 0; + buttonComposite.setLayout(buttonCompositeLayout); + + userpasswordButton = new Button(buttonComposite, SWT.RADIO); + userpasswordButton.setText(Messages.getString("CredentialsDialog.UserPasswordTypeLabel")); //$NON-NLS-1$ + userpasswordButton.setSelection(true); + + patButton = new Button(buttonComposite, SWT.RADIO); + patButton.setText(Messages.getString("CredentialsDialog.PatTypeLabel")); //$NON-NLS-1$ + patButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + onCredentialTypeSelected(); + } + }); + final Label usernameLabel = new Label(dialogArea, SWT.NONE); usernameLabel.setText(Messages.getString("CredentialsDialog.UserNameLabelText")); //$NON-NLS-1$ @@ -201,9 +232,31 @@ public void widgetSelected(final SelectionEvent e) { } } + if (getCredentials() == null || getCredentials() instanceof PatCredentials) { + patButton.setSelection(true); + userpasswordButton.setSelection(false); + } else if (getCredentials() instanceof UsernamePasswordCredentials) { + savedUserName = ((UsernamePasswordCredentials) getCredentials()).getUsername(); + usernameText.setText(savedUserName); + patButton.setSelection(false); + userpasswordButton.setSelection(true); + } + if (usernameText.getText().length() > 0) { passwordText.setFocus(); } + + onCredentialTypeSelected(); + } + + /** + * {@inheritDoc} + */ + @Override + protected void createButtonsForButtonBar(final Composite parent) { + super.createButtonsForButtonBar(parent); + final Button okButton = getButton(IDialogConstants.OK_ID); + new ButtonValidatorBinding(okButton).bind(new TextControlValidator(passwordText)); } private void toggleInsecureWarning() { @@ -244,18 +297,32 @@ private void createInsecureWarning() { IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH).applyTo(insecureSaveTextLabel); } + private void onCredentialTypeSelected() { + if (patButton.getSelection()) { + savedUserName = usernameText.getText(); + usernameText.setText(StringUtil.EMPTY); + } else { + usernameText.setText(savedUserName); + } + usernameText.setEnabled(userpasswordButton.getSelection()); + } + @Override protected void okPressed() { final String username = usernameText.getText(); final String password = passwordText.getText(); - credentials = new UsernamePasswordCredentials(username, password); + if (userpasswordButton.getSelection()) { + credentials = new UsernamePasswordCredentials(username, password); + } else if (patButton.getSelection()) { + credentials = new PatCredentials(password); + } /* Save the username and password if the user requested it. */ if (allowSavePassword && savePasswordButton.getSelection()) { if (!CredentialsManagerFactory.getCredentialsManager( DefaultPersistenceStoreProvider.INSTANCE).setCredentials( - new CachedCredentials(serverURI, usernameText.getText(), passwordText.getText()))) { + new CachedCredentials(serverURI, credentials))) { Shell shell = ShellUtils.getBestParent(null); if (shell == null) { diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java deleted file mode 100644 index 3924b8763..000000000 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/ServerAuthDialog.java +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See License.txt in the repository root. - -package com.microsoft.tfs.client.common.ui.dialogs.connect; - -import java.net.URI; -import java.text.MessageFormat; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -import com.microsoft.tfs.client.common.ui.Messages; -import com.microsoft.tfs.client.common.ui.framework.dialog.BaseDialog; -import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; -import com.microsoft.tfs.core.httpclient.Credentials; -import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; -import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials.PatCredentials; -import com.microsoft.tfs.util.Check; -import com.microsoft.tfs.util.StringUtil; - -public class ServerAuthDialog extends BaseDialog { - - private final URI serverURI; - private Credentials credentials; - private String savedUserName = StringUtil.EMPTY; - - private Text usernameText; - private Text passwordText; - private Button userpasswordButton; - private Button patButton; - - public ServerAuthDialog(final Shell parent, final URI serverURI) { - super(parent); - - Check.notNull(serverURI, "serverURI"); //$NON-NLS-1$ - this.serverURI = serverURI; - - setOptionPersistGeometry(false); - } - - public void setCredentials(final Credentials credentials) { - this.credentials = credentials; - } - - public Credentials getCredentials() { - return credentials; - } - - @Override - protected String provideDialogTitle() { - return Messages.getString("ServerAuthDialog.DialogTitleText"); //$NON-NLS-1$ - } - - @Override - protected void hookAddToDialogArea(final Composite dialogArea) { - final GridLayout layout = new GridLayout(2, false); - layout.marginWidth = getHorizontalMargin(); - layout.marginHeight = getVerticalMargin(); - layout.horizontalSpacing = getHorizontalSpacing(); - layout.verticalSpacing = getVerticalSpacing(); - dialogArea.setLayout(layout); - - final String messageFormat = Messages.getString("ServerAuthDialog.PromptMessageFormat"); //$NON-NLS-1$ - final String message = MessageFormat.format(messageFormat, serverURI.toString()); - - final Label promptLabel = new Label(dialogArea, SWT.NONE); - promptLabel.setText(message); - GridDataBuilder.newInstance().hSpan(2).hGrab().hFill().wHint( - convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH)).applyTo(promptLabel); - - final Label credentialsTypeLabel = new Label(dialogArea, SWT.NONE); - credentialsTypeLabel.setText(Messages.getString("ServerAuthDialog.CredentialsTypeLabel")); //$NON-NLS-1$ - - final Composite buttonComposite = new Composite(dialogArea, SWT.NONE); - final GridLayout buttonCompositeLayout = new GridLayout(2, false); - buttonCompositeLayout.horizontalSpacing = getHorizontalSpacing(); - buttonCompositeLayout.verticalSpacing = getVerticalSpacing(); - buttonCompositeLayout.marginWidth = 0; - buttonCompositeLayout.marginHeight = 0; - buttonComposite.setLayout(buttonCompositeLayout); - - userpasswordButton = new Button(buttonComposite, SWT.RADIO); - userpasswordButton.setText(Messages.getString("ServerAuthDialog.UserPasswordTypeLabel")); //$NON-NLS-1$ - userpasswordButton.setSelection(true); - // userpasswordButton.addSelectionListener(new SelectionAdapter() { - // @Override - // public void widgetSelected(final SelectionEvent e) { - // onCredentialTypeSelected(); - // } - // }); - - patButton = new Button(buttonComposite, SWT.RADIO); - patButton.setText(Messages.getString("ServerAuthDialog.PatTypeLabel")); //$NON-NLS-1$ - patButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - onCredentialTypeSelected(); - } - }); - - final Label usernameLabel = new Label(dialogArea, SWT.NONE); - usernameLabel.setText(Messages.getString("ServerAuthDialog.UsernameLabel")); //$NON-NLS-1$ - - usernameText = new Text(dialogArea, SWT.BORDER); - GridDataBuilder.newInstance().hGrab().hFill().applyTo(usernameText); - - final Label passwordLabel = new Label(dialogArea, SWT.NONE); - passwordLabel.setText(Messages.getString("ServerAuthDialog.PasswordTokenLabel")); //$NON-NLS-1$ - - passwordText = new Text(dialogArea, SWT.PASSWORD | SWT.BORDER); - GridDataBuilder.newInstance().hGrab().hFill().wCHint(passwordText, 16).applyTo(passwordText); - - if (credentials == null || credentials instanceof PatCredentials) { - patButton.setSelection(true); - userpasswordButton.setSelection(false); - } else if (credentials instanceof UsernamePasswordCredentials) { - savedUserName = ((UsernamePasswordCredentials) credentials).getUsername(); - usernameText.setText(savedUserName); - patButton.setSelection(false); - userpasswordButton.setSelection(true); - } - - if (usernameText.getText().length() > 0) { - passwordText.setFocus(); - } - - onCredentialTypeSelected(); - } - - private void onCredentialTypeSelected() { - if (patButton.getSelection()) { - savedUserName = usernameText.getText(); - usernameText.setText(StringUtil.EMPTY); - } else { - usernameText.setText(savedUserName); - } - usernameText.setEnabled(userpasswordButton.getSelection()); - } - - @Override - protected void okPressed() { - final String username = usernameText.getText(); - final String password = passwordText.getText(); - - if (userpasswordButton.getSelection()) { - credentials = new UsernamePasswordCredentials(username, password); - } else if (patButton.getSelection()) { - credentials = new PatCredentials(password); - } - - super.okPressed(); - } -} diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties index d47f539fc..83fb7ae49 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties @@ -74,6 +74,10 @@ AddServerControl.ProtocolHTTPSButton=HTTPS AddServerControl.ProtocolPrompt=Protocol: AddServerControl.ServerPrompt=Name or URL of Team Foundation Server: AddServerDialog.AddServerDialogTitle=Add Team Foundation Server +AddServerDialog.AuthButtonText=Enter Credentials... +AddServerDialog.ClearButtonText=Clear Credentials +AddServerDialog.ClearCredentialsMessageFormat=Do you want to clear saved credentials for {0}? +AddServerDialog.ClearCredentialsTitleText=Clear Saved Credentials AddServerDialog.ServerExistsErrorTitle=Team Foundation Server Exists AddServerDialog.ServerExistsErrorFormat=Team Foundation Server {0} already exists. AdvancedPropertiesTab.ColumnNameProperty=Property @@ -490,14 +494,17 @@ CopiableLabel.CopyActionTooltip=Copy text to clipboard CopyWorkItemsDialog.DialogTitle=Copy Work Item CopyWorkItemsDialog.TeamProjectLabelText=Team project: CopyWorkItemsDialog.TypeLabelText=Work item type: -CredentialsDialog.DialogTitle=Enter Password -CredentialsDialog.EnterPasswordFormat=Enter password for {0} +CredentialsDialog.DialogTitle=Server authentication +CredentialsDialog.EnterPasswordFormat=Enter credentials for {0} CredentialsDialog.InsecureStorageWarning=Warning: your password will be saved in plain text. -CredentialsDialog.PasswordLabelText=Password: -CredentialsDialog.SavePasswordButtonText=Save password +CredentialsDialog.PasswordLabelText=Password/Token: +CredentialsDialog.SavePasswordButtonText=Save credentials CredentialsDialog.SavePasswordFailedMessage=Could not save your credentials. CredentialsDialog.SavePasswordFailedTitle=Credential storage failed CredentialsDialog.UserNameLabelText=Username: +CredentialsDialog.CredentialsTypeLabel=Credentials type: +CredentialsDialog.PatTypeLabel=Personal access token +CredentialsDialog.UserPasswordTypeLabel=Username and password CredentialsHelper.InteractiveAuthenticationFailedDetailedLog1=Failed to authenticate interactively with web browser. This requires either JavaFX or SWT based web browser control: CredentialsHelper.InteractiveAuthenticationFailedDetailedLog2=1. JavaFX web browser control is only supported on Oracle Java SE 7 update 6 or higher, Oracle Java SE 8, or OpenJDK 8 runtime (Please note you may need to compile OpenJFX project yourself). CredentialsHelper.InteractiveAuthenticationFailedDetailedLog3=2. To launch SWT browser with a specific XULRunner, please set the value of Java system property 'org.eclipse.swt.browser.XULRunnerPath' to the full path of the specific XULRunner. @@ -1503,13 +1510,6 @@ SelectMergeVersionWizardPage.VersionTypeLabelText=&Version type: SelectQueryItemDialog.PromptLabelTextFormat={0}: SelectQueryItemDialog.SelectQueryDialogTitle=Select Query SelectQueryItemDialog.SelectQueryFolderDialogTitle=Select Query Folder -ServerAuthDialog.CredentialsTypeLabel=Credentials type: -ServerAuthDialog.DialogTitleText=Server authentication -ServerAuthDialog.PasswordTokenLabel=Password/Token -ServerAuthDialog.PatTypeLabel=Personal access token -ServerAuthDialog.PromptMessageFormat=Enter credentials for {0} -ServerAuthDialog.UsernameLabel=Username: -ServerAuthDialog.UserPasswordTypeLabel=Username and password ServerFolderPathCellEditor.BrowseForFolderDialogTitle=Browse for Folder ServerItemByItemSpecGenerator.NoServerItemFormat=No server item exists at path "{0}" in {1} ServerItemByItemSpecGenerator.ProgressQueryingServerFormat=Querying server items: {0} @@ -1531,10 +1531,10 @@ ServerItemTreeDialog.ItemPathLabelText=Item path: ServerItemTreeDialog.ItemsLabelText=Items: ServerItemTreeDialog.TfsLabelText=Team Project Collection: ServerListControl.AddButtonText=Add... -ServerListControl.AuthButtonText=Authentication... -ServerListControl.ClearButtonText=Clear -ServerListControl.ClearServerPromptFormat=Do you want to clear saved credentials for Team Foundation Server {0}? -ServerListControl.ClearServersPrompt=Do you want to clear saved credentials for the selected Team Foundation Servers? +ServerListControl.AuthButtonText=Enter Credentials... +ServerListControl.ClearButtonText=Clear Credentials +ServerListControl.ClearServerPromptFormat=Do you want to clear saved credentials for {0}? +ServerListControl.ClearServersPrompt=Do you want to clear saved credentials for the selected Servers/Services? ServerListControl.ClearServersTitle=Clear Saved Credentials ServerListControl.DeleteButtonText=Remove ServerListDialog.AddRemoveDialogTitle=Add/Remove Team Foundation Server diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/CredentialsPreferencePage.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/CredentialsPreferencePage.java index 491259ba2..a7fe127fd 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/CredentialsPreferencePage.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/CredentialsPreferencePage.java @@ -20,20 +20,17 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbench; +import com.microsoft.tfs.client.common.credentials.EclipseCredentialsManagerFactory; import com.microsoft.tfs.client.common.ui.Messages; import com.microsoft.tfs.client.common.ui.controls.generic.CredentialsTable; import com.microsoft.tfs.client.common.ui.dialogs.connect.CredentialsDialog; import com.microsoft.tfs.client.common.ui.framework.helper.ButtonHelper; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; -import com.microsoft.tfs.core.config.persistence.DefaultPersistenceStoreProvider; import com.microsoft.tfs.core.credentials.CachedCredentials; import com.microsoft.tfs.core.credentials.CredentialsManager; -import com.microsoft.tfs.core.credentials.CredentialsManagerFactory; -import com.microsoft.tfs.util.Platform; public class CredentialsPreferencePage extends BasePreferencePage { - private final CredentialsManager credentialsManager = - CredentialsManagerFactory.getCredentialsManager(DefaultPersistenceStoreProvider.INSTANCE); + private final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager(); private CredentialsTable credentialsTable; @@ -68,24 +65,31 @@ protected Control createContents(final Composite parent) { layout.verticalSpacing = getVerticalSpacing(); container.setLayout(layout); - /* Windows and Mac platforms do not allow editing the credentials. */ - if (Platform.isCurrentPlatform(Platform.WINDOWS) || Platform.isCurrentPlatform(Platform.MAC_OS_X)) { - String message; - - if (Platform.isCurrentPlatform(Platform.WINDOWS)) { - message = Messages.getString("CredentialsPreferencePage.EditingNotSupportedWindows"); //$NON-NLS-1$ - } else if (Platform.isCurrentPlatform(Platform.MAC_OS_X)) { - message = Messages.getString("CredentialsPreferencePage.EditingNotSupportedMac"); //$NON-NLS-1$ - } else { - message = Messages.getString("CredentialsPreferencePage.EditingNotSupportedGeneric"); //$NON-NLS-1$ - } - - final Label label = new Label(container, SWT.NONE); - label.setText(message); - GridDataBuilder.newInstance().hSpan(3).hGrab().hFill().applyTo(label); - - return container; - } + // /* Windows and Mac platforms do not allow editing the credentials. */ + // if (Platform.isCurrentPlatform(Platform.WINDOWS) || + // Platform.isCurrentPlatform(Platform.MAC_OS_X)) { + // String message; + // + // if (Platform.isCurrentPlatform(Platform.WINDOWS)) { + // message = + // Messages.getString("CredentialsPreferencePage.EditingNotSupportedWindows"); + // //$NON-NLS-1$ + // } else if (Platform.isCurrentPlatform(Platform.MAC_OS_X)) { + // message = + // Messages.getString("CredentialsPreferencePage.EditingNotSupportedMac"); + // //$NON-NLS-1$ + // } else { + // message = + // Messages.getString("CredentialsPreferencePage.EditingNotSupportedGeneric"); + // //$NON-NLS-1$ + // } + // + // final Label label = new Label(container, SWT.NONE); + // label.setText(message); + // GridDataBuilder.newInstance().hSpan(3).hGrab().hFill().applyTo(label); + // + // return container; + // } final Label label = new Label(container, SWT.NONE); label.setText(Messages.getString("CredentialsPreferencePage.Description")); //$NON-NLS-1$ diff --git a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java index 85866e1b7..f17dc4922 100644 --- a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java +++ b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java @@ -4,6 +4,8 @@ package com.microsoft.tfs.client.common.credentials.internal; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,18 +20,19 @@ import com.microsoft.tfs.core.credentials.CredentialsManagerFactory; import com.microsoft.tfs.core.httpclient.Credentials; import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials; +import com.microsoft.tfs.core.util.URIUtils; import com.microsoft.tfs.util.Check; import com.microsoft.tfs.util.StringUtil; public class EclipseCredentialsManager implements CredentialsManager { - public static final String GIT_PATH_PREFIX = "/GIT/"; //$NON-NLS-1$ + public static final String GIT_PATH_PREFIX = "/GIT"; //$NON-NLS-1$ private static final String USER_NAME = "user"; //$NON-NLS-1$ private static final String PASSWORD = "password"; //$NON-NLS-1$ private static final String HTTP_SCHEME = "http"; //$NON-NLS-1$ private static final String HTTPS_SCHEME = "https"; //$NON-NLS-1$ private static final String ENCODED_SLASH = "\\2f"; //$NON-NLS-1$ - private static final String COOKIE_PREFIX = "FedAuth"; //$NON-NLS-1$ + private static final String SLASH = "/"; //$NON-NLS-1$ private static final Log log = LogFactory.getLog(EclipseCredentialsManager.class); @@ -68,8 +71,26 @@ public boolean isSecure() { @Override public CachedCredentials[] getCredentials() { - // not used anywhere yet - return null; + final List credentials = new ArrayList(100); + final ISecurePreferences rootNode = preferences.node(rootPathPrefix); + final String[] children = rootNode.childrenNames(); + + for (final String child : children) { + final String url = child.replace(ENCODED_SLASH, SLASH); + try { + final URI serverURI = URIUtils.newURI(url); + final CachedCredentials cachedCredentials = getCredentials(serverURI); + if (cachedCredentials != null) { + credentials.add(cachedCredentials); + } + } catch (final Exception e) { + // Log and ignore exception. Maybe the node has been created not + // by the TEE plugin. + log.error("Unexpected node in the Eclipse credentials storage", e); //$NON-NLS-1$ + } + } + + return credentials.toArray(new CachedCredentials[credentials.size()]); } @Override @@ -173,6 +194,7 @@ private String getNodePath(final URI serverURI) { Check.notNull(serverURI.getHost(), "serverURI.getHost()"); //$NON-NLS-1$ final StringBuffer sb = new StringBuffer(rootPathPrefix); + sb.append(SLASH); final String scheme = serverURI.getScheme(); sb.append(scheme.toLowerCase()); diff --git a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/credentials/CachedCredentials.java b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/credentials/CachedCredentials.java index 34a60f580..4b27075aa 100644 --- a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/credentials/CachedCredentials.java +++ b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/credentials/CachedCredentials.java @@ -153,11 +153,12 @@ public boolean isCookieCredentials() { } public boolean isPatCredentials() { - return PatCredentials.USERNAME_FOR_CODE_ACCESS_PAT.equals(username); + return !StringUtil.isNullOrEmpty(password) + && (StringUtil.isNullOrEmpty(username) || PatCredentials.USERNAME_FOR_CODE_ACCESS_PAT.equals(username)); } public boolean isUsernamePasswordCredentials() { - return !isCookieCredentials() && !isPatCredentials() && username != null; + return !isCookieCredentials() && !isPatCredentials() && !StringUtil.isNullOrEmpty(username); } public Credentials toCredentials() { From 8bcaf4ac0a558168f634bd9cf6f89c2766a8d598 Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Wed, 7 Jun 2017 19:19:23 -0400 Subject: [PATCH 4/8] Check network protocol scanning Eclipse credentials --- .../internal/EclipseCredentialsManager.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java index f17dc4922..179fffb25 100644 --- a/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java +++ b/source/com.microsoft.tfs.client.common/src/com/microsoft/tfs/client/common/credentials/internal/EclipseCredentialsManager.java @@ -77,16 +77,33 @@ public CachedCredentials[] getCredentials() { for (final String child : children) { final String url = child.replace(ENCODED_SLASH, SLASH); + try { final URI serverURI = URIUtils.newURI(url); - final CachedCredentials cachedCredentials = getCredentials(serverURI); - if (cachedCredentials != null) { - credentials.add(cachedCredentials); + + final boolean isHttp; + if (serverURI == null || StringUtil.isNullOrEmpty(serverURI.getScheme())) { + isHttp = false; + } else if (serverURI.getScheme().equalsIgnoreCase("http") || //$NON-NLS-1$ + serverURI.getScheme().equalsIgnoreCase("https")) { //$NON-NLS-1$ + isHttp = true; + } else { + isHttp = false; + } + + if (isHttp) { + final CachedCredentials cachedCredentials = getCredentials(serverURI); + + if (cachedCredentials != null) { + credentials.add(cachedCredentials); + } } } catch (final Exception e) { - // Log and ignore exception. Maybe the node has been created not - // by the TEE plugin. - log.error("Unexpected node in the Eclipse credentials storage", e); //$NON-NLS-1$ + /* + * Log and ignore the exception. Maybe the node has been created not + * by the TEE plugin. + */ + log.warn("Ignoring the unexpected node " + url + " in the Eclipse credentials storage", e); //$NON-NLS-1$ //$NON-NLS-2$ } } From 4870b78d4ff741a5a2efaebb0db6516b91f7df25 Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Thu, 8 Jun 2017 13:36:32 -0400 Subject: [PATCH 5/8] Add plugin preference for Device Flow --- .../common/ui/helpers/CredentialsHelper.java | 103 ++++++++++++------ .../tfs/client/common/ui/messages.properties | 1 + .../common/ui/prefs/MainPreferencePage.java | 14 +++ .../ui/prefs/UIPreferenceConstants.java | 5 + .../ui/prefs/UIPreferenceInitializer.java | 4 + 5 files changed, 93 insertions(+), 34 deletions(-) diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java index 9422ae139..733bc8744 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java @@ -8,6 +8,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.eclipse.jface.preference.IPreferenceStore; import com.microsoft.alm.auth.Authenticator; import com.microsoft.alm.auth.PromptBehavior; @@ -27,7 +28,9 @@ import com.microsoft.alm.visualstudio.services.delegatedauthorization.SessionToken; import com.microsoft.tfs.client.common.credentials.EclipseCredentialsManagerFactory; import com.microsoft.tfs.client.common.ui.Messages; +import com.microsoft.tfs.client.common.ui.TFSCommonUIClientPlugin; import com.microsoft.tfs.client.common.ui.config.UIClientConnectionAdvisor; +import com.microsoft.tfs.client.common.ui.prefs.UIPreferenceConstants; import com.microsoft.tfs.core.TFSConnection; import com.microsoft.tfs.core.config.ConnectionInstanceData; import com.microsoft.tfs.core.credentials.CachedCredentials; @@ -105,49 +108,81 @@ public static Credentials getOAuthCredentials( final Action callback) { removeStaleOAuth2Token(); - final Authenticator authenticator; - final OAuth2Authenticator oauth2Authenticator = - OAuth2Authenticator.getAuthenticator(CLIENT_ID, REDIRECT_URL, accessTokenStore, callback); - final Token token; + final IPreferenceStore prefStore = TFSCommonUIClientPlugin.getDefault().getPreferenceStore(); + final String saverUserAgentProvider = System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY); + + if (prefStore.getBoolean(UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION)) { + /* + * The OAuth device flow has been requested either by an Eclipse + * preference or by JVM system property. We're setting the system + * property -DuserAgentProvider to "none". + */ + System.setProperty( + UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY, + UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE); + } else if (UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE.equalsIgnoreCase( + System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY))) { + /* + * The OAuth device flow has not been requested by an Eclipse + * preference. We're removing the system property + * -DuserAgentProvider only if it is set to "none". It might be also + * set by the user to "StandardWidgetToolkit" or "JavaFx". + */ + System.getProperties().remove(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY); + } - final AuthLibHttpClientFactory authLibHttpClientFactory = new AuthLibHttpClientFactory(); - Global.setHttpClientFactory(authLibHttpClientFactory); + try { + final Authenticator authenticator; + final OAuth2Authenticator oauth2Authenticator = + OAuth2Authenticator.getAuthenticator(CLIENT_ID, REDIRECT_URL, accessTokenStore, callback); + final Token token; - if (serverURI != null) { - log.debug("Interactively retrieving credential based on oauth2 flow for " + serverURI.toString()); //$NON-NLS-1$ - log.debug("Trying to persist credential, generating a PAT"); //$NON-NLS-1$ + final AuthLibHttpClientFactory authLibHttpClientFactory = new AuthLibHttpClientFactory(); + Global.setHttpClientFactory(authLibHttpClientFactory); - authenticator = new VstsPatAuthenticator(oauth2Authenticator, tokenStore); + if (serverURI != null) { + log.debug("Interactively retrieving credential based on oauth2 flow for " + serverURI.toString()); //$NON-NLS-1$ + log.debug("Trying to persist credential, generating a PAT"); //$NON-NLS-1$ - final String tokenKey = - authenticator.getUriToKeyConversion().convert(serverURI, authenticator.getAuthType()); - removeStalePersonalAccessToken(tokenKey, serverURI); + authenticator = new VstsPatAuthenticator(oauth2Authenticator, tokenStore); - final TokenPair oauth2Token = - (accessToken == null) ? null : new TokenPair(accessToken.getAccessToken(), "null"); //$NON-NLS-1$ + final String tokenKey = + authenticator.getUriToKeyConversion().convert(serverURI, authenticator.getAuthType()); + removeStalePersonalAccessToken(tokenKey, serverURI); - token = authenticator.getPersonalAccessToken( - serverURI, - VsoTokenScope.AllScopes, - getAccessTokenDescription(serverURI.toString()), - PromptBehavior.AUTO, - oauth2Token); - } else { - log.debug("Interactively retrieving credential based on oauth2 flow for VSTS"); //$NON-NLS-1$ - log.debug("Do not try to persist, generating oauth2 token."); //$NON-NLS-1$ + final TokenPair oauth2Token = + (accessToken == null) ? null : new TokenPair(accessToken.getAccessToken(), "null"); //$NON-NLS-1$ - authenticator = oauth2Authenticator; + token = authenticator.getPersonalAccessToken( + serverURI, + VsoTokenScope.AllScopes, + getAccessTokenDescription(serverURI.toString()), + PromptBehavior.AUTO, + oauth2Token); + } else { + log.debug("Interactively retrieving credential based on oauth2 flow for VSTS"); //$NON-NLS-1$ + log.debug("Do not try to persist, generating oauth2 token."); //$NON-NLS-1$ - final TokenPair tokenPair = authenticator.getOAuth2TokenPair(); - token = tokenPair != null ? tokenPair.AccessToken : null; - } + authenticator = oauth2Authenticator; - if (token != null && token.Type != null && !StringUtil.isNullOrEmpty(token.Value)) { - switch (token.Type) { - case Personal: - return new PatCredentials(token.Value); - case Access: - return new JwtCredentials(token.Value); + final TokenPair tokenPair = authenticator.getOAuth2TokenPair(); + token = tokenPair != null ? tokenPair.AccessToken : null; + } + + if (token != null && token.Type != null && !StringUtil.isNullOrEmpty(token.Value)) { + switch (token.Type) { + case Personal: + return new PatCredentials(token.Value); + case Access: + return new JwtCredentials(token.Value); + } + } + } finally { + if (StringUtil.isNullOrEmpty(saverUserAgentProvider)) { + System.getProperties().remove(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY); + + } else { + System.setProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY, saverUserAgentProvider); } } diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties index 83fb7ae49..522b12d0a 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties @@ -1077,6 +1077,7 @@ MainPreferencePage.GeneralPreferencesText=General Team Foundation Server prefere MainPreferencePage.NoteText=Note: MainPreferencePage.ReconnectButtonText=Automatically connect Team Explorer on start-up MainPreferencePage.SupportButtonText=Support Information... +MainPreferencePage.UseDeviceFlowButtonText=Use Device Flow authentication with Visual Studio Team Services MergeTask.NoChangesToMergeDialogTitle=Merge Status MemoryUsageProvider.FreeMemoryProperty=Free memory MemoryUsageProvider.Java5HeapComittedProperty=Java5+ heap committed diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/MainPreferencePage.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/MainPreferencePage.java index 0221d5aeb..dd9c6fe33 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/MainPreferencePage.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/MainPreferencePage.java @@ -31,6 +31,7 @@ public class MainPreferencePage extends BasePreferencePage { public static final String CONNECT_AT_IMPORT_CHECKBOX_ID = "MainPreferencePage.connectAtImportButton"; //$NON-NLS-1$ public static final String ACCEPT_UNTRUSTED_CERTIFICATES_CHECKBOX_ID = "MainPreferencePage.acceptUntrustedCertificates"; //$NON-NLS-1$ + private static final String USE_DEVICE_FLOW_AUTHENTICATION_CHECKBOX_ID = "MainPreferencePage.useDeviceFlow"; //$NON-NLS-1$ /** * This constant is since SWT 3.7, so we duplicate it here. @@ -40,6 +41,7 @@ public class MainPreferencePage extends BasePreferencePage { private Button reconnectButton; private Button connectAtImportButton; private Button acceptUntrustedCertificatesButton; + private Button useDeviceFlowAuthenticationButton; private Button embeddedBrowserDefault; private Button embeddedBrowserMozilla; @@ -90,6 +92,11 @@ public void widgetSelected(final SelectionEvent e) { } }); + useDeviceFlowAuthenticationButton = new Button(composite, SWT.CHECK); + AutomationIDHelper.setWidgetID(useDeviceFlowAuthenticationButton, USE_DEVICE_FLOW_AUTHENTICATION_CHECKBOX_ID); + useDeviceFlowAuthenticationButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); + useDeviceFlowAuthenticationButton.setText(Messages.getString("MainPreferencePage.UseDeviceFlowButtonText")); //$NON-NLS-1$ + if (showBrowserPreference()) { final Group browserGroup = new Group(composite, SWT.NONE); browserGroup.setText(Messages.getString("MainPreferencePage.EmbeddedBrowserGroupTitle")); //$NON-NLS-1$ @@ -143,6 +150,8 @@ private void initializeValues() { connectAtImportButton.setSelection(store.getBoolean(UIPreferenceConstants.CONNECT_MAPPED_PROJECTS_AT_IMPORT)); acceptUntrustedCertificatesButton.setSelection( store.getBoolean(UIPreferenceConstants.ACCEPT_UNTRUSTED_CERTIFICATES)); + useDeviceFlowAuthenticationButton.setSelection( + store.getBoolean(UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION)); if (showBrowserPreference()) { setEmbeddedBrowserType(store.getInt(UIPreferenceConstants.EMBEDDED_WEB_BROWSER_TYPE)); @@ -158,6 +167,8 @@ protected void performDefaults() { store.getDefaultBoolean(UIPreferenceConstants.CONNECT_MAPPED_PROJECTS_AT_IMPORT)); acceptUntrustedCertificatesButton.setSelection( store.getDefaultBoolean(UIPreferenceConstants.ACCEPT_UNTRUSTED_CERTIFICATES)); + useDeviceFlowAuthenticationButton.setSelection( + store.getDefaultBoolean(UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION)); if (showBrowserPreference()) { setEmbeddedBrowserType(store.getDefaultInt(UIPreferenceConstants.EMBEDDED_WEB_BROWSER_TYPE)); @@ -175,6 +186,9 @@ public boolean performOk() { store.setValue( UIPreferenceConstants.ACCEPT_UNTRUSTED_CERTIFICATES, acceptUntrustedCertificatesButton.getSelection()); + store.setValue( + UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION, + useDeviceFlowAuthenticationButton.getSelection()); if (showBrowserPreference()) { store.setValue(UIPreferenceConstants.EMBEDDED_WEB_BROWSER_TYPE, getEmbeddedBrowserType()); diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceConstants.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceConstants.java index 5b4a515b4..9d6cab685 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceConstants.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceConstants.java @@ -46,6 +46,11 @@ public class UIPreferenceConstants { // Whether to accept untrusted SSL certificates public static final String ACCEPT_UNTRUSTED_CERTIFICATES = "com.microsoft.tfs.acceptUntrustedCertificates"; //$NON-NLS-1$ + // Whether to use device flow authentication with VSTS + public static final String USE_DEVICE_FLOW_AUTHENTICATION = "com.microsoft.tfs.useDeviceFlowAuthentication"; //$NON-NLS-1$ + public static final String USER_AGENT_PROVIDER_PROPERTY = "userAgentProvider"; //$NON-NLS-1$ + public static final String USER_AGENT_PROVIDER_VALUE = "none"; //$NON-NLS-1$ + // The type of web browser to specify when using the SWT.Browser class. The // value is an integer: SWT.NONE (to use the default for this platform, IE // on Windows), SWT.MOZILLA, or SWT.WEBKIT diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java index 02adbc87f..1ce785239 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java @@ -18,6 +18,10 @@ public void initializeDefaultPreferences() { prefs.setDefault(UIPreferenceConstants.RECONNECT_AT_STARTUP, true); prefs.setDefault(UIPreferenceConstants.CONNECT_MAPPED_PROJECTS_AT_IMPORT, true); prefs.setDefault(UIPreferenceConstants.ACCEPT_UNTRUSTED_CERTIFICATES, false); + prefs.setDefault( + UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION, + UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE.equalsIgnoreCase( + System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY))); prefs.setDefault(UIPreferenceConstants.EMBEDDED_WEB_BROWSER_TYPE, SWT.NONE); // default lock level for automatic checkout from edits, and default in From c87de9dc225666873118ab01b18d9200bc8ab8ba Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Thu, 8 Jun 2017 16:35:44 -0400 Subject: [PATCH 6/8] Review changes --- .../TeamExplorerSearchControlPopup.java | 15 ++++++++++++++- .../connect/OAuth2DeviceFlowCallbackDialog.java | 15 +++++++++++++++ .../common/ui/framework/dialog/BaseDialog.java | 15 ++++++++++++++- .../telemetry/ClientTelemetryHelper.java | 11 +++++------ .../common/ui/helpers/CredentialsHelper.java | 2 +- .../tfs/client/common/ui/messages.properties | 2 +- .../common/ui/prefs/UIPreferenceInitializer.java | 5 +---- .../tfs/core/telemetry/TfsTelemetryConstants.java | 2 ++ 8 files changed, 53 insertions(+), 14 deletions(-) diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/teamexplorer/TeamExplorerSearchControlPopup.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/teamexplorer/TeamExplorerSearchControlPopup.java index 6b4c35a19..ea2a7067d 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/teamexplorer/TeamExplorerSearchControlPopup.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/controls/teamexplorer/TeamExplorerSearchControlPopup.java @@ -6,7 +6,9 @@ import java.text.Collator; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.jface.viewers.DoubleClickEvent; @@ -134,7 +136,7 @@ public void widgetDisposed(final DisposeEvent e) { @Override public int open() { - ClientTelemetryHelper.sendDialogOpened(this); + ClientTelemetryHelper.sendDialogOpened(this, getTelemetryProperties()); final int ret = super.open(); @@ -144,6 +146,17 @@ public int open() { return ret; } + /** + * Returns a set of dialog specific telemetry properties that should be sent + * into the DialogOpened telemetry event. The default set of properties is + * empty. Derived dialogs may override this method. * + * + * @return + */ + protected Map getTelemetryProperties() { + return new HashMap(); + } + /** * Call to automatically size the popup and its shell to its content. */ diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/OAuth2DeviceFlowCallbackDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/OAuth2DeviceFlowCallbackDialog.java index 105972afe..f42c1352d 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/OAuth2DeviceFlowCallbackDialog.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/dialogs/connect/OAuth2DeviceFlowCallbackDialog.java @@ -7,6 +7,7 @@ import java.net.URL; import java.text.MessageFormat; import java.util.Date; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -28,6 +29,8 @@ import com.microsoft.tfs.client.common.ui.framework.dialog.BaseDialog; import com.microsoft.tfs.client.common.ui.framework.helper.SWTUtil; import com.microsoft.tfs.client.common.ui.framework.layout.GridDataBuilder; +import com.microsoft.tfs.client.common.ui.prefs.UIPreferenceConstants; +import com.microsoft.tfs.core.telemetry.TfsTelemetryConstants; public class OAuth2DeviceFlowCallbackDialog extends BaseDialog { private static final Log log = LogFactory.getLog(OAuth2DeviceFlowCallbackDialog.class); @@ -99,6 +102,18 @@ public void linkActivated(final HyperlinkEvent e) { } + /** + * {@inheritDoc} + */ + @Override + protected Map getTelemetryProperties() { + Map properties = super.getTelemetryProperties(); + properties.put( + TfsTelemetryConstants.OAUTH_USER_AGENT_PROVIDER, + System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY)); + return properties; + } + /** * {@inheritDoc} */ diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/dialog/BaseDialog.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/dialog/BaseDialog.java index 65f054fa4..48180415c 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/dialog/BaseDialog.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/dialog/BaseDialog.java @@ -5,8 +5,10 @@ import java.text.MessageFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -303,11 +305,22 @@ public int open() { DialogSettingsHelper.recordDialogOpened(dialogSettingsKey); lastOpenedTime = System.currentTimeMillis(); - ClientTelemetryHelper.sendDialogOpened(this); + ClientTelemetryHelper.sendDialogOpened(this, getTelemetryProperties()); return super.open(); } + /** + * Returns a set of dialog specific telemetry properties that should be sent + * into the DialogOpened telemetry event. The default set of properties is + * empty. Derived dialogs may override this method. * + * + * @return + */ + protected Map getTelemetryProperties() { + return new HashMap(); + } + /** * The base class overrides getShellStyle() to support setting the resizable * bit on the Shell style. Subclasses can modify the resizable behavior by diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/telemetry/ClientTelemetryHelper.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/telemetry/ClientTelemetryHelper.java index 270b74de6..596122399 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/telemetry/ClientTelemetryHelper.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/framework/telemetry/ClientTelemetryHelper.java @@ -37,24 +37,23 @@ public static void sendWizardOpened(final ExtendedWizard wizard) { sendPageView(pageName, properties); } - public static void sendDialogOpened(final BaseDialog dialog) { + public static void sendDialogOpened(final BaseDialog dialog, final Map properties) { Check.notNull(dialog, "dialog"); //$NON-NLS-1$ final String dialogName = getName(dialog); - sendDialogOpened(dialogName); + sendDialogOpened(dialogName, properties); } - public static void sendDialogOpened(final PopupDialog dialog) { + public static void sendDialogOpened(final PopupDialog dialog, final Map properties) { Check.notNull(dialog, "dialog"); //$NON-NLS-1$ final String dialogName = getName(dialog); - sendDialogOpened(dialogName); + sendDialogOpened(dialogName, properties); } - private static void sendDialogOpened(final String dialogName) { + private static void sendDialogOpened(final String dialogName, final Map properties) { final String pageName = MessageFormat.format(TfsTelemetryConstants.DIALOG_PAGE_VIEW_NAME_FORMAT, dialogName); - final Map properties = new HashMap(); addContextProperties(properties); sendPageView(pageName, properties); diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java index 733bc8744..ee38b4f53 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/helpers/CredentialsHelper.java @@ -120,6 +120,7 @@ public static Credentials getOAuthCredentials( System.setProperty( UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY, UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE); + // ClientTelemetryHelper.sendDialogOpened(this); } else if (UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE.equalsIgnoreCase( System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY))) { /* @@ -180,7 +181,6 @@ public static Credentials getOAuthCredentials( } finally { if (StringUtil.isNullOrEmpty(saverUserAgentProvider)) { System.getProperties().remove(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY); - } else { System.setProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY, saverUserAgentProvider); } diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties index 522b12d0a..b6fe41921 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/messages.properties @@ -503,7 +503,7 @@ CredentialsDialog.SavePasswordFailedMessage=Could not save your credentials. CredentialsDialog.SavePasswordFailedTitle=Credential storage failed CredentialsDialog.UserNameLabelText=Username: CredentialsDialog.CredentialsTypeLabel=Credentials type: -CredentialsDialog.PatTypeLabel=Personal access token +CredentialsDialog.PatTypeLabel=Personal access token (all scopes) CredentialsDialog.UserPasswordTypeLabel=Username and password CredentialsHelper.InteractiveAuthenticationFailedDetailedLog1=Failed to authenticate interactively with web browser. This requires either JavaFX or SWT based web browser control: CredentialsHelper.InteractiveAuthenticationFailedDetailedLog2=1. JavaFX web browser control is only supported on Oracle Java SE 7 update 6 or higher, Oracle Java SE 8, or OpenJDK 8 runtime (Please note you may need to compile OpenJFX project yourself). diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java index 1ce785239..5ddd72caf 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/prefs/UIPreferenceInitializer.java @@ -18,10 +18,7 @@ public void initializeDefaultPreferences() { prefs.setDefault(UIPreferenceConstants.RECONNECT_AT_STARTUP, true); prefs.setDefault(UIPreferenceConstants.CONNECT_MAPPED_PROJECTS_AT_IMPORT, true); prefs.setDefault(UIPreferenceConstants.ACCEPT_UNTRUSTED_CERTIFICATES, false); - prefs.setDefault( - UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION, - UIPreferenceConstants.USER_AGENT_PROVIDER_VALUE.equalsIgnoreCase( - System.getProperty(UIPreferenceConstants.USER_AGENT_PROVIDER_PROPERTY))); + prefs.setDefault(UIPreferenceConstants.USE_DEVICE_FLOW_AUTHENTICATION, true); prefs.setDefault(UIPreferenceConstants.EMBEDDED_WEB_BROWSER_TYPE, SWT.NONE); // default lock level for automatic checkout from edits, and default in diff --git a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/telemetry/TfsTelemetryConstants.java b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/telemetry/TfsTelemetryConstants.java index 087634c45..17c71171e 100644 --- a/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/telemetry/TfsTelemetryConstants.java +++ b/source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/telemetry/TfsTelemetryConstants.java @@ -44,6 +44,8 @@ public class TfsTelemetryConstants { public static final String DIALOG_PAGE_VIEW_NAME_FORMAT = "TEE/Plugin/Dialog/{0}"; //$NON-NLS-1$ public static final String EXPLORER_PAGE_VIEW_NAME_FORMAT = "TEE/Plugin/Explorer/{0}"; //$NON-NLS-1$ + public static final String OAUTH_USER_AGENT_PROVIDER = "TEE.OAuth.User.Agent.Provider"; //$NON-NLS-1$ + public static final String CLC_COMMAND_EVENT_NAME_FORMAT = "TEE/TeamFoundationServer/CLC/Command/{0}"; //$NON-NLS-1$ public static final String PLUGIN_COMMAND_EVENT_NAME_FORMAT = "TEE/TeamFoundationServer/Plugin/Command/{0}"; //$NON-NLS-1$ public static final String PLUGIN_ACTION_EVENT_NAME_FORMAT = "TEE/TeamFoundationServer/Plugin/Action/{0}"; //$NON-NLS-1$ From b8fdbc603f957c92a7fc0dbea0233d5ca52fcfcd Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Thu, 8 Jun 2017 16:47:21 -0400 Subject: [PATCH 7/8] Bump up version to 14.119.1 --- build/build-1-config.xml | 4 ++-- build/category.xml | 14 +++++++------- build/product_version.properties | 4 ++-- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../content/InstallTEE.htm | 10 +++++----- .../content/InstallTEE_LP.htm | 4 ++-- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../com.microsoft.tfs.client.eclipse.ui/about.ini | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../com.microsoft.tfs.console/META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../com.microsoft.tfs.core.ws/META-INF/MANIFEST.MF | 2 +- source/com.microsoft.tfs.core/META-INF/MANIFEST.MF | 2 +- source/com.microsoft.tfs.core/about.html | 2 +- .../src/com.microsoft.tfs.core-version.properties | 2 +- source/com.microsoft.tfs.jni/META-INF/MANIFEST.MF | 2 +- .../com.microsoft.tfs.logging/META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../.classpath-sdk | 2 +- .../build.xml | 2 +- .../readme.txt | 4 ++-- .../.classpath-sdk | 2 +- .../build.xml | 2 +- .../readme.txt | 4 ++-- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- source/com.microsoft.tfs.sdk/readme.html | 6 +++--- source/com.microsoft.tfs.sdk/redist/redist.txt | 2 +- source/com.microsoft.tfs.util/META-INF/MANIFEST.MF | 2 +- 47 files changed, 64 insertions(+), 64 deletions(-) diff --git a/build/build-1-config.xml b/build/build-1-config.xml index 9f91d7a40..1332c1899 100644 --- a/build/build-1-config.xml +++ b/build/build-1-config.xml @@ -29,8 +29,8 @@ number.version.minor ("0") number.version.service ("2") number.version.build ("1234XYZ") - string.version.1-2-3 ("14.119.0") - string.version.1-2-3-4 ("14.119.0.1234XYZ") + string.version.1-2-3 ("14.119.1") + string.version.1-2-3-4 ("14.119.1.1234XYZ") --> diff --git a/build/category.xml b/build/category.xml index 1cb447ed3..a024e0496 100644 --- a/build/category.xml +++ b/build/category.xml @@ -1,24 +1,24 @@ - + - + - + - + - + - + - + diff --git a/build/product_version.properties b/build/product_version.properties index da5164f73..b9e49da9a 100644 --- a/build/product_version.properties +++ b/build/product_version.properties @@ -1,7 +1,7 @@ -# This comment contains the full version number (14.119.0) so this file gets +# This comment contains the full version number (14.119.1) so this file gets # picked up when doing workspace searches for the version number string. number.version.major=14 number.version.minor=119 -number.version.service=0 +number.version.service=1 # number.version.build gets defined at build time. \ No newline at end of file diff --git a/source/com.microsoft.tfs.checkinpolicies.build/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies.build/META-INF/MANIFEST.MF index eaf4e1508..8964c199f 100644 --- a/source/com.microsoft.tfs.checkinpolicies.build/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies.build/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies.build; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.checkinpolicies.build.TFSBuildCheckinPolicyPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.checkinpolicies.checkforcomments/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies.checkforcomments/META-INF/MANIFEST.MF index c2ec3402a..dcbbaf718 100644 --- a/source/com.microsoft.tfs.checkinpolicies.checkforcomments/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies.checkforcomments/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies.checkforcomments; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.checkinpolicies.checkforcomments diff --git a/source/com.microsoft.tfs.checkinpolicies.forbiddenpatterns/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies.forbiddenpatterns/META-INF/MANIFEST.MF index 9f4ac7155..09f491457 100644 --- a/source/com.microsoft.tfs.checkinpolicies.forbiddenpatterns/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies.forbiddenpatterns/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies.forbiddenpatterns; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.checkinpolicies.forbiddenpatterns, diff --git a/source/com.microsoft.tfs.checkinpolicies.workitempolicy/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies.workitempolicy/META-INF/MANIFEST.MF index e553ce086..313e6d502 100644 --- a/source/com.microsoft.tfs.checkinpolicies.workitempolicy/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies.workitempolicy/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies.workitempolicy; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, diff --git a/source/com.microsoft.tfs.checkinpolicies.workitemquerypolicy/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies.workitemquerypolicy/META-INF/MANIFEST.MF index 0fa92e897..7951cf85b 100644 --- a/source/com.microsoft.tfs.checkinpolicies.workitemquerypolicy/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies.workitemquerypolicy/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies.workitemquerypolicy; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.checkinpolicies.workitemquerypolicy, diff --git a/source/com.microsoft.tfs.checkinpolicies/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.checkinpolicies/META-INF/MANIFEST.MF index d722629c0..77a029cb4 100644 --- a/source/com.microsoft.tfs.checkinpolicies/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.checkinpolicies/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.checkinpolicies; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.checkinpolicies.TFSCheckinPoliciesPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.client.clc.feature/feature.xml b/source/com.microsoft.tfs.client.clc.feature/feature.xml index f71d32e25..5620f1f3a 100644 --- a/source/com.microsoft.tfs.client.clc.feature/feature.xml +++ b/source/com.microsoft.tfs.client.clc.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/source/com.microsoft.tfs.client.clc/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.clc/META-INF/MANIFEST.MF index 2f2c4477e..beeac6a11 100644 --- a/source/com.microsoft.tfs.client.clc/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.clc/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.clc -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Require-Bundle: com.microsoft.tfs.console, diff --git a/source/com.microsoft.tfs.client.common.pid/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common.pid/META-INF/MANIFEST.MF index 7458fa9de..ab8e1cb9d 100644 --- a/source/com.microsoft.tfs.client.common.pid/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common.pid/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common.pid -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/source/com.microsoft.tfs.client.common.ui.teambuild.egit/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common.ui.teambuild.egit/META-INF/MANIFEST.MF index a1f026794..4eab4c6ab 100644 --- a/source/com.microsoft.tfs.client.common.ui.teambuild.egit/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common.ui.teambuild.egit/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common.ui.teambuild.egit;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/source/com.microsoft.tfs.client.common.ui.teambuild/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common.ui.teambuild/META-INF/MANIFEST.MF index fe960d0be..86e66d14d 100644 --- a/source/com.microsoft.tfs.client.common.ui.teambuild/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common.ui.teambuild/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common.ui.teambuild; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.common.ui.teambuild.TFSTeamBuildPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.client.common.ui.vcexplorer/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common.ui.vcexplorer/META-INF/MANIFEST.MF index 7291dea65..8268c88b4 100644 --- a/source/com.microsoft.tfs.client.common.ui.vcexplorer/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common.ui.vcexplorer/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common.ui.vcexplorer; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.common.ui.vcexplorer.TFSVersionControlExplorerPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.client.common.ui/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common.ui/META-INF/MANIFEST.MF index 067743253..d3d714e57 100644 --- a/source/com.microsoft.tfs.client.common.ui/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common.ui; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.common.ui.TFSCommonUIClientPlugin Bundle-Vendor: %Bundle-Vendor Eclipse-LazyStart: true diff --git a/source/com.microsoft.tfs.client.common/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.common/META-INF/MANIFEST.MF index 6b0bf2b2d..41446cc3c 100644 --- a/source/com.microsoft.tfs.client.common/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.common/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.common; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.common.TFSCommonClientPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.client.eclipse.feature/feature.xml b/source/com.microsoft.tfs.client.eclipse.feature/feature.xml index 46ba8d67c..66791d086 100644 --- a/source/com.microsoft.tfs.client.eclipse.feature/feature.xml +++ b/source/com.microsoft.tfs.client.eclipse.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/source/com.microsoft.tfs.client.eclipse.help/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.eclipse.help/META-INF/MANIFEST.MF index 7bca898de..b293e8a7d 100644 --- a/source/com.microsoft.tfs.client.eclipse.help/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.eclipse.help/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.eclipse.help; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Eclipse-LazyStart: true diff --git a/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE.htm b/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE.htm index b64860c9f..ceeb2a9e0 100644 --- a/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE.htm +++ b/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE.htm @@ -515,7 +515,7 @@

To install the plug-in from the update site a the internet or the organization prefers that a specific version of the plug-in is installed by everyone then following method may more suitable.

-
  • Use the link on this page to download TFSEclipsePlugin-UpdateSiteArchive-14.119.0.zip.
  • +
  • Use the link on this page to download TFSEclipsePlugin-UpdateSiteArchive-14.119.1.zip.
  • Open Eclipse.
  • On the Help menu, choose Install New Software.
  • The Install dialog box appears.
  • @@ -524,7 +524,7 @@

    To install the plug-in from the update site a
  • For the name, enter "Local Team Explorer Everywhere update archive".
  • Choose the Archive button.
  • The Repository archive dialog box appears.
  • -
  • Find and select the downloaded "TFSEclipsePlugin-UpdateSiteArchive-14.119.0.zip" file as the File name.
  • +
  • Find and select the downloaded "TFSEclipsePlugin-UpdateSiteArchive-14.119.1.zip" file as the File name.
  • Choose the Open button.
  • Choose the OK button.
  • In the list of features in the Install dialog box, select the check box that corresponds to the Team Explorer Everywhere Plug-in for Eclipse.
  • @@ -538,12 +538,12 @@

    To install the plug-in from the update site a

    You can perform many version control operations from the Cross-platform Command-line Client for Team Foundation Server. Before you can use this client, you must install it and configure your shell or system path to include the installation folder.

    To install the Cross-Platform Command-Line Client for Team Foundation Server

      -
    1. Use the link on this page to download TEE-CLC-14.119.0.zip.
    2. -
    3. Unzip the archive (TEE-CLC-14.119.0.zip file) that contains the client.
    4. +
    5. Use the link on this page to download TEE-CLC-14.119.1.zip.
    6. +
    7. Unzip the archive (TEE-CLC-14.119.1.zip file) that contains the client.
    8. Configure your shell or system path to include the folder to which you unzipped the archive.
    9. To verify that the client is working, at a command prompt, type tf, and then press the ENTER key.
    - If the client is correctly installed, output appears, starting with "Microsoft Team Explorer Everywhere Command-line Client (version 14.119.0)".
    + If the client is correctly installed, output appears, starting with "Microsoft Team Explorer Everywhere Command-line Client (version 14.119.1)".

    For information about any of the commands, you can type tf help Command, where Command is the name of the command for which you want information. For example, you could type tf help checkin. You can also type tf command /help or tf command -help to obtain help.

    Note
    diff --git a/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE_LP.htm b/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE_LP.htm index d809815d0..dacbf48f7 100644 --- a/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE_LP.htm +++ b/source/com.microsoft.tfs.client.eclipse.help/content/InstallTEE_LP.htm @@ -484,7 +484,7 @@

    To install the Team Explorer Everywhere addit
  • Specify the location of the archive file and click Open.
    - Selected the downloaded archive file TFSEclipsePlugin-NL1-UpdateSiteArchive-14.119.0.zip. + Selected the downloaded archive file TFSEclipsePlugin-NL1-UpdateSiteArchive-14.119.1.zip.
  • @@ -515,7 +515,7 @@

    To install the Team Explorer Everywhere addit

    You can install the language pack to provide additional language support to the cross-platform command-line client for Team Foundation Server. Locale-specific environment variables must be configured for your desired language and character encoding, and your terminal program must be configured to display characters in this encoding. See the locale(1) manual page and the documentation for your terminal program for more information.

    To install the Cross-Platform Command-Line Client additional languages

    1. - Unzip the archive file (TEE-CLC-NL1-14.119.0.zip) that contains the languages into the same location as the cross-platform command-line client. + Unzip the archive file (TEE-CLC-NL1-14.119.1.zip) that contains the languages into the same location as the cross-platform command-line client.
    diff --git a/source/com.microsoft.tfs.client.eclipse.metafeature/feature.xml b/source/com.microsoft.tfs.client.eclipse.metafeature/feature.xml index bb65db12b..2014ee44f 100644 --- a/source/com.microsoft.tfs.client.eclipse.metafeature/feature.xml +++ b/source/com.microsoft.tfs.client.eclipse.metafeature/feature.xml @@ -2,7 +2,7 @@ diff --git a/source/com.microsoft.tfs.client.eclipse.ui.egit/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.eclipse.ui.egit/META-INF/MANIFEST.MF index 0c5be96cf..900e18486 100644 --- a/source/com.microsoft.tfs.client.eclipse.ui.egit/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.eclipse.ui.egit/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.eclipse.ui.egit;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/source/com.microsoft.tfs.client.eclipse.ui/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.eclipse.ui/META-INF/MANIFEST.MF index f2a86b992..bae6f70e5 100644 --- a/source/com.microsoft.tfs.client.eclipse.ui/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.eclipse.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.eclipse.ui; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.eclipse.ui.TFSEclipseClientUIPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.client.eclipse.ui/about.ini b/source/com.microsoft.tfs.client.eclipse.ui/about.ini index feb442645..e9b1724c1 100644 --- a/source/com.microsoft.tfs.client.eclipse.ui/about.ini +++ b/source/com.microsoft.tfs.client.eclipse.ui/about.ini @@ -1,5 +1,5 @@ # This is really a Java properties file, and as such MUST be ISO 8859-1 # (http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/about_customization.html) -aboutText=Team Explorer Everywhere\nVersion 14.119.0\n\n Copyright (c) Microsoft. All rights reserved.\nLicensed under the MIT license. See License.txt in the repository root. +aboutText=Team Explorer Everywhere\nVersion 14.119.1\n\n Copyright (c) Microsoft. All rights reserved.\nLicensed under the MIT license. See License.txt in the repository root. featureImage=images/about.gif diff --git a/source/com.microsoft.tfs.client.eclipse/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.client.eclipse/META-INF/MANIFEST.MF index 6f009391f..eef5e3b2d 100644 --- a/source/com.microsoft.tfs.client.eclipse/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.client.eclipse/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.client.eclipse; singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.client.eclipse.TFSEclipseClientPlugin Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/source/com.microsoft.tfs.console/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.console/META-INF/MANIFEST.MF index 57ccfcfdc..1581822a1 100644 --- a/source/com.microsoft.tfs.console/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.console/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.console;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.console, diff --git a/source/com.microsoft.tfs.core.httpclient/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.core.httpclient/META-INF/MANIFEST.MF index e4f7b50aa..323ecb8e8 100644 --- a/source/com.microsoft.tfs.core.httpclient/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.core.httpclient/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.core.httpclient;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-ClassPath: com.microsoft.tfs.core.httpclient.jar, libs/commons-codec-1.6/commons-codec-1.6.jar Bundle-Vendor: %Bundle-Vendor diff --git a/source/com.microsoft.tfs.core.ws.runtime/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.core.ws.runtime/META-INF/MANIFEST.MF index 4471ce951..337005acd 100644 --- a/source/com.microsoft.tfs.core.ws.runtime/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.core.ws.runtime/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.core.ws.runtime;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-ClassPath: com.microsoft.tfs.core.ws.runtime.jar, lib/woodstox-asl-4.0.3/stax-api-1.0.1.jar, lib/woodstox-asl-4.0.3/stax2-api-3.0.1.jar, diff --git a/source/com.microsoft.tfs.core.ws/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.core.ws/META-INF/MANIFEST.MF index e477ed907..b3fc342b9 100644 --- a/source/com.microsoft.tfs.core.ws/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.core.ws/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.core.ws;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: ms.sql.reporting.reportingservices, diff --git a/source/com.microsoft.tfs.core/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.core/META-INF/MANIFEST.MF index f5550a891..3f5d9b260 100644 --- a/source/com.microsoft.tfs.core/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.core;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-ClassPath: com.microsoft.tfs.core.jar, libs/AlmHttpClient-15.105.0.20161011/alm-vss-client-15.105.0-SNAPSHOT.jar, libs/AlmHttpClient-15.105.0.20161011/alm-gallery-client-15.105.0-SNAPSHOT.jar, diff --git a/source/com.microsoft.tfs.core/about.html b/source/com.microsoft.tfs.core/about.html index ff40fc4cd..1dd7aacd5 100644 --- a/source/com.microsoft.tfs.core/about.html +++ b/source/com.microsoft.tfs.core/about.html @@ -6,7 +6,7 @@

    Microsoft® Team Explorer Everywhere

    -

    Release 14.119.0



    +

    Release 14.119.1



    Copyright (c) Microsoft. All rights reserved.
    Licensed under the MIT license. See License.txt in the repository root.
    diff --git a/source/com.microsoft.tfs.core/src/com.microsoft.tfs.core-version.properties b/source/com.microsoft.tfs.core/src/com.microsoft.tfs.core-version.properties index e7eeb7b25..21bc34b06 100644 --- a/source/com.microsoft.tfs.core/src/com.microsoft.tfs.core-version.properties +++ b/source/com.microsoft.tfs.core/src/com.microsoft.tfs.core-version.properties @@ -2,5 +2,5 @@ # This version gets checked in so debugging/tfdev works. number.version.major=14 number.version.minor=119 -number.version.service=0 +number.version.service=1 number.version.build=SNAPSHOT \ No newline at end of file diff --git a/source/com.microsoft.tfs.jni/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.jni/META-INF/MANIFEST.MF index 204433e5d..85dd44bed 100644 --- a/source/com.microsoft.tfs.jni/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.jni/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.jni;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.jni, diff --git a/source/com.microsoft.tfs.logging/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.logging/META-INF/MANIFEST.MF index 6386968fa..9ab081a86 100644 --- a/source/com.microsoft.tfs.logging/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.logging/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.logging;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/source/com.microsoft.tfs.sdk.samples.checkinpolicy/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.sdk.samples.checkinpolicy/META-INF/MANIFEST.MF index 28a6efb41..dd4700ff2 100644 --- a/source/com.microsoft.tfs.sdk.samples.checkinpolicy/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.sdk.samples.checkinpolicy/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Sample TFS Check-in Policy Bundle-SymbolicName: com.microsoft.tfs.sdk.samples.checkinpolicy;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: Microsoft Corporation Export-Package: com.microsoft.tfs.sdk.samples.checkinpolicy Require-Bundle: org.eclipse.core.runtime, diff --git a/source/com.microsoft.tfs.sdk.samples.console/.classpath-sdk b/source/com.microsoft.tfs.sdk.samples.console/.classpath-sdk index f151b4450..4f5437618 100644 --- a/source/com.microsoft.tfs.sdk.samples.console/.classpath-sdk +++ b/source/com.microsoft.tfs.sdk.samples.console/.classpath-sdk @@ -3,5 +3,5 @@ - + diff --git a/source/com.microsoft.tfs.sdk.samples.console/build.xml b/source/com.microsoft.tfs.sdk.samples.console/build.xml index 66028fc5b..b2d0aa1cd 100644 --- a/source/com.microsoft.tfs.sdk.samples.console/build.xml +++ b/source/com.microsoft.tfs.sdk.samples.console/build.xml @@ -9,7 +9,7 @@ - + diff --git a/source/com.microsoft.tfs.sdk.samples.console/readme.txt b/source/com.microsoft.tfs.sdk.samples.console/readme.txt index 69acaa41f..04c8dd065 100644 --- a/source/com.microsoft.tfs.sdk.samples.console/readme.txt +++ b/source/com.microsoft.tfs.sdk.samples.console/readme.txt @@ -10,7 +10,7 @@ Instructions for Using Console Samples 3. Run each snippet program like: (Windows) - java -Dcom.microsoft.tfs.jni.native.base-directory=..\..\redist\native -classpath ..\..\redist\lib\com.microsoft.tfs.sdk-14.119.0.jar;.\bin com.microsoft.tfs.sdk.samples.console.ConsoleSampleClassName + java -Dcom.microsoft.tfs.jni.native.base-directory=..\..\redist\native -classpath ..\..\redist\lib\com.microsoft.tfs.sdk-14.119.1.jar;.\bin com.microsoft.tfs.sdk.samples.console.ConsoleSampleClassName (Unix and Mac OS) - java -Dcom.microsoft.tfs.jni.native.base-directory=../../redist/native -classpath ../../redist/lib/com.microsoft.tfs.sdk-14.119.0.jar:./bin com.microsoft.tfs.sdk.samples.console.ConsoleSampleClassName + java -Dcom.microsoft.tfs.jni.native.base-directory=../../redist/native -classpath ../../redist/lib/com.microsoft.tfs.sdk-14.119.1.jar:./bin com.microsoft.tfs.sdk.samples.console.ConsoleSampleClassName diff --git a/source/com.microsoft.tfs.sdk.samples.snippets/.classpath-sdk b/source/com.microsoft.tfs.sdk.samples.snippets/.classpath-sdk index 73ec52746..d4525af42 100644 --- a/source/com.microsoft.tfs.sdk.samples.snippets/.classpath-sdk +++ b/source/com.microsoft.tfs.sdk.samples.snippets/.classpath-sdk @@ -3,5 +3,5 @@ - + diff --git a/source/com.microsoft.tfs.sdk.samples.snippets/build.xml b/source/com.microsoft.tfs.sdk.samples.snippets/build.xml index cd448e927..7b7dc6e4f 100644 --- a/source/com.microsoft.tfs.sdk.samples.snippets/build.xml +++ b/source/com.microsoft.tfs.sdk.samples.snippets/build.xml @@ -9,7 +9,7 @@ - + diff --git a/source/com.microsoft.tfs.sdk.samples.snippets/readme.txt b/source/com.microsoft.tfs.sdk.samples.snippets/readme.txt index 7d21d6b63..3593565cb 100644 --- a/source/com.microsoft.tfs.sdk.samples.snippets/readme.txt +++ b/source/com.microsoft.tfs.sdk.samples.snippets/readme.txt @@ -10,7 +10,7 @@ Instructions for Using Snippets 3. Run each snippet program like: (Windows) - java -Dcom.microsoft.tfs.jni.native.base-directory=..\..\redist\native -classpath ..\..\redist\lib\com.microsoft.tfs.sdk-14.119.0.jar;.\bin com.microsoft.tfs.sdk.samples.snippets.SnippetClassName + java -Dcom.microsoft.tfs.jni.native.base-directory=..\..\redist\native -classpath ..\..\redist\lib\com.microsoft.tfs.sdk-14.119.1.jar;.\bin com.microsoft.tfs.sdk.samples.snippets.SnippetClassName (Unix and Mac OS) - java -Dcom.microsoft.tfs.jni.native.base-directory=../../redist/native -classpath ../../redist/lib/com.microsoft.tfs.sdk-14.119.0.jar:./bin com.microsoft.tfs.sdk.samples.snippets.SnippetClassName + java -Dcom.microsoft.tfs.jni.native.base-directory=../../redist/native -classpath ../../redist/lib/com.microsoft.tfs.sdk-14.119.1.jar:./bin com.microsoft.tfs.sdk.samples.snippets.SnippetClassName diff --git a/source/com.microsoft.tfs.sdk.samples.teamexplorer/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.sdk.samples.teamexplorer/META-INF/MANIFEST.MF index ca9f1b101..f80c9a5fa 100644 --- a/source/com.microsoft.tfs.sdk.samples.teamexplorer/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.sdk.samples.teamexplorer/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Sample Team Explorer Extensions Bundle-SymbolicName: com.microsoft.tfs.sdk.samples.teamexplorer;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Activator: com.microsoft.tfs.sdk.samples.teamexplorer.Activator Bundle-Vendor: Microsoft Corporation Require-Bundle: org.eclipse.ui, diff --git a/source/com.microsoft.tfs.sdk.samples.witcontrols/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.sdk.samples.witcontrols/META-INF/MANIFEST.MF index 039e089bf..b5f5e4ef0 100644 --- a/source/com.microsoft.tfs.sdk.samples.witcontrols/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.sdk.samples.witcontrols/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Sample TFS Custom Work item Controls Bundle-SymbolicName: com.microsoft.tfs.sdk.samples.witcontrols;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: Microsoft Corporation Export-Package: com.microsoft.tfs.sdk.samples.witcontrols Require-Bundle: com.microsoft.tfs.core, diff --git a/source/com.microsoft.tfs.sdk/readme.html b/source/com.microsoft.tfs.sdk/readme.html index 3ea5cbd2f..881dd5d0a 100644 --- a/source/com.microsoft.tfs.sdk/readme.html +++ b/source/com.microsoft.tfs.sdk/readme.html @@ -164,13 +164,13 @@

    Getting Started

    Follow these steps to get started using the client object model:

      -
    • Copy the redist/lib/com.microsoft.tfs.sdk-14.119.0.jar +
    • Copy the redist/lib/com.microsoft.tfs.sdk-14.119.1.jar file and redist/native directory (including all subdirectories and files) to your application's development or runtime location.
    • Configure your application's Java classpath to include the com.microsoft.tfs.sdk-14.119.0.jar file.
    • + class="path">com.microsoft.tfs.sdk-14.119.1.jar file.
    • Use classes from the client object model in your application. Sample client application source code can be found in the Java Build Path

  • When the Properties dialog containing the Java Build Path page appears, click the Libraries tab then click the Add External JARs... button
  • -
  • Browse to the SDK's redist/lib/com.microsoft.tfs.sdk-14.119.0.jar +
  • Browse to the SDK's redist/lib/com.microsoft.tfs.sdk-14.119.1.jar file and click Open
  • Click OK to close the Properties dialog
  • diff --git a/source/com.microsoft.tfs.sdk/redist/redist.txt b/source/com.microsoft.tfs.sdk/redist/redist.txt index 3cd499eaa..bd9a10589 100644 --- a/source/com.microsoft.tfs.sdk/redist/redist.txt +++ b/source/com.microsoft.tfs.sdk/redist/redist.txt @@ -8,7 +8,7 @@ Software License Terms. ThirdPartyNotices.html -lib/com.microsoft.tfs.sdk-14.119.0.jar +lib/com.microsoft.tfs.sdk-14.119.1.jar native/macosx/libnative_misc.jnilib native/macosx/libnative_keychain.jnilib diff --git a/source/com.microsoft.tfs.util/META-INF/MANIFEST.MF b/source/com.microsoft.tfs.util/META-INF/MANIFEST.MF index 512ecd6f8..03bf8ade9 100644 --- a/source/com.microsoft.tfs.util/META-INF/MANIFEST.MF +++ b/source/com.microsoft.tfs.util/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: com.microsoft.tfs.util;singleton:=true -Bundle-Version: 14.119.0.qualifier +Bundle-Version: 14.119.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Export-Package: com.microsoft.tfs.util, From 8cedad43f832146242e4e9002d82c4b7ffd29c31 Mon Sep 17 00:00:00 2001 From: Alex Rukhlin Date: Thu, 8 Jun 2017 17:19:41 -0400 Subject: [PATCH 8/8] PR comments... --- .../client/common/ui/config/UITransportRequestHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java index 089d1ee06..068ad0c0c 100644 --- a/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java +++ b/source/com.microsoft.tfs.client.common.ui/src/com/microsoft/tfs/client/common/ui/config/UITransportRequestHandler.java @@ -297,8 +297,8 @@ else if (exception instanceof UnauthorizedException && service.isPromptForCreden if (EnvironmentVariables.getBoolean(EnvironmentVariables.USE_OAUTH_LIBRARY, true) && usedCredentials != null - && new CachedCredentials(serverUrl, usedCredentials).isPatCredentials() - && isHosted) { + && isHosted + && new CachedCredentials(serverUrl, usedCredentials).isPatCredentials()) { // PAT token is probably expired. Remove it from the Eclipse // secure storage and retry. final CredentialsManager credentialsManager = EclipseCredentialsManagerFactory.getCredentialsManager();