From ff9219e8386c9f187e8268d0db0307ee8888a1e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Oct 2026 09:22:02 +0000 Subject: [PATCH 1/5] Initial plan From ae81fe417ff58314e5b6d49383230f6df807f132 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Oct 2026 09:28:39 +0000 Subject: [PATCH 2/5] Validate enterprise authentication endpoints require HTTPS Co-authored-by: jdneo <6193897+jdneo@users.noreply.github.com> --- .../GeneralPreferencesPageTest.java | 102 ++++++++++++++++++ .../preferences/GeneralPreferencesPage.java | 22 +++- .../eclipse/ui/preferences/Messages.java | 2 + .../ui/preferences/messages.properties | 2 + 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java new file mode 100644 index 000000000..a74dfee85 --- /dev/null +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package com.microsoft.copilot.eclipse.ui.preferences; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.PreferenceStore; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import com.microsoft.copilot.eclipse.core.Constants; +import com.microsoft.copilot.eclipse.ui.utils.SwtUtils; + +class GeneralPreferencesPageTest { + + private Shell shell; + private TestPreferencesPage page; + + @AfterEach + void tearDown() { + SwtUtils.invokeOnDisplayThread(() -> { + if (page != null) { + page.dispose(); + } + if (shell != null && !shell.isDisposed()) { + shell.dispose(); + } + }); + } + + @ParameterizedTest + @ValueSource(strings = {"", "https://company.ghe.com", "https://company.ghe.com/", + "https://github.company.example:8443", "HTTPS://company.ghe.com", "HtTpS://company.ghe.com"}) + void testEnterpriseEndpoint_validStoredValue_pageIsValid(String endpoint) { + SwtUtils.invokeOnDisplayThread(() -> { + createPage(endpoint); + assertTrue(page.isValid()); + assertNull(page.getErrorMessage()); + }); + } + + @ParameterizedTest + @ValueSource(strings = {"http://company.ghe.com/", "company.ghe.com", "ftp://company.ghe.com", + "https://", "https:///company.ghe.com", "https://company ghe.com", "https://company.ghe.com/%", + " ", " https://company.ghe.com", "https://company.ghe.com "}) + void testEnterpriseEndpoint_invalidStoredValue_pageShowsError(String endpoint) { + SwtUtils.invokeOnDisplayThread(() -> { + createPage(endpoint); + assertFalse(page.isValid()); + assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); + }); + } + + @Test + void testEnterpriseEndpoint_editValue_validationUpdatesImmediately() { + SwtUtils.invokeOnDisplayThread(() -> { + createPage(""); + page.endpointField.setStringValue("http://company.ghe.com/"); + assertFalse(page.isValid()); + assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); + + page.endpointField.setStringValue("https://company.ghe.com/"); + assertTrue(page.isValid()); + assertNull(page.getErrorMessage()); + + page.endpointField.setStringValue(""); + assertTrue(page.isValid()); + assertNull(page.getErrorMessage()); + }); + } + + private void createPage(String endpoint) { + shell = new Shell(Display.getDefault()); + PreferenceStore store = new PreferenceStore(); + store.setValue(Constants.GITHUB_ENTERPRISE, endpoint); + page = new TestPreferencesPage(); + page.setPreferenceStore(store); + page.createControl(shell); + } + + private static class TestPreferencesPage extends GeneralPreferencesPage { + private StringFieldEditor endpointField; + + @Override + protected void addField(FieldEditor editor) { + super.addField(editor); + if (Constants.GITHUB_ENTERPRISE.equals(editor.getPreferenceName())) { + endpointField = (StringFieldEditor) editor; + } + } + } +} diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java index 6b7da3e3a..880239023 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java @@ -3,6 +3,9 @@ package com.microsoft.copilot.eclipse.ui.preferences; +import java.net.URI; + +import org.apache.commons.lang3.StringUtils; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jface.layout.GridDataFactory; @@ -82,9 +85,26 @@ public void createFieldEditors() { ctnGhe.setLayout(gl); ctnGhe.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); StringFieldEditor sftGhe = new StringFieldEditor(Constants.GITHUB_ENTERPRISE, - Messages.preferences_page_github_enterprise, ctnGhe); + Messages.preferences_page_github_enterprise, ctnGhe) { + @Override + protected boolean doCheckState() { + String endpoint = getStringValue(); + if (StringUtils.isEmpty(endpoint)) { + return true; + } + try { + URI uri = URI.create(endpoint); + return "https".equalsIgnoreCase(uri.getScheme()) && StringUtils.isNotBlank(uri.getHost()); + } catch (IllegalArgumentException e) { + return false; + } + } + }; + sftGhe.setErrorMessage(Messages.preferences_page_github_enterprise_validation_error); sftGhe.getLabelControl(ctnGhe).setToolTipText(Messages.preferences_page_github_enterprise_tooltip); addField(sftGhe); + new WrappableNoteLabel(grpAuth, Messages.preferences_page_note_prefix + " ", + Messages.preferences_page_github_enterprise_hint); // What's new group Group whatsNewGroup = new Group(parent, SWT.NONE); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java index ae4051b53..4c0702a85 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java @@ -69,6 +69,8 @@ public class Messages extends NLS { public static String preferences_page_enable_strict_ssl_tooltip; public static String preferences_page_proxy_config_link_tooltip; public static String preferences_page_github_enterprise_tooltip; + public static String preferences_page_github_enterprise_hint; + public static String preferences_page_github_enterprise_validation_error; public static String preferences_page_mcp_tooltip; public static String preferences_page_mcp_note_content; public static String preferences_page_mcp_disabled_tip; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties index d81ecf669..cd6a58e17 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties @@ -59,6 +59,8 @@ preferences_page_mcp_settings= MCP Servers preferences_page_enable_strict_ssl_tooltip= Only disable this if your proxy server is not configured to use SSL and do not have a trusted certificate installed. preferences_page_proxy_config_link_tooltip= Configure proxy settings in Eclipse preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint if you are using GitHub Enterprise. +preferences_page_github_enterprise_hint= Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com. +preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise authentication endpoint starting with https://, or leave it empty to use GitHub.com. preferences_page_mcp_tooltip= Model Context Protocol server configurations. preferences_page_note_prefix= Note: preferences_page_note_content= You can configure proxy settings in Eclipse by clicking on the Configure Proxy link. The Strict SSL option takes effect only when you are accessing GitHub Copilot from a network protected by a proxy server. From de9cc33f6b0132f4bf87f7d5dcde4cebe1179937 Mon Sep 17 00:00:00 2001 From: jdneo <6193897+jdneo@users.noreply.github.com> Date: Mon, 19 Oct 2026 05:25:20 +0000 Subject: [PATCH 3/5] Use native hints for the enterprise endpoint preference Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../GeneralPreferencesPageTest.java | 35 +++++++++++++++++++ .../preferences/GeneralPreferencesPage.java | 6 ++-- .../eclipse/ui/preferences/Messages.java | 2 +- .../ui/preferences/messages.properties | 4 +-- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java index a74dfee85..c76117aab 100644 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java @@ -5,14 +5,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -61,6 +65,22 @@ void testEnterpriseEndpoint_invalidStoredValue_pageShowsError(String endpoint) { }); } + @ParameterizedTest + @ValueSource(strings = {"", "https://company.ghe.com"}) + void testEnterpriseEndpoint_nativeHints_preserveValue(String endpoint) { + SwtUtils.invokeOnDisplayThread(() -> { + createPage(endpoint); + Text endpointText = findTextControl((Composite) page.getControl()); + assertNotNull(endpointText); + assertEquals(Messages.preferences_page_github_enterprise_placeholder, endpointText.getMessage()); + assertEquals(Messages.preferences_page_github_enterprise_tooltip, endpointText.getToolTipText()); + assertEquals(endpoint, endpointText.getText()); + + page.endpointField.store(); + assertEquals(endpoint, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE)); + }); + } + @Test void testEnterpriseEndpoint_editValue_validationUpdatesImmediately() { SwtUtils.invokeOnDisplayThread(() -> { @@ -88,6 +108,21 @@ private void createPage(String endpoint) { page.createControl(shell); } + private Text findTextControl(Composite parent) { + for (Control child : parent.getChildren()) { + if (child instanceof Text text) { + return text; + } + if (child instanceof Composite composite) { + Text text = findTextControl(composite); + if (text != null) { + return text; + } + } + } + return null; + } + private static class TestPreferencesPage extends GeneralPreferencesPage { private StringFieldEditor endpointField; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java index 880239023..9264befa6 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java @@ -17,6 +17,7 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.osgi.service.prefs.BackingStoreException; @@ -102,9 +103,10 @@ protected boolean doCheckState() { }; sftGhe.setErrorMessage(Messages.preferences_page_github_enterprise_validation_error); sftGhe.getLabelControl(ctnGhe).setToolTipText(Messages.preferences_page_github_enterprise_tooltip); + Text endpointText = sftGhe.getTextControl(ctnGhe); + endpointText.setMessage(Messages.preferences_page_github_enterprise_placeholder); + endpointText.setToolTipText(Messages.preferences_page_github_enterprise_tooltip); addField(sftGhe); - new WrappableNoteLabel(grpAuth, Messages.preferences_page_note_prefix + " ", - Messages.preferences_page_github_enterprise_hint); // What's new group Group whatsNewGroup = new Group(parent, SWT.NONE); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java index 4c0702a85..a002e3472 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java @@ -69,7 +69,7 @@ public class Messages extends NLS { public static String preferences_page_enable_strict_ssl_tooltip; public static String preferences_page_proxy_config_link_tooltip; public static String preferences_page_github_enterprise_tooltip; - public static String preferences_page_github_enterprise_hint; + public static String preferences_page_github_enterprise_placeholder; public static String preferences_page_github_enterprise_validation_error; public static String preferences_page_mcp_tooltip; public static String preferences_page_mcp_note_content; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties index cd6a58e17..2a98e46c3 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties @@ -58,8 +58,8 @@ preferences_page_auth_settings= Authentication preferences_page_mcp_settings= MCP Servers preferences_page_enable_strict_ssl_tooltip= Only disable this if your proxy server is not configured to use SSL and do not have a trusted certificate installed. preferences_page_proxy_config_link_tooltip= Configure proxy settings in Eclipse -preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint if you are using GitHub Enterprise. -preferences_page_github_enterprise_hint= Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com. +preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com. +preferences_page_github_enterprise_placeholder= https://your-company.ghe.com preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise authentication endpoint starting with https://, or leave it empty to use GitHub.com. preferences_page_mcp_tooltip= Model Context Protocol server configurations. preferences_page_note_prefix= Note: From 1f285dc706cc4677cf9dc9f441b7d386f2a22ed0 Mon Sep 17 00:00:00 2001 From: jdneo <6193897+jdneo@users.noreply.github.com> Date: Mon, 19 Oct 2026 07:26:43 +0000 Subject: [PATCH 4/5] Normalize GitHub Enterprise authentication endpoints to HTTPS Accept hostnames and HTTP/HTTPS URLs, preview the resolved address, and share normalization across persistence and language server settings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 8 ++ .../GeneralPreferencesPageTest.java | 82 +++++++++++++++++-- .../GitHubEnterpriseEndpointTest.java | 50 +++++++++++ .../LanguageServerSettingManagerTests.java | 63 ++++++++++++++ .../preferences/GeneralPreferencesPage.java | 33 ++++++-- .../preferences/GitHubEnterpriseEndpoint.java | 41 ++++++++++ .../LanguageServerSettingManager.java | 18 +++- .../eclipse/ui/preferences/Messages.java | 2 + .../ui/preferences/messages.properties | 8 +- 9 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java create mode 100644 com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java diff --git a/README.md b/README.md index af297c28a..6499a0721 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,14 @@ a separate online update site. 3. Select **GitHub Copilot** and complete installation. 4. Restart Eclipse and sign in. +### GitHub Enterprise authentication + +In **Window > Preferences > Copilot > General**, enter your GitHub Enterprise hostname +(for example, `your-company.ghe.com`) or an HTTP/HTTPS URL. The page previews the HTTPS +address that will be saved and used for authentication. Hostnames receive an `https://` +prefix, and HTTP URLs are upgraded to HTTPS before use, preserving ports and paths. +Malformed addresses are rejected. Leave the endpoint blank to sign in to GitHub.com. + ## Core capabilities ### Code completions diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java index c76117aab..84574e025 100644 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java @@ -12,14 +12,17 @@ import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import com.microsoft.copilot.eclipse.core.Constants; @@ -43,31 +46,47 @@ void tearDown() { } @ParameterizedTest - @ValueSource(strings = {"", "https://company.ghe.com", "https://company.ghe.com/", - "https://github.company.example:8443", "HTTPS://company.ghe.com", "HtTpS://company.ghe.com"}) - void testEnterpriseEndpoint_validStoredValue_pageIsValid(String endpoint) { + @CsvSource({ + "'', ''", + "' ', ''", + "company.ghe.com, https://company.ghe.com", + "http://company.ghe.com/, https://company.ghe.com/", + "https://company.ghe.com, https://company.ghe.com", + "HTTPS://company.ghe.com, https://company.ghe.com", + "' https://company.ghe.com ', https://company.ghe.com", + "github.company.example:8443/copilot%2Flogin, https://github.company.example:8443/copilot%2Flogin", + "http://company.ghe.com/login?a=1&b=2, https://company.ghe.com/login?a=1&b=2" + }) + void testEnterpriseEndpoint_validStoredValue_previewsAndStoresHttps(String endpoint, String expected) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); + assertPreview(expected); + + page.endpointField.store(); + assertEquals(expected, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE)); + assertEquals(expected, page.endpointField.getStringValue()); }); } @ParameterizedTest - @ValueSource(strings = {"http://company.ghe.com/", "company.ghe.com", "ftp://company.ghe.com", + @ValueSource(strings = {"ftp://company.ghe.com", "http://", "company ghe.com", "https://", "https:///company.ghe.com", "https://company ghe.com", "https://company.ghe.com/%", - " ", " https://company.ghe.com", "https://company.ghe.com "}) + "company.ghe.com:invalid"}) void testEnterpriseEndpoint_invalidStoredValue_pageShowsError(String endpoint) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); assertFalse(page.isValid()); assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); + assertNotNull(findLabel((Composite) page.getControl(), + Messages.preferences_page_github_enterprise_validation_error)); }); } @ParameterizedTest - @ValueSource(strings = {"", "https://company.ghe.com"}) - void testEnterpriseEndpoint_nativeHints_preserveValue(String endpoint) { + @ValueSource(strings = {"", "https://company.ghe.com", "http://company.ghe.com", "company.ghe.com"}) + void testEnterpriseEndpoint_nativeHints_preserveValueUntilSave(String endpoint) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); Text endpointText = findTextControl((Composite) page.getControl()); @@ -76,7 +95,6 @@ void testEnterpriseEndpoint_nativeHints_preserveValue(String endpoint) { assertEquals(Messages.preferences_page_github_enterprise_tooltip, endpointText.getToolTipText()); assertEquals(endpoint, endpointText.getText()); - page.endpointField.store(); assertEquals(endpoint, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE)); }); } @@ -86,19 +104,46 @@ void testEnterpriseEndpoint_editValue_validationUpdatesImmediately() { SwtUtils.invokeOnDisplayThread(() -> { createPage(""); page.endpointField.setStringValue("http://company.ghe.com/"); + assertTrue(page.isValid()); + assertNull(page.getErrorMessage()); + assertPreview("https://company.ghe.com/"); + + page.endpointField.setStringValue("ftp://company.ghe.com/"); assertFalse(page.isValid()); assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); - page.endpointField.setStringValue("https://company.ghe.com/"); + page.endpointField.setStringValue("company.ghe.com"); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); + assertPreview("https://company.ghe.com"); page.endpointField.setStringValue(""); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); + assertPreview(""); + }); + } + + @Test + void testEnterpriseEndpoint_restoreDefaults_resetsValidationAndPreview() { + SwtUtils.invokeOnDisplayThread(() -> { + createPage("ftp://company.ghe.com"); + assertFalse(page.isValid()); + + page.restoreDefaults(); + assertTrue(page.isValid()); + assertNull(page.getErrorMessage()); + assertEquals("", page.endpointField.getStringValue()); + assertPreview(""); }); } + private void assertPreview(String endpoint) { + String expected = endpoint.isEmpty() ? Messages.preferences_page_github_enterprise_default + : NLS.bind(Messages.preferences_page_github_enterprise_preview, endpoint.replace("&", "&&")); + assertNotNull(findLabel((Composite) page.getControl(), expected)); + } + private void createPage(String endpoint) { shell = new Shell(Display.getDefault()); PreferenceStore store = new PreferenceStore(); @@ -123,6 +168,21 @@ private Text findTextControl(Composite parent) { return null; } + private Label findLabel(Composite parent, String text) { + for (Control child : parent.getChildren()) { + if (child instanceof Label label && text.equals(label.getText())) { + return label; + } + if (child instanceof Composite composite) { + Label label = findLabel(composite, text); + if (label != null) { + return label; + } + } + } + return null; + } + private static class TestPreferencesPage extends GeneralPreferencesPage { private StringFieldEditor endpointField; @@ -133,5 +193,9 @@ protected void addField(FieldEditor editor) { endpointField = (StringFieldEditor) editor; } } + + private void restoreDefaults() { + performDefaults(); + } } } diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java new file mode 100644 index 000000000..becf8d900 --- /dev/null +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package com.microsoft.copilot.eclipse.ui.preferences; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +class GitHubEnterpriseEndpointTest { + + @ParameterizedTest + @CsvSource({ + "company.ghe.com, https://company.ghe.com", + "company.ghe.com/, https://company.ghe.com/", + "http://company.ghe.com, https://company.ghe.com", + "http://company.ghe.com/, https://company.ghe.com/", + "https://company.ghe.com, https://company.ghe.com", + "HTTPS://company.ghe.com, https://company.ghe.com", + "HtTp://company.ghe.com, https://company.ghe.com", + "' https://company.ghe.com ', https://company.ghe.com", + "' company.ghe.com ', https://company.ghe.com", + "' ', ''", + "github.company.example:8443, https://github.company.example:8443", + "http://github.company.example:8080/copilot, https://github.company.example:8080/copilot", + "https://company.ghe.com/login%2Foauth?a=1&b=2#section, https://company.ghe.com/login%2Foauth?a=1&b=2#section" + }) + void testNormalize_validEndpoint_returnsHttpsUrl(String input, String expected) { + assertEquals(expected, GitHubEnterpriseEndpoint.normalize(input)); + assertEquals(expected, GitHubEnterpriseEndpoint.normalize(expected)); + } + + @ParameterizedTest + @NullAndEmptySource + void testNormalize_noEndpoint_preservesGitHubComDefault(String input) { + assertEquals(input, GitHubEnterpriseEndpoint.normalize(input)); + } + + @ParameterizedTest + @ValueSource(strings = {"ftp://company.ghe.com", "file://company.ghe.com", "https://", "http://", + "https:///company.ghe.com", "https://company ghe.com", "company ghe.com", "https://company.ghe.com/%", + "https://company.ghe.com:invalid", "company.ghe.com:invalid", "//company.ghe.com"}) + void testNormalize_invalidEndpoint_throws(String input) { + assertThrows(IllegalArgumentException.class, () -> GitHubEnterpriseEndpoint.normalize(input)); + } +} diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java index d13447259..d85d04cde 100644 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java @@ -10,6 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -21,9 +22,13 @@ import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.lsp4j.DidChangeConfigurationParams; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -51,6 +56,64 @@ class LanguageServerSettingManagerTests { @Mock private IProxyService mockProxyService; + @ParameterizedTest + @CsvSource({ + "company.ghe.com, https://company.ghe.com", + "http://company.ghe.com/, https://company.ghe.com/", + "HTTPS://company.ghe.com, https://company.ghe.com", + "' http://github.company.example:8443/copilot%2Flogin ', https://github.company.example:8443/copilot%2Flogin", + "'', ''" + }) + void testEnterpriseEndpoint_initialization_syncsNormalizedEndpoint(String endpoint, String expected) { + when(mockPreferenceStore.getString(Constants.GITHUB_ENTERPRISE)).thenReturn(endpoint); + LanguageServerSettingManager manager = new LanguageServerSettingManager(mockLsConnection, mockProxyService, + mockPreferenceStore); + manager.syncConfiguration(); + + ArgumentCaptor paramsCaptor = ArgumentCaptor + .forClass(DidChangeConfigurationParams.class); + verify(mockLsConnection).updateConfig(paramsCaptor.capture()); + CopilotLanguageServerSettings capturedSettings = (CopilotLanguageServerSettings) paramsCaptor.getValue() + .getSettings(); + assertEquals(expected, capturedSettings.getGithubEnterprise().getUri()); + } + + @ParameterizedTest + @CsvSource({ + "company.ghe.com, https://company.ghe.com", + "http://company.ghe.com/, https://company.ghe.com/", + "HTTPS://company.ghe.com, https://company.ghe.com", + "' http://github.company.example:8443/copilot%2Flogin ', https://github.company.example:8443/copilot%2Flogin", + "'', ''" + }) + void testEnterpriseEndpoint_preferenceChange_syncsNormalizedEndpoint(String endpoint, String expected) { + PreferenceStore store = new PreferenceStore(); + store.setValue(Constants.GITHUB_ENTERPRISE, "https://old-company.ghe.com"); + new LanguageServerSettingManager(mockLsConnection, mockProxyService, store); + + store.setValue(Constants.GITHUB_ENTERPRISE, endpoint); + + ArgumentCaptor paramsCaptor = ArgumentCaptor + .forClass(DidChangeConfigurationParams.class); + verify(mockLsConnection).updateConfig(paramsCaptor.capture()); + CopilotLanguageServerSettings capturedSettings = (CopilotLanguageServerSettings) paramsCaptor.getValue() + .getSettings(); + assertEquals(expected, capturedSettings.getGithubEnterprise().getUri()); + } + + @ParameterizedTest + @ValueSource(strings = {"ftp://company.ghe.com", "https://", "company ghe.com"}) + void testEnterpriseEndpoint_invalidChange_keepsPreviousEndpointWithoutSyncing(String endpoint) { + PreferenceStore store = new PreferenceStore(); + store.setValue(Constants.GITHUB_ENTERPRISE, "https://company.ghe.com"); + LanguageServerSettingManager manager = new LanguageServerSettingManager(mockLsConnection, mockProxyService, store); + + store.setValue(Constants.GITHUB_ENTERPRISE, endpoint); + + assertEquals("https://company.ghe.com", manager.getSettings().getGithubEnterprise().getUri()); + verify(mockLsConnection, never()).updateConfig(any()); + } + @Test void testNoProxy() { // when no proxy is applicable diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java index 9264befa6..ba33a7e45 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java @@ -3,8 +3,6 @@ package com.microsoft.copilot.eclipse.ui.preferences; -import java.net.URI; - import org.apache.commons.lang3.StringUtils; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; @@ -12,11 +10,13 @@ import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -89,23 +89,29 @@ public void createFieldEditors() { Messages.preferences_page_github_enterprise, ctnGhe) { @Override protected boolean doCheckState() { - String endpoint = getStringValue(); - if (StringUtils.isEmpty(endpoint)) { - return true; - } try { - URI uri = URI.create(endpoint); - return "https".equalsIgnoreCase(uri.getScheme()) && StringUtils.isNotBlank(uri.getHost()); + GitHubEnterpriseEndpoint.normalize(getStringValue()); + return true; } catch (IllegalArgumentException e) { return false; } } + + @Override + protected void doStore() { + setStringValue(GitHubEnterpriseEndpoint.normalize(getStringValue())); + super.doStore(); + } }; sftGhe.setErrorMessage(Messages.preferences_page_github_enterprise_validation_error); sftGhe.getLabelControl(ctnGhe).setToolTipText(Messages.preferences_page_github_enterprise_tooltip); Text endpointText = sftGhe.getTextControl(ctnGhe); endpointText.setMessage(Messages.preferences_page_github_enterprise_placeholder); endpointText.setToolTipText(Messages.preferences_page_github_enterprise_tooltip); + Label endpointPreview = new Label(ctnGhe, SWT.WRAP); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).hint(400, SWT.DEFAULT).applyTo(endpointPreview); + endpointText.addModifyListener(event -> updateEnterpriseEndpointPreview(endpointText.getText(), endpointPreview)); + updateEnterpriseEndpointPreview(endpointText.getText(), endpointPreview); addField(sftGhe); // What's new group @@ -125,6 +131,17 @@ protected boolean doCheckState() { addField(showWhatsNewField); } + private void updateEnterpriseEndpointPreview(String input, Label preview) { + try { + String endpoint = GitHubEnterpriseEndpoint.normalize(input); + preview.setText(StringUtils.isEmpty(endpoint) ? Messages.preferences_page_github_enterprise_default + : NLS.bind(Messages.preferences_page_github_enterprise_preview, endpoint.replace("&", "&&"))); + } catch (IllegalArgumentException e) { + preview.setText(Messages.preferences_page_github_enterprise_validation_error); + } + preview.requestLayout(); + } + @Override public void init(IWorkbench workbench) { setPreferenceStore(CopilotUi.getPlugin().getPreferenceStore()); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java new file mode 100644 index 000000000..37f48a355 --- /dev/null +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package com.microsoft.copilot.eclipse.ui.preferences; + +import java.net.URI; + +import org.apache.commons.lang3.StringUtils; + +/** + * Normalizes GitHub Enterprise authentication endpoints before saving or using them. + */ +final class GitHubEnterpriseEndpoint { + + private GitHubEnterpriseEndpoint() { + } + + /** + * Resolves a hostname or HTTP/HTTPS URL to HTTPS, preserving the rest of the URL. + * + * @param endpoint the configured endpoint; null or blank selects GitHub.com + * @return the HTTPS endpoint, or the original null/trimmed empty value for GitHub.com + * @throws IllegalArgumentException if the endpoint is not a valid HTTP/HTTPS URL with a hostname + */ + static String normalize(String endpoint) { + String value = StringUtils.trim(endpoint); + if (StringUtils.isEmpty(value)) { + return value; + } + if (!value.contains("://")) { + value = "https://" + value; + } + + URI uri = URI.create(value); + if (!("http".equalsIgnoreCase(uri.getScheme()) || "https".equalsIgnoreCase(uri.getScheme())) + || StringUtils.isBlank(uri.getHost())) { + throw new IllegalArgumentException("Expected a GitHub Enterprise hostname or HTTP/HTTPS URL."); + } + return "https" + value.substring(uri.getScheme().length()); + } +} diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java index 525c4bbca..8000b108f 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java @@ -85,7 +85,7 @@ public LanguageServerSettingManager(CopilotLanguageServerConnection conn, IProxy getSettings().setEnableAutoCompletions(preferenceStore.getBoolean(Constants.AUTO_SHOW_COMPLETION)); getSettings().getHttp().setProxyStrictSsl(preferenceStore.getBoolean(Constants.ENABLE_STRICT_SSL)); getSettings().getHttp().setProxyKerberosServicePrincipal(preferenceStore.getString(Constants.PROXY_KERBEROS_SP)); - getSettings().getGithubEnterprise().setUri(preferenceStore.getString(Constants.GITHUB_ENTERPRISE)); + updateGitHubEnterpriseEndpoint(); // agent related settings getSettings().getGithubSettings().getCopilotSettings().getAgent() @@ -161,7 +161,9 @@ public void propertyChange(PropertyChangeEvent event) { singleSetting = new CopilotLanguageServerSettings(null, settings.getHttp(), null, null); break; case Constants.GITHUB_ENTERPRISE: - settings.getGithubEnterprise().setUri(preferenceStore.getString(Constants.GITHUB_ENTERPRISE)); + if (!updateGitHubEnterpriseEndpoint()) { + return; + } singleSetting = new CopilotLanguageServerSettings(null, null, settings.getGithubEnterprise(), null); break; case Constants.MCP: @@ -224,6 +226,18 @@ public void propertyChange(PropertyChangeEvent event) { syncSingleConfiguration(singleSetting); } + private boolean updateGitHubEnterpriseEndpoint() { + try { + settings.getGithubEnterprise() + .setUri(GitHubEnterpriseEndpoint.normalize(preferenceStore.getString(Constants.GITHUB_ENTERPRISE))); + return true; + } catch (IllegalArgumentException e) { + CopilotCore.LOGGER.error( + "Invalid GitHub Enterprise authentication endpoint. Update it in Copilot preferences.", e); + return false; + } + } + /** * Synchronizes the configuration with the language server. */ diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java index a002e3472..265a47b4a 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java @@ -71,6 +71,8 @@ public class Messages extends NLS { public static String preferences_page_github_enterprise_tooltip; public static String preferences_page_github_enterprise_placeholder; public static String preferences_page_github_enterprise_validation_error; + public static String preferences_page_github_enterprise_preview; + public static String preferences_page_github_enterprise_default; public static String preferences_page_mcp_tooltip; public static String preferences_page_mcp_note_content; public static String preferences_page_mcp_disabled_tip; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties index 2a98e46c3..639d80a7f 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties @@ -58,9 +58,11 @@ preferences_page_auth_settings= Authentication preferences_page_mcp_settings= MCP Servers preferences_page_enable_strict_ssl_tooltip= Only disable this if your proxy server is not configured to use SSL and do not have a trusted certificate installed. preferences_page_proxy_config_link_tooltip= Configure proxy settings in Eclipse -preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com. -preferences_page_github_enterprise_placeholder= https://your-company.ghe.com -preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise authentication endpoint starting with https://, or leave it empty to use GitHub.com. +preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Enter a hostname or HTTP/HTTPS URL. Addresses are normalized to HTTPS. Leave empty to sign in to GitHub.com. +preferences_page_github_enterprise_placeholder= your-company.ghe.com +preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise hostname or HTTP/HTTPS URL, or leave it empty to use GitHub.com. +preferences_page_github_enterprise_preview= Sign in using {0} +preferences_page_github_enterprise_default= Sign in to GitHub.com. preferences_page_mcp_tooltip= Model Context Protocol server configurations. preferences_page_note_prefix= Note: preferences_page_note_content= You can configure proxy settings in Eclipse by clicking on the Configure Proxy link. The Strict SSL option takes effect only when you are accessing GitHub Copilot from a network protected by a proxy server. From 230456df37393f6f34bbd43677a0d0731ff728c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Oct 2026 06:53:56 +0000 Subject: [PATCH 5/5] Revert enterprise endpoint normalization commit Co-authored-by: jdneo <6193897+jdneo@users.noreply.github.com> --- README.md | 8 -- .../GeneralPreferencesPageTest.java | 82 ++----------------- .../GitHubEnterpriseEndpointTest.java | 50 ----------- .../LanguageServerSettingManagerTests.java | 63 -------------- .../preferences/GeneralPreferencesPage.java | 33 ++------ .../preferences/GitHubEnterpriseEndpoint.java | 41 ---------- .../LanguageServerSettingManager.java | 18 +--- .../eclipse/ui/preferences/Messages.java | 2 - .../ui/preferences/messages.properties | 8 +- 9 files changed, 22 insertions(+), 283 deletions(-) delete mode 100644 com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java delete mode 100644 com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java diff --git a/README.md b/README.md index 6499a0721..af297c28a 100644 --- a/README.md +++ b/README.md @@ -68,14 +68,6 @@ a separate online update site. 3. Select **GitHub Copilot** and complete installation. 4. Restart Eclipse and sign in. -### GitHub Enterprise authentication - -In **Window > Preferences > Copilot > General**, enter your GitHub Enterprise hostname -(for example, `your-company.ghe.com`) or an HTTP/HTTPS URL. The page previews the HTTPS -address that will be saved and used for authentication. Hostnames receive an `https://` -prefix, and HTTP URLs are upgraded to HTTPS before use, preserving ports and paths. -Malformed addresses are rejected. Leave the endpoint blank to sign in to GitHub.com. - ## Core capabilities ### Code completions diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java index 84574e025..c76117aab 100644 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPageTest.java @@ -12,17 +12,14 @@ import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.jface.preference.StringFieldEditor; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import com.microsoft.copilot.eclipse.core.Constants; @@ -46,47 +43,31 @@ void tearDown() { } @ParameterizedTest - @CsvSource({ - "'', ''", - "' ', ''", - "company.ghe.com, https://company.ghe.com", - "http://company.ghe.com/, https://company.ghe.com/", - "https://company.ghe.com, https://company.ghe.com", - "HTTPS://company.ghe.com, https://company.ghe.com", - "' https://company.ghe.com ', https://company.ghe.com", - "github.company.example:8443/copilot%2Flogin, https://github.company.example:8443/copilot%2Flogin", - "http://company.ghe.com/login?a=1&b=2, https://company.ghe.com/login?a=1&b=2" - }) - void testEnterpriseEndpoint_validStoredValue_previewsAndStoresHttps(String endpoint, String expected) { + @ValueSource(strings = {"", "https://company.ghe.com", "https://company.ghe.com/", + "https://github.company.example:8443", "HTTPS://company.ghe.com", "HtTpS://company.ghe.com"}) + void testEnterpriseEndpoint_validStoredValue_pageIsValid(String endpoint) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); - assertPreview(expected); - - page.endpointField.store(); - assertEquals(expected, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE)); - assertEquals(expected, page.endpointField.getStringValue()); }); } @ParameterizedTest - @ValueSource(strings = {"ftp://company.ghe.com", "http://", "company ghe.com", + @ValueSource(strings = {"http://company.ghe.com/", "company.ghe.com", "ftp://company.ghe.com", "https://", "https:///company.ghe.com", "https://company ghe.com", "https://company.ghe.com/%", - "company.ghe.com:invalid"}) + " ", " https://company.ghe.com", "https://company.ghe.com "}) void testEnterpriseEndpoint_invalidStoredValue_pageShowsError(String endpoint) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); assertFalse(page.isValid()); assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); - assertNotNull(findLabel((Composite) page.getControl(), - Messages.preferences_page_github_enterprise_validation_error)); }); } @ParameterizedTest - @ValueSource(strings = {"", "https://company.ghe.com", "http://company.ghe.com", "company.ghe.com"}) - void testEnterpriseEndpoint_nativeHints_preserveValueUntilSave(String endpoint) { + @ValueSource(strings = {"", "https://company.ghe.com"}) + void testEnterpriseEndpoint_nativeHints_preserveValue(String endpoint) { SwtUtils.invokeOnDisplayThread(() -> { createPage(endpoint); Text endpointText = findTextControl((Composite) page.getControl()); @@ -95,6 +76,7 @@ void testEnterpriseEndpoint_nativeHints_preserveValueUntilSave(String endpoint) assertEquals(Messages.preferences_page_github_enterprise_tooltip, endpointText.getToolTipText()); assertEquals(endpoint, endpointText.getText()); + page.endpointField.store(); assertEquals(endpoint, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE)); }); } @@ -104,46 +86,19 @@ void testEnterpriseEndpoint_editValue_validationUpdatesImmediately() { SwtUtils.invokeOnDisplayThread(() -> { createPage(""); page.endpointField.setStringValue("http://company.ghe.com/"); - assertTrue(page.isValid()); - assertNull(page.getErrorMessage()); - assertPreview("https://company.ghe.com/"); - - page.endpointField.setStringValue("ftp://company.ghe.com/"); assertFalse(page.isValid()); assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage()); - page.endpointField.setStringValue("company.ghe.com"); + page.endpointField.setStringValue("https://company.ghe.com/"); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); - assertPreview("https://company.ghe.com"); page.endpointField.setStringValue(""); assertTrue(page.isValid()); assertNull(page.getErrorMessage()); - assertPreview(""); - }); - } - - @Test - void testEnterpriseEndpoint_restoreDefaults_resetsValidationAndPreview() { - SwtUtils.invokeOnDisplayThread(() -> { - createPage("ftp://company.ghe.com"); - assertFalse(page.isValid()); - - page.restoreDefaults(); - assertTrue(page.isValid()); - assertNull(page.getErrorMessage()); - assertEquals("", page.endpointField.getStringValue()); - assertPreview(""); }); } - private void assertPreview(String endpoint) { - String expected = endpoint.isEmpty() ? Messages.preferences_page_github_enterprise_default - : NLS.bind(Messages.preferences_page_github_enterprise_preview, endpoint.replace("&", "&&")); - assertNotNull(findLabel((Composite) page.getControl(), expected)); - } - private void createPage(String endpoint) { shell = new Shell(Display.getDefault()); PreferenceStore store = new PreferenceStore(); @@ -168,21 +123,6 @@ private Text findTextControl(Composite parent) { return null; } - private Label findLabel(Composite parent, String text) { - for (Control child : parent.getChildren()) { - if (child instanceof Label label && text.equals(label.getText())) { - return label; - } - if (child instanceof Composite composite) { - Label label = findLabel(composite, text); - if (label != null) { - return label; - } - } - } - return null; - } - private static class TestPreferencesPage extends GeneralPreferencesPage { private StringFieldEditor endpointField; @@ -193,9 +133,5 @@ protected void addField(FieldEditor editor) { endpointField = (StringFieldEditor) editor; } } - - private void restoreDefaults() { - performDefaults(); - } } } diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java deleted file mode 100644 index becf8d900..000000000 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpointTest.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -package com.microsoft.copilot.eclipse.ui.preferences; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.junit.jupiter.params.provider.ValueSource; - -class GitHubEnterpriseEndpointTest { - - @ParameterizedTest - @CsvSource({ - "company.ghe.com, https://company.ghe.com", - "company.ghe.com/, https://company.ghe.com/", - "http://company.ghe.com, https://company.ghe.com", - "http://company.ghe.com/, https://company.ghe.com/", - "https://company.ghe.com, https://company.ghe.com", - "HTTPS://company.ghe.com, https://company.ghe.com", - "HtTp://company.ghe.com, https://company.ghe.com", - "' https://company.ghe.com ', https://company.ghe.com", - "' company.ghe.com ', https://company.ghe.com", - "' ', ''", - "github.company.example:8443, https://github.company.example:8443", - "http://github.company.example:8080/copilot, https://github.company.example:8080/copilot", - "https://company.ghe.com/login%2Foauth?a=1&b=2#section, https://company.ghe.com/login%2Foauth?a=1&b=2#section" - }) - void testNormalize_validEndpoint_returnsHttpsUrl(String input, String expected) { - assertEquals(expected, GitHubEnterpriseEndpoint.normalize(input)); - assertEquals(expected, GitHubEnterpriseEndpoint.normalize(expected)); - } - - @ParameterizedTest - @NullAndEmptySource - void testNormalize_noEndpoint_preservesGitHubComDefault(String input) { - assertEquals(input, GitHubEnterpriseEndpoint.normalize(input)); - } - - @ParameterizedTest - @ValueSource(strings = {"ftp://company.ghe.com", "file://company.ghe.com", "https://", "http://", - "https:///company.ghe.com", "https://company ghe.com", "company ghe.com", "https://company.ghe.com/%", - "https://company.ghe.com:invalid", "company.ghe.com:invalid", "//company.ghe.com"}) - void testNormalize_invalidEndpoint_throws(String input) { - assertThrows(IllegalArgumentException.class, () -> GitHubEnterpriseEndpoint.normalize(input)); - } -} diff --git a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java index d85d04cde..d13447259 100644 --- a/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java +++ b/com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManagerTests.java @@ -10,7 +10,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -22,13 +21,9 @@ import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.lsp4j.DidChangeConfigurationParams; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -56,64 +51,6 @@ class LanguageServerSettingManagerTests { @Mock private IProxyService mockProxyService; - @ParameterizedTest - @CsvSource({ - "company.ghe.com, https://company.ghe.com", - "http://company.ghe.com/, https://company.ghe.com/", - "HTTPS://company.ghe.com, https://company.ghe.com", - "' http://github.company.example:8443/copilot%2Flogin ', https://github.company.example:8443/copilot%2Flogin", - "'', ''" - }) - void testEnterpriseEndpoint_initialization_syncsNormalizedEndpoint(String endpoint, String expected) { - when(mockPreferenceStore.getString(Constants.GITHUB_ENTERPRISE)).thenReturn(endpoint); - LanguageServerSettingManager manager = new LanguageServerSettingManager(mockLsConnection, mockProxyService, - mockPreferenceStore); - manager.syncConfiguration(); - - ArgumentCaptor paramsCaptor = ArgumentCaptor - .forClass(DidChangeConfigurationParams.class); - verify(mockLsConnection).updateConfig(paramsCaptor.capture()); - CopilotLanguageServerSettings capturedSettings = (CopilotLanguageServerSettings) paramsCaptor.getValue() - .getSettings(); - assertEquals(expected, capturedSettings.getGithubEnterprise().getUri()); - } - - @ParameterizedTest - @CsvSource({ - "company.ghe.com, https://company.ghe.com", - "http://company.ghe.com/, https://company.ghe.com/", - "HTTPS://company.ghe.com, https://company.ghe.com", - "' http://github.company.example:8443/copilot%2Flogin ', https://github.company.example:8443/copilot%2Flogin", - "'', ''" - }) - void testEnterpriseEndpoint_preferenceChange_syncsNormalizedEndpoint(String endpoint, String expected) { - PreferenceStore store = new PreferenceStore(); - store.setValue(Constants.GITHUB_ENTERPRISE, "https://old-company.ghe.com"); - new LanguageServerSettingManager(mockLsConnection, mockProxyService, store); - - store.setValue(Constants.GITHUB_ENTERPRISE, endpoint); - - ArgumentCaptor paramsCaptor = ArgumentCaptor - .forClass(DidChangeConfigurationParams.class); - verify(mockLsConnection).updateConfig(paramsCaptor.capture()); - CopilotLanguageServerSettings capturedSettings = (CopilotLanguageServerSettings) paramsCaptor.getValue() - .getSettings(); - assertEquals(expected, capturedSettings.getGithubEnterprise().getUri()); - } - - @ParameterizedTest - @ValueSource(strings = {"ftp://company.ghe.com", "https://", "company ghe.com"}) - void testEnterpriseEndpoint_invalidChange_keepsPreviousEndpointWithoutSyncing(String endpoint) { - PreferenceStore store = new PreferenceStore(); - store.setValue(Constants.GITHUB_ENTERPRISE, "https://company.ghe.com"); - LanguageServerSettingManager manager = new LanguageServerSettingManager(mockLsConnection, mockProxyService, store); - - store.setValue(Constants.GITHUB_ENTERPRISE, endpoint); - - assertEquals("https://company.ghe.com", manager.getSettings().getGithubEnterprise().getUri()); - verify(mockLsConnection, never()).updateConfig(any()); - } - @Test void testNoProxy() { // when no proxy is applicable diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java index ba33a7e45..9264befa6 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GeneralPreferencesPage.java @@ -3,6 +3,8 @@ package com.microsoft.copilot.eclipse.ui.preferences; +import java.net.URI; + import org.apache.commons.lang3.StringUtils; import org.eclipse.core.runtime.preferences.ConfigurationScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; @@ -10,13 +12,11 @@ import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.StringFieldEditor; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -89,29 +89,23 @@ public void createFieldEditors() { Messages.preferences_page_github_enterprise, ctnGhe) { @Override protected boolean doCheckState() { - try { - GitHubEnterpriseEndpoint.normalize(getStringValue()); + String endpoint = getStringValue(); + if (StringUtils.isEmpty(endpoint)) { return true; + } + try { + URI uri = URI.create(endpoint); + return "https".equalsIgnoreCase(uri.getScheme()) && StringUtils.isNotBlank(uri.getHost()); } catch (IllegalArgumentException e) { return false; } } - - @Override - protected void doStore() { - setStringValue(GitHubEnterpriseEndpoint.normalize(getStringValue())); - super.doStore(); - } }; sftGhe.setErrorMessage(Messages.preferences_page_github_enterprise_validation_error); sftGhe.getLabelControl(ctnGhe).setToolTipText(Messages.preferences_page_github_enterprise_tooltip); Text endpointText = sftGhe.getTextControl(ctnGhe); endpointText.setMessage(Messages.preferences_page_github_enterprise_placeholder); endpointText.setToolTipText(Messages.preferences_page_github_enterprise_tooltip); - Label endpointPreview = new Label(ctnGhe, SWT.WRAP); - GridDataFactory.fillDefaults().span(2, 1).grab(true, false).hint(400, SWT.DEFAULT).applyTo(endpointPreview); - endpointText.addModifyListener(event -> updateEnterpriseEndpointPreview(endpointText.getText(), endpointPreview)); - updateEnterpriseEndpointPreview(endpointText.getText(), endpointPreview); addField(sftGhe); // What's new group @@ -131,17 +125,6 @@ protected void doStore() { addField(showWhatsNewField); } - private void updateEnterpriseEndpointPreview(String input, Label preview) { - try { - String endpoint = GitHubEnterpriseEndpoint.normalize(input); - preview.setText(StringUtils.isEmpty(endpoint) ? Messages.preferences_page_github_enterprise_default - : NLS.bind(Messages.preferences_page_github_enterprise_preview, endpoint.replace("&", "&&"))); - } catch (IllegalArgumentException e) { - preview.setText(Messages.preferences_page_github_enterprise_validation_error); - } - preview.requestLayout(); - } - @Override public void init(IWorkbench workbench) { setPreferenceStore(CopilotUi.getPlugin().getPreferenceStore()); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java deleted file mode 100644 index 37f48a355..000000000 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GitHubEnterpriseEndpoint.java +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -package com.microsoft.copilot.eclipse.ui.preferences; - -import java.net.URI; - -import org.apache.commons.lang3.StringUtils; - -/** - * Normalizes GitHub Enterprise authentication endpoints before saving or using them. - */ -final class GitHubEnterpriseEndpoint { - - private GitHubEnterpriseEndpoint() { - } - - /** - * Resolves a hostname or HTTP/HTTPS URL to HTTPS, preserving the rest of the URL. - * - * @param endpoint the configured endpoint; null or blank selects GitHub.com - * @return the HTTPS endpoint, or the original null/trimmed empty value for GitHub.com - * @throws IllegalArgumentException if the endpoint is not a valid HTTP/HTTPS URL with a hostname - */ - static String normalize(String endpoint) { - String value = StringUtils.trim(endpoint); - if (StringUtils.isEmpty(value)) { - return value; - } - if (!value.contains("://")) { - value = "https://" + value; - } - - URI uri = URI.create(value); - if (!("http".equalsIgnoreCase(uri.getScheme()) || "https".equalsIgnoreCase(uri.getScheme())) - || StringUtils.isBlank(uri.getHost())) { - throw new IllegalArgumentException("Expected a GitHub Enterprise hostname or HTTP/HTTPS URL."); - } - return "https" + value.substring(uri.getScheme().length()); - } -} diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java index 8000b108f..525c4bbca 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/LanguageServerSettingManager.java @@ -85,7 +85,7 @@ public LanguageServerSettingManager(CopilotLanguageServerConnection conn, IProxy getSettings().setEnableAutoCompletions(preferenceStore.getBoolean(Constants.AUTO_SHOW_COMPLETION)); getSettings().getHttp().setProxyStrictSsl(preferenceStore.getBoolean(Constants.ENABLE_STRICT_SSL)); getSettings().getHttp().setProxyKerberosServicePrincipal(preferenceStore.getString(Constants.PROXY_KERBEROS_SP)); - updateGitHubEnterpriseEndpoint(); + getSettings().getGithubEnterprise().setUri(preferenceStore.getString(Constants.GITHUB_ENTERPRISE)); // agent related settings getSettings().getGithubSettings().getCopilotSettings().getAgent() @@ -161,9 +161,7 @@ public void propertyChange(PropertyChangeEvent event) { singleSetting = new CopilotLanguageServerSettings(null, settings.getHttp(), null, null); break; case Constants.GITHUB_ENTERPRISE: - if (!updateGitHubEnterpriseEndpoint()) { - return; - } + settings.getGithubEnterprise().setUri(preferenceStore.getString(Constants.GITHUB_ENTERPRISE)); singleSetting = new CopilotLanguageServerSettings(null, null, settings.getGithubEnterprise(), null); break; case Constants.MCP: @@ -226,18 +224,6 @@ public void propertyChange(PropertyChangeEvent event) { syncSingleConfiguration(singleSetting); } - private boolean updateGitHubEnterpriseEndpoint() { - try { - settings.getGithubEnterprise() - .setUri(GitHubEnterpriseEndpoint.normalize(preferenceStore.getString(Constants.GITHUB_ENTERPRISE))); - return true; - } catch (IllegalArgumentException e) { - CopilotCore.LOGGER.error( - "Invalid GitHub Enterprise authentication endpoint. Update it in Copilot preferences.", e); - return false; - } - } - /** * Synchronizes the configuration with the language server. */ diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java index 265a47b4a..a002e3472 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/Messages.java @@ -71,8 +71,6 @@ public class Messages extends NLS { public static String preferences_page_github_enterprise_tooltip; public static String preferences_page_github_enterprise_placeholder; public static String preferences_page_github_enterprise_validation_error; - public static String preferences_page_github_enterprise_preview; - public static String preferences_page_github_enterprise_default; public static String preferences_page_mcp_tooltip; public static String preferences_page_mcp_note_content; public static String preferences_page_mcp_disabled_tip; diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties index 639d80a7f..2a98e46c3 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/messages.properties @@ -58,11 +58,9 @@ preferences_page_auth_settings= Authentication preferences_page_mcp_settings= MCP Servers preferences_page_enable_strict_ssl_tooltip= Only disable this if your proxy server is not configured to use SSL and do not have a trusted certificate installed. preferences_page_proxy_config_link_tooltip= Configure proxy settings in Eclipse -preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Enter a hostname or HTTP/HTTPS URL. Addresses are normalized to HTTPS. Leave empty to sign in to GitHub.com. -preferences_page_github_enterprise_placeholder= your-company.ghe.com -preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise hostname or HTTP/HTTPS URL, or leave it empty to use GitHub.com. -preferences_page_github_enterprise_preview= Sign in using {0} -preferences_page_github_enterprise_default= Sign in to GitHub.com. +preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com. +preferences_page_github_enterprise_placeholder= https://your-company.ghe.com +preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise authentication endpoint starting with https://, or leave it empty to use GitHub.com. preferences_page_mcp_tooltip= Model Context Protocol server configurations. preferences_page_note_prefix= Note: preferences_page_note_content= You can configure proxy settings in Eclipse by clicking on the Configure Proxy link. The Strict SSL option takes effect only when you are accessing GitHub Copilot from a network protected by a proxy server.