From ff47da7c17ddcfaba52420936317cedc76ba1f98 Mon Sep 17 00:00:00 2001 From: Matt Cooper Date: Thu, 7 Apr 2022 11:27:01 -0400 Subject: [PATCH 01/83] remove "experimental" moniker from Azure DevOps OAuth in docs --- README.md | 2 +- docs/azrepos-users-and-tokens.md | 8 ++++---- docs/configuration.md | 4 ++-- docs/environment.md | 4 ++-- docs/usage.md | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0536d8364..2784ecdc4 100644 --- a/README.md +++ b/README.md @@ -239,11 +239,11 @@ See detailed information [here](https://aka.ms/gcm/httpproxy). - [Credential stores](docs/credstores.md) - [Architectural overview](docs/architecture.md) - [Host provider specification](docs/hostprovider.md) +- [Azure Repos OAuth tokens](docs/azrepos-users-and-tokens.md) ## Experimental Features - [Windows broker (experimental)](docs/windows-broker.md) -- [Azure Repos OAuth tokens (experimental)](docs/azrepos-users-and-tokens.md) ## Contributing diff --git a/docs/azrepos-users-and-tokens.md b/docs/azrepos-users-and-tokens.md index 153e7f8d4..cc26598bb 100644 --- a/docs/azrepos-users-and-tokens.md +++ b/docs/azrepos-users-and-tokens.md @@ -5,11 +5,11 @@ The Azure Repos host provider supports creating multiple types of credential: - Azure DevOps personal access tokens -- Microsoft identity OAuth tokens (experimental) +- Microsoft identity OAuth tokens To select which type of credential the Azure Repos host provider will create -and use, you can set the [`credential.azreposCredentialType`](configuration.md#credentialazreposcredentialtype-experimental) -configuration entry (or [`GCM_AZREPOS_CREDENTIALTYPE`](environment.md#GCM_AZREPOS_CREDENTIALTYPE-experimental) +and use, you can set the [`credential.azreposCredentialType`](configuration.md#credentialazreposcredentialtype) +configuration entry (or [`GCM_AZREPOS_CREDENTIALTYPE`](environment.md#GCM_AZREPOS_CREDENTIALTYPE) environment variable). ### Azure DevOps personal access tokens @@ -24,7 +24,7 @@ PATs have a limited lifetime and new tokens must be created once they expire. In Git Credential Manager, when a PAT expired (or was manually revoked) this resulted in a new authentication prompt. -### Microsoft identity OAuth tokens (experimental) +### Microsoft identity OAuth tokens "Microsoft identity OAuth token" is the generic term for OAuth-based access tokens issued by Azure Active Directory for either Work and School Accounts diff --git a/docs/configuration.md b/docs/configuration.md index c1c14761a..e7a7e1cd2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -508,7 +508,7 @@ Credential: "git:https://bob@github.com/example/myrepo" (user = bob) --- -### credential.azreposCredentialType _(experimental)_ +### credential.azreposCredentialType Specify the type of credential the Azure Repos host provider should return. @@ -527,4 +527,4 @@ More information about Azure Access tokens can be found [here](azrepos-azuretoke git config --global credential.azreposCredentialType oauth ``` -**Also see: [GCM_AZREPOS_CREDENTIALTYPE](environment.md#GCM_AZREPOS_CREDENTIALTYPE-experimental)** +**Also see: [GCM_AZREPOS_CREDENTIALTYPE](environment.md#GCM_AZREPOS_CREDENTIALTYPE)** diff --git a/docs/environment.md b/docs/environment.md index bf50971a3..9237cca94 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -670,7 +670,7 @@ export GCM_MSAUTH_USEBROKER="false" --- -### GCM_AZREPOS_CREDENTIALTYPE _(experimental)_ +### GCM_AZREPOS_CREDENTIALTYPE Specify the type of credential the Azure Repos host provider should return. @@ -695,4 +695,4 @@ SET GCM_AZREPOS_CREDENTIALTYPE="oauth" export GCM_AZREPOS_CREDENTIALTYPE="oauth" ``` -**Also see: [credential.azreposCredentialType](configuration.md#azreposcredentialtype-experimental)** +**Also see: [credential.azreposCredentialType](configuration.md#azreposcredentialtype)** diff --git a/docs/usage.md b/docs/usage.md index bb0426e2b..1f64cbd1a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -31,7 +31,7 @@ Set your user-level Git configuration (`~/.gitconfig`) to use GCM. If you pass `--system` to these commands, they act on the system-level Git configuration (`/etc/gitconfig`) instead. -### azure-repos (experimental) +### azure-repos Interact with the Azure Repos host provider to bind/unbind user accounts to Azure DevOps organizations or specific remote URLs, and manage the authentication authority cache. From 3a9603059357093db27fb3258180ec9851c9a087 Mon Sep 17 00:00:00 2001 From: Matt Cooper Date: Thu, 7 Apr 2022 11:40:04 -0400 Subject: [PATCH 02/83] when falling back, be explicit about what to use --- src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs index 48809e4b6..55fb408f4 100644 --- a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs +++ b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs @@ -389,7 +389,7 @@ private static string GetAccountNameForCredentialQuery(InputArguments input) /// True if Personal Access Tokens should be used, false otherwise. private bool UsePersonalAccessTokens() { - // Default to using PATs whilst the Azure AT functionality is being tested + // Default to using PATs const bool defaultValue = true; if (_context.Settings.TryGetSetting( @@ -410,7 +410,7 @@ private bool UsePersonalAccessTokens() default: _context.Streams.Error.WriteLine( - $"warning: unknown Azure Repos credential type '{valueStr}' - using default option"); + $"warning: unknown Azure Repos credential type '{valueStr}' - using PATs"); return defaultValue; } } From 89bfb76befb80f9d0054fba5f53b51fd337f5b78 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Mon, 18 Apr 2022 11:05:37 -0700 Subject: [PATCH 03/83] docs: add supported Linux distributions to README.md Update README.md to call out explicitly supported Linux distributions. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2784ecdc4..e1c9650c3 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Git Credential Manager (GCM) replaces the .NET Framework-based [Git Credential M ## Current status -Git Credential Manager is currently available for Windows, macOS, and Linux. GCM only works with HTTP(S) remotes; you can still use Git with SSH: +Git Credential Manager is currently available for Windows, macOS, and Linux\*. GCM only works with HTTP(S) remotes; you can still use Git with SSH: - [Azure DevOps SSH](https://docs.microsoft.com/en-us/azure/devops/repos/git/use-ssh-keys-to-authenticate?view=azure-devops) - [GitHub SSH](https://help.github.com/en/articles/connecting-to-github-with-ssh) @@ -20,7 +20,7 @@ Git Credential Manager is currently available for Windows, macOS, and Linux. GCM Feature|Windows|macOS|Linux -|:-:|:-:|:-: -Installer/uninstaller|✓|✓|✓\* +Installer/uninstaller|✓|✓|✓ Secure platform credential storage|✓
[(see more)](docs/credstores.md)|✓
[(see more)](docs/credstores.md)|✓
[(see more)](docs/credstores.md) Multi-factor authentication support for Azure DevOps|✓|✓|✓ Two-factor authentication support for GitHub|✓|✓|✓ @@ -34,10 +34,11 @@ Proxy support|✓|✓|✓ `arm64` support|best effort|via Rosetta 2|best effort, no packages `armhf` support|_N/A_|_N/A_|best effort, no packages -**Notes:** - -(\*) Fedora packages planned but not yet available. +(\*) GCM guarantees support for the below Linux distributions. GCM maintainers also monitor and evaluate issues opened against other distributions to determine community interest/engagement and whether an emerging platform should become fully-supported. +- Debian/Ubuntu/Linux Mint +- Fedora/CentOS/RHEL +- Alpine ## Download and Install ### macOS Homebrew From 2c827d015bdef16e0eeea1db4b9481764ab6816b Mon Sep 17 00:00:00 2001 From: M Hickford Date: Tue, 19 Apr 2022 15:04:15 +0100 Subject: [PATCH 04/83] Link to GitLab support docs --- README.md | 1 + docs/gitlab.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e1c9650c3..2ba416d9a 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,7 @@ See detailed information [here](https://aka.ms/gcm/httpproxy). - [Architectural overview](docs/architecture.md) - [Host provider specification](docs/hostprovider.md) - [Azure Repos OAuth tokens](docs/azrepos-users-and-tokens.md) +- [GitLab support](docs/gitlab.md) ## Experimental Features diff --git a/docs/gitlab.md b/docs/gitlab.md index c7eddbc06..fd923cb02 100644 --- a/docs/gitlab.md +++ b/docs/gitlab.md @@ -10,7 +10,7 @@ To use on another instance, eg. `https://gitlab.example.com` requires setup and 2. Copy the application ID and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientId ` 3. Copy the application secret and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientSecret ` 4. Configure authentication modes to include 'browser' `git config --global credential.https://gitlab.example.com.gitLabAuthModes browser` -5. For good measure, configure `git config --global credential.https://gitlab.example.com.provider gitlab` +5. For good measure, configure `git config --global credential.https://gitlab.example.com.provider gitlab`. This may be necessary to recognise the domain as a GitLab instance. 6. Verify the config is as expected `git config --global --get-urlmatch credential https://gitlab.example.com` ### Clearing config From 614a2aa7e0ccad754358c795334d5cbef7d2a077 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Tue, 19 Apr 2022 10:37:25 -0700 Subject: [PATCH 05/83] docs: highlight GitLab support in README.md Add GitLab to list of supported host providers. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1c9650c3..522595ba5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [Git Credential Manager](https://github.com/GitCredentialManager/git-credential-manager) (GCM) is a secure Git credential helper built on [.NET](https://dotnet.microsoft.com) that runs on Windows, macOS, and Linux. -Compared to Git's [built-in credential helpers]((https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage)) (Windows: wincred, macOS: osxkeychain, Linux: gnome-keyring/libsecret) which provides single-factor authentication support working on any HTTP-enabled Git repository, GCM provides multi-factor authentication support for [Azure DevOps](https://dev.azure.com/), Azure DevOps Server (formerly Team Foundation Server), GitHub, and Bitbucket. +Compared to Git's [built-in credential helpers]((https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage)) (Windows: wincred, macOS: osxkeychain, Linux: gnome-keyring/libsecret) which provides single-factor authentication support working on any HTTP-enabled Git repository, GCM provides multi-factor authentication support for [Azure DevOps](https://dev.azure.com/), Azure DevOps Server (formerly Team Foundation Server), GitHub, Bitbucket, and GitLab. Git Credential Manager (GCM) replaces the .NET Framework-based [Git Credential Manager for Windows](https://github.com/microsoft/Git-Credential-Manager-for-Windows) (GCM), and the Java-based [Git Credential Manager for Mac and Linux](https://github.com/microsoft/Git-Credential-Manager-for-Mac-and-Linux) (Java GCM), providing a consistent authentication experience across all platforms. From dbb8e4181bba55a96ee095584b9a815dba282a46 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 22:09:03 +0100 Subject: [PATCH 06/83] Fix md lint errors that do not alter content --- CONTRIBUTING.md | 24 +++++++++---------- README.md | 33 ++++++++++++++------------- SECURITY.md | 2 ++ docs/bitbucket-development.md | 6 ++--- docs/configuration.md | 9 ++++---- docs/development.md | 9 ++++---- docs/enterprise-config.md | 7 +++--- docs/environment.md | 43 +++++++++++++++++------------------ docs/faq.md | 8 +++---- docs/github-apideprecation.md | 28 +++++++++++------------ docs/gitlab.md | 10 ++++---- docs/multiple-users.md | 2 +- docs/windows-broker.md | 8 +++++-- 13 files changed, 99 insertions(+), 90 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff2f5b2ee..e4aaad228 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -## Contributing +# Contributing -[issue]: https://github.com/GitCredentialManager/git-credential-manager/issues +[issue]: https://github.com/GitCredentialManager/git-credential-manager/issues [fork]: https://github.com/GitCredentialManager/git-credential-manager/fork [pr]: https://github.com/GitCredentialManager/git-credential-manager/compare [code-of-conduct]: CODE_OF_CONDUCT.md @@ -13,24 +13,24 @@ Please note that this project is released with a [Contributor Code of Conduct][c ## Start with an issue -0. Open an [issue][issue] to discuss the change you want to see. +1. Open an [issue][issue] to discuss the change you want to see. This helps us coordinate and reduce duplication. -0. Once we've had some discussion, you're ready to code! +2. Once we've had some discussion, you're ready to code! ## Submitting a pull request -0. [Fork][fork] and clone the repository -0. Configure and install the dependencies: `dotnet restore` -0. Make sure the tests pass on your machine: `dotnet test` -0. Create a new branch: `git switch -c my-branch-name` -0. Make your change, add tests, and make sure the tests still pass -0. For UI updates, test your changes by executing a `dotnet run` in applicable UI-related project directories: +1. [Fork][fork] and clone the repository +2. Configure and install the dependencies: `dotnet restore` +3. Make sure the tests pass on your machine: `dotnet test` +4. Create a new branch: `git switch -c my-branch-name` +5. Make your change, add tests, and make sure the tests still pass +6. For UI updates, test your changes by executing a `dotnet run` in applicable UI-related project directories: - `Atlassian.Bitbucket.UI.Avalonia` - `GitHub.UI.Avalonia` - `Atlassian.Bitbucket.UI.Windows` - `GitHub.UI.Windows` -0. Push to your fork and [submit a pull request][pr] -0. Pat your self on the back and wait for your pull request to be reviewed and merged. +7. Push to your fork and [submit a pull request][pr] +8. Pat your self on the back and wait for your pull request to be reviewed and merged. Here are a few things you can do that will increase the likelihood of your pull request being accepted: diff --git a/README.md b/README.md index b24f31ae1..8c4b63627 100644 --- a/README.md +++ b/README.md @@ -97,24 +97,24 @@ run the following: 1. To ensure `curl` is installed: -```shell -curl --version -``` + ```shell + curl --version + ``` -If `curl` is not installed, please use your distribution's package manager -to install it. + If `curl` is not installed, please use your distribution's package manager + to install it. -0. To download and run the script: +2. To download and run the script: -```shell -curl -LO https://raw.githubusercontent.com/GitCredentialManager/git-credential-manager/main/src/linux/Packaging.Linux/install-from-source.sh && -sh ./install-from-source.sh && -git-credential-manager-core configure -``` + ```shell + curl -LO https://raw.githubusercontent.com/GitCredentialManager/git-credential-manager/main/src/linux/Packaging.Linux/install-from-source.sh && + sh ./install-from-source.sh && + git-credential-manager-core configure + ``` -__Note:__ You will be prompted to enter your credentials so that the script -can download GCM's dependencies using your distribution's package -manager. + **Note:** You will be prompted to enter your credentials so that the script + can download GCM's dependencies using your distribution's package + manager. #### Ubuntu/Debian distributions @@ -124,7 +124,8 @@ Download the latest [.deb package](https://github.com/GitCredentialManager/git-c sudo dpkg -i git-credential-manager-core configure ``` -__Note:__ Although packages were previously offered on certain + +**Note:** Although packages were previously offered on certain [Microsoft Ubuntu package feeds](https://packages.microsoft.com/repos/), GCM no longer publishes to these repositories. Please install the Debian package using the above instructions instead. @@ -249,7 +250,7 @@ See detailed information [here](https://aka.ms/gcm/httpproxy). ## Contributing -This project welcomes contributions and suggestions. +This project welcomes contributions and suggestions. See the [contributing guide](CONTRIBUTING.md) to get started. This project follows [GitHub's Open Source Code of Conduct](CODE_OF_CONDUCT.md). diff --git a/SECURITY.md b/SECURITY.md index 5b2208269..8785fd5ba 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,5 @@ +# Security + If you discover a security issue in this repo, please submit it through the [GitHub Security Bug Bounty](https://hackerone.com/github) Thanks for helping make GitHub products safe for everyone. diff --git a/docs/bitbucket-development.md b/docs/bitbucket-development.md index 26dddda90..7e299743f 100644 --- a/docs/bitbucket-development.md +++ b/docs/bitbucket-development.md @@ -65,18 +65,18 @@ The Access and Refresh Tokens will be stored against the username and the userna # On-Premise Bitbucket -On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, https://bitbucket.org. +On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, https://bitbucket.org. As far as GCMC is concerned the main difference it doesn't support OAuth so only Basic Authentication is available. It is possible to test with Bitbucket Server by running it locally using the following command from the Atlassian SDK: - ❯ atlas-run-standalone --product bitbucket + ❯ atlas-run-standalone --product bitbucket See https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/. This will download and run a standalone instance of Bitbucket Server which can be accessed using the credentials `admin`/`admin` at - https://localhost:7990/bitbucket + https://localhost:7990/bitbucket Instructions on how to download and install the Atlassian SDK can be found here: https://developer.atlassian.com/server/framework/atlassian-sdk/ diff --git a/docs/configuration.md b/docs/configuration.md index e7a7e1cd2..826489096 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -196,7 +196,6 @@ git config --global credential.httpsProxy http://john.doe:password@proxy.contoso Override the available authentication modes presented during Bitbucket authentication. If this option is not set, then the available authentication modes will be automatically detected. - **Note:** This setting only applies to Bitbucket.org, and not Server or DC instances. **Note:** This setting supports multiple values separated by commas. @@ -227,7 +226,6 @@ Enabling this option will improve performance when using Oauth2 and interacting Enabling this option will decrease performance when using Basic Auth by requiring the user the re-enter credentials everytime. - Value|Refresh Credentials Before Returning -|- `true`, `1`, `yes`, `on` |Always @@ -295,7 +293,6 @@ git config --global credential.gitLabAuthModes "browser" --- - ### credential.namespace Use a custom namespace prefix for credentials read and written in the OS credential store. @@ -332,7 +329,7 @@ _(unset)_|Windows: `wincredman`
macOS: `keychain`
Linux: _(none)_|- `cache`|Git's built-in [credential cache](https://git-scm.com/docs/git-credential-cache).|Windows, macOS, Linux `plaintext`|Store credentials in plaintext files (**UNSECURE**). Customize the plaintext store location with [`credential.plaintextStorePath`](#credentialplaintextstorepath).|Windows, macOS, Linux -##### Example +#### Example ```bash git config --global credential.credentialStore gpg @@ -475,6 +472,7 @@ Credential: "git:https://github.com" (user = alice) https://github.com/contoso/widgets https://alice@github.com/contoso/widgets ``` + ```text Credential: "git:https://bob@github.com" (user = bob) @@ -489,17 +487,20 @@ Credential: "git:https://github.com/foo/bar" (user = alice) https://github.com/foo/bar ``` + ```text Credential: "git:https://github.com/contoso/widgets" (user = alice) https://github.com/contoso/widgets https://alice@github.com/contoso/widgets ``` + ```text Credential: "git:https://bob@github.com/foo/bar" (user = bob) https://bob@github.com/foo/bar ``` + ```text Credential: "git:https://bob@github.com/example/myrepo" (user = bob) diff --git a/docs/development.md b/docs/development.md index 0e8f2dc41..4f4207647 100644 --- a/docs/development.md +++ b/docs/development.md @@ -106,7 +106,7 @@ $ dotnet test --collect:"XPlat Code Coverage" --settings=./.code-coverage/coverl Or via the VSCode Terminal/Run Task: -``` +```console test with coverage ``` @@ -115,6 +115,7 @@ HTML reports can be generated using ReportGenerator, this should be installed du ```shell $ dotnet ~/.nuget/packages/reportgenerator/*/*/net6.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage ``` + or ```shell @@ -123,12 +124,12 @@ $ dotnet {$env:USERPROFILE}/.nuget/packages/reportgenerator/*/*/net6.0/ReportGen Or via VSCode Terminal/Run Task: -``` +```console report coverage - nix ``` or -``` +```console report coverage - win -``` \ No newline at end of file +``` diff --git a/docs/enterprise-config.md b/docs/enterprise-config.md index 754d0766d..78a96c818 100644 --- a/docs/enterprise-config.md +++ b/docs/enterprise-config.md @@ -18,7 +18,7 @@ The addition of the enterprise system administrator defaults enables those administrators to configure many GCM settings using familiar MDM tooling, rather than having to modify the Git installation configuration files. -### User Freedom +## User Freedom We believe the user should _always_ be at liberty to configure Git and GCM exactly as they wish. By prefering environment variables and Git @@ -30,13 +30,13 @@ that can always be overriden by the user in the usual ways. Default setting values come from the Windows Registry, specifically the following keys: -**32-bit Windows** +### 32-bit Windows ```text HKEY_LOCAL_MACHINE\SOFTWARE\GitCredentialManager\Configuration ``` -**64-bit Windows** +### 64-bit Windows ```text HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\GitCredentialManager\Configuration @@ -55,7 +55,6 @@ those of the [Git configuration](configuration.md) settings. The type of each registry key can be either `REG_SZ` (string) or `REG_DWORD` (integer). - ## macOS/Linux Default configuration setting stores has not been implemented. diff --git a/docs/environment.md b/docs/environment.md index 9237cca94..f04d07c31 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -325,13 +325,13 @@ Configure GCM to use the a proxy for network operations. **Note:** Git itself does _not_ respect this setting; this affects GCM _only_. -##### Windows +#### Windows ```batch SET GCM_HTTP_PROXY=http://john.doe:password@proxy.contoso.com ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_HTTP_PROXY=http://john.doe:password@proxy.contoso.com @@ -356,13 +356,13 @@ _(unset)_|Automatically detect modes `oauth`|OAuth-based authentication `basic`|Basic/PAT-based authentication -##### Windows +#### Windows ```batch SET GCM_BITBUCKET_AUTHMODES="oauth,basic" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_BITBUCKET_AUTHMODES="oauth,basic" @@ -382,19 +382,18 @@ Enabling this option will improve performance when using Oauth2 and interacting Enabling this option will decrease performance when using Basic Auth by requiring the user the re-enter credentials everytime. - Value|Refresh Credentials Before Returning -|- `true`, `1`, `yes`, `on` |Always `false`, `0`, `no`, `off`_(default)_|Only when the credentials are found to be invalid -##### Windows +#### Windows ```batch SET GCM_BITBUCKET_ALWAYS_REFRESH_CREDENTIALS=1 ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_BITBUCKET_ALWAYS_REFRESH_CREDENTIALS=1 @@ -422,13 +421,13 @@ _(unset)_|Automatically detect modes `basic`|Basic authentication using username and password `pat`|Personal Access Token (pat)-based authentication -##### Windows +#### Windows ```batch SET GCM_GITHUB_AUTHMODES="oauth,basic" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_GITHUB_AUTHMODES="oauth,basic" @@ -452,13 +451,13 @@ _(unset)_|Automatically detect modes `basic`|Basic authentication using username and password `pat`|Personal Access Token (pat)-based authentication -##### Windows +#### Windows ```batch SET GCM_GITLAB_AUTHMODES="browser" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_GITLAB_AUTHMODES="browser" @@ -475,13 +474,13 @@ Credentials will be stored in the format `{namespace}:{service}`. Defaults to the value `git`. -##### Windows +#### Windows ```batch SET GCM_NAMESPACE="my-namespace" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_NAMESPACE="my-namespace" @@ -510,13 +509,13 @@ _(unset)_|Windows: `wincredman`
macOS: `keychain`
Linux: _(none)_|- `cache`|Git's built-in [credential cache](https://git-scm.com/docs/git-credential-cache).|Windows, macOS, Linux `plaintext`|Store credentials in plaintext files (**UNSECURE**). Customize the plaintext store location with [`GCM_PLAINTEXT_STORE_PATH`](#gcm_plaintext_store_path).|Windows, macOS, Linux -##### Windows +#### Windows ```batch SET GCM_CREDENTIAL_STORE="gpg" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_CREDENTIAL_STORE="gpg" @@ -597,7 +596,7 @@ Specify the path (_including_ the executable name) to the version of `gpg` used If not specified, GCM defaults to using the version of `gpg2` on the `$PATH`, falling back on `gpg` if `gpg2` is not found. -##### macOS/Linux +#### macOS/Linux ```bash export GCM_GPG_PATH="/usr/local/bin/gpg2" @@ -625,13 +624,13 @@ Value|Authentication Flow `system`|Open the user's default web browser. `devicecode`|Show a device code. -##### Windows +#### Windows ```batch SET GCM_MSAUTH_FLOW="devicecode" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_MSAUTH_FLOW="devicecode" @@ -654,13 +653,13 @@ Value|Description `true`|Use the operating system account manager as an authentication broker. `false` _(default)_|Do not use the broker. -##### Windows +#### Windows ```batch SET GCM_MSAUTH_USEBROKER="true" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_MSAUTH_USEBROKER="false" @@ -683,13 +682,13 @@ Value|Description More information about Azure Access tokens can be found [here](azrepos-azuretokens.md). -##### Windows +#### Windows ```batch SET GCM_AZREPOS_CREDENTIALTYPE="oauth" ``` -##### macOS/Linux +#### macOS/Linux ```bash export GCM_AZREPOS_CREDENTIALTYPE="oauth" diff --git a/docs/faq.md b/docs/faq.md index d95365cf9..130850344 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -14,17 +14,17 @@ Please follow these steps to diagnose or resolve the problem: 1. If all else fails, create an issue [here](https://github.com/GitCredentialManager/git-credential-manager/issues/create), making sure to include the trace log. -### Q: I got an error saying unsecure HTTP is not supported. +### Q: I got an error saying unsecure HTTP is not supported To keep your data secure, Git Credential Manager will not send credentials for Azure Repos, Azure DevOps Server (TFS), GitHub, and Bitbucket, over HTTP connections that are not secured using TLS (HTTPS). Please make sure your remote URLs use "https://" rather than "http://". -### Q: I got an authentication error and I am behind a network proxy. +### Q: I got an authentication error and I am behind a network proxy You probably need to configure Git and GCM to use a proxy. Please see detailed information [here](https://aka.ms/gcm/httpproxy). -### Q: I'm getting errors about picking a credential store on Linux. +### Q: I'm getting errors about picking a credential store on Linux On Linux you must [select and configure a credential store](https://aka.ms/gcm/credstores), as due to the varied nature of distributions and installations, we cannot guarantee a suitable storage solution is available. @@ -65,7 +65,7 @@ GCM Windows was not designed with a cross-platform architecture. ### What level of support does GCM have? -Support will be best-effort. We would really appreciate your feedback to make this a great experience across each platform we support. +Support will be best-effort. We would really appreciate your feedback to make this a great experience across each platform we support. ### Q: Why does GCM not support operating system/distribution 'X', or Git hosting provider 'Y'? diff --git a/docs/github-apideprecation.md b/docs/github-apideprecation.md index a9c010714..2c33e4241 100644 --- a/docs/github-apideprecation.md +++ b/docs/github-apideprecation.md @@ -53,14 +53,14 @@ GCM for Windows bundled with the Git for Windows installation. If you are unable to use Git Credential Manager due to a bug or compatibility issue we'd [like to know why](https://github.com/GitCredentialManager/git-credential-manager/issues/new/choose)! -## Help! I cannot make any changes to my Windows machine without an Administrator! +## Help! I cannot make any changes to my Windows machine without an Administrator If you do not have permission to change your installation (for example in a corporate environment) you can use the per-user installer. Check out the [latest release](https://aka.ms/gcm/latest) and download the `gcmcoreuser-win-*.exe` executable. -### Help! I still cannot or don't want to install anything! +### Help! I still cannot or don't want to install anything There is a workaround which should work and doesn't require installing anything. @@ -71,24 +71,24 @@ There is a workaround which should work and doesn't require installing anything. 3. Enter a name ("note") for the token and ensure the `repo`, `gist`, and `workflow` scopes are selected: -![image](https://user-images.githubusercontent.com/5658207/95448332-1beb2000-095b-11eb-9a48-9c05b1926a6b.png) -... -![image](https://user-images.githubusercontent.com/5658207/95447304-6f5c6e80-0959-11eb-924b-50b86c2b3d77.png) -... -![image](https://user-images.githubusercontent.com/5658207/95447450-a3d02a80-0959-11eb-82a8-2d2834d5aa16.png) -... -![image](https://user-images.githubusercontent.com/5658207/95447343-7b483080-0959-11eb-8e00-151d53893f3f.png) + ![image](https://user-images.githubusercontent.com/5658207/95448332-1beb2000-095b-11eb-9a48-9c05b1926a6b.png) + ... + ![image](https://user-images.githubusercontent.com/5658207/95447304-6f5c6e80-0959-11eb-924b-50b86c2b3d77.png) + ... + ![image](https://user-images.githubusercontent.com/5658207/95447450-a3d02a80-0959-11eb-82a8-2d2834d5aa16.png) + ... + ![image](https://user-images.githubusercontent.com/5658207/95447343-7b483080-0959-11eb-8e00-151d53893f3f.png) -3. Click "Generate Token" +4. Click "Generate Token" -![image](https://user-images.githubusercontent.com/5658207/95448393-31f8e080-095b-11eb-9568-cfd1c567a65c.png) + ![image](https://user-images.githubusercontent.com/5658207/95448393-31f8e080-095b-11eb-9568-cfd1c567a65c.png) -4. **[IMPORTANT]** Keep the resulting page open as this contains your new token +5. **[IMPORTANT]** Keep the resulting page open as this contains your new token (this will only be displayed once!) -![image](https://user-images.githubusercontent.com/5658207/95448288-ff4ee800-095a-11eb-9709-8e37bde8b716.png) + ![image](https://user-images.githubusercontent.com/5658207/95448288-ff4ee800-095a-11eb-9709-8e37bde8b716.png) -5. Save the generated PAT in the Windows Credential Manager: +6. Save the generated PAT in the Windows Credential Manager: 1. If you prefer to use the command-line, open a command prompt (cmd.exe) and type the following: diff --git a/docs/gitlab.md b/docs/gitlab.md index fd923cb02..00f5dff38 100644 --- a/docs/gitlab.md +++ b/docs/gitlab.md @@ -15,7 +15,7 @@ To use on another instance, eg. `https://gitlab.example.com` requires setup and ### Clearing config -``` +```console git config --global --unset-all credential.https://gitlab.example.com.GitLabDevClientId git config --global --unset-all credential.https://gitlab.example.com.GitLabDevClientSecret git config --global --unset-all credential.https://gitlab.example.com.provider @@ -23,17 +23,19 @@ To use on another instance, eg. `https://gitlab.example.com` requires setup and ## Preferences -``` +```console Select an authentication method for 'https://gitlab.com/': 1. Web browser (default) 2. Personal access token 3. Username/password -option (enter for default): +option (enter for default): ``` If you have a preferred authentication mode, you can specify [credential.gitLabAuthModes](configuration.md#credential.gitLabAuthModes): - `git config --global credential.gitlabauthmodes browser` +```console +git config --global credential.gitlabauthmodes browser +``` ## Caveats diff --git a/docs/multiple-users.md b/docs/multiple-users.md index 20f1fd3cf..76e9bc591 100644 --- a/docs/multiple-users.md +++ b/docs/multiple-users.md @@ -10,7 +10,7 @@ Separate from the user strings in commits, Git recognizes the "user" part of a r Git hosting providers (like GitHub or Bitbucket) _do_ have a concept of "user". Typically it's an identity like a username or email address, plus a password or other credential to perform actions as that user. You may have guessed by now that GCM (the Git **Credential** Manager) does work with this notion of a user. -## People, identities, credentials, oh my! +## People, identities, credentials, oh my You (a physical person) may have one or more user accounts (identities) with one or more Git hosting providers. Since most Git hosts don't put a "user" part in their URLs, by default, Git will treat the user part for a remote as the empty string. If you have multiple identites on one domain, you'll need to insert a unique user part per-identity yourself. diff --git a/docs/windows-broker.md b/docs/windows-broker.md index 1ab1cc73b..62b422ee5 100644 --- a/docs/windows-broker.md +++ b/docs/windows-broker.md @@ -31,6 +31,7 @@ The GCM team isn't responsible for the user experience or choices made by WAM, b Therefore, we want you to be aware of some defaults and experiences if you choose to use WAM integration. ### For work or school accounts (Azure AD-backed identities) + When you sign into an Azure DevOps organization backed by Azure AD (often your company or school email), if your machine is already joined to Azure AD matching that Azure DevOps organization, you'll get a seamless and easy-to-use experience. If your machine isn't Azure AD-joined, or is Azure AD-joined to a different tenant, WAM will present you with a dialog box suggesting you stay signed in and allow the organization to manage your device. @@ -57,6 +58,7 @@ Similar to the above, your organization's Conditional Access policies may preven If Conditional Access is required to access your organization's Git repositories, you can [enable WAM integration](environment.md#GCM_MSAUTH_USEBROKER-experimental) (or follow other instructions your organization provides). #### Removing device management + If you've allowed your computer to be managed and want to undo it, you can go into **Settings**, **Accounts**, **Access work or school**. In the section where you see your email address and organization name, click **Disconnect**. @@ -65,6 +67,7 @@ In the section where you see your email address and organization name, click **D ![Disconnecting from Azure AD](img/aad-disconnect.png) ### For Microsoft accounts + When you sign into an Azure DevOps organization backed by Microsoft account (MSA) identities (email addresses like `@outlook.com` or `@gmail.com` fall into this category), you may be prompted to select an existing "work or school account" or use a different one. In order to sign in with an MSA you should continue and select "Use a different [work or school] account", but enter your MSA credentials when prompted. @@ -81,8 +84,9 @@ For any connected MSA, you can control whether or not the account is available t ![Microsoft apps must ask to access your identity](img/apps-must-ask.png) Two very important things to note: -* If you haven't connected any Microsoft accounts to Windows before, the first account you connect will cause the local Windows user account to be converted to a connected account. -* In addition, you can't change the usage preference for the first Microsoft account connected to Windows: all Microsoft apps will be able to sign you in with that account. + +- If you haven't connected any Microsoft accounts to Windows before, the first account you connect will cause the local Windows user account to be converted to a connected account. +- In addition, you can't change the usage preference for the first Microsoft account connected to Windows: all Microsoft apps will be able to sign you in with that account. As far as we can tell, there are no workarounds for either of these behaviors (other than to not use the WAM broker). From 3f42fcee3df858fa2867386ecf2872cc86f23c7e Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 22:30:42 +0100 Subject: [PATCH 07/83] Fix bare URLs --- CODE_OF_CONDUCT.md | 10 ++++++---- docs/bitbucket-development.md | 6 +++--- docs/gitlab.md | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3a64696bc..6fb415727 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -68,9 +68,11 @@ members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +available at [Contributor Covenant Code of Conduct][coc]. -[homepage]: https://www.contributor-covenant.org +For answers to common questions about this code of conduct, see the +[Contributor Covenant FAQ][faq] -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +[homepage]: https://www.contributor-covenant.org +[coc]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +[faq]: https://www.contributor-covenant.org/faq diff --git a/docs/bitbucket-development.md b/docs/bitbucket-development.md index 7e299743f..373e6e261 100644 --- a/docs/bitbucket-development.md +++ b/docs/bitbucket-development.md @@ -65,7 +65,7 @@ The Access and Refresh Tokens will be stored against the username and the userna # On-Premise Bitbucket -On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, https://bitbucket.org. +On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, [bitbucket.org](https://bitbucket.org). As far as GCMC is concerned the main difference it doesn't support OAuth so only Basic Authentication is available. @@ -73,10 +73,10 @@ It is possible to test with Bitbucket Server by running it locally using the fol ❯ atlas-run-standalone --product bitbucket -See https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/. +See the devloper documentation for [atlas-run-standalone](https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/). This will download and run a standalone instance of Bitbucket Server which can be accessed using the credentials `admin`/`admin` at https://localhost:7990/bitbucket -Instructions on how to download and install the Atlassian SDK can be found here: https://developer.atlassian.com/server/framework/atlassian-sdk/ +Atlassian has [documentation](https://developer.atlassian.com/server/framework/atlassian-sdk/) on how to download and install their SDK. diff --git a/docs/gitlab.md b/docs/gitlab.md index 00f5dff38..970640d82 100644 --- a/docs/gitlab.md +++ b/docs/gitlab.md @@ -41,6 +41,6 @@ git config --global credential.gitlabauthmodes browser Improved support requires changes in GitLab. Please vote for these issues if they affect you: -1. No support for OAuth device authorization (necessary for machines without web browser) https://gitlab.com/gitlab-org/gitlab/-/issues/332682 -2. Only domains with prefix `gitlab.` are recognised as GitLab remotes https://gitlab.com/gitlab-org/gitlab/-/issues/349464 -3. Username/password authentication is suggested even if disabled on server https://gitlab.com/gitlab-org/gitlab/-/issues/349463 +1. No support for OAuth device authorization (necessary for machines without web browser): [GitLab issue 332682](https://gitlab.com/gitlab-org/gitlab/-/issues/332682) +2. Only domains with prefix `gitlab.` are recognised as GitLab remotes: [GitLab issue 349464](https://gitlab.com/gitlab-org/gitlab/-/issues/349464) +3. Username/password authentication is suggested even if disabled on server: [GitLab issue 349463](https://gitlab.com/gitlab-org/gitlab/-/issues/349463) From e78add706baa3e2b974084136cb6fbb6d890521a Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 22:49:28 +0100 Subject: [PATCH 08/83] Fix inline HTML --- README.md | 6 ++---- docs/configuration.md | 18 +++++++++--------- docs/environment.md | 16 ++++++++-------- docs/github-apideprecation.md | 2 +- docs/migration.md | 6 +++--- docs/wsl.md | 2 +- 6 files changed, 24 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8c4b63627..944f97354 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ Git Credential Manager is currently available for Windows, macOS, and Linux\*. G Feature|Windows|macOS|Linux -|:-:|:-:|:-: -Installer/uninstaller|✓|✓|✓ -Secure platform credential storage|✓
[(see more)](docs/credstores.md)|✓
[(see more)](docs/credstores.md)|✓
[(see more)](docs/credstores.md) +Installer/uninstaller|✓|✓|✓\* +Secure platform credential storage|✓ [(see more)](docs/credstores.md)|✓ [(see more)](docs/credstores.md)|✓ [(see more)](docs/credstores.md) Multi-factor authentication support for Azure DevOps|✓|✓|✓ Two-factor authentication support for GitHub|✓|✓|✓ Two-factor authentication support for Bitbucket|✓|✓|✓ @@ -86,8 +86,6 @@ sudo /usr/local/share/gcm-core/uninstall.sh --- - - ### Linux #### Experimental: install from source helper script diff --git a/docs/configuration.md b/docs/configuration.md index 826489096..06a46eb5a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -39,8 +39,8 @@ The following table summarizes the change in behavior and the mapping of older v Value(s)|Old meaning|New meaning -|-|- `auto`|Prompt if required – use cached credentials if possible|_(unchanged)_ -`never`,
`false`| Never prompt – fail if interaction is required|_(unchanged)_ -`always`,
`force`,
`true`|Always prompt – don't use cached credentials|Prompt if required (same as the old `auto` value) +`never`, `false`| Never prompt – fail if interaction is required|_(unchanged)_ +`always`, `force`, `true`|Always prompt – don't use cached credentials|Prompt if required (same as the old `auto` value) #### Example @@ -64,7 +64,7 @@ ID|Provider `azure-repos`|Azure Repos `github`|GitHub `bitbucket`|Bitbucket -`gitlab`|GitLab
_(supports OAuth in browser, personal access token and Basic Authentication)_ +`gitlab`|GitLab _(supports OAuth in browser, personal access token and Basic Authentication)_ `generic`|Generic (any other provider not listed above) Automatic provider selection is based on the remote URL. @@ -92,11 +92,11 @@ Select the host provider to use when authenticating by which authority is suppor Authority|Provider(s) -|- `auto` _(default)_|_\[automatic\]_ -`msa`, `microsoft`, `microsoftaccount`,
`aad`, `azure`, `azuredirectory`,
`live`, `liveconnect`, `liveid`|Azure Repos
_(supports Microsoft Authentication)_ -`github`|GitHub
_(supports GitHub Authentication)_ -`bitbucket`|Bitbucket.org
_(supports Basic Authentication and OAuth)_
Bitbucket Server
_(supports Basic Authentication)_ -`gitlab`|GitLab
_(supports OAuth in browser, personal access token and Basic Authentication)_ -`basic`, `integrated`, `windows`, `kerberos`, `ntlm`,
`tfs`, `sso`|Generic
_(supports Basic and Windows Integrated Authentication)_ +`msa`, `microsoft`, `microsoftaccount`, `aad`, `azure`, `azuredirectory`, `live`, `liveconnect`, `liveid`|Azure Repos _(supports Microsoft Authentication)_ +`github`|GitHub _(supports GitHub Authentication)_ +`bitbucket`|Bitbucket.org _(supports Basic Authentication and OAuth)_, Bitbucket Server _(supports Basic Authentication)_ +`gitlab`|GitLab _(supports OAuth in browser, personal access token and Basic Authentication)_ +`basic`, `integrated`, `windows`, `kerberos`, `ntlm`, `tfs`, `sso`|Generic _(supports Basic and Windows Integrated Authentication)_ #### Example @@ -320,7 +320,7 @@ Default value on Windows is `wincredman`, on macOS is `keychain`, and is unset o Value|Credential Store|Platforms -|-|- -_(unset)_|Windows: `wincredman`
macOS: `keychain`
Linux: _(none)_|- +_(unset)_|Windows: `wincredman`, macOS: `keychain`, Linux: _(none)_|- `wincredman`|Windows Credential Manager (not available over SSH).|Windows `dpapi`|DPAPI protected files. Customize the DPAPI store location with [credential.dpapiStorePath](#credentialdpapistorepath)|Windows `keychain`|macOS Keychain.|macOS diff --git a/docs/environment.md b/docs/environment.md index f04d07c31..bef45f916 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -137,8 +137,8 @@ The following table summarizes the change in behavior and the mapping of older v Value(s)|Old meaning|New meaning -|-|- `auto`|Prompt if required – use cached credentials if possible|_(unchanged)_ -`never`,
`false`| Never prompt – fail if interaction is required|_(unchanged)_ -`always`,
`force`,
`true`|Always prompt – don't use cached credentials|Prompt if required (same as the old `auto` value) +`never`, `false`| Never prompt – fail if interaction is required|_(unchanged)_ +`always`, `force`, `true`|Always prompt – don't use cached credentials|Prompt if required (same as the old `auto` value) #### Example @@ -169,7 +169,7 @@ ID|Provider `auto` _(default)_|_\[automatic\]_ ([learn more](autodetect.md)) `azure-repos`|Azure Repos `github`|GitHub -`gitlab`|GitLab
_(supports OAuth in browser, personal access token and Basic Authentication)_ +`gitlab`|GitLab _(supports OAuth in browser, personal access token and Basic Authentication)_ `generic`|Generic (any other provider not listed above) Automatic provider selection is based on the remote URL. @@ -205,10 +205,10 @@ Select the host provider to use when authenticating by which authority is suppor Authority|Provider(s) -|- `auto` _(default)_|_\[automatic\]_ -`msa`, `microsoft`, `microsoftaccount`,
`aad`, `azure`, `azuredirectory`,
`live`, `liveconnect`, `liveid`|Azure Repos
_(supports Microsoft Authentication)_ -`github`|GitHub
_(supports GitHub Authentication)_ -`gitlab`|GitLab
_(supports OAuth in browser, personal access token and Basic Authentication)_ -`basic`, `integrated`, `windows`, `kerberos`, `ntlm`,
`tfs`, `sso`|Generic
_(supports Basic and Windows Integrated Authentication)_ +`msa`, `microsoft`, `microsoftaccount`, `aad`, `azure`, `azuredirectory`, `live`, `liveconnect`, `liveid`|Azure Repos _(supports Microsoft Authentication)_ +`github`|GitHub _(supports GitHub Authentication)_ +`gitlab`|GitLab _(supports OAuth in browser, personal access token and Basic Authentication)_ +`basic`, `integrated`, `windows`, `kerberos`, `ntlm`, `tfs`, `sso`|Generic _(supports Basic and Windows Integrated Authentication)_ #### Example @@ -500,7 +500,7 @@ Default value on Windows is `wincredman`, on macOS is `keychain`, and is unset o Value|Credential Store|Platforms -|-|- -_(unset)_|Windows: `wincredman`
macOS: `keychain`
Linux: _(none)_|- +_(unset)_|Windows: `wincredman`, macOS: `keychain`, Linux: _(none)_|- `wincredman`|Windows Credential Manager (not available over SSH).|Windows `dpapi`|DPAPI protected files. Customize the DPAPI store location with [`GCM_DPAPI_STORE_PATH`](#gcm_dpapi_store_path)|Windows `keychain`|macOS Keychain.|macOS diff --git a/docs/github-apideprecation.md b/docs/github-apideprecation.md index 2c33e4241..c4a9ff08a 100644 --- a/docs/github-apideprecation.md +++ b/docs/github-apideprecation.md @@ -98,7 +98,7 @@ There is a workaround which should work and doesn't require installing anything. ``` You will be prompted to enter a password – copy the newly generated PAT in - step 4 and paste it here, and press Enter + step 4 and paste it here, and press the `Enter` key ![image](https://user-images.githubusercontent.com/5658207/95448479-4fc64580-095b-11eb-9970-0b6faf7f4ae7.png) diff --git a/docs/migration.md b/docs/migration.md index a2be4cfe7..88ba8da89 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -10,12 +10,12 @@ Because both Basic HTTP authentication and Windows Integrated Authentication (WI The following table shows the correct replacement for all legacy authorities values: -GCM_AUTHORITY
(credential.authority)|→|GCM_PROVIDER
(credential.provider)|GCM_ALLOW_WINDOWSAUTH
(credential.allowWindowsAuth) +GCM_AUTHORITY (credential.authority)|→|GCM_PROVIDER (credential.provider)|GCM_ALLOW_WINDOWSAUTH (credential.allowWindowsAuth) -|-|-|- -`msa`, `microsoft`, `microsoftaccount`,
`aad`, `azure`, `azuredirectory`,
`live`, `liveconnect`, `liveid`|→|`azure-repos`|_N/A_ +`msa`, `microsoft`, `microsoftaccount`, `aad`, `azure`, `azuredirectory`, `live`, `liveconnect`, `liveid`|→|`azure-repos`|_N/A_ `github`|→|`github`|_N/A_ `basic`|→|`generic`|`false` -`integrated`, `windows`, `kerberos`, `ntlm`,
`tfs`, `sso`|→|`generic`|`true` _(default)_ +`integrated`, `windows`, `kerberos`, `ntlm`, `tfs`, `sso`|→|`generic`|`true` _(default)_ For example if you had previous set the authority for the `example.com` host to `basic`.. diff --git a/docs/wsl.md b/docs/wsl.md index 63b99e9ea..ccf606b18 100644 --- a/docs/wsl.md +++ b/docs/wsl.md @@ -102,7 +102,7 @@ installation, and not shared with others or the Windows host. Yes. Rather than install GCM as a Windows application (and have WSL Git invoke the Windows GCM), can you install GCM as a Linux application instead. -To do this, simply follow the [GCM installation instructions for Linux](../README.md#linux-install-instructions). +To do this, simply follow the [GCM installation instructions for Linux](../README.md#linux). **Note:** In this scenario, because GCM is running as a Linux application it cannot utilize authentication or credential storage features of the host From 9f3b26983aca9a21b477b23bd809534b5e9c186f Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 22:58:13 +0100 Subject: [PATCH 09/83] Remove spaces inside code-span elements --- docs/netconfig.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/netconfig.md b/docs/netconfig.md index 7a6d5f51c..017d727e0 100644 --- a/docs/netconfig.md +++ b/docs/netconfig.md @@ -76,7 +76,7 @@ addresses. GCM supports the cURL environment variable `no_proxy` (and Like with the [other cURL proxy environment variables](#other-proxy-options), the lowercase variant will take precedence over the uppercase form. -This environment variable should contain a comma (`,`) or space (` `) separated +This environment variable should contain a comma-separated or space-separated list of host names that should not be proxied (should connect directly). GCM attempts to match [libcurl's behaviour](https://curl.se/libcurl/c/CURLOPT_NOPROXY.html), From 637bf1a970b3eee7dd2bd16a60200eb2b96fe9bb Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 23:09:26 +0100 Subject: [PATCH 10/83] Fix multiple top-level headings --- docs/bitbucket-development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bitbucket-development.md b/docs/bitbucket-development.md index 373e6e261..22f98146d 100644 --- a/docs/bitbucket-development.md +++ b/docs/bitbucket-development.md @@ -63,7 +63,7 @@ Assuming the user successfully logins into Bitbucket and authorizes the GCM this The Access and Refresh Tokens will be stored against the username and the username/Access Token credentials returned to Git. -# On-Premise Bitbucket +## On-Premise Bitbucket On-premise Bitbucket, more correctly known as Bitbucket Server or Bitbucket DC, has a number of differences compared to the cloud instance of Bitbucket, [bitbucket.org](https://bitbucket.org). From 1f21050fe02a9c8cb869d750553fe018b1e50347 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 15 Apr 2022 23:09:56 +0100 Subject: [PATCH 11/83] Fix console commands without output --- docs/development.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/development.md b/docs/development.md index 4f4207647..fdec0d8b7 100644 --- a/docs/development.md +++ b/docs/development.md @@ -101,7 +101,7 @@ $ GCM_TRACE=1 git-credential-manager-core version If you want code coverage metrics these can be generated either from the command line: ```shell -$ dotnet test --collect:"XPlat Code Coverage" --settings=./.code-coverage/coverlet.settings.xml +dotnet test --collect:"XPlat Code Coverage" --settings=./.code-coverage/coverlet.settings.xml ``` Or via the VSCode Terminal/Run Task: @@ -113,13 +113,13 @@ test with coverage HTML reports can be generated using ReportGenerator, this should be installed during the build process, from the command line: ```shell -$ dotnet ~/.nuget/packages/reportgenerator/*/*/net6.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage +dotnet ~/.nuget/packages/reportgenerator/*/*/net6.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage ``` or ```shell -$ dotnet {$env:USERPROFILE}/.nuget/packages/reportgenerator/*/*/net6.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage +dotnet {$env:USERPROFILE}/.nuget/packages/reportgenerator/*/*/net6.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage ``` Or via VSCode Terminal/Run Task: From a319c6a4f1edc732e44cfd0c82dfb05e7ac90359 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Sat, 16 Apr 2022 17:53:02 +0100 Subject: [PATCH 12/83] Add markdown linting to workflows --- .github/workflows/lint-docs.yml | 19 +++++++++++++++++++ .markdownlint.jsonc | 6 ++++++ 2 files changed, 25 insertions(+) create mode 100644 .github/workflows/lint-docs.yml create mode 100644 .markdownlint.jsonc diff --git a/.github/workflows/lint-docs.yml b/.github/workflows/lint-docs.yml new file mode 100644 index 000000000..665e041e2 --- /dev/null +++ b/.github/workflows/lint-docs.yml @@ -0,0 +1,19 @@ +name: "Lint documentation" + +on: + workflow_dispatch: + push: + branches: [ main, linux ] + pull_request: + branches: [ main, linux ] + +jobs: + lint-markdown: + name: Lint markdown files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 + + - uses: DavidAnson/markdownlint-cli2-action@744f913a124058ee903768d3adb92a4847e5d132 + with: + globs: "**/*.md" diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 000000000..6e0ac4ada --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,6 @@ +// For information on writing markdownlint configuration see: +// https://github.com/DavidAnson/markdownlint/blob/main/README.md#optionsconfig +{ + "MD013": false, // Line length and line breaking convention not yet standardised across docs + "MD024": false // The format for some files require repeated headings, e.g. "Example" +} From 2379ac18d5e0c07843718ddf83adbc4084e85184 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Sat, 16 Apr 2022 18:10:15 +0100 Subject: [PATCH 13/83] Fix spellings --- docs/azrepos-users-and-tokens.md | 4 ++-- docs/bitbucket-development.md | 2 +- docs/enterprise-config.md | 4 ++-- docs/environment.md | 2 +- docs/multiple-users.md | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/azrepos-users-and-tokens.md b/docs/azrepos-users-and-tokens.md index cc26598bb..1aab32262 100644 --- a/docs/azrepos-users-and-tokens.md +++ b/docs/azrepos-users-and-tokens.md @@ -64,7 +64,7 @@ credential. This may change in the future. Normally you won't need to worry about managing which user accounts Git Credential Manager is using as this is configured automatically when you first -authenticate for a particular Azure DevOps organziation. +authenticate for a particular Azure DevOps organization. In advanced scenarios (such as using multiple accounts) you can interact with and manage remembered user accounts using the 'azure-repos' provider command: @@ -181,7 +181,7 @@ fabrikam: ``` In the above example, the `~/myrepo` repository has a single Git remote named -`origin` that points to the `contoso` Azure DevOps organziation. There is no +`origin` that points to the `contoso` Azure DevOps organization. There is no user account specifically associated with the `origin` remote, so the global user account binding for `contoso` will be used (the global binding is inherited). diff --git a/docs/bitbucket-development.md b/docs/bitbucket-development.md index 22f98146d..dc7140770 100644 --- a/docs/bitbucket-development.md +++ b/docs/bitbucket-development.md @@ -73,7 +73,7 @@ It is possible to test with Bitbucket Server by running it locally using the fol ❯ atlas-run-standalone --product bitbucket -See the devloper documentation for [atlas-run-standalone](https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/). +See the developer documentation for [atlas-run-standalone](https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-run-standalone/). This will download and run a standalone instance of Bitbucket Server which can be accessed using the credentials `admin`/`admin` at diff --git a/docs/enterprise-config.md b/docs/enterprise-config.md index 78a96c818..36f927b29 100644 --- a/docs/enterprise-config.md +++ b/docs/enterprise-config.md @@ -21,9 +21,9 @@ than having to modify the Git installation configuration files. ## User Freedom We believe the user should _always_ be at liberty to configure -Git and GCM exactly as they wish. By prefering environment variables and Git +Git and GCM exactly as they wish. By preferring environment variables and Git configuration files over system admin values, these only act as _default values_ -that can always be overriden by the user in the usual ways. +that can always be overridden by the user in the usual ways. ## Windows diff --git a/docs/environment.md b/docs/environment.md index bef45f916..1089c071a 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -380,7 +380,7 @@ This is especially relevant to OAuth credentials. Bitbucket.org access tokens ex Enabling this option will improve performance when using Oauth2 and interacting with Bitbucket.org if, on average, commits are done less frequently than every 2 hours. -Enabling this option will decrease performance when using Basic Auth by requiring the user the re-enter credentials everytime. +Enabling this option will decrease performance when using Basic Auth by requiring the user the re-enter credentials every time. Value|Refresh Credentials Before Returning -|- diff --git a/docs/multiple-users.md b/docs/multiple-users.md index 76e9bc591..7446aef0e 100644 --- a/docs/multiple-users.md +++ b/docs/multiple-users.md @@ -12,9 +12,9 @@ Git hosting providers (like GitHub or Bitbucket) _do_ have a concept of "user". ## People, identities, credentials, oh my -You (a physical person) may have one or more user accounts (identities) with one or more Git hosting providers. Since most Git hosts don't put a "user" part in their URLs, by default, Git will treat the user part for a remote as the empty string. If you have multiple identites on one domain, you'll need to insert a unique user part per-identity yourself. +You (a physical person) may have one or more user accounts (identities) with one or more Git hosting providers. Since most Git hosts don't put a "user" part in their URLs, by default, Git will treat the user part for a remote as the empty string. If you have multiple identities on one domain, you'll need to insert a unique user part per-identity yourself. -There are good reasons for having multiple identities on one domain. You might use one GitHub identity for your personal work, another for your open source work, and a third for your employer's work. You can ask Git to assign a different credential to different repositories hosted on the same provider. HTTPS URLs include an optional "name" part before an `@` sign in the domain name, and you can use this to force Git to distiguish multiple users. This should likely be your username on the Git hosting service, since there are cases where GCM will use it like a username. +There are good reasons for having multiple identities on one domain. You might use one GitHub identity for your personal work, another for your open source work, and a third for your employer's work. You can ask Git to assign a different credential to different repositories hosted on the same provider. HTTPS URLs include an optional "name" part before an `@` sign in the domain name, and you can use this to force Git to distinguish multiple users. This should likely be your username on the Git hosting service, since there are cases where GCM will use it like a username. ## Setting it up From 43ee90b62f0a5a0f70378da1c5236f147826c290 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Fri, 22 Apr 2022 19:35:09 +0100 Subject: [PATCH 14/83] Ignore lint for anchor for Linux install instructions --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 944f97354..ccf10b9a3 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,10 @@ sudo /usr/local/share/gcm-core/uninstall.sh --- + + + + ### Linux #### Experimental: install from source helper script From b48ad393acc98638bba675540b09ed7c33409d54 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Sat, 23 Apr 2022 10:08:19 +0100 Subject: [PATCH 15/83] Adjust list numbering format --- CONTRIBUTING.md | 16 ++++++++-------- README.md | 2 +- docs/enterprise-config.md | 10 +++++----- docs/github-apideprecation.md | 10 +++++----- docs/gitlab.md | 14 +++++++------- docs/netconfig.md | 4 ++-- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e4aaad228..9e6774c1e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,22 +15,22 @@ Please note that this project is released with a [Contributor Code of Conduct][c 1. Open an [issue][issue] to discuss the change you want to see. This helps us coordinate and reduce duplication. -2. Once we've had some discussion, you're ready to code! +1. Once we've had some discussion, you're ready to code! ## Submitting a pull request 1. [Fork][fork] and clone the repository -2. Configure and install the dependencies: `dotnet restore` -3. Make sure the tests pass on your machine: `dotnet test` -4. Create a new branch: `git switch -c my-branch-name` -5. Make your change, add tests, and make sure the tests still pass -6. For UI updates, test your changes by executing a `dotnet run` in applicable UI-related project directories: +1. Configure and install the dependencies: `dotnet restore` +1. Make sure the tests pass on your machine: `dotnet test` +1. Create a new branch: `git switch -c my-branch-name` +1. Make your change, add tests, and make sure the tests still pass +1. For UI updates, test your changes by executing a `dotnet run` in applicable UI-related project directories: - `Atlassian.Bitbucket.UI.Avalonia` - `GitHub.UI.Avalonia` - `Atlassian.Bitbucket.UI.Windows` - `GitHub.UI.Windows` -7. Push to your fork and [submit a pull request][pr] -8. Pat your self on the back and wait for your pull request to be reviewed and merged. +1. Push to your fork and [submit a pull request][pr] +1. Pat your self on the back and wait for your pull request to be reviewed and merged. Here are a few things you can do that will increase the likelihood of your pull request being accepted: diff --git a/README.md b/README.md index ccf10b9a3..411a76717 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ run the following: If `curl` is not installed, please use your distribution's package manager to install it. -2. To download and run the script: +1. To download and run the script: ```shell curl -LO https://raw.githubusercontent.com/GitCredentialManager/git-credential-manager/main/src/linux/Packaging.Linux/install-from-source.sh && diff --git a/docs/enterprise-config.md b/docs/enterprise-config.md index 36f927b29..96ce891d5 100644 --- a/docs/enterprise-config.md +++ b/docs/enterprise-config.md @@ -4,12 +4,12 @@ Git Credential Manager (GCM) can be configured using multiple different mechanisms. In order of preference, those mechanisms are: 1. [Environment variables](environment.md) -2. [Standard Git configuration files](configuration.md) +1. [Standard Git configuration files](configuration.md) 1. Repository/local configuration (`.git/config`) - 2. User/global configuration (`$HOME/.gitconfig` or `%HOME%\.gitconfig`) - 3. Installation/system configuration (`etc/gitconfig`) -3. Enterprise system administrator defaults -4. Compiled default values + 1. User/global configuration (`$HOME/.gitconfig` or `%HOME%\.gitconfig`) + 1. Installation/system configuration (`etc/gitconfig`) +1. Enterprise system administrator defaults +1. Compiled default values This model largely matches what Git itself supports, namely environment variables that take precedence over Git configuration files. diff --git a/docs/github-apideprecation.md b/docs/github-apideprecation.md index c4a9ff08a..9d5c3b9a3 100644 --- a/docs/github-apideprecation.md +++ b/docs/github-apideprecation.md @@ -67,9 +67,9 @@ There is a workaround which should work and doesn't require installing anything. 1. Tell your system administrator they should start planning to upgrade the installed version of Git for Windows to at least 2.29! 😁 -2. [Create a new personal access token](https://github.com/settings/tokens/new?scopes=repo,gist,workflow) (see official [documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)) +1. [Create a new personal access token](https://github.com/settings/tokens/new?scopes=repo,gist,workflow) (see official [documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)) -3. Enter a name ("note") for the token and ensure the `repo`, `gist`, and +1. Enter a name ("note") for the token and ensure the `repo`, `gist`, and `workflow` scopes are selected: ![image](https://user-images.githubusercontent.com/5658207/95448332-1beb2000-095b-11eb-9a48-9c05b1926a6b.png) ... @@ -79,16 +79,16 @@ There is a workaround which should work and doesn't require installing anything. ... ![image](https://user-images.githubusercontent.com/5658207/95447343-7b483080-0959-11eb-8e00-151d53893f3f.png) -4. Click "Generate Token" +1. Click "Generate Token" ![image](https://user-images.githubusercontent.com/5658207/95448393-31f8e080-095b-11eb-9568-cfd1c567a65c.png) -5. **[IMPORTANT]** Keep the resulting page open as this contains your new token +1. **[IMPORTANT]** Keep the resulting page open as this contains your new token (this will only be displayed once!) ![image](https://user-images.githubusercontent.com/5658207/95448288-ff4ee800-095a-11eb-9709-8e37bde8b716.png) -6. Save the generated PAT in the Windows Credential Manager: +1. Save the generated PAT in the Windows Credential Manager: 1. If you prefer to use the command-line, open a command prompt (cmd.exe) and type the following: diff --git a/docs/gitlab.md b/docs/gitlab.md index 970640d82..0d876d514 100644 --- a/docs/gitlab.md +++ b/docs/gitlab.md @@ -7,11 +7,11 @@ Git Credential Manager supports [gitlab.com](https://gitlab.com) out the box. To use on another instance, eg. `https://gitlab.example.com` requires setup and configuration: 1. [Create an OAuth application](https://docs.gitlab.com/ee/integration/oauth_provider.html). This can be at the user, group or instance level. Specify a name and use a redirect URI of `http://127.0.0.1/`. _Unselect_ the 'Confidential' option, and ensure the 'Expire access tokens' option is selected. Set the scope to 'write_repository'. -2. Copy the application ID and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientId ` -3. Copy the application secret and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientSecret ` -4. Configure authentication modes to include 'browser' `git config --global credential.https://gitlab.example.com.gitLabAuthModes browser` -5. For good measure, configure `git config --global credential.https://gitlab.example.com.provider gitlab`. This may be necessary to recognise the domain as a GitLab instance. -6. Verify the config is as expected `git config --global --get-urlmatch credential https://gitlab.example.com` +1. Copy the application ID and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientId ` +1. Copy the application secret and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientSecret ` +1. Configure authentication modes to include 'browser' `git config --global credential.https://gitlab.example.com.gitLabAuthModes browser` +1. For good measure, configure `git config --global credential.https://gitlab.example.com.provider gitlab`. This may be necessary to recognise the domain as a GitLab instance. +1. Verify the config is as expected `git config --global --get-urlmatch credential https://gitlab.example.com` ### Clearing config @@ -42,5 +42,5 @@ git config --global credential.gitlabauthmodes browser Improved support requires changes in GitLab. Please vote for these issues if they affect you: 1. No support for OAuth device authorization (necessary for machines without web browser): [GitLab issue 332682](https://gitlab.com/gitlab-org/gitlab/-/issues/332682) -2. Only domains with prefix `gitlab.` are recognised as GitLab remotes: [GitLab issue 349464](https://gitlab.com/gitlab-org/gitlab/-/issues/349464) -3. Username/password authentication is suggested even if disabled on server: [GitLab issue 349463](https://gitlab.com/gitlab-org/gitlab/-/issues/349463) +1. Only domains with prefix `gitlab.` are recognised as GitLab remotes: [GitLab issue 349464](https://gitlab.com/gitlab-org/gitlab/-/issues/349464) +1. Username/password authentication is suggested even if disabled on server: [GitLab issue 349463](https://gitlab.com/gitlab-org/gitlab/-/issues/349463) diff --git a/docs/netconfig.md b/docs/netconfig.md index 017d727e0..35cf9dc80 100644 --- a/docs/netconfig.md +++ b/docs/netconfig.md @@ -49,11 +49,11 @@ GCM supports other ways of configuring a proxy for convenience and compatibility 1. GCM-specific configuration options (_**only** respected by GCM; **deprecated**_): - `credential.httpProxy` - `credential.httpsProxy` -2. cURL environment variables (_also respected by Git_): +1. cURL environment variables (_also respected by Git_): - `http_proxy` - `https_proxy`/`HTTPS_PROXY` - `all_proxy`/`ALL_PROXY` -3. `GCM_HTTP_PROXY` environment variable (_**only** respected by GCM; **deprecated**_) +1. `GCM_HTTP_PROXY` environment variable (_**only** respected by GCM; **deprecated**_) Note that with the cURL environment variables there are both lowercase and uppercase variants. From 192b5b70ea0261df03437da646261bf993095b59 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Sat, 23 Apr 2022 10:10:48 +0100 Subject: [PATCH 16/83] Improve link reference IDs --- CODE_OF_CONDUCT.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 6fb415727..a7a7e0e63 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -67,12 +67,12 @@ members of the project's leadership. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [Contributor Covenant Code of Conduct][coc]. +This Code of Conduct is adapted from the [Contributor Covenant][cc-homepage], version 1.4, +available at [Contributor Covenant Code of Conduct][cc-coc]. For answers to common questions about this code of conduct, see the -[Contributor Covenant FAQ][faq] +[Contributor Covenant FAQ][cc-faq] -[homepage]: https://www.contributor-covenant.org -[coc]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html -[faq]: https://www.contributor-covenant.org/faq +[cc-homepage]: https://www.contributor-covenant.org +[cc-coc]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +[cc-faq]: https://www.contributor-covenant.org/faq From 5b763c0f7ea82f7796cb43cbbac5dfd51f7fa70a Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Sat, 23 Apr 2022 19:36:51 +0100 Subject: [PATCH 17/83] Fix new list lint issue --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 411a76717..7071f57e3 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Proxy support|✓|✓|✓ - Debian/Ubuntu/Linux Mint - Fedora/CentOS/RHEL - Alpine + ## Download and Install ### macOS Homebrew From d549e5f5f354b4b507e996bfddb7de8d1dc89c59 Mon Sep 17 00:00:00 2001 From: M Hickford Date: Fri, 31 Dec 2021 16:01:01 +0000 Subject: [PATCH 18/83] Add link to GitHub application settings --- src/shared/GitHub/GitHubConstants.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/GitHub/GitHubConstants.cs b/src/shared/GitHub/GitHubConstants.cs index a564e290d..b6f222b48 100644 --- a/src/shared/GitHub/GitHubConstants.cs +++ b/src/shared/GitHub/GitHubConstants.cs @@ -9,6 +9,7 @@ public static class GitHubConstants public const string DefaultAuthenticationHelper = "GitHub.UI"; + // https://github.com/settings/connections/applications/0120e057bd645470c1ed public const string OAuthClientId = "0120e057bd645470c1ed"; // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="OAuth2 public client application 'secrets' are required and permitted to be public")] From d218e6e8065a7e9c06177e0fa3cc84222689cbb6 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Thu, 28 Apr 2022 10:47:36 +0100 Subject: [PATCH 19/83] docs: add GitHub.com app revoke info to FAQ Add an entry to the FAQ doc explaining how to revoke access to the GCM OAuth app for GitHub.com --- docs/faq.md | 10 ++++++++++ docs/img/github-oauthapp-revoke.png | Bin 0 -> 453250 bytes 2 files changed, 10 insertions(+) create mode 100644 docs/img/github-oauthapp-revoke.png diff --git a/docs/faq.md b/docs/faq.md index 130850344..1777daa7c 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -136,3 +136,13 @@ information. You may also set these variables to the empty string `""` to force terminal/ text-based prompts instead. + +### How do I revoke consent for GCM for GitHub.com? + +In your GitHub user settings, navigate to +[Integrations > Applications > Authorized OAuth Apps > Git Credential Manager](https://github.com/settings/connections/applications/0120e057bd645470c1ed) +and pick "Revoke access". + +![Revoke GCM OAuth app access](img/github-oauthapp-revoke.png) + +After revoking access, any tokens created by GCM will be invalidated and can no longer be used to access your repositories. The next time GCM attempts to access GitHub.com you will be prompted to consent again. diff --git a/docs/img/github-oauthapp-revoke.png b/docs/img/github-oauthapp-revoke.png new file mode 100644 index 0000000000000000000000000000000000000000..38151bdcf0de8639f91cc12cfa8ee3b406ebfb03 GIT binary patch literal 453250 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

b`dGzil zP&;CQKOqO;g;K`-#`+-zDi0~mOC**LCO24uH*%3yykm~bTaN}P9 zNxq%VAl_*OG5rEOnx zYST0fU*>++di+vI; zeV6aeJcC``b4+nE8n{Lh{s>&&u4HSRSHb@P1Ed#BJ<$Ld?ew;InnqOx1XQ9{%oQ-3 z36qA?{s;_EQ+z`7JR@l`9^^x|>G43Y~DEWWDMHmWtT%3S15#=YrC9)*UF5axZWxcfYBe}y@i`^^VMiz5kt9;R#gXq2*rCE9eC*`~)OLReW<0&-B+8v^~i zYi_XUQrbwFYTk3vMsl7qAQ=D=Co89q5XZw#3Yk~$Qlsdp;@d`$AzeGC>J?RR^Qwvz zlZMC+Rh%hpp{R0GUZV+`z>~bty}^~!+Fk&2-A?p6agi#g$clw9 z(>9rdK|u4N2wox(I#S;XsWuD=Hqn&u!j|D|#Um5Ljx+Z;Ff5UcF#PxBLqF~I5$5|> zs`u3~92=}CU@->IE8DRSBK7tMZ)Mqht5K1O5oQQm%TcK35H|#foj2kJ$-M1m=+F%v zbQ%%!hI&4lI9m6hNn-c;QC})rZkV-+LGiPw%?S<<(aj-Xdp}#&{+aBtEgnS3Oc&vz zkLE=1H-yMTYX01XgNEe|sqo?3;XBl*?@ZJyTWw=Y6NLzzP0gXYY}nbG9M?^g>*@iRgVq@?K|hlsl9q^RLJQ zNmN?Ffe=d(Ww_z~t_`<6tdO0>Xw6sPlKu4um z)Q#MB5c*|T4}AlzR@T9)CjCurBC~L|66vP0D8>+eJ>k*%0Us>^(=R?=_Mj_uvf->5 zk`RX<3uAIvBUAya0@~kz@wh?%4TnH_JJ#5|<*O`UlfRGN;zR(9*(+e5bTc`!C1Pu!c z#TuCAH{$I+KQ4p zu3>i}>TyU?Dv9yhJanJ?tVBC@OVrO>lLJ4LzJGII0}oKjXk79uE4aw;G0)tj@j&Rx zfKH64c}?f;2S53F@=hJS)BX5~J>^>n{v67TTtBF5aO?ElDUtQcYt4n8!)WWEBF}im zajH9{#wyGZji`%QUxt@rbcYiggIwCsZFBZbi5MxBxmPy?a}&~TW+6g3NGmgc`@T$6i2%3{+I+~HQ)>= zp_d{X#ZkUJMb#!`yScxiTLcCNTt8y5@l82lmmFEl_`DnHT^t?+9quJJbN$}BTcWx1 z2+$`h@h0BTqSW44=XI0hb<>)U-o5Dcq%Du}_dqHD<+r&}mR^shdbWPrR-!s2=Ed&% zV#8-U3+*jtZKrakkQP-c&^st=Fb@%5DJz5u8FI(4g&C7&;wr+mFD zP?PYxMvpF(rC&JpNGzOPS#%wbB{7b_Z^mg6B}uvOgOdehsLOeFPYJqJ#)m+;2KPNw zh0{Df+V(X@;%rZeYFEJpiIQWS6)C!M7n=Xc3fM?AJml!HKgPapo;!K%>${W3jZR)F ze%?=qVykAt;mP;#%M0{{PAN4yiky_GR39-_WzEB?ynBuM!dCW7zU5NoJPWgvULL4K8jaBDwx{vGm?vI+3@6$ftEL5W z*=Bfz9C>Ql{+{f6F~s|*HfEflR;l{GcZ-T|HzaD#!k=8x_IrAeA{Hl9V-Pv{rSRNI z-Wd0#gUsWvIYeQz=}{k!Nan+C#(m~e`t)3fyEGIxnxFcm9CicI4{KP3U%4|Oj-}P0 zyp@v0JZhXum`=+39o#@Ef#TXYdSWY$=jOhBrq)gs>S-{T^l_XJSJe4h?oX7CsgXRm z`I5t{lZ)!o+ik1y?b4Tf^a+~&Xlo*P3w!Y0m6(P?M_KUCg*qZ2t!e}ET~n_#^qVoMa+V;X!9Jl-9v>}i{{*zr_A?q z@~vW$epthuv+A__+;+1&yk5(Wx62Cnl3so52|8`{X7J^*g-uFVnt;KVCm=${dzA+F z{K8WTi=T9!Ar|H<->(^*6fcWHKaDvAGoEv6YBNdvF5r_zKoOHCgs|ZeG+!4zB0B2^ zdo1RSDHOn12}${*)!OG~<&8T&a-3w1+`I4Tq@KI`sVB?=h3Amg*Dp5C z)49mY2-2s2vR3?2_v%QI>6rc^_ay>9=y}5pv9o0G-5)z2G|P%=oSB1%m|g%EE8BQv z@rJ$0La!+hHF8v^ch0eP-9AP&$H7wG4H&>f z+Dw17o=%1_&DTgUUf#>!K8+b>MGQarZfc@;kMg6N<1g%|t?=qSfH`s_Ayh%V{!-7c zo`U_L--+VS(7d1}?Tf+_{3c7rBhvvmEnW|WCS4_*o%C3$zKbtii~P(L4y#iclmy&0 zN&_QlF_-+%-|(X1*Kjufq7_m!qqtk%s6a>8p@(XXzV`3hJ}JAd(`OmLQAj&$2U*PJqf3RYfBB~Cw|p70ntqur*!u5dZTZA zPG&J;dp81oaq=o@+kh6?Y|iCpdm`@G?3Y9_GBie{%s7cHW$WBwB{s>*EE-{f1mfn8 zHwP!|zH9kY&wOzHr5fL~IW47N)3tQ}81vd@8zuE1L9^C9p%-t+w&Klz|`zT27WPPR^nyE3y$OU0Z2OeO1I>nfTS2REOCc~JhA9gDI!djQ~r6|ilEVZ@>RK!6)i+v#E8hCcZ`^E7l@SOcd& zQWR&{-Bp~D2fbhz(ZEkMT=iaadUgCM;*l;pa57}9h|$NSVTP&DfbW$0H*4k+b6*)^ zk|O4!BMAhfZg(X{S!vUv&a{C2d&b4z))V_G15us&<^xgx`Ylgq zT+JbRdetfGUJ11@fu;Yzo8rj+^ccwa=I*IF%a_HI6!oxEVTw{YQ{ptVrG(_rb6qH}Kt zjds#nC$sZ7{-|Iz^K2hLbMJrV%DN$$45~n(^eC!vNsJgvWfVKi_fI`Q+Rr|304qa= z)qod6nc#aTR;VhW_l+o-IEOve9b`UO}kDd7Zc0R7gE2btMf5VK)KrW z(ks7T!dcoJF7XCW`}~vN{H?nA#YNhubbRB6Gy zWyK_W2LG-0V?Ok>{d!wrRY~7J!_fxq)xc60+qWMIj_8xQXnDSf+cENb$&G^>(^Q`X zK*_*}j>2^rOh8ON29y9t!9=jK%=u$W=cW}PE}H8w`h4yh4DK%S?wr>;@kYe~#(pk) z!=#vt(Wl$@els0>*z(QpH1G15YIPZCG{>_)PpgvC*+c5&EteP^7b&|c6+hV)-ITEd z=db>?tP8_UI@S}1KIsBBu_1(1b&EJL-8-VVjLY={Ctcq02B#pcWb{= zrD_eF{_0V{xrWK@lmPX=jk(acS|mf;V| z*j)Lqn)&a3U#-bwJT+P}p0mGycD zyCy>00Goo@^i5>2_vNz}q3bZ*JXuQlPX<_~x+!*$h0p#C%E-n7U)?OT1yy$AHqE`7 zA}WvyB3rOsk3y(i`(4Uih$TwZ`5Pm@pbA#caNSa_TpJWjxIo-+&1=?-9oI-W6QY~F zE!fS;MXqk+ot(B?3-IYsD4^MOh@ZZz02nyF+3&D?C+{qIzC0mTZI=sFuzLWFw?MWz4qkQb}y>QF}fcL+Mq=;0@Qp(}|)9+Yo&md`(c!PKs^S-9as zb^52?W%`AZqA(+(?Ixd>Ivuw5sQYFB@U-l=*;@tp-$3KTjN#HzLn+zuq{!R1Tv!G} zRMBz4sK7AaFMvd-+1l^8G>1EVJ!d7$uOry1&*d6V$(rJpM%T6!OhfwyO12C)T+%Y{ zg5{P?qhyb(2N8$0Cb@)tbLccP<)Gch8s_(`Z-f?8&-*ohPloE;6RZlnl)bO(p|+%$ z6nC%Ypp{d!h0+Er>!pqYL6GV z1-AE^xXnIac3yG)ju9f+j-WqmOVNfy416$G?S;{jh!x?-`=%-{+_QXc&{3*+=Ia-A+~-?~Tf_v?^G)I;?~l35?fM030nH6|6oWMHEp8t0uA1$k~NX?pTwziz7@-1s(3x^OjB z1{U4_;{xMS^bczo9{_N$=t|e#TAF+bNUu$2R7p6V%f6aJnSRK)&i@$CoeU-Yr+R7QEXh4E^u*X&STaebzgjlMqWQL9rLx zpLrAa2%kN@3H{kdvMA&xa{Yyk*{?;;BkG&$+@3X8YEbt%QqQGF7$}xvOE7Ioa<{AB zgI}E7FA8eUk%@d#jE}YF&1oic>8_sDxOfHUSa{gax+0~Lz?+WAh#1HzR{hACCZM~6o;;r2d zA?4~@Xk7S@b{$=9ijd7Yk;%bjhsLSvSMx)yc;a(@hgoMoaLpkKxNmoQ#f`;H`qobe zt;#=p(=ZgOJ{~J406Xw$vUaULWU+@BO7>{kK98pNGXx6w#X5@KPyZOXByj-Rse-24 z@Az3iUj3fD`&@Tg&2IJQvD`OqwPM%Em5TF^L+x}0pE6kiA2?^GywA_0z-}N@ipJ+7 zAO5<~`w3_WCE?!kWp@s9VB{_J(URi9MV&sL*}V|^x7Euf_JP|=T+dqsoGt!K9x^&1 z7c|1g(Ym;w`SVn(SO-89Ite~tY?W9&69KBe(1Dxn>%4i>1XngvJIABRQX(MJ|j@(0y=dsWVdy#A}u|Q z^O>nrc~lcE=TPI}#lE&l{iUh*R;oSk8~>_xe|n4eLB%!P4hvx8GMbA$i14F{sGN6q zPT4x8rYb3+*p;zjjj>}7#uV2@<#@#6e@4TsQpYzdt5!I*ggjJ? zuExBE57l#eHOzoXGRg%OKrb{EWYzUa}P zRm?)w(a@~TpWr-iL3OhSKaJl5r&bI7(R(X6SJWr|t8+e`E(iARcPvcT1ztnkuK92G zyBc2B=%=(gM;xR!N*3~*ZE&PNGFsu5S%ATQZcJVoGs*Eh>-FNKPCILI=0yHahcZ<7 zO&xO=vSb^+jjAHQ0aEQxw6kD-kGNgznQ-@cEaYl&GzHl zK3@+R+5FDc}I(FgQE3!c=ho>6Pl$kpd+1eSI6__epv9!wzoJT)h0%t-C*& zuVe6rSCL5#A6(^4<&givQg>V@%~N(B8I-?r4c0XMxA?_P|77%XE`||EtTsyD9(dsV9Gaz&sn(l#Sf|Np!btUq0NJl+RO8^PATuQ;!CbQ}15rZGB(` zXSF~*x`Mi*R359I zYtt&@+#!8^{E3?Ruw~??(5~G3!4e0Fc#pT$)Q{|S?*lD`3c9c|2Y0ddxOLzP z43qSoJND$=4cYNW9LL2-D21gvA>h5NvG;NVCt&TH>f@;U*!O$-l?E zUeE3oCGb>S$_UT%5I?Y&AC&BoThN|3mK!%Xe>dIELO0L)t_k>CvNbc{=O<)6w#3Tg zi&lgo>F9%$`%L7X@FY(oZhkWT&O*I!-A-CIEwVS$_1kzi_qwZMwl5KbqI?=?DZ@GB z{0j4)<{rBvBIQNz`e!O}E)in#P`-5JH_hYx;PekhXl=-F|4Zc$2@@?rv%V;@WNgg= zs{fuV?L4D?wAVg<&TaU^VxF3Ui>7&YFRcBa4Lr@R>6SC-4vBOB0V8p%ghpM)M_O%M zs?>kzPtr{Vm!_CZ{v!3I2NYwU-J|ymgx17Ga9zNbfafa$x`4#w8ANq*k|oK9YrdM*a-g@frp#|q0ujX898+p)H1%0T^86m z`MBl@_6V~xJOFW))~r>bc3(=Y1SkzX;l!~lQ#O4i=At>w+HI%VaJA#3(yp3Iw_Sk9 zsV^Vhr#4r;yle_yaWZoT2B>`xMvSo1z(H|!nCcFN%3F)2 z6>nPp*S_rm9q5)Nh!cb_GFtu^48aDp3-yn8!VBtDaS$P|+IZS_U`g%Wgb>3{l(`T* z`ns(9!PHGmc2q&}edgSYah}M+Turq4V3kSqUQD9|CHGJHgo9g5A7+OB)C1V`vCyyl;CAL-_>&(Q^V!-~|Yh{6b*rT6M9qTO*%O!$CjxjZW z|1@mx?|;f^J5vDj3nXl)yK9Gi!Ju*sqfzf(>*Bil@}8b?PcvGpi=FcL<7@D+e0b+R zwRXft)AmAU%%%yrU-R5uKfzCj!N1;A;FCi0Be;x6#MCX*DTThAhz~1Zd^m&orngF| z!Q{sUtfIPkXx-GMlXVH&`wg2U{)Tv+El7OFOF$1c^r0th*3D^NVY?^&kJN=;vsbe= zMAVf=eR0rl<>#QIj{b3zUYUKFNugh?fJcz}MCG4qpWLkkJeeZ`cm{BZPJL=N zI_y4WsLV23Ja&12OU{F5fNKZj@>l7VWAxKh<%Z%vRWScQ3Ixt(p=;Hw+C zdh_KWWF@EAx$NMl!K-`UyrQC#`*Wa9%NzY=F>Y~1f$yght=Nk5l%wI8oe_qBX39FH zyW*6e_)0p-J>A~F9tUE|qD;iy1d_iz&3^U?exeK@g(|w;aJA}3Jp@?AW)rIyNX2CE z1k)W>5wHCMHYxtVije}epx$3mC3pVI*ZFJ{nto1du>ph9@YwmWk>OsJJr#H+R;mhy zR>!?%$8FcFKBc5X!i!u)qp-`k_NP*EsGN%dCwQg=Nt;3q!?d4eQys&6EWJZ&+y$o> zRjbFXL6Uo-rFEB7I!*7>CqoYy%@J$7-%rs*@1SZ-A{5Aw3IDS5SyBtdLmkZ({z_KP zPExC{&4DYAl(3?TCSCz2;?lv@Y2&?2*Q^^ixZ5Fw&!&w_VS2z^MQ-qHmu8F_X5oUN zxCB}l3HV5@U6Vl8QNw4HRNSCIo{LDf=MAkbUPg=-l@4-;Ee?=MpUD@#-V_Mu!Xyh( zg^-!r`)hdMCS#X5d;gos??AC6#NM(va{HNRCUQbYvHg@4gRe{SVEy#9@#Hmt6B_j9 z%3?qM!&a{>xFz#-vPuKOTDmxvk!Gg{Mi_?g;SU>{F28*s7TC^mi}A29j(7X=_+wuO z;q&#|-%q6+nLe{wn-2v#$+f+FLY!C!r^e0S(JoGy_O#Tybu_NGNk;?3)sVYg$Q~H+ zHuI7B<=+gMS4lQYNmKs?S3 zM{-PjxwM&&hhUF|ANSRPd%B$m&vR`T@nj;kWx9^tel2P4I~=^SKp7?J#zqj0Rcb#K z`p7hY*?5`EeXZtwqT%qdoBJG_cLpB({oraKO47(4FR+sj_ZvZmTXH{=KO_4`?OXz* zKt!X6^_{UK15Gh*`%_*xw<-r}jzz<}TrZAY+p|8%wctGy^w%lFuFN~lS9Pgg|2Ds&KSD)g@mfd@0>`nnmwohanFJxWoFzH|^$t{+$PD3dF z>M82lljX7+5154%@b5VX)ZZcgQ01&?Y0470nRrt`9h9hc_U;)W zD;j6$tI8&Nw@A~ZbBIHxab}l+4+_;ir7v%O7&8hzepFS}>rK;)sWUOW8MNc3IsY=d z(Z)cC1N?Vi0%cn8y`CIMLQ8b zO6FB@z0vt(c=QTFlmX3Wouy?`M4GS*P5vehmMQueA82dkixFJV(~L=9b*)hraygIA z6E*&pzI)(*>PeVo2Cq&sb6t;I_XAGA!}{jmIBc+>ngxVYf$l8m;N0!F!@4R$J=#tvrG6(0OZp1?W+alt*hgL8hy56$qx8vTb>o1QU zgEo-l!7-p%VcI^2i>OB|Qs|lVDgDD;J2HvKSQo-O7PfdtKRx>kDpvch(A=Nm}gOTm9r~B zIoM+&%DR`G+}V|10_>Wy7K=4l|X90oDexxo75Yw zv$l`9qov#K{{kBEaq+~Y3BpNe`teTR^~UPLT6|(=>pNTat@bSAPtZ&n{gr&ppanSm z$9%|7T5WELs*Jr$tlt|7;khn^`7nwoqN(?T6dD zEz>q;Q(H!3?nks`;ivu~03Nv5u|XAkI)@TmXu&O29isOAvgl7<&25ZRzan8yU1 zJhACh$TR<0RAL6;K$(%Dp3;}o|6#gpbuARZ#wKdpA)q5MegAqofeAn~wWzZPYeSOy zSJzn;92(1<*aZLj>#R}zYS$lo9G`10+Qzqqdr!llZEylGGdM_#Q#KAL{~xIzW>cJg zc>$H(HWJGJ`sY6}?S$8f^cMUmT$@V$zgil9xH)EHsq|BB`@2Gy}F?M60bfW)5>kmO2>BfwsK72L)kL5;asU}KsDD1;sDmp`SYc*%{`u#r_WQSAX>K%~@O4N-daQl}GksrwY1Wf) zeVvrTGz5Y#%6B8pDKHyE|NoXwOmP~haY9rw*x--Q%s2G+>e0PAK%2}UCV6_ zQ#`blLx1<1YRkSGsvRv+aPuQ-VYKRz*B?R-el&gWm4Ft9&}8plNm;3P&uSL&aCHgs zjyh!jP_$4wPCzDpR~!HcCZ`X%8)TV2y*>Y4Oq&UZ?f2Vy{xkd~+PNYtF5}Fnnosbt zid0Qd*iFgxPcYc9!3k72;RE#SQW7}&(EWWX znbXM&Yvb(@HVz3?LaYGTDL(xRX2)^RPyfUGFDx10t3(9>$@%oJUKzuPj~O7Cfxu}d z&mCv9HaO97$^RLqo4z{n$b)QVkNye`;{AX7s|tVIOWNec!8Y8*SF*`7*=-vIxnE`$R1N!M(w%cm+YNh3t4FZH?pS^!!3m4GO zJRKop&i`v3eGUDIv*y1%+*ZvY-Sei?|55&!Q(iElm-?S+`OWmu&76|{2hT~eqTtLD zfqG=d$c)?3he#o$uQzGQ_jHz_4wEmr z)g-{)<7Yqd+Mlt9wH~I=ssC687^_X&U^+ia8O2k074)-ym__4U*1wcZFkc@&W{l}S zOm(1}!UH@u7y?mk*ad+PR zfWS@miJjkRUbB=ok-K%9RZ5&|Yc0O7Ha@BS9kP@YawXD#WBG&Ty2<~QSEhdKTrGy2 zN9D}P4Zh(&^@9^XILwYy{#Nc4&*}ej{zG2_Z+T?@2cLer%TCo#f4q}rah&X9{3FIy zG8G5@Zrx_7j*zTo)s>d_I+bz#Y20!u*%Kxb$&qbor{@LgOKMLaoyy_h>L;k=<{XxI`wZ@gjG@qMRV|$Nk zKh4pojL`p*WoiM^>B+qQ%yWek5BbX-_ug;( z$9zV~+@Soy+y?V|tSjcyTxnh@ zMzF3}OR^x`@UpJRe3SvppjZ#@r?ksxtYm|0EzK`6=f)a~{9@V@*T$dq@4$WclAL!P z$%JN?iNZxJGuc#f2lzi?^ymsx(6}JGk^dwQlECbL;eR>~7Ij#(VgoaDYqQQ0A73y(6kqSuf8>Z*n*cxZ zPudE9^#AFA9{F=Y*!v%<2b>5Jxn3)vXzaP7=ILzs9<6yg^JB(;l&@?4lNx}4QsQHO ze~{+TD_SPd5F3y7Nw!-ON(vJDJnO zo4-orbjg3RLVoMxk zAxTH)ySoH!EMz@NFYri<$+(5*4I$WTZ!+l$SC>CT=_7cPq4^6|GFi%9pZE;dq#XXU z5My#0uHp3$q$!PHi*zrIVqrlleR>upjR}2oa>0J}BNnaBx*p@py&C}G2&4HZFxZ}E zBPbnt_2V74_rT}K<$?YFqc!jxeaODD0sZq9yx@t;Uuip)f5~H4{B5|yWeXW#Y>f1Q z&w>$@M64fv?>pAI;OnKAMwKuSMV*6=4Kz?^s>Hw23d<=9@pPnJ+PM5q-GMCvH{D2@ zuljuDmDi=g`+gmrMK~vPI)rmG2~UhmNw~{|q?FqpyOqf-0E$C{d;4v+Fi$Wk(8+<) z6_PG4@H?d*`Ahwyy)~|UE8V(U+^}FJZD5RN(odSY{`-SRI3O-K-+bcR+Ik~hgMZtt zH>+lyNs~!=j~p{rVc|x;G}`oIqkUZoeoGPs2L2tiC@{N~4ii7P8b3VI#|Evw%n|fh zY5C=e>Hn{wA*iVOZ-MA;671I}tDGQkt+m>!h6ih2*AZ;ulL{)#(vqhdKfwqvBO+fd zhi5~7;%`N$Un&239 z(o2rC#wsg%Vju8IuzpzdG3h+|;C;N1B+VF=v8$%w?#w1Y$wk(`Rn-3Gnqw}*bsKjk zbmx!yYF@{_{HnCRB;a!#Wp(@!_8Hzt27KK1F< z(@7FPAIX114-{IkVkSr0gtT#Kxh8(v`19H{qpET$FP()mO2B5{Ruc3juQN}}FSDdh zJ<0^9;!w7U->sU$kiSa}q+Oj03y2YD*m|IC1)_DN#mfV(!ViYV|S3=Anx?mqLsF&G)$^z@`f#RkOxk&&Qk62{q0@<+4TBc zrX>oA757-|uKI#NB3wg10wl8kg*Gt}9HdLLdoN2<7LE2c|2bt%{mVKF{xQ-ZXZ&aU ziH&n52^JgV%2J#_DFKF!cxh}MI7V4>&${jBdXwuMW62=6l;Cth$}@!PL{ z@Zu!#pu!j%c;b!E4r!b6%c=1^A?FA}Hj^~GF=qrln8XASP?(cO{bT+@f8;3ft0x+T znB&877g^&--35OMY}3!8&-L74N~0tTXyJ;Y1pY5GCzgYLgtKpIZbkWTzwH)QYA7fi zhq)eFkz{y;HW=FYDL&di0(Q({b#{gSCRAGVI+>8>?h5y0LZg@AQUBIhRXF^WkIE)i zpw?y`2{iYTe!&O7{pqXWm%{Y_7Hy(^A^~57N$5SzwAId1@IXMfWUuZ8j?!r3l?2Rp zFcF0_bUm<@&b)Ldow98l5CezjIt4#k>CAr!`;|8B!Zr1elcUV7i1Nxf=2nrjsDCm4 zUSpM2ynz4|gVGPe5KgA>{f4wWlYYh-m#@I|*F7_slupNH!jDbsj#lJx8UrOplP7>dJaJOf8r|E#-?lNx%- z3m!|cmQy|0WvB0HZZo5N8vNX+wa~ot8~hJe&S^vLmtQ-z!m4i|YsnUReZ@V|kn zBe{nD`1p^~ACwqGc@zo-u)JlK0UYHf5-^*W8-yeTKX)&AZlVtqrP9$yy#9Kuzqa3Y zbMZk6VFc>IFMY(f*P{JOSm!>1z=9t_1aEEiAr=G@6sfDFmTB65%&kc!rw7Uv%wza| z=j~kIfXy*F;U~$It~32%7GC3(U}9Dl_pkbY*6Nv`k3al}QWX61r2b=x17T%XH=?XR zsQW@!Mnm8(OiolZ^-m!|mew8LVEzG%jbyR}m8_F+4gDxjX8oV=7WEA}6vOQ= z>VGcblU_$?J=n-ZBObWizvoj?0uzu*JJEb>mmknhqMwK`?#xj;(Hf2{zM(Zxrb_vG)-)Nz8yUfzKazMX{lf_@Q@h-64i$ z0oF0?HRU&!KWIIf<6cUZ{rwrK$P5iGE1*!l;X%R8Lriwp<^vecinz|dRxi2{;%^)czga12H zK;k6Chf*%aIt%zY3GDfp=;IW0;xoBQ%{SH+FumNyPyL@x@;~SwtvPg8*LD5fmcQ)z zvt0#Bv_X7vbE(WZy?vyVB(~YKOMO-**i^vma5BRw^+2&1LSL8p%+Bts>mPF=*6XW? z-gH_2)?O2NiOhOQp&2ubb3PQpc(%2aAz;|pR~S3m_@n-Dm)i=Q zN-ian^rO(7<&T1N6hi!Dd4wO>>>~(*sZY*OcTHPA^9WgtQw!wRvNdo=94FwcYn?Cd}!WefGCi)phCy!fQUR3LdBKasg&@Simk$`fSeVOd?7 zFhT39k_!5<$i)0+-8I)V7)3J-e@yWR{CFF07yO;02Y$yiP(oXNe6{L-(*M5!|8$)R zjZP{V0s(aBZP$EJDLTh*$Lsu_@d6@YerrBU^o*xZA^PvafA<3qxsfic%7;d0I_{KM zRYxh&n!8upUps2SGzI;t&G4YRcFHO9nuNj_Osa5^D)%*Dw^{RbIp`{p^|r_&adLx- zY+yu@w4##!vtFT@@y6YX6e2s{6&e2U8josXk zB0Qh6FDsK5BP8(Wj+}QSjQ{wfe^~Ry!VG1Y2~Ifh7r2R^mOh0e&k?WWR=l5VVLt;- z5Am^anNQ_d8#)V0Gx;@j98AQwE|I1Yu7Ib7xOV9ib!IEfJvowuFcLu7b@+nx=~ccQ zpXTlqE+EEcIrp=0By~=iAZhsI*8;mUP0iP2->-pb8??93p8DW};MGfG#{jD3I&8+p z0QEql-TAIFA5qaVon3#KG=iZPAO7Hfx)%TO%0wBgU-&#ui*(X=m(U{lPn5(@87{Q& z{JvX(N!ga07f^ynan3I7hcux@xG(kUf(T+H}i}@n%tBQ#7bbU0XL2r2y&LHgx zU&Jm?@+p5Ip(m6P+PT2=2xcfoSqMpd3CFzg8OMxIJNqx@ z2ZKuIK0-K^Z%i;Qr$vF=p8#i^MaqS$0WqGmb;_TXK;2L0{Ae=G9Rpl;$E1!^F4$-P z@S_hM&FpJYj3@Zv0h45xKYj$LVtU{+{dlxpXZi^-em_b)CFT?U+vz8Q(JUV$FKMDJ zwrGY%Ol2TJ^z6B~PYR3@Z>Dq^FJm|Oxnpbi$d@dfw{oYwin1eVmN(7q3CC_ z&Fc}Ljj&|QChM$t`m@PVR1u08r5ijp_RnlF}v@zzwb6% zQJZIsgs3t+PtP4!2gOcRYA)#F7I9W6WV`yt=Z=8ZYMgqf4h z@Ek{gF%R~FG~CbtOZ;CNzjC2SXcE-{?acZe&L`Y}h&S!O=VI-#2j7h6*T`cRz$kA3 zZ*l6PGE+m$j45dk@sm4xnoK2J#n%7VbRWcv60D3BtVyza&m!&vwK-ssTcfOD^Q}L7 zI#lmCy|?&Jec<9~#_iE##|j>BKURDGKq;gB8$l%YEBrUu;>QPG=|@$Iy9(UH zMVu}8|Ef-P_Gp=w!5j~QBTjZ;hUz1k*q~oQ;|@xUCx|t!zS5Rs4ERF8PWbn8G!}Q$ zc)gs=11+OEyP}18nFG>uk#qDv9o6}NyHYUaD`MQI8$9=Ay=y$oWsFZxU$`qAoJ29{ zevlwtN7Y?)yvfFmTm(msn;7{P{Kq_7@-goA$nfTOF`aUv#zt|#DX zyG>31p1X{6Z37!WS#H%2|k8}4(R z#Nl27HgE__`lmMkCO++#({x#9Nih%OjP6ln!|v%J8fW(0zgo6WFKh3wrg3I*k29U| z2XCDlz}n>(3R##v9wsg5hh@HPJ#F0K-ccR&iAY7X*|w4j#WD(u@rP52hFuq)BYBQY zIWd=fOQs~z7&iY^|Dqna6eBVvDt|!a_*06ugtvc^u0S|kifh!>StP(~gsjBRcvZEe zc;h-t68WbiKm23<&5694geFQxwfREkHX}99#AFY5X>p3da~q&ADQr1lL19m=tMpS~ zH-KHPZ@q03w2oQRuY|;RURwa`*QBe?ZNRQS^`gY2uf5v%3;(HaO>P?g&%-HX1#oXs zI!vd9n_S&=%bhX}Jw#EW{CI+Au+30bGLiPGa5wObL=nPVVuKNQGfpc@5c)UcjMHnL zGi|5*5+%W0IysF7flVAIl08Aemy1u*V zgmt(=x$yPS*oQOf7Jk+Me6lf^buxk*j7#?E={^IWdj6$%zW=Z19|BJQLpt9ZCKzq{ zIgyj~|DPz56vvvMGU@;TKmbWZK~(w|{zv~`=pd}grektK2~(EDSZ}R0q=2-Z-!r0V z3j*tQGD7!4SmvSf`%q@I-q0EVu;5D<-$0!@|1+M;9|FAcigF#UxfzxG>*gQai^1CP zCCv?!|MWAF@3slQ20y2a$Rh3M%gfB_ua(RLWiRg4MHzK2WFCO7 zUF6eVz>|N{9tw1vDxcPyM1*Glm+>*<#$USs3i$)gi1~lI%r5m5wwPv4ie`W#D$&=q zKd0;PNnF-mjSKoQQHi7YFooE5iG~w)iGQ@lmU^88)8O3K;g1**MF3Y{ZAINLG+ZVZ zUno4UWHxt*@nhPJ^#b>LKmF_wn>R$!6LYQbe_5SUbe{BJObGzUAKLlOa+QLbl(aBo z#+_0%GH00@jhCUBpB^*ihx{e(F>A9q${#BmMT95)o9o52~UxF{-`ArY6Z&X%TNtq;A zA#)8lu(MtF@Xg#{$pj^!w`Fo~%$Tv2>?t}?6uSUt#PBsO^+S;o|BGz&=zH-+7cq4E zlSb*|U1mpn^)Qsq50uBh^!oXE)>-1m2OoV>eXMoXi=3neKLivg0gESpde(KtpXCAn zl?Ed86KOP`w;T=&6CGCikH}H}5l4JP7OM~Ly~?>_9Z$fzyA5aT0$ZPP@2XClYV#7L z8G{qsSTw=B{XT~rr#^?L1UB;_pN4n;-B+YpGY|-C_+o0)8 z|NnIS^+r$9+z?_~MWcr_(UCFir9fgvBWg1u-dk}?V8D$uKsG$X=$zue8$Uu!%z3bL z`G$58fAXt+odM@q$UpyF_T}~Qo{mi;80gchd!e$>q&QS)%sqS+{alL3Mo%-@EW8xG z9E%To-~!Txem0%p3;17`0Cs6>T8RHftp~q2e+Mts_6l%^=op|TxDMB;0v$b1N3@6- zfnE8}#le^9P6o^jfuEA)KW}sjvC|u%r@-%Mfq~aL1MvX_fg+qgF07p-?GjB$ME^ny z#2`_!94JdVOyayIdg{$9g*N?@v>vso*2Y?rbwzJ)I+Rn6Ijs8gMSrVCY7+H@OxX;Q z86F1IewSTqEx3JTi@klBTfolTXAVt*ZG)ey`%)-EcbZ@^<4TUYWGoh+aDB39o)1b) zzcUvgO-nmjycg3AQ7EJ;^bwkT#k1`quV?|I*#=;E=@&!j-2NzoaXKE4sk;V$lvo~l zc78Kd;H_b%I^+76{&f}tfBji7W7g~2((1;}{KGQsv`smkf!Q`FVe*Maak^J^3?0yO z*j8~1reA}8cxk7K!KHAq(L;pJF6fFh0Ch>&GeQzN{;(RYf(!{RXAHshYrqOFwQQ<=d3wCwSMGcwS*{o(h9CVmmf=2$?ORuk}8 z5b)jPmAkF724@<6G4FATE@B>0Hb!caz|4o@M4l6xJPTO*BZ-KNr;deRCdi0@DK3I| z1`yY$CIMIt!2X@mNPvyzk21AzZps@(z)Jk|xq#zRQv@|^>b4!R$#vrAE{nfib)!v4 z5>kUCCwwSwq{$T6Opp4=y$uPgiA9=pK_g$>E96PJpkZG+p-oADKunykNKoN-JqAf* zIs0D|Dez`pX@756<0Wuo*5CjgQNLLCT5u^N_rcx&$YZvJ%jA@k1DIW6Q#F88Iz_mD z_2<7{=6gyocQjnK$zRmQ3Y*~z>InHScHc#IcY6y#$z9DXN-c97_|Z^XM;b*BJTjnq zNO!)acHbj1l?uMqb%Ha5kwL`k)Md3@>^tMy(BfU%K$N=*1)JJjDn9)*)2a3;|Al_n zoj_ln4gc|o`p+8>72ALnCmWA_BXnx`gUWzutvbd3+VQ{8qG+`PE*ET{a^{~r{*WhQ z{#T*?av-DE zJZoz7)5o;whuC)c8<<%UynOBT5DEa8J}6v^SMoslXI7m6`&i}|Qsd2>FbL)`m{W*6 z;+1Y%DysfRbs$D@E&NeR8PE#v;uUatM*XKhY2Sm<#vemULJs<0kuWqf$tDU}3*jig z1$uz5dEU-KiDCR%|Dt+IXswL__eTnic#)EK#&_r^zw{Ne_nA#6Oq%kapgH{bvN6}R z5fTIp=0B4(=VyZmPjC{{b>7^jKg&NfVy7(shzk^I##9^;x;V!Z)2w8wu&DnX>U;OA z{_@w$wb41)8rQ=$FBqW>(QBlMjybts?*5}9%n7WV+Sy-s`CM|vHQtQ)-~;vVYAgI< zMrD1q6;6<4TOk|S=7REo!+aE8%w?@_;zVeh9<(qa5dIV2Cv^-DZ<$%uMngM3xNs05_DX1<82Zi&Zm<_J6nMz(*~3&`5&3({+)Goj{z5O zzaaB%pGinPgYU&89Fsz+JOMllz{USLC7i(}|NWr{^pgkt>1v4|^a?+L?te>cf0MiH z8T2k@(k8+=LVox+f+7v}>8Z~%AfPQSQzQtRf+9>FgvB#L`R49}#7}73Vfy4!+3ElL zo%hRIv5i&_C#U_}Ls_+hLvg zZ>}pCXpM{ahX2$zJEI9aP5~X@uaioVkp8N;H>7mIT@n!?%M89mx_?UGI7u5|b7;K{ z4B9`jtO2gKOaTDeOi=k1{0Bg?Au|9>zc+!M>2H!myhw;3k%aL3<#FR=`JzVz7=FNN zQ%zv4U9Mov!lxs)=`C}fuK2C_Eq-8vC!N!@=$}a@VlzLUe-+Mr)AJ7jd1q@HKNBziezAuQ>?HMwkKK!zWM(i!}T~KjnJqmDhU>P_qTRJytnmza$M6fzxX{`&cc`XIq&9RnT6IHZp!gwB*VZj?EF12Jl* zUi7LQ5eM&xU~^8V9CN5-9+z5KmJNGk9#1{PrG{oBS5w08SjWyNn*{i^G#iP|*aK4eUh za%nv$iMX#2MTp0q98^6y@L6y443Q~wAoS_kU1lp|P7I>Jp%>+^?kh_UYW!;dRGq+I z0-XfUlCR<&W9HY(UxG^w9KXR#Iqv^TSL0Xa!dzO^s|;`RKm8(2#2c&AnkSxqw$>FN zn?7jB`KKw*`fn~Iw19-nwJ}c?Vab2b*_9SwEGdM{m2^SbLXy=)iWW@2GT)z1o5b(h zTw-7%85wi(d^pI^6qZyce(nXN?Q%T;E@<{^d5;v4!xAd^V_$i#IzfHhhmzyu{5$%H z5~mHQhFhR0Ebs>&o|$F*bN(A3G?ro-QSHSRMC!g-cbuwB#|k%$P)1;4;@Z^yaXFk+!Z2ZqKx zCT6&>6C2Ri-F#~?o0NH&TrIY6XvRbT8{;RcTox;VK~N37(AUOqjX|ZWU3snPbwKbV zg7g#|PIEA*vRnRE5r#~y{3mD;#Kgy%8Hr!t=JizQk8%~hXvo4&qABqg#zi>!*Z;m7 ztZyOS%NnS-e4P6T(EJ9}CNleEPn-PiM8l>ad2m0-%EdMtCk`={l)kk@bx7m^cq6_}<`qB`?}nrVplTT(2H+F|0dF&d_b2hq8Z1f z=(ChI4&k)_Z~=t-QMll8g0v^?>UxteYU6~7Z}hd(7h%8aUog^jvW?$$OUa{+mzq|< zQUBfaYh)47mH)ttluh}Q1nqY=&uXn`!{O1;PhG5&J6y1Y_qfylD05ijT%VR$tkvdb zo6Ti-*s-TL9(-*8fIrfgic<(8M&#|d)6c3nktGyWci^u2t!T>ra$F zbs+G7BQi>E?1&10F5};VR>-04O!l2-#Eq1ZjIYmhl4}O_z1YR?90*Wg>IZs^jEDS% zhxT75sDZ}I1l{?Q^`A{=obQ-aTFU!pGNG}6{X3UG+K%911F4(lubCgyZYcQ(JkAnc z`kWg5&U^$19pE>k8#wiMAuU4!D0t-HgI)a6r|m=E`x$-jb244{qWa#!-V|h$^0-s~ zsJ{2WrtekS)pRnGzp>+9)g|6)E6=H|NDKT6Nd&pv7A3Pof46sLxfG@F3uW>@H>wd- z;4)XxA0Lx-pB3|zsDBG-Zcsbm_+Ra#m*7VyICU^grT?C>`nNrPUVZx0&noUZ^Ejgo zu8%+dL}UAe>bTR+td2kYpsIJT?uHi``Rew!y6)DQMuGyyHSXYCXYDntfJOeXTi-a% zCCer(0<>_M(;%3yq!%Afxo5nrfAzRgl2YEhe!+?MPW+H>%}1aF{X~ZUy?gYi?tADl z*L#F|)=noHuB00|dUU)SM*|El8;*Vxe)J(EE~4#HJ~mYQ#w#VM$C;QleE0#nH&Y5u2{-#c=(_T{n_>+hAZ)664S>u;o5WrN zoD`cyUVk?^G+T^c1zGnA&QZgw8lTfaONYm)|LFWcS`XK0{oi86l=aWi^)Q3{ zv#|Q@V`cj3op&Vj(20;C8eax$qX&g9lnpKOIPG}%%}!mz&zGPnSoM&Wj8k7S>{SUY`C?_rC6U1o&4kb+JHh0~|!XtaOD#Y#w88^|cY z;k4>UIt2p73tR5crTrUzrU+Pxzia#FZWT+Otypr@ae!o~!jaP22WC+53b>yD;y!T-pQo;4go_0gh#O8gBSO}Ye-VFB5= z%4?f`a5Ufl^YCjVNdgLCH4z!oCLmavPZwY&Zxy;B)&8(R%+h!G2cCjWpfY0dDW6UF ze=Yud9(YhFxr}Ot>f|F2PEz#SU_4J65HF1#TRkj|WHd>qk#H$<=}MwTi;e54(T`Al zyaoq^p}mV>tfpV-)Yr&%^>}HTEKp!3WbWp9)p^6NG@BveM1R!GR$k*3GiJ^Ar5Qc;WpDJ<_=%-Vf3895L)q_T0>nlR?(u<75vqL6SDks{(SniHwwx$&EJ4of z65Dw75(qV}Mqv4L3Ub9IWZ(^dKYhXHxN)ylVEgFD{S9pm_Bv|uDsf6ZA0r`5 zx~}+Nd0nO=M04+6JrpJIbFn4bc-$Gn-3(2wYu*xG{zm@wMV3{uI#E(S@TL7RS&l{8 zWSJ-XSnW0(%)MQ^l+!D1UN5cjDwK*?CXiVb}6cNNfmk>WPiq0Z$ClC7jZfRUqc6 zmS48F^O{*-vQKXv4X13SF^DTbG93Qr7=g*lbhP*Ee`w<*O#Ded_(3djj^T#Cp2|3N zB3%AD)ba2yUw(7_iO4?Ti}^M-B)*D%-xUDC0Ffj8$1>5zohS7FoA=#N_NI5Lb3mNe zba#u9Po@4h<9`820y(07D7a(CGH>XpwlduBxAG3$H>YU-;A!YnhU|(@`OI)M=~i4} zxlVZ{I-A7Fe@u}8bExkOiT1(?9mY{y4eM2e60zp3c-X+2dZat;&l8ho9;MHlsF)aWr9549<#z#z2{Tzp2q^0EU6 z4;OVMW2G;@@W1;KQrIxC4z;bf(|s~j2R0s;?%mxWYWOTboD&1dOc`YQ zJ4($bC-=iurN+~_{u^P5Iz|6S8PxSN0Za`)0D}G{nH%VxWHrxAl7goGsc9=dQ{WdZ zb)2#QKpz0=Gvrqr#j=D^WDchql=mm2GCY;G5;pplwV-(-Mg1F!A2?z_?TNMN0BM# z&vPriajz$*i)tr0xT(`0v`v+Mr2#*iTiB5|tvW6Guugk2&XDGj$Di~@Ps5+i{5RtA z;9~A|)>_>sM;{W5i?g9`gwKNeGijV zuGFXa0FAtY|A{|>n)W|{wVWa%>_79QqXfZV%P%_}f@wgc3@(7j?*>|b$q)Pu>`2xX zKlz4!T;#U~Zy%*s6k{lv&O8PF5?JUDD48?ziVrUE#=F96Ac;RB;%$@Q4)4(Xqg(YY z2}>h-`|8ssB^!f9};f{^7?5DxV$ILAt1X zUfsoHS_``D|M0WSL(JmT&zUD4S%3$kFWC{aYp=hH7e4~P_|v$ijkpDr3J*ESf7Y`j zW#(&~P60blPFx5sK4Zs?GfR4Q?_NL)e?}or{qCY_zJ>4W+TYx|BW=@-*4O=*>-lPc zORv14f>$5Nyzj6VM{2INobU;Ff#2jW%0KStR9?h;uYKl^J4`b^2|p`qpBc6GLE#RL z{8z{y8u|-M%1_QeBhzjELy8C~#gqIuO*C5leRcm=6%(ETm3gksGu zO)ZgJ`hmZsnF7D!HvA2Sv#EoU#&g4lN$HIZ1etV`8EoLqpmh`TOy)wEcpIscutZox z7uz>3$DhRCgtYN{{sH~UL%3Ff;|G7_cxIW?|BROc)B^Jtv-pk?QMqgL6ZH)<%``(j z-!KIDZzw#w^#6tbd2%GckqZ2sz6^u;O!^+M&z`#DC)O1PulO$`Yx%1BFMnF{o4QwS zLCr7Q?H^PjbLCXwboKlaTqQS_q2@dO>5%hIM4?X^?%lJye6btKFOkgu zAazO2!!Y0Wvg(;#0IBhln$xCV%6uhvz+oL=2>ei{=zsQ?^^RO;1pv`B?iKTcIJAm3 z|G%>Qi45~8fBlp$R(_MK-bMb(<}jx2xvvlBs#5Zs@)tJZI2m0#_^&_x4-6$y!3Grl zFM%W~@G_hr%+4>bzg>Q?y<}u#tK(1kgV%!h-v3~0qo;HGCtbQW{awqyMp)AysS-cA zcKQU?`fbw>oJ8rg`Jwp#6YzU%h(e`8ki~GJ8OeL*IKuqQXb#dx){5evDO|Mj%kTJY zKLgkQEBtJ*yrv5p$>y%AG>b|I&L6gT7hPmw4N438d-t7pbS0)S57aJV$)$fNG$=yr zlu8#g7Q*$zge;1@*q$x)XJuhWmEFkX2|%HrlRmfI6(?$XN-MW3|JxNbizx;xaPt>G z7I>r0B)_X~xW#wuBrblzb=*m3R(tMyNOj=vPau{3u&+)>gti&3jenT53@~*D-Q+*f zK}0kt0aaR?HgYT=;P59EKiLrYVpE}qp1Ql?$w4wV7ecOf{k!e({B2WCX7~XNa@5lq%wCH^|wDsHc6R*av zw^v`2xgo{Jq!`*i&~B$6j#6?$CF09N|H04Z!@}wS$^TU<7mnzrBRT%Zo_uEY>wOQc z4m|R>PW)%k$nrOj72giPQ>8zG3FBgAq79IZ*IJmUZzt6+mo(b8wQ$77L!>SJeSG*C zNd4p?0CoM#NpZr4S&{OHZS4^Gq}vx3() zxhQx((uT!Nx-GCjvDcfy1D|>O1^R%7Ap=Ljyc;1HV^~?sz*n3oYs&8mEJ$q1(0oeX0r7 z#g|=EU8wsJUK;hX(*0eR{B3z!T8)6Sr{ z_hO7EKhS|~`@|P{n>zk?-hLM>>hGqc|Apbhbz%JHEjVCP->3;)aI>Sj=(4K{U?B|# zYSHwO+wY#gJG8p!Z&x}Ed0kpUQlboc>RC-3V?x*Dv8t}W`S$A9zdNkjL+Mg$hWmUR zM~|EO-x;v-DOk9hZoAWXxT65aDTd3hxl#Sxjowsh(~tJkHk)s(d{E9+^?|g#j0gN;1fF|A}LGf+wNqs6G-2GxFe;j)*7;S+5&q+0Yp8AI(!@6i8GX)wK`4e#VLKzw=#52eliBvTR*Gnsq?I{e#D zutyl7+5UMW>%_cNV`kiSClBK4?^7M6$E+Xy|D4)9L60%q~c#}$|-h%18w9b z>tB>Y-2XxS4AqHbrL6Yx(=VDhzq=f{)mvN1Gt|B4}dYPGC%jnDG%4&a9j1MPBmo; zXGn1`lX)1ji2tGz%;O@Co}w$V-|*kzlzB2wZ?Rl0B)0Gej^a^%h>bsEPz|DmlW3H0 z=AtWp>Kfs79u>1!kJ!vpNa>Fk{k@&`9%3&bAA6pN8s;T|47%B zez0_Ru==FBk-4P8 zIThK)k2X7PV)%&BrYasrC1nQgVjZh=*^Zs90$PCeKPiac4zDri)M-mXF1zM>^-%+* zWKU^%u(J@RW66xUTr&KahCF z!=Lfte0SzQCZ`!chiul#)T z`A5l-7@a(&{-=X}P&AJS3;uy$b-@wjUzj>tcOqYK$yG|yQSG$d*1AM}DTNgf2`T{k zi6RLNp;!0r4sGLq0htFDOzKP&{En%f)c9kam-sXLvE>3{@>W17-BN7uD%0<&Z+@^f z*G-z3|8U}lL`!MS6HXa`7r;_x%qw1TZTbZy;n-WjcieNo$BM@uAJjxwBCJO2r2D50 zKyahKplu~!g#>dGiTV=80ODxvqcPsDg`fLf_mJ!Y`Ndx|T(Q5o{GnC;&P(LY&yvkX z{*WG#tu!mhJ*8N0Nq)pHG(aD5!zcNc^fRYhK>f5m3~U)a$9|smGwJWCl`jPEe~`4R+7SJrdms<^m)HpCS6$v zpb)x{?ywFVCZ<*XUyZ-?)^(l)AktBv&4`je@w~V0y^V++)n6~Yf~e+QJhX6&$>Y z?|zzJCVoPA$E-T@OVahw{efBj4lm_4c*xLZEv*1^T90dPy0tFW2&{~N8bHu#1=07`Djq@C7sOLVXMAI}vt%tTD~y?-~|c89aEg!q`W zIS+~(5R>KzZO1Ww=rMJnoOp%ixL3>S3NoK?fwWhT?!JqX{+E6StrgKSRC+!{CIM zTld?nSP2|sQqJ|3<;U@$BA0JU<8WDG8GU04G9^o;a%*c5uae~ckXmWx%>|vKufCgK zhV=~nrkEbCTsdFdJX2D%H+T%!te=gebXxl$g4=>WItj&7t$H{6)6DJd5ua5kibHh? zV=f_Ta_iom8BcMf-uzFAoy3-4N&bgn6&J8(!=;{TiEFpLRRpJG0-7~zCY_W^tMNh)- hYIpfvFuUGSxt3-Ph~RpXx-DCJt}Wh7lw6=~c?6$6o<(`){zK z8T8%*(-9_pU5M}V!RhraG5Or{~y8DR2CJsHb( zBq9Ohu8UosU|J$lLSKfWvSGn06YKjnGq-0b znSS1UKZC2YuKapdw+&WNh6p%ZQ?G^=Sp_4eXR{T&y+t|h!+i=yvc9}L8UGP}ZzpwD zh|gbB-v!V9?Utl_fjK(-B}Kg;?MnJCv!#cbx|JD2P5dT@Nz={p(hFGxeJM?ay%jLJ zu^QC3g8%ZYUw!lt@+5Uf6yCaQvb1?Pyu1ix$pH18Hk2!nuIn?T z;(Zjh$Al{1W5||ZUSM~CB_w&CMMv)7MU0zn4H|M<#4> zogQiGV>=ExTJ0|j{LDFmZg1O-+CRILx9|(%@_xLIKGgv76MjalXWX41S#Hb4_QiVM z?6*wUye2@M@@+Sg6+p?hN=|rJ?tbjMvh>!@*+4^3us@(|)v%C64UX;h^5pr#_%wXt z$Wxg3R5P|nRg0_FY{O&n?}*}4_4F&uY71E%p67e#Z^Uof;|S5Va<;SDJX@i&*_<=# z=iEGBxBVFo&YKM^6on!T{8E0i^{*Udd-j{K0A>2~rq3;YBR&ZWp%8O?5V`p#GIPtI zby0{(b1kD~h-xqLh^q7S6H5F_F;+2AjKk)n+YVrp-Se>@1WnoR@@O{`AGE0(ocaTB zeOvpQN#3#SXXv=8LIK2p`qzl0^GQlW@0OHvJ_DBMvu@T&qiYnm7)tle+&kmQ#Bbc&Zx1=bq9RxwZ2Hf@mIAwgF_10(V1d;_oWG7ds-TZXq8}E2 zrDHDj`fk>^b=-d1OKB5sn3qy~#AKAr;6aw9J2x~5%RRs5zh3|CI`b5Bs*jv!>6Tm3 zrVyk

HVr&JQ8O5Od^%91IqbBaf#oB=zm1dD7>-R<@-&Civs+%dP8y1LiF-vz3pFGG;iPt4}QQ)hfB0yah*PUfq&A%C$jPefJ-OxGFAdM>K-xPEjb=KS#Y?{tG|tZ zjfzeh!meyMhG^xjQV3F~6#qtcg_VtG z9gD^Yvs<~8kYwT&bnX8YMvF%iN5!XWi<`$nOJy- z_gv(?`I6Nw^bZ*NW?*YHI8Qcg5s^^oLJ!N*N%kWT`{t?>!9?Geo3rlG+e#nN^ca-1 z6fbHH}tJlx@0cAnF!|y)w9(PuE|1kYm<-2INn_I`7Vx-VqcTgOD8d zQ<9^pp@i-pW}J9VFs>*jwt{}{C;&XAy~Df9ex}nWlRT=!OZko%nTI)CzT z70@IQZ5uitIZDi|TNEnff#}NH6e%AKSw^DPUQm>tV%-d%obBk z`c@8PGr`f8f9W}iy<2dAzw~rBo0gI zTq-bC7+R3SFI85Sg+BPj@pW{$oMN_@M7I!U(rvoOskEUoN%%B4P*zcz`~vp4h12K4xhk z9E{5I{73RWy4>k)q1ssoP}hgLR1=Y#HFZpBKKFEC#AfT`R8!(Er*7DOYkWx1SPD#v zY%6~$C^&BSVVuA69Uk$$*Ugg9=0`KvF1_0_T0Rq9iNCxB&eq?<(D(-n)H8^mId2a? z7^g_SKRw)=b9XM4)L8wEP48d!GG3~7Qed&7@+FQRy0eEVJVBsM&8P7X^7vo2AgRnC zrV9Oj9;VjNqFH|VYmg{2u9GA+tuHjLP5DqOl`(`JE6B5b=aH(WEz5eFG>>t&KG9pC zORI{7e_^=J+mY;|FARk$By>UNIqFhBT0w5BddJ9zd3g5%Er33(Dq@6S^GG;C0qdk= zYcaHl+(ag@a46h@@QYbMoGU5989#_mae^3Xbv>C zAqC8|vKCf?<{Nf4v6&WuSBz&G_E{T5Yp$#j=FiF9f&If*COf=bqh8At)pRko;u5y_ z;=^IFk6TZg)+HdR__?SMg=r7%Fw!6Pw_Ea4n;6TAy>Sat3-6~ra>_h8*V(CjhTPIQ zn$iE-^pJY}prE?B z;|9yh+K+Wrv3-gk(*3n>E7}mlZ}`eDVsA+94+9xH#O zJ6P&XSqEP2S+lwC%{}BpEY<=FEt9|IMq1W~ertOO~n?fWM6W?rNT{Y8KfM#ZE8T z_@t>mN1^^;Gx&Q;i1DD(>Xc~3z|C?FvIg`LBJY1?Su#IKz4JXQEMQpJQGTk;SLMeLdsXKjJgD zt*C+tcX*(i14_RNUX-^kyF`!vSnHfP$YQhLr}ko=UA5x>li{vCJMDd``Wqm`OvuL^ zv`<}W9zqUv-o@(|XoNgsVoAN+N4phxVllJb{dmt{HmCZ^uW~uQLoVao^=8D)sknCg z3ENw!ktHk0Ifb(}$~2u!<{eS_)TSpuY-;LLkwD*oI&AO_3AvD;HMy=7ykLxX@0;RA zN8@PL{L%JFk%Ltb=J?2!L!GuK!+4un>jhWIp9{;mD2BDpWGV~pATS}m&)IV*bMU!X0+9&`-ba09RO>2Gr2tqz;$@I(nXam6qpT_&Y<3hD(`l%9}OmFdK(k^6f8cJ?&mc!5X-sDsP ze<3o0SjdA&f&skw?cW1=Yu+(Bv7McU5OIPZuvV5O=HA`vUZr%H%gbFgM&y#(lbcuQ zpXfMMJG=sqgTvHPLvpEFrU6OM_B5o4yC_p0c|tlKtjJ~!+mv8C;WS&({`mNJ?(&Fc z0WnJS;5!2@Y3H5$0_vwytmB^^-^6GdH*(I^UIX zeB{|u#*0&z8LPXXrpSeAet@Lyrx712TYFy$L}W1WSPyQg@lFx<+i1k#3uGtp^`3S0 zSHD&R>#Fct$__fu*8ttS8*=vEe^w+~r^8R|#_y8{GvC)}FkMGO$s#0ngc}*mT>pkJ zh~hQFq&T>-$Lv6y?6X7SiOJ!Kfy6U9S7>tCuVX1pIqGaWBF9rC>=PIvI*eR~`_TnJ zter0QDR5iK2{NnWIXkk1xFZM))C0GT{ z7_cpuo46Qtx^dZuPSu(hr`c$2h83burH6RaPn~vdrE^3bdfUGjqo|YNJ&@@W^5U7n zs;xKYD1z8)dT=j;ngcr>ef@cO#!Fd#8RFoL=lY2FTR`j~OQP-Xy;9#n?%}bI>LMa2 ztYSb6wFA(j)hc7yHX4lo4Be&d9U{RU@0xqoz7a(NwIE&8GH(rcPd+$8uZc#71;@=Z zvy(ibkfg(4tCHksAJZ$LR-J~;NaZ*>?};4lqv4Ft*Y!2p6kT+NS zVrTkNz{$Cva6FwRC^pn_(+67g1&H$kYONnj{s@GK4YD2UN(e

{Yb6?tjpyIWOA? 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%0D?Z~g@oSXpPe+MqZ-PjOG^%Hw^V>=; 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 literal 0 HcmV?d00001 From 8285e105930745737196ad854128aea9f3e17b54 Mon Sep 17 00:00:00 2001 From: Easwar Hariharan Date: Tue, 3 May 2022 17:05:17 +0000 Subject: [PATCH 20/83] Pass through $PATH to find dotnet Signed-off-by: Easwar Hariharan --- src/linux/Packaging.Linux/build.sh | 14 +++++++++----- src/linux/Packaging.Linux/install-from-source.sh | 8 ++++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/linux/Packaging.Linux/build.sh b/src/linux/Packaging.Linux/build.sh index 5250f4664..20e3e4b84 100755 --- a/src/linux/Packaging.Linux/build.sh +++ b/src/linux/Packaging.Linux/build.sh @@ -106,9 +106,13 @@ else mkdir -p "$INSTALL_LOCATION" fi +if [ -z "$DOTNET_ROOT" ]; then + DOTNET_ROOT="$(dirname $(which dotnet))" +fi + # Publish core application executables echo "Publishing core application..." -dotnet publish "$GCM_SRC" \ +$DOTNET_ROOT/dotnet publish "$GCM_SRC" \ --configuration="$CONFIGURATION" \ --framework="$FRAMEWORK" \ --runtime="$RUNTIME" \ @@ -117,7 +121,7 @@ dotnet publish "$GCM_SRC" \ --output="$(make_absolute "$PAYLOAD")" || exit 1 echo "Publishing Bitbucket UI helper..." -dotnet publish "$BITBUCKET_UI_SRC" \ +$DOTNET_ROOT/dotnet publish "$BITBUCKET_UI_SRC" \ --configuration="$CONFIGURATION" \ --framework="$FRAMEWORK" \ --runtime="$RUNTIME" \ @@ -126,7 +130,7 @@ dotnet publish "$BITBUCKET_UI_SRC" \ --output="$(make_absolute "$PAYLOAD")" || exit 1 echo "Publishing GitHub UI helper..." -dotnet publish "$GITHUB_UI_SRC" \ +$DOTNET_ROOT/dotnet publish "$GITHUB_UI_SRC" \ --configuration="$CONFIGURATION" \ --framework="$FRAMEWORK" \ --runtime="$RUNTIME" \ @@ -135,7 +139,7 @@ dotnet publish "$GITHUB_UI_SRC" \ --output="$(make_absolute "$PAYLOAD")" || exit 1 echo "Publishing GitLab UI helper..." -dotnet publish "$GITLAB_UI_SRC" \ +$DOTNET_ROOT/dotnet publish "$GITLAB_UI_SRC" \ --configuration="$CONFIGURATION" \ --framework="$FRAMEWORK" \ --runtime="$RUNTIME" \ @@ -225,4 +229,4 @@ if [ $INSTALL_FROM_SOURCE = false ]; then dpkg-deb --build "$DEBROOT" "$DEBPKG" || exit 1 fi -echo $MESSAGE \ No newline at end of file +echo $MESSAGE diff --git a/src/linux/Packaging.Linux/install-from-source.sh b/src/linux/Packaging.Linux/install-from-source.sh index 335230dca..cf57321f9 100755 --- a/src/linux/Packaging.Linux/install-from-source.sh +++ b/src/linux/Packaging.Linux/install-from-source.sh @@ -178,6 +178,10 @@ if [ "z$script_path" = "z$toplevel_path" ] || [ ! -f "$toplevel_path/Git-Credent test -d "$toplevel_path" || git clone https://github.com/GitCredentialManager/git-credential-manager fi +if [ -z "$DOTNET_ROOT" ]; then + DOTNET_ROOT="$(dirname $(which dotnet))" +fi + cd "$toplevel_path" -$sudo_cmd dotnet build ./src/linux/Packaging.Linux/Packaging.Linux.csproj -c Release -p:InstallFromSource=true -add_to_PATH "/usr/local/bin" \ No newline at end of file +$sudo_cmd env "PATH=$PATH" $DOTNET_ROOT/dotnet build ./src/linux/Packaging.Linux/Packaging.Linux.csproj -c Release -p:InstallFromSource=true +add_to_PATH "/usr/local/bin" From 9a13f350734a51db4c739baabdf3bae4d99c10d0 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Tue, 10 May 2022 20:00:08 -0700 Subject: [PATCH 21/83] docs: update WSL guide with new Git For Windows path Update WSL guide to reflect GCM's move from the libexec/git-core directory in Git for Windows to the bin directory. --- docs/wsl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wsl.md b/docs/wsl.md index ccf606b18..b5852f367 100644 --- a/docs/wsl.md +++ b/docs/wsl.md @@ -22,7 +22,7 @@ _Inside your WSL installation_, run the following command to set GCM as the Git credential helper: ```shell -git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-credential-manager-core.exe" +git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager-core.exe" ``` If you intend to use Azure DevOps you must _also_ set the following Git From a14a300c59693b11ebe109f9c11345a4bdb0c5c8 Mon Sep 17 00:00:00 2001 From: Bene81 Date: Fri, 13 May 2022 19:39:38 +0200 Subject: [PATCH 22/83] Allowing host names only now. --- src/shared/Core/UriExtensions.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shared/Core/UriExtensions.cs b/src/shared/Core/UriExtensions.cs index 939a45029..3e2688c46 100644 --- a/src/shared/Core/UriExtensions.cs +++ b/src/shared/Core/UriExtensions.cs @@ -102,6 +102,16 @@ public static IEnumerable GetGitConfigurationScopes(this Uri uri) } } + // check whether the host specification contains of hostname only + // this usually means, the git hosting instance is part of your local + // network. + if (!(string.IsNullOrWhiteSpace(host) || string.IsNullOrEmpty(host)) && + !host.Contains(".")) + { + yield return $"{schemeAndDelim}{host}"; + yield break; + } + // Unfold the host by sub-domain, left-to-right while (!string.IsNullOrWhiteSpace(host)) { From d4ec9de8749e281b59c8bf7ddde505d3dc872a3b Mon Sep 17 00:00:00 2001 From: Bene81 Date: Fri, 13 May 2022 19:56:45 +0200 Subject: [PATCH 23/83] Adapted test expectation to changed behaviour. modified: src/shared/Core.Tests/UriExtensionsTests.cs --- src/shared/Core.Tests/UriExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/Core.Tests/UriExtensionsTests.cs b/src/shared/Core.Tests/UriExtensionsTests.cs index 6c722480b..2adb955b3 100644 --- a/src/shared/Core.Tests/UriExtensionsTests.cs +++ b/src/shared/Core.Tests/UriExtensionsTests.cs @@ -27,7 +27,7 @@ public void UriExtensions_GetQueryParameters() } [Theory] - [InlineData("http://com")] + [InlineData("http://hostname", "http://hostname")] [InlineData("http://example.com", "http://example.com")] [InlineData("http://foo.example.com", From 10913dd21e9bf9fb5e950b575357d3dd526ea2d2 Mon Sep 17 00:00:00 2001 From: wolf99 <281700+wolf99@users.noreply.github.com> Date: Tue, 19 Apr 2022 22:33:25 +0100 Subject: [PATCH 24/83] Add dependabot I am not familiar enough with nuget and dot net projects to know if it is worth adding nuget package-ecosystem (or others). If someone in the know could comment here I will be happy to adjust as needed. Info on dependabot usage can be seen here: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates --- .github/dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b0f8d194a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 + +updates: + + # Enable version updates for GitHub ecosystem + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" From 9d827ff0ec25056407d313595d502c9fb52b9121 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Mon, 16 May 2022 09:53:44 -0700 Subject: [PATCH 25/83] docs: update contributor guidelines Customize CONTRIBUTING.md intro for GCM and update issue link to point to the 'New Issue' page rather than the pre-existing issues page. --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e6774c1e..9fca75fff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,13 @@ # Contributing -[issue]: https://github.com/GitCredentialManager/git-credential-manager/issues +[issue]: https://github.com/GitCredentialManager/git-credential-manager/issues/new/choose [fork]: https://github.com/GitCredentialManager/git-credential-manager/fork [pr]: https://github.com/GitCredentialManager/git-credential-manager/compare [code-of-conduct]: CODE_OF_CONDUCT.md -Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. +Hi there! We're thrilled that you'd like to contribute to GCM :tada:. Your help is essential for keeping it great. -Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE). +Contributions to GCM are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE). Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. From 839e45aaedd332abfd262b5581491e836af47451 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Mon, 16 May 2022 09:56:13 -0700 Subject: [PATCH 26/83] docs: update commit requirements for contributors Update CONTRIBUTING.md with a link to Victoria Dye's recent talk on crafting logical, well-ordered commit messages. Move this link into the 'Submitting a pull request' section so that new contributors are more likely to see it while following the prescribed steps. --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9fca75fff..41c925a91 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,7 @@ [fork]: https://github.com/GitCredentialManager/git-credential-manager/fork [pr]: https://github.com/GitCredentialManager/git-credential-manager/compare [code-of-conduct]: CODE_OF_CONDUCT.md +[commits]: https://www.youtube.com/watch?v=4qLtKx9S9a8 Hi there! We're thrilled that you'd like to contribute to GCM :tada:. Your help is essential for keeping it great. @@ -29,6 +30,7 @@ This helps us coordinate and reduce duplication. - `GitHub.UI.Avalonia` - `Atlassian.Bitbucket.UI.Windows` - `GitHub.UI.Windows` +1. Organize your changes into one or more [logical, descriptive commits][commits]. 1. Push to your fork and [submit a pull request][pr] 1. Pat your self on the back and wait for your pull request to be reviewed and merged. @@ -37,7 +39,6 @@ Here are a few things you can do that will increase the likelihood of your pull - Match existing code style. - Write tests. - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. -- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). ## Resources From 46e22a3875403bb5ed1784a777f57d89a1410883 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 18:26:09 +0000 Subject: [PATCH 27/83] build(deps): bump actions/upload-artifact from 2 to 3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-installers.yml | 2 +- .github/workflows/build-signed-deb.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-installers.yml b/.github/workflows/build-installers.yml index ebd8b1c8a..60cff2528 100644 --- a/.github/workflows/build-installers.yml +++ b/.github/workflows/build-installers.yml @@ -29,7 +29,7 @@ jobs: run: dotnet build -c Release src/linux/Packaging.Linux/Packaging.Linux.csproj - name: Upload Installers - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Installers path: | diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml index 6437225d1..f4ac9d448 100644 --- a/.github/workflows/build-signed-deb.yml +++ b/.github/workflows/build-signed-deb.yml @@ -26,7 +26,7 @@ jobs: run: dotnet build -c Release src/linux/Packaging.Linux/Packaging.Linux.csproj - name: Upload Installers - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: LinuxInstallers path: | @@ -86,7 +86,7 @@ jobs: python .github/run_esrp_signing.py - name: Upload Installer - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: DebianInstallerSigned path: | From 192690d61d486ef4904fb8a3960fa4d671d05e6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 18:26:12 +0000 Subject: [PATCH 28/83] build(deps): bump actions/setup-python from 2 to 3 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 3. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-signed-deb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml index 6437225d1..a710e72cc 100644 --- a/.github/workflows/build-signed-deb.yml +++ b/.github/workflows/build-signed-deb.yml @@ -39,7 +39,7 @@ jobs: needs: build steps: - name: setup python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: 3.8 From bdc37e15ef362f37c06dc80b8473cfb60802a822 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 18:26:16 +0000 Subject: [PATCH 29/83] build(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-installers.yml | 2 +- .github/workflows/build-signed-deb.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/continuous-integration.yml | 2 +- .github/workflows/lint-docs.yml | 2 +- .github/workflows/validate-install-from-source.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-installers.yml b/.github/workflows/build-installers.yml index ebd8b1c8a..73b3856d0 100644 --- a/.github/workflows/build-installers.yml +++ b/.github/workflows/build-installers.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml index 6437225d1..c1cdc2ff5 100644 --- a/.github/workflows/build-signed-deb.yml +++ b/.github/workflows/build-signed-deb.yml @@ -10,7 +10,7 @@ jobs: name: "Build" runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. @@ -43,7 +43,7 @@ jobs: with: python-version: 3.8 - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: 'Download Installer Artifact' uses: actions/download-artifact@v2 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bea685ec4..f70347afc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 # patch around Nerdbank.GitVersioning failure diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 47c68a10a..2e875b21d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -17,7 +17,7 @@ jobs: os: [ubuntu-18.04, ubuntu-20.04, windows-2019, macos-10.15] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. diff --git a/.github/workflows/lint-docs.yml b/.github/workflows/lint-docs.yml index 665e041e2..c723963ea 100644 --- a/.github/workflows/lint-docs.yml +++ b/.github/workflows/lint-docs.yml @@ -12,7 +12,7 @@ jobs: name: Lint markdown files runs-on: ubuntu-latest steps: - - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 + - uses: actions/checkout@v3 - uses: DavidAnson/markdownlint-cli2-action@744f913a124058ee903768d3adb92a4847e5d132 with: diff --git a/.github/workflows/validate-install-from-source.yml b/.github/workflows/validate-install-from-source.yml index 23e61aa89..a02c2bad1 100644 --- a/.github/workflows/validate-install-from-source.yml +++ b/.github/workflows/validate-install-from-source.yml @@ -22,7 +22,7 @@ jobs: - image: alpine container: ${{matrix.vector.image}} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - run: | if [ ${{matrix.vector.image}} == "centos" ]; then sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-* From 95bbff81a2aab04ef2d55bfcc8bb4ae847f344eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 18:26:19 +0000 Subject: [PATCH 30/83] build(deps): bump actions/setup-dotnet from 1 to 2 Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-installers.yml | 2 +- .github/workflows/build-signed-deb.yml | 2 +- .github/workflows/continuous-integration.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-installers.yml b/.github/workflows/build-installers.yml index ebd8b1c8a..48d0035cd 100644 --- a/.github/workflows/build-installers.yml +++ b/.github/workflows/build-installers.yml @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.201 diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml index 6437225d1..568dade3c 100644 --- a/.github/workflows/build-signed-deb.yml +++ b/.github/workflows/build-signed-deb.yml @@ -15,7 +15,7 @@ jobs: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.201 diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 47c68a10a..6d11ba6de 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -22,7 +22,7 @@ jobs: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.201 From bf93b051f4fd327f89583f95b288f30b73e65895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 May 2022 14:58:27 +0000 Subject: [PATCH 31/83] build(deps): bump actions/download-artifact from 2 to 3 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 3. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-signed-deb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml index f80226f0d..f452963a0 100644 --- a/.github/workflows/build-signed-deb.yml +++ b/.github/workflows/build-signed-deb.yml @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v3 - name: 'Download Installer Artifact' - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: LinuxInstallers From 70e0af6d514f4f41b406e8cda974ef77a75985de Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Wed, 18 May 2022 08:23:15 -0700 Subject: [PATCH 32/83] fixup! Add validation workflow --- .github/workflows/validate-install-from-source.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/validate-install-from-source.yml b/.github/workflows/validate-install-from-source.yml index a02c2bad1..f6648e602 100644 --- a/.github/workflows/validate-install-from-source.yml +++ b/.github/workflows/validate-install-from-source.yml @@ -23,6 +23,8 @@ jobs: container: ${{matrix.vector.image}} steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - run: | if [ ${{matrix.vector.image}} == "centos" ]; then sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-* From d4300afd0967c4180df3f2a6e1d809fd3d848cfa Mon Sep 17 00:00:00 2001 From: Bene81 Date: Wed, 18 May 2022 21:13:01 +0200 Subject: [PATCH 33/83] Apply suggestions from code review. Co-authored-by: Lessley Dennington --- src/shared/Core/UriExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/Core/UriExtensions.cs b/src/shared/Core/UriExtensions.cs index 3e2688c46..074b1e84f 100644 --- a/src/shared/Core/UriExtensions.cs +++ b/src/shared/Core/UriExtensions.cs @@ -102,13 +102,13 @@ public static IEnumerable GetGitConfigurationScopes(this Uri uri) } } - // check whether the host specification contains of hostname only - // this usually means, the git hosting instance is part of your local - // network. - if (!(string.IsNullOrWhiteSpace(host) || string.IsNullOrEmpty(host)) && + // Check whether the URL only contains hostname. + // This usually means the host is on your local network. + if (!string.IsNullOrWhiteSpace(host) && !host.Contains(".")) { yield return $"{schemeAndDelim}{host}"; + // If we have reached this point, there are no more subdomains to unfold, so exit early. yield break; } From b1f65797fcaa4b5b25c8edefcdede6f18a614521 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 May 2022 20:43:57 +0000 Subject: [PATCH 34/83] build(deps): bump github/codeql-action from 1 to 2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f70347afc..e4ead0dc0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -29,7 +29,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} @@ -37,4 +37,4 @@ jobs: dotnet build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From d23215156ccf2da0b2be3d5ff951cf8c2f424725 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 25 May 2022 17:41:42 +0100 Subject: [PATCH 35/83] generic: update generic provider to support all protocols Update the generic host provider to support all protocols, not just HTTP/HTTPS. Since Git can also call upon credential helpers for credentials for `send-mail` and friends, we should try and provide basic storage and recall for all protocols. --- .../Core.Tests/GenericHostProviderTests.cs | 47 +++++++++++++++++-- src/shared/Core/GenericHostProvider.cs | 11 +++-- src/shared/Core/HostProviderRegistry.cs | 14 ++++-- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/shared/Core.Tests/GenericHostProviderTests.cs b/src/shared/Core.Tests/GenericHostProviderTests.cs index 5d50c5845..d118ff57e 100644 --- a/src/shared/Core.Tests/GenericHostProviderTests.cs +++ b/src/shared/Core.Tests/GenericHostProviderTests.cs @@ -17,9 +17,18 @@ public class GenericHostProviderTests [InlineData("https", true)] [InlineData("HTTPS", true)] [InlineData("hTtPs", true)] - [InlineData("ssh", false)] - [InlineData("SSH", false)] - [InlineData("sSh", false)] + [InlineData("ssh", true)] + [InlineData("SSH", true)] + [InlineData("sSh", true)] + [InlineData("smpt", true)] + [InlineData("SmtP", true)] + [InlineData("SMTP", true)] + [InlineData("imap", true)] + [InlineData("iMAp", true)] + [InlineData("IMAP", true)] + [InlineData("file", true)] + [InlineData("fIlE", true)] + [InlineData("FILE", true)] [InlineData("", false)] [InlineData(null, false)] public void GenericHostProvider_IsSupported(string protocol, bool expected) @@ -90,7 +99,6 @@ public async Task GenericHostProvider_CreateCredentialAsync_WiaNotAllowed_Return basicAuthMock.Verify(x => x.GetCredentials(It.IsAny(), It.IsAny()), Times.Once); } - [Fact] public async Task GenericHostProvider_CreateCredentialAsync_LegacyAuthorityBasic_ReturnsBasicCredentialNoWiaCheck() { @@ -125,6 +133,37 @@ public async Task GenericHostProvider_CreateCredentialAsync_LegacyAuthorityBasic basicAuthMock.Verify(x => x.GetCredentials(It.IsAny(), It.IsAny()), Times.Once); } + [Fact] + public async Task GenericHostProvider_CreateCredentialAsync_NonHttpProtocol_ReturnsBasicCredentialNoWiaCheck() + { + var input = new InputArguments(new Dictionary + { + ["protocol"] = "smtp", + ["host"] = "example.com", + }); + + const string testUserName = "basicUser"; + const string testPassword = "basicPass"; + var basicCredential = new GitCredential(testUserName, testPassword); + + var context = new TestCommandContext(); + var basicAuthMock = new Mock(); + basicAuthMock.Setup(x => x.GetCredentials(It.IsAny(), It.IsAny())) + .Returns(basicCredential) + .Verifiable(); + var wiaAuthMock = new Mock(); + + var provider = new GenericHostProvider(context, basicAuthMock.Object, wiaAuthMock.Object); + + ICredential credential = await provider.GenerateCredentialAsync(input); + + Assert.NotNull(credential); + Assert.Equal(testUserName, credential.Account); + Assert.Equal(testPassword, credential.Password); + wiaAuthMock.Verify(x => x.GetIsSupportedAsync(It.IsAny()), Times.Never); + basicAuthMock.Verify(x => x.GetCredentials(It.IsAny(), It.IsAny()), Times.Once); + } + [PlatformFact(Platforms.Posix)] public async Task GenericHostProvider_CreateCredentialAsync_NonWindows_WiaSupported_ReturnsBasicCredential() { diff --git a/src/shared/Core/GenericHostProvider.cs b/src/shared/Core/GenericHostProvider.cs index cedbd6cdf..c0e794d4d 100644 --- a/src/shared/Core/GenericHostProvider.cs +++ b/src/shared/Core/GenericHostProvider.cs @@ -40,8 +40,8 @@ public GenericHostProvider(ICommandContext context, public override bool IsSupported(InputArguments input) { - return input != null && (StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "http") || - StringComparer.OrdinalIgnoreCase.Equals(input.Protocol, "https")); + // The generic provider should support all possible protocols (HTTP, HTTPS, SMTP, IMAP, etc) + return input != null && !string.IsNullOrWhiteSpace(input.Protocol); } public override async Task GenerateCredentialAsync(InputArguments input) @@ -51,7 +51,12 @@ public override async Task GenerateCredentialAsync(InputArguments i Uri uri = input.GetRemoteUri(); // Determine the if the host supports Windows Integration Authentication (WIA) - if (IsWindowsAuthAllowed) + if (!StringComparer.OrdinalIgnoreCase.Equals(uri.Scheme, "http") && + !StringComparer.OrdinalIgnoreCase.Equals(uri.Scheme, "https")) + { + // Cannot check WIA support for non-HTTP based protocols + } + else if (IsWindowsAuthAllowed) { if (PlatformUtils.IsWindows()) { diff --git a/src/shared/Core/HostProviderRegistry.cs b/src/shared/Core/HostProviderRegistry.cs index d45d0678f..237c32e54 100644 --- a/src/shared/Core/HostProviderRegistry.cs +++ b/src/shared/Core/HostProviderRegistry.cs @@ -154,12 +154,16 @@ public async Task GetProviderAsync(InputArguments input) throw new Exception("Unable to detect host provider without a remote URL"); } + // We can only probe HTTP(S) URLs - for SMTP, IMAP, etc we cannot do network probing + bool canProbeUri = StringComparer.OrdinalIgnoreCase.Equals(uri.Scheme, "http") || + StringComparer.OrdinalIgnoreCase.Equals(uri.Scheme, "https"); + var probeTimeout = TimeSpan.FromMilliseconds(_context.Settings.AutoDetectProviderTimeout); _context.Trace.WriteLine($"Auto-detect probe timeout is {probeTimeout.TotalSeconds} ms."); HttpResponseMessage probeResponse = null; - async Task MatchProviderAsync(HostProviderPriority priority) + async Task MatchProviderAsync(HostProviderPriority priority, bool probe) { if (_hostProviders.TryGetValue(priority, out ICollection providers)) { @@ -174,7 +178,7 @@ async Task MatchProviderAsync(HostProviderPriority priority) // Try matching using the HTTP response from a query to the remote URL (expensive). // The user may have disabled this feature with a zero or negative timeout for performance reasons. // We only probe the remote once and reuse the same response for all providers. - if (probeTimeout.TotalMilliseconds > 0) + if (probe && probeTimeout.TotalMilliseconds > 0) { if (probeResponse is null) { @@ -215,9 +219,9 @@ async Task MatchProviderAsync(HostProviderPriority priority) } // Match providers starting with the highest priority - IHostProvider match = await MatchProviderAsync(HostProviderPriority.High) ?? - await MatchProviderAsync(HostProviderPriority.Normal) ?? - await MatchProviderAsync(HostProviderPriority.Low) ?? + IHostProvider match = await MatchProviderAsync(HostProviderPriority.High, canProbeUri) ?? + await MatchProviderAsync(HostProviderPriority.Normal, canProbeUri) ?? + await MatchProviderAsync(HostProviderPriority.Low, canProbeUri) ?? throw new Exception("No host provider available to service this request."); // If we ended up making a network call then set the host provider explicitly From e4d4f168cf8f743f32374b930cd6a025ca631224 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 25 May 2022 21:45:23 +0100 Subject: [PATCH 36/83] bitbucket: show on-prem URL in UI and use better help links Update the Bitbucket credential UI to show the URL of the Bitbucket Server or Data Center instance, if we're talking to them. Also fix up the help links to point to a host-relative location; not always to Bitbucket Cloud pages. Note that the OAuth prompt will never been shown for Server/DC since 2FA is not supported there. --- .../Views/CredentialsView.axaml | 3 +++ .../Commands/CredentialsCommand.cs | 9 +++++++-- .../Commands/OAuthCommand.cs | 5 +++++ .../ViewModels/CredentialsViewModel.cs | 20 +++++++++++++++++-- .../ViewModels/OAuthViewModel.cs | 7 ++++--- .../BitbucketAuthentication.cs | 5 +++++ .../Atlassian.Bitbucket/BitbucketConstants.cs | 9 +++++++++ 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/CredentialsView.axaml b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/CredentialsView.axaml index 0f4ad4e96..48cd95bcf 100644 --- a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/CredentialsView.axaml +++ b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/CredentialsView.axaml @@ -23,6 +23,9 @@ + diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs index 81c9a9e5b..009625335 100644 --- a/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs +++ b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs @@ -15,6 +15,10 @@ public abstract class CredentialsCommand : HelperCommand protected CredentialsCommand(ICommandContext context) : base(context, "userpass", "Show authentication prompt.") { + AddOption( + new Option("--url", "Bitbucket Server or Data Center URL") + ); + AddOption( new Option("--username", "Username or email.") ); @@ -23,13 +27,14 @@ protected CredentialsCommand(ICommandContext context) new Option("--show-oauth", "Show OAuth option.") ); - Handler = CommandHandler.Create(ExecuteAsync); + Handler = CommandHandler.Create(ExecuteAsync); } - private async Task ExecuteAsync(string userName, bool showOAuth) + private async Task ExecuteAsync(Uri url, string userName, bool showOAuth) { var viewModel = new CredentialsViewModel(Context.Environment) { + Url = url, UserName = userName, ShowOAuth = showOAuth }; diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs index 0851bebe8..6203e1c81 100644 --- a/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs +++ b/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.CommandLine; using System.CommandLine.Invocation; using System.Threading; using System.Threading.Tasks; @@ -14,6 +15,10 @@ public abstract class OAuthCommand : HelperCommand protected OAuthCommand(ICommandContext context) : base(context, "oauth", "Show OAuth required prompt.") { + AddOption( + new Option("--url", "Bitbucket Server or Data Center URL") + ); + Handler = CommandHandler.Create(ExecuteAsync); } diff --git a/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs b/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs index 2a2d1fa81..38475e9be 100644 --- a/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs +++ b/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel; using System.Windows.Input; using GitCredentialManager; @@ -10,6 +11,7 @@ public class CredentialsViewModel : WindowViewModel { private readonly IEnvironment _environment; + private Uri _url; private string _userName; private string _password; private bool _showOAuth; @@ -64,12 +66,26 @@ private bool CanAcceptOAuth() private void ForgotPassword() { - BrowserUtils.OpenDefaultBrowser(_environment, "https://bitbucket.org/account/password/reset/"); + Uri passwordResetUri = _url is null + ? new Uri(BitbucketConstants.HelpUrls.PasswordReset) + : new Uri(_url, BitbucketConstants.HelpUrls.DataCenterPasswordReset); + + BrowserUtils.OpenDefaultBrowser(_environment, passwordResetUri); } private void SignUp() { - BrowserUtils.OpenDefaultBrowser(_environment, "https://bitbucket.org/account/signup/"); + Uri signUpUri = _url is null + ? new Uri(BitbucketConstants.HelpUrls.SignUp) + : new Uri(_url, BitbucketConstants.HelpUrls.DataCenterLogin); + + BrowserUtils.OpenDefaultBrowser(_environment, signUpUri); + } + + public Uri Url + { + get => _url; + set => SetAndRaisePropertyChanged(ref _url, value); } public string UserName diff --git a/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs b/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs index 95d850d6c..a9376a3a2 100644 --- a/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs +++ b/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs @@ -30,17 +30,18 @@ public OAuthViewModel(IEnvironment environment) private void LearnMore() { - BrowserUtils.OpenDefaultBrowser(_environment, "https://confluence.atlassian.com/bitbucket/two-step-verification-777023203.html"); + // 2FA is not supported on Server/DC so this prompt will never be seen outside of Bitbucket Cloud + BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.TwoFactor); } private void ForgotPassword() { - BrowserUtils.OpenDefaultBrowser(_environment, "https://bitbucket.org/account/password/reset/"); + BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.PasswordReset); } private void SignUp() { - BrowserUtils.OpenDefaultBrowser(_environment, "https://bitbucket.org/account/signup/"); + BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.SignUp); } ///

diff --git a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs index ae9cdc539..25a10647a 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs @@ -94,6 +94,11 @@ public async Task GetCredentialsAsync(Uri targetUri, st TryFindHelperExecutablePath(out string helperPath)) { var cmdArgs = new StringBuilder("userpass"); + if (!BitbucketHostProvider.IsBitbucketOrg(targetUri)) + { + cmdArgs.AppendFormat(" --url {0}", QuoteCmdArg(targetUri.ToString())); + } + if (!string.IsNullOrWhiteSpace(userName)) { cmdArgs.AppendFormat(" --username {0}", QuoteCmdArg(userName)); diff --git a/src/shared/Atlassian.Bitbucket/BitbucketConstants.cs b/src/shared/Atlassian.Bitbucket/BitbucketConstants.cs index 520b7c612..d995fa276 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketConstants.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketConstants.cs @@ -49,6 +49,15 @@ public static class Credential } } + public static class HelpUrls + { + public const string DataCenterPasswordReset = "/passwordreset"; + public const string DataCenterLogin = "/login"; + public const string PasswordReset = "https://bitbucket.org/account/password/reset/"; + public const string SignUp = "https://bitbucket.org/account/signup/"; + public const string TwoFactor = "https://support.atlassian.com/bitbucket-cloud/docs/enable-two-step-verification/"; + } + /// /// Supported authentication modes for Bitbucket.org /// From ab91f00b477a7e06add5f249b3dca110eb13f85f Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 21 Apr 2022 10:00:57 -0700 Subject: [PATCH 37/83] macOS release: build, lay out, and codesign payload Add step one of the macOS release process to build, run applicable unit tests, lay out the symbols/payload, codesign the payload, and upload the payload and symbols as artifacts. --- .github/run_developer_signing.sh | 46 ++++++++++++++++++ .github/workflows/release.yml | 64 ++++++++++++++++++++++++++ src/osx/Installer.Mac/build.sh | 2 +- src/osx/Installer.Mac/entitlements.xml | 12 +++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100755 .github/run_developer_signing.sh create mode 100644 .github/workflows/release.yml create mode 100644 src/osx/Installer.Mac/entitlements.xml diff --git a/.github/run_developer_signing.sh b/.github/run_developer_signing.sh new file mode 100755 index 000000000..8b3de88a3 --- /dev/null +++ b/.github/run_developer_signing.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +SIGN_DIR=$1 +DEVELOPER_ID=$2 +ENTITLEMENTS_FILE=$3 + +if [ -z "$SIGN_DIR" ]; then + echo "error: missing directory argument" + exit 1 +elif [ -z "$DEVELOPER_ID" ]; then + echo "error: missing developer id argument" + exit 1 +elif [ -z "$ENTITLEMENTS_FILE" ]; then + echo "error: missing entitlements file argument" + exit 1 +fi + +echo "======== INPUTS ========" +echo "Directory: $SIGN_DIR" +echo "Developer ID: $DEVELOPER_ID" +echo "Entitlements: $ENTITLEMENTS_FILE" +echo "======== END INPUTS ========" + +cd $SIGN_DIR +for f in * +do + macho=$(file --mime $f | grep mach) + # Runtime sign dylibs and Mach-O binaries + if [[ $f == *.dylib ]] || [ ! -z "$macho" ]; + then + echo "Runtime Signing $f" + codesign -s "$DEVELOPER_ID" $f --timestamp --force --options=runtime --entitlements $ENTITLEMENTS_FILE + elif [ -d "$f" ]; + then + echo "Signing files in subdirectory $f" + cd $f + for i in * + do + codesign -s "$DEVELOPER_ID" $i --timestamp --force + done + cd .. + else + echo "Signing $f" + codesign -s "$DEVELOPER_ID" $f --timestamp --force + fi +done \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..c32703104 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,64 @@ +name: release + +on: + workflow_dispatch: + push: + branches: [ release ] + +jobs: +# ================================ +# macOS +# ================================ + osx-build: + name: Build macOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. + + - name: Set up dotnet + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.201 + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: | + dotnet build --configuration=MacRelease + + - name: Run macOS unit tests + run: | + dotnet test --configuration=MacRelease + + - name: Lay out payload and symbols + run: | + src/osx/Installer.Mac/layout.sh --configuration=MacRelease --output=payload --symbol-output=symbols + + - name: Create keychain + env: + CERT_BASE64: ${{ secrets.DEVELOPER_CERTIFICATE_BASE64 }} + CERT_PASSPHRASE: ${{ secrets.DEVELOPER_CERTIFICATE_PASSWORD }} + run: | + security create-keychain -p pwd $RUNNER_TEMP/buildagent.keychain + security default-keychain -s $RUNNER_TEMP/buildagent.keychain + security unlock-keychain -p pwd $RUNNER_TEMP/buildagent.keychain + echo $CERT_BASE64 | base64 -D > $RUNNER_TEMP/cert.p12 + security import $RUNNER_TEMP/cert.p12 -k $RUNNER_TEMP/buildagent.keychain -P $CERT_PASSPHRASE -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $RUNNER_TEMP/buildagent.keychain + + - name: Developer sign + env: + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + .github/run_developer_signing.sh payload $APPLE_TEAM_ID $GITHUB_WORKSPACE/src/osx/Installer.Mac/entitlements.xml + + - name: Upload macOS artifacts + uses: actions/upload-artifact@v3 + with: + name: tmp.osx-build + path: | + payload + symbols \ No newline at end of file diff --git a/src/osx/Installer.Mac/build.sh b/src/osx/Installer.Mac/build.sh index ba5308da1..816c621ec 100755 --- a/src/osx/Installer.Mac/build.sh +++ b/src/osx/Installer.Mac/build.sh @@ -42,7 +42,7 @@ OUTDIR="$INSTALLER_OUT/pkg/$CONFIGURATION" PAYLOAD="$OUTDIR/payload" COMPONENTDIR="$OUTDIR/components" COMPONENTOUT="$COMPONENTDIR/com.microsoft.gitcredentialmanager.component.pkg" -DISTOUT="$OUTDIR/gcmcore-osx-$VERSION.pkg" +DISTOUT="$OUTDIR/gcm-osx-x64-$VERSION.pkg" # Layout and pack "$INSTALLER_SRC/layout.sh" --configuration="$CONFIGURATION" --output="$PAYLOAD" || exit 1 diff --git a/src/osx/Installer.Mac/entitlements.xml b/src/osx/Installer.Mac/entitlements.xml new file mode 100644 index 000000000..9acbcfa5c --- /dev/null +++ b/src/osx/Installer.Mac/entitlements.xml @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + \ No newline at end of file From 69769f5b2698358ab783346a2115f4a4b47a1bfc Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 21 Apr 2022 10:23:40 -0700 Subject: [PATCH 38/83] macOS release: sign payload Add step two of the macOS release process to download the unsigned payload, use ESRP to sign it, and upload the signed payload as an artifact. Additionally, genericize the existing run_esrp_signing.py script to allow for signing of macOS payload/pkg and Windows exes in addition to Debian packages. --- .github/run_esrp_signing.py | 96 ++++++++++++++++++++--------------- .github/set_up_esrp.ps1 | 12 +++++ .github/workflows/release.yml | 63 ++++++++++++++++++++++- 3 files changed, 130 insertions(+), 41 deletions(-) create mode 100644 .github/set_up_esrp.ps1 diff --git a/.github/run_esrp_signing.py b/.github/run_esrp_signing.py index fd137976e..dc598fdcd 100644 --- a/.github/run_esrp_signing.py +++ b/.github/run_esrp_signing.py @@ -1,3 +1,4 @@ +import argparse import json import os import glob @@ -6,40 +7,44 @@ import sys import re +parser = argparse.ArgumentParser(description='Sign binaries for Windows, macOS, and Linux') +parser.add_argument('path', help='Path to file for signing') +parser.add_argument('keycode', help='Platform-specific key code for signing') +parser.add_argument('opcode', help='Platform-specific operation code for signing') +# Setting nargs=argparse.REMAINDER allows us to pass in params that begin with `--` +parser.add_argument('--params', nargs=argparse.REMAINDER, help='Parameters for signing') +args = parser.parse_args() + esrp_tool = os.path.join("esrp", "tools", "EsrpClient.exe") aad_id = os.environ['AZURE_AAD_ID'].strip() +# We temporarily need two AAD IDs, as we're using an SSL certificate associated +# with an older App Registration until we have the required hardware to approve +# the new certificate in SSL Admin. +aad_id_ssl = os.environ['AZURE_AAD_ID_SSL'].strip() workspace = os.environ['GITHUB_WORKSPACE'].strip() -source_root_location = os.path.join(workspace, "deb", "Release") -destination_location = os.path.join(workspace) - -files = glob.glob(os.path.join(source_root_location, "*.deb")) +source_location = args.path +files = glob.glob(os.path.join(source_location, "*")) print("Found files:") pprint.pp(files) -if len(files) < 1 or not files[0].endswith(".deb"): - print("Error: cannot find .deb to sign") - exit(1) - -file_to_sign = os.path.basename(files[0]) - auth_json = { - "Version": "1.0.0", - "AuthenticationType": "AAD_CERT", - "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", - "ClientId": aad_id, - "AuthCert": { - "SubjectName": f"CN={aad_id}.microsoft.com", - "StoreLocation": "LocalMachine", - "StoreName": "My", - }, - "RequestSigningCert": { - "SubjectName": f"CN={aad_id}", - "StoreLocation": "LocalMachine", - "StoreName": "My", - } + "Version": "1.0.0", + "AuthenticationType": "AAD_CERT", + "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", + "ClientId": f"{aad_id}", + "AuthCert": { + "SubjectName": f"CN={aad_id_ssl}.microsoft.com", + "StoreLocation": "LocalMachine", + "StoreName": "My" + }, + "RequestSigningCert": { + "SubjectName": f"CN={aad_id}", + "StoreLocation": "LocalMachine", + "StoreName": "My" + } } input_json = { @@ -47,21 +52,15 @@ "SignBatches": [ { "SourceLocationType": "UNC", - "SourceRootDirectory": source_root_location, + "SourceRootDirectory": source_location, "DestinationLocationType": "UNC", - "DestinationRootDirectory": destination_location, - "SignRequestFiles": [ - { - "CustomerCorrelationId": "01A7F55F-6CDD-4123-B255-77E6F212CDAD", - "SourceLocation": file_to_sign, - "DestinationLocation": os.path.join("Signed", file_to_sign), - } - ], + "DestinationRootDirectory": workspace, + "SignRequestFiles": [], "SigningInfo": { "Operations": [ { - "KeyCode": "CP-450779-Pgp", - "OperationCode": "LinuxSign", + "KeyCode": f"{args.keycode}", + "OperationCode": f"{args.opcode}", "Parameters": {}, "ToolName": "sign", "ToolVersion": "1.0", @@ -72,10 +71,27 @@ ] } +# add files to sign +for f in files: + name = os.path.basename(f) + input_json["SignBatches"][0]["SignRequestFiles"].append( + { + "SourceLocation": name, + "DestinationLocation": os.path.join("signed", name), + } + ) + +# add parameters to input.json (e.g. enabling the hardened runtime for macOS) +if args.params is not None: + i = 0 + while i < len(args.params): + input_json["SignBatches"][0]["SigningInfo"]["Operations"][0]["Parameters"][args.params[i]] = args.params[i + 1] + i += 2 + policy_json = { "Version": "1.0.0", "Intent": "production release", - "ContentType": "Debian package", + "ContentType": "binary", } configs = [ @@ -106,7 +122,7 @@ '***', result.stdout, flags=re.IGNORECASE|re.MULTILINE) -printf(log) +print(log) if result.returncode != 0: print("Failed to run ESRPClient.exe") @@ -117,6 +133,6 @@ with open(esrp_out, 'r') as fp: pprint.pp(json.load(fp)) -signed_file = os.path.join(destination_location, "Signed", file_to_sign) -if os.path.isfile(signed_file): - print(f"Success!\nSigned {signed_file}") +for file in files: + if os.path.isfile(os.path.join("signed", file)): + print(f"Success!\nSigned {file}") \ No newline at end of file diff --git a/.github/set_up_esrp.ps1 b/.github/set_up_esrp.ps1 new file mode 100644 index 000000000..099cd50c2 --- /dev/null +++ b/.github/set_up_esrp.ps1 @@ -0,0 +1,12 @@ +# Install ESRP client +az storage blob download --file esrp.zip --account-key "$env:AZURE_STORAGE_KEY" --account-name gcmesrp --container microsoft-esrp-client --name microsoft.esrpclient.1.2.76.nupkg +Expand-Archive -Path esrp.zip -DestinationPath .\esrp + +# Install certificates +az keyvault secret download --vault-name "$env:AZURE_VAULT" --name "$env:AUTH_CERT" --file out.pfx +certutil -f -importpfx out.pfx +Remove-Item out.pfx + +az keyvault secret download --vault-name "$env:AZURE_VAULT" --name "$env:REQUEST_SIGNING_CERT" --file out.pfx +certutil -f -importpfx out.pfx +Remove-Item out.pfx \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c32703104..d4ed61f15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,4 +61,65 @@ jobs: name: tmp.osx-build path: | payload - symbols \ No newline at end of file + symbols + + osx-payload-sign: + name: Sign macOS payload + # ESRP service requires signing to run on Windows + runs-on: windows-latest + needs: osx-build + steps: + - name: Check out repository + uses: actions/checkout@v3 + + - name: Download payload + uses: actions/download-artifact@v3 + with: + name: tmp.osx-build + + - name: Zip unsigned payload + shell: pwsh + run: | + Compress-Archive -Path payload payload/payload.zip + cd payload + Get-ChildItem -Exclude payload.zip | Remove-Item -Recurse -Force + + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Set up ESRP client + shell: pwsh + env: + AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }} + AZURE_VAULT: ${{ secrets.AZURE_VAULT }} + AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }} + REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }} + run: | + .github\set_up_esrp.ps1 + + - name: Run ESRP client + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }} + APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }} + run: | + python .github\run_esrp_signing.py payload $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE --params 'Hardening' '--options=runtime' + + - name: Unzip signed payload + shell: pwsh + run: | + Expand-Archive signed/payload.zip -DestinationPath signed + Remove-Item signed/payload.zip + + - name: Upload signed payload + uses: actions/upload-artifact@v3 + with: + name: osx-payload-sign + path: | + signed From 984d3749644b10563fb747983fd156c14411fb7d Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Mon, 23 May 2022 17:28:10 -0700 Subject: [PATCH 39/83] install-from-source: add instructions to uninstall Add instructions for Linux users on supported distros to remove GCM and its dependencies after installing from source. --- docs/faq.md | 4 +++ docs/linux-fromsrc-uninstall.md | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 docs/linux-fromsrc-uninstall.md diff --git a/docs/faq.md b/docs/faq.md index 1777daa7c..a67b3c119 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -146,3 +146,7 @@ and pick "Revoke access". ![Revoke GCM OAuth app access](img/github-oauthapp-revoke.png) After revoking access, any tokens created by GCM will be invalidated and can no longer be used to access your repositories. The next time GCM attempts to access GitHub.com you will be prompted to consent again. + +### I used the install from source script to install GCM on my Linux distribution. Now how can I uninstall GCM and its dependencies? + +Please see full instructions [here](./linux-fromsrc-uninstall.md). diff --git a/docs/linux-fromsrc-uninstall.md b/docs/linux-fromsrc-uninstall.md new file mode 100644 index 000000000..79c959932 --- /dev/null +++ b/docs/linux-fromsrc-uninstall.md @@ -0,0 +1,55 @@ +# Uninstalling after installing from source + +These instructions will guide you in removing GCM after running the [install from source script](../src/linux/Packaging.Linux/install-from-source.sh) on your Linux distribution. + +:siren: PROCEED WITH CAUTION :siren: + +For completeness, we provide uninstall instructions for _the GCM application, the GCM repo, and the maximum number of dependencies*_ for all distributions. This repo and these dependencies may or may not have already been present on your system when you ran the install from source script, and uninstalling them could impact other programs and/or your normal workflows. Please keep this in mind when following the instructions below. + +*Certain distributions require some dependencies of the script to function as expected, so we only include instructions to remove the non-required dependencies. + +## All distributions + +**Note:** If you ran the install from source script from a pre-existing clone of the `git-credential-manager` repo or outside of your `$HOME` directory, you will need to modify the final two commands below to point to the location of your pre-existing clone or the directory from which you ran the install from source script. + +```console +git-credential-manager-core unconfigure && +sudo rm $(command -v git-credential-manager-core) && +sudo rm -rf /usr/local/share/gcm-core && +sudo rm -rf ~/git-credential-manager && +sudo rm ~/install-from-source.sh +``` + +## Debian/Ubuntu + +**Note:** If you had a pre-existing installation of dotnet that was not installed via `apt` or `apt-get` when you ran the install from source script, you will need to remove it using [these instructions](https://docs.microsoft.com/en-us/dotnet/core/install/remove-runtime-sdk-versions?pivots=os-linux#uninstall-net) and remove `dotnet-*` from the below command. + +```console +sudo apt remove dotnet-* dpkg-dev apt-transport-https git curl wget +``` + +## Linux Mint + +**Note:** If you had a pre-existing installation of dotnet when you ran the install from source script that was not located at `~/.dotnet`, you will need to modify the first command below to point to the custom install location. If you would like to remove the specific version of dotnet that the script installed and keep other versions, you can do so with [these instructions](https://docs.microsoft.com/en-us/dotnet/core/install/remove-runtime-sdk-versions?pivots=os-linux#uninstall-net). + +```console +sudo rm -rf ~/.dotnet && +sudo apt remove git curl +``` + +## Fedora/CentOS/RHEL + +**Note:** If you had a pre-existing installation of dotnet when you ran the install from source script that was not located at `~/.dotnet`, you will need to modify the first command below to point to the custom install location. If you would like to remove the specific version of dotnet that the script installed and keep other versions, you can do so with [these instructions](https://docs.microsoft.com/en-us/dotnet/core/install/remove-runtime-sdk-versions?pivots=os-linux#uninstall-net). + +```console +sudo rm -rf ~/.dotnet +``` + +## Alpine + +**Note:** If you had a pre-existing installation of dotnet when you ran the install from source script that was not located at `~/.dotnet`, you will need to modify the first command below to point to the custom install location. If you would like to remove the specific version of dotnet that the script installed and keep other versions, you can do so with [these instructions](https://docs.microsoft.com/en-us/dotnet/core/install/remove-runtime-sdk-versions?pivots=os-linux#uninstall-net). + +```console +sudo rm -rf ~/.dotnet && +sudo apk del icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib which bash coreutils gcompat git curl +``` From 6dd3098406e6cc7b4e3cac889f3d68dac19ce153 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Wed, 25 May 2022 13:57:44 -0700 Subject: [PATCH 40/83] fixup! Add install from source instructions --- README.md | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7071f57e3..7373b4219 100644 --- a/README.md +++ b/README.md @@ -93,32 +93,6 @@ sudo /usr/local/share/gcm-core/uninstall.sh ### Linux -#### Experimental: install from source helper script - -If you would like to help dogfood our new install from source helper script, -run the following: - -1. To ensure `curl` is installed: - - ```shell - curl --version - ``` - - If `curl` is not installed, please use your distribution's package manager - to install it. - -1. To download and run the script: - - ```shell - curl -LO https://raw.githubusercontent.com/GitCredentialManager/git-credential-manager/main/src/linux/Packaging.Linux/install-from-source.sh && - sh ./install-from-source.sh && - git-credential-manager-core configure - ``` - - **Note:** You will be prompted to enter your credentials so that the script - can download GCM's dependencies using your distribution's package - manager. - #### Ubuntu/Debian distributions Download the latest [.deb package](https://github.com/GitCredentialManager/git-credential-manager/releases/latest), and run the following: @@ -142,6 +116,8 @@ sudo dpkg -r gcmcore #### Other distributions +##### Option 1: Tarball + Download the latest [tarball](https://github.com/GitCredentialManager/git-credential-manager/releases/latest), and run the following: ```shell @@ -156,6 +132,33 @@ git-credential-manager-core unconfigure rm $(command -v git-credential-manager-core) ``` +#### Option 2: Install from source helper script + +1. Ensure `curl` is installed: + + ```shell + curl --version + ``` + + If `curl` is not installed, please use your distribution's package manager + to install it. + +1. Download and run the script: + + ```shell + curl -LO https://raw.githubusercontent.com/GitCredentialManager/git-credential-manager/main/src/linux/Packaging.Linux/install-from-source.sh && + sh ./install-from-source.sh && + git-credential-manager-core configure + ``` + + **Note:** You will be prompted to enter your credentials so that the script + can download GCM's dependencies using your distribution's package + manager. + +To uninstall: + +[Follow these instructions](docs/linux-fromsrc-uninstall.md) for your distribution. + **Note:** all Linux distributions [require additional configuration](https://aka.ms/gcm/credstores) to use GCM. --- From 42fc0810dd6ffc6e1c6e91a4eab39ee3fb3ed9a4 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Fri, 13 May 2022 18:55:34 -0700 Subject: [PATCH 41/83] macOS release: package payload Add step three of the macOS release process to package the payload and upload the pkg artifact. --- .github/workflows/release.yml | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4ed61f15..e28039f3f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,3 +123,43 @@ jobs: name: osx-payload-sign path: | signed + + osx-pack: + name: Package macOS payload + runs-on: macos-latest + needs: osx-payload-sign + steps: + - name: Check out repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. + + - name: Set up dotnet + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.201 + + # Install Nerdbank.GitVersioning + - uses: dotnet/nbgv@master + with: + setCommonVars: true + + - name: Download signed payload + uses: actions/download-artifact@v3 + with: + name: osx-payload-sign + + - name: Create component package + run: | + src/osx/Installer.Mac/pack.sh --payload=payload --version=$GitBuildVersionSimple --output=components/com.microsoft.gitcredentialmanager.component.pkg + + - name: Create product archive + run: | + src/osx/Installer.Mac/dist.sh --package-path=components --version=$GitBuildVersionSimple --output=pkg/gcm-osx-x64-$GitBuildVersionSimple.pkg || exit 1 + + - name: Upload package + uses: actions/upload-artifact@v3 + with: + name: tmp.osx-pack + path: | + pkg From 7f20a523df3efe1f05027098bffb0116be7c4590 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Fri, 13 May 2022 19:05:29 -0700 Subject: [PATCH 42/83] macOS release: sign and notarize package Add step four of the macOS release process to sign and notarize the pkg and upload it as the final installer. --- .github/workflows/release.yml | 75 ++++++++++ src/osx/SignFiles.Mac/SignFiles.Mac.csproj | 94 ------------ src/osx/SignFiles.Mac/notarize-pkg.sh | 163 --------------------- 3 files changed, 75 insertions(+), 257 deletions(-) delete mode 100644 src/osx/SignFiles.Mac/SignFiles.Mac.csproj delete mode 100755 src/osx/SignFiles.Mac/notarize-pkg.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e28039f3f..e850abef7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -163,3 +163,78 @@ jobs: name: tmp.osx-pack path: | pkg + + osx-sign: + name: Sign and notarize macOS package + # ESRP service requires signing to run on Windows + runs-on: windows-latest + needs: osx-pack + steps: + - name: Check out repository + uses: actions/checkout@v3 + + - name: Download unsigned package + uses: actions/download-artifact@v3 + with: + name: tmp.osx-pack + path: pkg + + - name: Zip unsigned package + shell: pwsh + run: | + Compress-Archive -Path pkg/*.pkg pkg/gcm-pkg.zip + cd pkg + Get-ChildItem -Exclude gcm-pkg.zip | Remove-Item -Recurse -Force + + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Set up ESRP client + shell: pwsh + env: + AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }} + AZURE_VAULT: ${{ secrets.AZURE_VAULT }} + AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }} + REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }} + run: | + .github\set_up_esrp.ps1 + + - name: Sign package + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }} + APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }} + run: | + python .github\run_esrp_signing.py pkg $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE + + - name: Unzip signed package + shell: pwsh + run: | + mkdir unsigned + Expand-Archive -LiteralPath signed\gcm-pkg.zip -DestinationPath .\unsigned -Force + Remove-Item signed\gcm-pkg.zip -Force + + - name: Notarize signed package + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }} + APPLE_NOTARIZATION_OP_CODE: ${{ secrets.APPLE_NOTARIZATION_OPERATION_CODE }} + run: | + python .github\run_esrp_signing.py unsigned $env:APPLE_KEY_CODE $env:APPLE_NOTARIZATION_OP_CODE --params 'BundleId' 'com.microsoft.gitcredentialmanager' + + - name: Publish signed package + uses: actions/upload-artifact@v3 + with: + name: osx-sign + path: signed/*.pkg \ No newline at end of file diff --git a/src/osx/SignFiles.Mac/SignFiles.Mac.csproj b/src/osx/SignFiles.Mac/SignFiles.Mac.csproj deleted file mode 100644 index 3de4601d9..000000000 --- a/src/osx/SignFiles.Mac/SignFiles.Mac.csproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - net6.0 - false - - $(RootDir) - $(BaseIntermediateOutputPath)\tmp\macsign - 8003 - - - - - - all - - - - - - Microsoft400 - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/osx/SignFiles.Mac/notarize-pkg.sh b/src/osx/SignFiles.Mac/notarize-pkg.sh deleted file mode 100755 index e7566b851..000000000 --- a/src/osx/SignFiles.Mac/notarize-pkg.sh +++ /dev/null @@ -1,163 +0,0 @@ -#!/bin/bash - -# This file was based on https://github.com/microsoft/BuildXL/blob/8c2348ff04e6ca78726bb945fb2a0f6a55a5c7d6/Private/macOS/notarize.sh -# -# For detailed explanation see: https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow - -usage() { - cat < -p -pkg - -id or --appleid # A valid Apple ID email address, account must have correct certificates available - -p or --password # The password for the specified Apple ID or Apple One-Time password (to avoid 2FA) - -pkg or --package # The path to an already signed flat-package -EOM - exit 0 -} - -declare arg_AppleId="" -declare arg_Password="" -declare arg_PackagePath="" - -[ $# -eq 0 ] && { usage; } - -function parseArgs() { - arg_Positional=() - while [[ $# -gt 0 ]]; do - cmd="$1" - case $cmd in - --help | -h) - usage - shift - exit 0 - ;; - --appleid | -id) - arg_AppleId=$2 - shift - ;; - --password | -p) - arg_Password="$2" - shift - ;; - --package | -pkg) - arg_PackagePath="$2" - shift - ;; - *) - arg_Positional+=("$1") - shift - ;; - esac - done -} - -function getPackageId { - local PKG=$(cd "$(dirname "$1")"; pwd)/$(basename "$1") - local PKGDEST=$(mktemp -d | tr -d '\r') - xar -x -f "${PKG}" --exclude '^(?:(?!PackageInfo).)*$' -C "${PKGDEST}" - if [ ! -e "${PKGDEST}/PackageInfo" ]; then - echo "error: can't find 'PackageInfo'; maybe meta-package" - return 1 - fi - cat "${PKGDEST}/PackageInfo" | tr -d '\r' | tr -d '\n' | sed 's:^.*identifier="\([^"]*\)".*$:\1:g' - rm -rf "${PKGDEST}" -} - -parseArgs "$@" - -if [[ -z $arg_AppleId ]]; then - echo "[ERROR] Must supply valid / non-empty Apple ID!" - exit 1 -fi - -if [[ -z $arg_Password ]]; then - echo "[ERROR] Must supply valid / non-empty password!" - exit 1 -fi - -if [[ ! -f $arg_PackagePath ]]; then - echo "[ERROR] Must supply valid / non-empty path to package!" - exit 1 -fi - -declare bundle_id=$(getPackageId ${arg_PackagePath}) - -if [[ -z $bundle_id ]]; then - echo "[ERROR] No identifier found in package info!" - exit 1 -fi - -echo "Notarizating $arg_PackagePath" - -echo -e "Current state:\n" -xcrun stapler validate -v "$arg_PackagePath" - -if [[ $? -eq 0 ]]; then - echo "$arg_PackagePath already notarized and stapled, nothing to do!" - exit 0 -fi - -set -e - -declare start_time=$(date +%s) - -declare output="/tmp/progress.xml" - -echo "Uploading package to notarization service, please wait..." -xcrun altool --notarize-app -t osx -f $arg_PackagePath --primary-bundle-id $bundle_id -u $arg_AppleId -p $arg_Password --output-format xml | tee $output - -declare request_id=$(/usr/libexec/PlistBuddy -c "print :notarization-upload:RequestUUID" $output) - -echo "Checking notarization request validity..." -if [[ $request_id =~ ^\{?[A-F0-9a-f]{8}-[A-F0-9a-f]{4}-[A-F0-9a-f]{4}-[A-F0-9a-f]{4}-[A-F0-9a-f]{12}\}?$ ]]; then - declare attempts=5 - - while : - do - echo "Waiting a bit before checking on notarization status again..." - - sleep 20 - xcrun altool --notarization-info $request_id -u $arg_AppleId -p $arg_Password --output-format xml | tee $output - - declare status=$(/usr/libexec/PlistBuddy -c "print :notarization-info:Status" $output) - echo "Status: $status" - - if [[ -z $status ]]; then - echo "Left attempts: $attempts" - - if (($attempts <= 0)); then - break - fi - - ((attempts--)) - else - if [[ $status != "in progress" ]]; then - break - fi - fi - done - - declare end_time=$(date +%s) - echo -e "Completed in $(($end_time-$start_time)) seconds\n" - - if [[ "$status" != "success" ]]; then - echo "Error notarizing, exiting..." >&2 - exit 1 - else - declare url=$(/usr/libexec/PlistBuddy -c "print :notarization-info:LogFileURL" $output) - - if [ "$url" ]; then - curl $url - fi - - # Staple the ticket to the package - xcrun stapler staple "$arg_PackagePath" - - echo -e "State after notarization:\n" - xcrun stapler validate -v "$arg_PackagePath" - echo -e "Stapler exit code: $? (must be zero on success!)\n" - fi -else - echo "Invalid request id found in 'altool' output, aborting!" >&2 - exit 1 -fi From b4826d056c86918f230a910ff0947628c6a278a5 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 21 Apr 2022 12:06:20 -0700 Subject: [PATCH 43/83] homebrew: update release asset name and uninstall script Update release-homebrew.yaml to reflect removal of core from pkg name. --- .github/workflows/release-homebrew.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-homebrew.yaml b/.github/workflows/release-homebrew.yaml index b847388f9..ca657863b 100644 --- a/.github/workflows/release-homebrew.yaml +++ b/.github/workflows/release-homebrew.yaml @@ -14,5 +14,5 @@ jobs: tap: microsoft/git name: git-credential-manager-core type: cask - releaseAsset: gcmcore-osx-(.*)\.pkg + releaseAsset: gcm-osx-x64-(.*)\.pkg alwaysUsePullRequest: true From 5c10997da52c24e2f79b203b9168b27b8035387f Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 26 May 2022 15:03:53 -0700 Subject: [PATCH 44/83] windows release: build, sign, and publish Add the Windows release process to: 1. Build and sign the payload 2. Use the signed payload to build and sign the user and system installers 3. Publish the signed installers, payload, and symbols This change also removes the no-longer-needed Payload.Windows project and removes the 'core' suffix from the Windows installers. --- .github/workflows/continuous-integration.yml | 2 +- .github/workflows/release.yml | 119 +++++++++++++++++- Git-Credential-Manager.sln | 13 -- README.md | 4 +- .../Installer.Windows.csproj | 30 +---- src/windows/Installer.Windows/Setup.iss | 4 +- src/windows/Installer.Windows/layout.ps1 | 67 ++++++++++ .../Payload.Windows/Payload.Windows.csproj | 77 ------------ 8 files changed, 194 insertions(+), 122 deletions(-) create mode 100644 src/windows/Installer.Windows/layout.ps1 delete mode 100644 src/windows/Payload.Windows/Payload.Windows.csproj diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f3ac48932..7a06deff1 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -42,4 +42,4 @@ jobs: run: dotnet build --configuration MacRelease - name: Test - run: dotnet test --no-restore --verbosity normal + run: dotnet test --verbosity normal diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e850abef7..53d175970 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -237,4 +237,121 @@ jobs: uses: actions/upload-artifact@v3 with: name: osx-sign - path: signed/*.pkg \ No newline at end of file + path: signed/*.pkg + +# ================================ +# Windows +# ================================ + win-sign: + name: Build and Sign Windows + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. + + - name: Set up dotnet + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.201 + + # Install Nerdbank.GitVersioning + - uses: dotnet/nbgv@master + with: + setCommonVars: true + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: | + dotnet build --configuration=WindowsRelease + + - name: Run Windows unit tests + run: | + dotnet test --configuration=WindowsRelease + + - name: Lay out Windows payload and symbols + shell: pwsh + run: | + cd src/windows/Installer.Windows/ + ./layout.ps1 -Configuration WindowsRelease -Output payload -SymbolOutput symbols + mkdir unsigned-payload + Get-ChildItem -Path payload/* -Include *.exe, *.dll | Move-Item -Destination unsigned-payload + + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Set up ESRP client + shell: pwsh + env: + AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }} + AZURE_VAULT: ${{ secrets.AZURE_VAULT }} + AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }} + REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }} + run: | + .github\set_up_esrp.ps1 + + - name: Run ESRP client for unsigned payload + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + WINDOWS_KEY_CODE: ${{ secrets.WINDOWS_KEY_CODE }} + WINDOWS_OP_CODE: ${{ secrets.WINDOWS_OPERATION_CODE }} + run: | + python .github\run_esrp_signing.py ` + src/windows/Installer.Windows/unsigned-payload ` + $env:WINDOWS_KEY_CODE $env:WINDOWS_OP_CODE ` + --params 'OpusName' 'Microsoft' ` + 'OpusInfo' 'http://www.microsoft.com' ` + 'FileDigest' '/fd "SHA256"' 'PageHash' '/NPH' ` + 'TimeStamp' '/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256' + + - name: Lay out signed payload + shell: pwsh + run: | + mkdir signed-payload + Move-Item -Path signed/* -Destination signed-payload + # ESRP will not sign the *.exe.config or NOTICE files, but they are needed to build the installers. + # Due to this, we copy them after signing. + Get-ChildItem -Path src/windows/Installer.Windows/payload/* -Include *.exe.config, NOTICE | Move-Item -Destination signed-payload + Remove-Item signed -Recurse -Force + + - name: Build with signed payload + shell: pwsh + run: | + dotnet build src/windows/Installer.Windows /p:PayloadPath=$env:GITHUB_WORKSPACE/signed-payload /p:NoLayout=true --configuration=WindowsRelease + + - name: Run ESRP client for installers + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + WINDOWS_KEY_CODE: ${{ secrets.WINDOWS_KEY_CODE }} + WINDOWS_OP_CODE: ${{ secrets.WINDOWS_OPERATION_CODE }} + run: | + python .github\run_esrp_signing.py ` + .\out\windows\Installer.Windows\bin\WindowsRelease\net472 ` + $env:WINDOWS_KEY_CODE ` + $env:WINDOWS_OP_CODE ` + --params 'OpusName' 'Microsoft' ` + 'OpusInfo' 'http://www.microsoft.com' ` + 'FileDigest' '/fd "SHA256"' 'PageHash' '/NPH' ` + 'TimeStamp' '/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256' + + - name: Publish final artifacts + uses: actions/upload-artifact@v3 + with: + name: win-sign + path: | + signed + signed-payload + src/windows/Installer.Windows/symbols \ No newline at end of file diff --git a/Git-Credential-Manager.sln b/Git-Credential-Manager.sln index 0330e693c..9b0e76ba8 100644 --- a/Git-Credential-Manager.sln +++ b/Git-Credential-Manager.sln @@ -31,8 +31,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Installer.Mac", "src\osx\In EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Installer.Windows", "src\windows\Installer.Windows\Installer.Windows.csproj", "{85903170-9E52-4B53-A6E4-3F416F684FAE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payload.Windows", "src\windows\Payload.Windows\Payload.Windows.csproj", "{8DBBAB0A-970D-4BE3-958C-8CDC92F76549}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Atlassian.Bitbucket", "src\shared\Atlassian.Bitbucket\Atlassian.Bitbucket.csproj", "{B49881A6-E734-490E-8EA7-FB0D9E296CFB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Atlassian.Bitbucket.Tests", "src\shared\Atlassian.Bitbucket.Tests\Atlassian.Bitbucket.Tests.csproj", "{025E5329-A0B1-4BA9-9203-B70B44A5F9E0}" @@ -229,16 +227,6 @@ Global {85903170-9E52-4B53-A6E4-3F416F684FAE}.WindowsRelease|Any CPU.Build.0 = Release|Any CPU {85903170-9E52-4B53-A6E4-3F416F684FAE}.LinuxDebug|Any CPU.ActiveCfg = Debug|Any CPU {85903170-9E52-4B53-A6E4-3F416F684FAE}.LinuxRelease|Any CPU.ActiveCfg = Release|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.MacDebug|Any CPU.ActiveCfg = Debug|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.MacRelease|Any CPU.ActiveCfg = Release|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.WindowsDebug|Any CPU.ActiveCfg = Debug|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.WindowsDebug|Any CPU.Build.0 = Debug|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.WindowsRelease|Any CPU.ActiveCfg = Release|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.WindowsRelease|Any CPU.Build.0 = Release|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.LinuxDebug|Any CPU.ActiveCfg = Debug|Any CPU - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549}.LinuxRelease|Any CPU.ActiveCfg = Release|Any CPU {B49881A6-E734-490E-8EA7-FB0D9E296CFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B49881A6-E734-490E-8EA7-FB0D9E296CFB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B49881A6-E734-490E-8EA7-FB0D9E296CFB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -499,7 +487,6 @@ Global {3D279E2D-E011-45CF-8EA8-3D71D1300443} = {A7FC1234-95E3-4496-B5F7-4306F41E6A0E} {74FA0AA4-B5C1-4F3B-B182-277FC2D50715} = {3D279E2D-E011-45CF-8EA8-3D71D1300443} {85903170-9E52-4B53-A6E4-3F416F684FAE} = {66722747-1B61-40E4-A89B-1AC8E6D62EA9} - {8DBBAB0A-970D-4BE3-958C-8CDC92F76549} = {66722747-1B61-40E4-A89B-1AC8E6D62EA9} {B49881A6-E734-490E-8EA7-FB0D9E296CFB} = {D5277A0E-997E-453A-8CB9-4EFCC8B16A29} {025E5329-A0B1-4BA9-9203-B70B44A5F9E0} = {D5277A0E-997E-453A-8CB9-4EFCC8B16A29} {2B3CD8FF-84A6-4B53-A28B-D7A75B0AB4D7} = {66722747-1B61-40E4-A89B-1AC8E6D62EA9} diff --git a/README.md b/README.md index 7071f57e3..25396cd4a 100644 --- a/README.md +++ b/README.md @@ -176,11 +176,11 @@ Installing GCM as a standalone package on Windows will forcibly override the ver There are two flavors of standalone installation on Windows: -- User (preferred) (`gcmcoreuser-win*`): +- User (preferred) (`gcmuser-win*`): Does not require administrator rights. Will install only for the current user and updates only the current user's Git configuration. -- System (`gcmcore-win*`): +- System (`gcm-win*`): Requires administrator rights. Will install for all users on the system and update the system-wide Git configuration. diff --git a/src/windows/Installer.Windows/Installer.Windows.csproj b/src/windows/Installer.Windows/Installer.Windows.csproj index 74830d703..ce9e4b9f5 100644 --- a/src/windows/Installer.Windows/Installer.Windows.csproj +++ b/src/windows/Installer.Windows/Installer.Windows.csproj @@ -5,51 +5,29 @@ net472 false - $(PlatformOutPath)Payload.Windows\bin\$(Configuration)\net472\win-x86 false + $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\win-x86 - - - - - - all - - - - - - Microsoft400 - false - - - - - - - - - - "$(NuGetPackageRoot)Tools.InnoSetup\6.0.5\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" "$(NuGetPackageRoot)Tools.InnoSetup\6.0.5\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" + + + diff --git a/src/windows/Installer.Windows/Setup.iss b/src/windows/Installer.Windows/Setup.iss index 972f0ebb5..8dff30c84 100644 --- a/src/windows/Installer.Windows/Setup.iss +++ b/src/windows/Installer.Windows/Setup.iss @@ -18,12 +18,12 @@ #if InstallTarget == "user" #define GcmAppId "{{aa76d31d-432c-42ee-844c-bc0bc801cef3}}" #define GcmLongName "Git Credential Manager (User)" - #define GcmSetupExe "gcmcoreuser" + #define GcmSetupExe "gcmuser" #define GcmConfigureCmdArgs "" #elif InstallTarget == "system" #define GcmAppId "{{fdfae50a-1bc1-4ead-9228-1e1c275e8d12}}" #define GcmLongName "Git Credential Manager" - #define GcmSetupExe "gcmcore" + #define GcmSetupExe "gcm" #define GcmConfigureCmdArgs "--system" #else #error Installer target property 'InstallTarget' must be 'user' or 'system' diff --git a/src/windows/Installer.Windows/layout.ps1 b/src/windows/Installer.Windows/layout.ps1 new file mode 100644 index 000000000..6b43a2cb9 --- /dev/null +++ b/src/windows/Installer.Windows/layout.ps1 @@ -0,0 +1,67 @@ +# Inputs +param ([Parameter(Mandatory)] $CONFIGURATION, [Parameter(Mandatory)] $OUTPUT, $SYMBOLOUTPUT) + +Write-Output "Output: $OUTPUT" + +# Directories +$THISDIR = $pwd.path +$ROOT = (Get-Item $THISDIR).parent.parent.parent.FullName +$SRC = "$ROOT/src" +$GCM_SRC = "$SRC/shared/Git-Credential-Manager" +$BITBUCKET_UI_SRC = "$SRC/windows/Atlassian.Bitbucket.UI.Windows" +$GITHUB_UI_SRC = "$SRC/windows/GitHub.UI.Windows" +$GITLAB_UI_SRC = "$SRC/windows/GitLab.UI.Windows" + +# Perform pre-execution checks +$PAYLOAD = "$OUTPUT" +if ($SYMBOLOUTPUT) +{ + $SYMBOLS = "$SYMBOLOUTPUT" +} else { + $SYMBOLS = "$PAYLOAD.sym" +} + +# Clean up any old payload and symbols directories +if (Test-Path -Path $PAYLOAD) +{ + Write-Output "Cleaning old payload directory '$PAYLOAD'..." + Remove-Item -Recurse "$PAYLOAD" -Force +} + +if (Test-Path -Path $SYMBOLS) +{ + Write-Output "Cleaning old symbols directory '$SYMBOLS'..." + Remove-Item -Recurse "$SYMBOLS" -Force +} + +# Ensure payload and symbol directories exist +mkdir -p "$PAYLOAD","$SYMBOLS" + +# Publish core application executables +Write-Output "Publishing core application..." +dotnet publish "$GCM_SRC" ` + --framework net472 ` + --configuration "$CONFIGURATION" ` + --runtime win-x86 ` + --output "$PAYLOAD" + +Write-Output "Publishing Bitbucket UI helper..." +dotnet publish "$BITBUCKET_UI_SRC" ` + --configuration "$CONFIGURATION" ` + --output "$PAYLOAD" + +Write-Output "Publishing GitHub UI helper..." +dotnet publish "$GITHUB_UI_SRC" ` + --configuration "$CONFIGURATION" ` + --output "$PAYLOAD" + +Write-Output "Publishing GitLab UI helper..." +dotnet publish "$GITLAB_UI_SRC" ` + --configuration "$CONFIGURATION" ` + --output "$PAYLOAD" + +# Collect symbols +Write-Output "Collecting managed symbols..." +Move-Item -Path "$PAYLOAD/*.pdb" -Destination "$SYMBOLS" + +Write-Output "Layout complete." \ No newline at end of file diff --git a/src/windows/Payload.Windows/Payload.Windows.csproj b/src/windows/Payload.Windows/Payload.Windows.csproj deleted file mode 100644 index a147461ad..000000000 --- a/src/windows/Payload.Windows/Payload.Windows.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - net472 - win-x86 - false - - - - - - - - - - - - all - - - - - - Microsoft400 - false - - - - - - - - - - - - - - - - - - - - - - - From 5672a773a1a1cd57ac1f34fb6afbd7ea9c1a3a9c Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Tue, 24 May 2022 09:29:28 -0700 Subject: [PATCH 45/83] linux release: build and lay out Add step one of Linux (Debian) release process to build and lay out Debian package. Additionally, drop 'core' suffix from package name and remove no-longer-needed build-installers workflow. --- .github/workflows/build-installers.yml | 37 -------------------------- .github/workflows/release.yml | 37 +++++++++++++++++++++++++- README.md | 2 +- src/linux/Packaging.Linux/build.sh | 8 +++--- 4 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 .github/workflows/build-installers.yml diff --git a/.github/workflows/build-installers.yml b/.github/workflows/build-installers.yml deleted file mode 100644 index b2a3dc134..000000000 --- a/.github/workflows/build-installers.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build-Installers - -on: - workflow_dispatch: - push: - branches: [ main, release ] - pull_request: - branches: [ main ] - -jobs: - linux: - name: "Linux" - - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - - - name: Setup .NET - uses: actions/setup-dotnet@v2 - with: - dotnet-version: 6.0.201 - - - name: Install dependencies - run: dotnet restore --force - - - name: Build Linux Payloads - run: dotnet build -c Release src/linux/Packaging.Linux/Packaging.Linux.csproj - - - name: Upload Installers - uses: actions/upload-artifact@v3 - with: - name: Installers - path: | - out/linux/Packaging.Linux/deb/Release/*.deb - out/linux/Packaging.Linux/tar/Release/*.tar.gz diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53d175970..7bd4c8764 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -354,4 +354,39 @@ jobs: path: | signed signed-payload - src/windows/Installer.Windows/symbols \ No newline at end of file + src/windows/Installer.Windows/symbols + +# ================================ +# Linux +# ================================ + linux-build: + name: Build Linux + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. + + - name: Setup .NET + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.201 + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration=LinuxRelease + + - name: Lay out + run: | + mkdir -p linux-build/deb linux-build/tar + mv out/linux/Packaging.Linux/deb/Release/*.deb linux-build/deb + mv out/linux/Packaging.Linux/tar/Release/*.tar.gz linux-build/tar + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: linux-build + path: | + linux-build diff --git a/README.md b/README.md index 25396cd4a..6f04facba 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ To uninstall: ```shell git-credential-manager-core unconfigure -sudo dpkg -r gcmcore +sudo dpkg -r gcm ``` #### Other distributions diff --git a/src/linux/Packaging.Linux/build.sh b/src/linux/Packaging.Linux/build.sh index 20e3e4b84..a9430850d 100755 --- a/src/linux/Packaging.Linux/build.sh +++ b/src/linux/Packaging.Linux/build.sh @@ -75,12 +75,12 @@ SYMBOLOUT="$PROJ_OUT/payload.sym/$CONFIGURATION" if [ $INSTALL_FROM_SOURCE = false ]; then TAROUT="$PROJ_OUT/tar/$CONFIGURATION" - TARBALL="$TAROUT/gcmcore-linux_$ARCH.$VERSION.tar.gz" - SYMTARBALL="$TAROUT/symbols-linux_$ARCH.$VERSION.tar.gz" + TARBALL="$TAROUT/gcm-linux_$ARCH.$VERSION.tar.gz" + SYMTARBALL="$TAROUT/gcm-linux_$ARCH.$VERSION-symbols.tar.gz" DEBOUT="$PROJ_OUT/deb/$CONFIGURATION" DEBROOT="$DEBOUT/root" - DEBPKG="$DEBOUT/gcmcore-linux_$ARCH.$VERSION.deb" + DEBPKG="$DEBOUT/gcm-linux_$ARCH.$VERSION.deb" else INSTALL_LOCATION="/usr/local" fi @@ -193,7 +193,7 @@ if [ $INSTALL_FROM_SOURCE = false ]; then # https://stackoverflow.com/questions/9349616/bash-eof-in-if-statement # for details cat >"$DEBROOT/DEBIAN/control" < Date: Sat, 14 May 2022 15:18:13 -0700 Subject: [PATCH 46/83] linux release: sign and publish Add step two of Linux release process to sign and upload final installer. Additionally, remove the no-longer-needed build-signed-deb workflow. --- .github/workflows/build-signed-deb.yml | 93 -------------------------- .github/workflows/release.yml | 48 +++++++++++++ 2 files changed, 48 insertions(+), 93 deletions(-) delete mode 100644 .github/workflows/build-signed-deb.yml diff --git a/.github/workflows/build-signed-deb.yml b/.github/workflows/build-signed-deb.yml deleted file mode 100644 index f452963a0..000000000 --- a/.github/workflows/build-signed-deb.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: "Build Signed Debian Installer" - -on: - workflow_dispatch: - release: - types: [released] - -jobs: - build: - name: "Build" - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. - - - name: Setup .NET - uses: actions/setup-dotnet@v2 - with: - dotnet-version: 6.0.201 - - - name: Install dependencies - run: dotnet restore --force - - - name: Build Linux Payloads - run: dotnet build -c Release src/linux/Packaging.Linux/Packaging.Linux.csproj - - - name: Upload Installers - uses: actions/upload-artifact@v3 - with: - name: LinuxInstallers - path: | - out/linux/Packaging.Linux/deb/Release/*.deb - out/linux/Packaging.Linux/tar/Release/*.tar.gz - - sign: - name: 'Sign' - runs-on: windows-latest - needs: build - steps: - - name: setup python - uses: actions/setup-python@v3 - with: - python-version: 3.8 - - - uses: actions/checkout@v3 - - - name: 'Download Installer Artifact' - uses: actions/download-artifact@v3 - with: - name: LinuxInstallers - - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - - name: 'Install ESRP Client' - shell: pwsh - env: - AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }} - run: | - az storage blob download --subscription "$env:AZ_SUB" --account-name gitcitoolstore -c tools -n microsoft.esrpclient.1.2.47.nupkg -f esrp.zip - Expand-Archive -Path esrp.zip -DestinationPath .\esrp - - - name: Install Certs - shell: pwsh - env: - AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }} - AZ_VAULT: ${{ secrets.AZURE_VAULT }} - SSL_CERT: ${{ secrets.VAULT_SSL_CERT_NAME }} - ESRP_CERT: ${{ secrets.VAULT_ESRP_CERT_NAME }} - run: | - az keyvault secret download --subscription "$env:AZ_SUB" --vault-name "$env:AZ_VAULT" --name "$env:SSL_CERT" -f out.pfx - certutil -f -importpfx out.pfx - Remove-Item out.pfx - - az keyvault secret download --subscription "$env:AZ_SUB" --vault-name "$env:AZ_VAULT" --name "$env:ESRP_CERT" -f out.pfx - certutil -f -importpfx out.pfx - Remove-Item out.pfx - - - name: Run ESRP Client - shell: pwsh - env: - AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} - run: | - python .github/run_esrp_signing.py - - - name: Upload Installer - uses: actions/upload-artifact@v3 - with: - name: DebianInstallerSigned - path: | - Signed/*.deb \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7bd4c8764..91b03fc56 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -390,3 +390,51 @@ jobs: name: linux-build path: | linux-build + + linux-sign: + name: Sign Debian package + # ESRP service requires signing to run on Windows + runs-on: windows-latest + needs: linux-build + steps: + - uses: actions/checkout@v3 + + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: linux-build + path: artifacts + + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Set up ESRP client + shell: pwsh + env: + AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }} + AZURE_VAULT: ${{ secrets.AZURE_VAULT }} + AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }} + REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }} + run: | + .github\set_up_esrp.ps1 + + - name: Run ESRP client + shell: pwsh + env: + AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }} + # We temporarily need two AAD IDs, as we're using an SSL certificate associated + # with an older App Registration until we have the required hardware to approve + # the new certificate in SSL Admin. + AZURE_AAD_ID_SSL: ${{ secrets.AZURE_AAD_ID_SSL }} + LINUX_KEY_CODE: ${{ secrets.LINUX_KEY_CODE }} + LINUX_OP_CODE: ${{ secrets.LINUX_OPERATION_CODE }} + run: | + python .github/run_esrp_signing.py artifacts/deb $env:LINUX_KEY_CODE $env:LINUX_OP_CODE + + - name: Upload signed Debian package + uses: actions/upload-artifact@v3 + with: + name: linux-sign + path: | + signed From d4e8720164ad52b7bb61832d8d58dd69b84d20ce Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Sat, 14 May 2022 15:22:15 -0700 Subject: [PATCH 47/83] release: publish draft release to GitHub Add final job to publish artifacts as a draft release on GitHub. This uses a custom github-script because the official action for adding assets to releases has been deprecated and archived. For more information, see: https://github.com/actions/create-release --- .github/workflows/release.yml | 96 +++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91b03fc56..1a601debc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -438,3 +438,99 @@ jobs: name: linux-sign path: | signed + +# ================================ +# Publish +# ================================ + create-github-release: + name: Publish GitHub draft release + runs-on: ubuntu-latest + needs: [ osx-sign, win-sign, linux-sign ] + steps: + - name: Check out repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. + + - name: Set up dotnet + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.201 + + # Install Nerdbank.GitVersioning + - uses: dotnet/nbgv@master + with: + setCommonVars: true + + - name: Download artifacts + uses: actions/download-artifact@v3 + + - name: Archive macOS payload and symbols + run: | + mkdir osx-payload-and-symbols + tar -C osx-payload-sign -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple.tar.gz . + tar -C tmp.osx-build/symbols -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple-symbols.tar.gz . + + - name: Archive Windows payload and symbols + shell: pwsh + run: | + mkdir win-x86-payload-and-symbols + Compress-Archive -Path win-sign/signed-payload/* win-x86-payload-and-symbols/gcm-win-x86-$env:GitBuildVersionSimple.zip + Compress-Archive -Path win-sign/src/windows/Installer.Windows/symbols/* win-x86-payload-and-symbols/gcm-win-x86-$env:GitBuildVersionSimple-symbols.zip + + - uses: actions/github-script@v4 + with: + script: | + const fs = require('fs'); + const path = require('path'); + const version = process.env.GitBuildVersionSimple + + var releaseMetadata = { + owner: context.repo.owner, + repo: context.repo.repo + }; + + // Create the release + var tagName = `v${version}`; + var createdRelease = await github.repos.createRelease({ + ...releaseMetadata, + draft: true, + tag_name: tagName, + name: `GCM ${version}` + }); + releaseMetadata.release_id = createdRelease.data.id; + + // Uploads contents of directory to the release created above + async function uploadDirectoryToRelease(directory, includeExtensions=[]) { + return fs.promises.readdir(directory) + .then(async(files) => Promise.all( + files.filter(file => { + return includeExtensions.length==0 || includeExtensions.includes(path.extname(file).toLowerCase()); + }) + .map(async (file) => { + var filePath = path.join(directory, file); + github.repos.uploadReleaseAsset({ + ...releaseMetadata, + name: file, + headers: { + "content-length": (await fs.promises.stat(filePath)).size + }, + data: fs.createReadStream(filePath) + }); + })) + ); + } + + await Promise.all([ + // Upload Windows artifacts + uploadDirectoryToRelease('win-sign/signed'), + uploadDirectoryToRelease('win-x86-payload-and-symbols'), + + // Upload macOS artifacts + uploadDirectoryToRelease('osx-sign'), + uploadDirectoryToRelease('osx-payload-and-symbols'), + + // Upload Linux artifacts + uploadDirectoryToRelease('linux-sign'), + uploadDirectoryToRelease('linux-build/tar') + ]); From e59b7d81569db5741a9500a8ee1e34fafd142423 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Fri, 13 May 2022 20:07:24 -0700 Subject: [PATCH 48/83] release: remove .azurepipelines directory Remove the no-longer-needed Azure Pipelines release workflows. --- .azure-pipelines/continuous-integration.yml | 32 --------- .azure-pipelines/pull-request.yml | 33 --------- .azure-pipelines/release.yml | 69 ------------------- .azure-pipelines/templates/linux/compile.yml | 22 ------ .../templates/linux/pack.unsigned.yml | 12 ---- .azure-pipelines/templates/osx/compile.yml | 22 ------ .../osx/pack.signed/step1-layout.yml | 15 ---- .../osx/pack.signed/step2-signpayload.yml | 48 ------------- .../templates/osx/pack.signed/step3-pack.yml | 31 --------- .../osx/pack.signed/step4-signpack.yml | 42 ----------- .../templates/osx/pack.signed/step5-dist.yml | 63 ----------------- .../templates/osx/pack.unsigned.yml | 34 --------- .../templates/windows/compile.signed.yml | 46 ------------- .../templates/windows/compile.yml | 29 -------- .azure-pipelines/templates/windows/pack.yml | 45 ------------ 15 files changed, 543 deletions(-) delete mode 100644 .azure-pipelines/continuous-integration.yml delete mode 100644 .azure-pipelines/pull-request.yml delete mode 100644 .azure-pipelines/release.yml delete mode 100644 .azure-pipelines/templates/linux/compile.yml delete mode 100644 .azure-pipelines/templates/linux/pack.unsigned.yml delete mode 100644 .azure-pipelines/templates/osx/compile.yml delete mode 100644 .azure-pipelines/templates/osx/pack.signed/step1-layout.yml delete mode 100644 .azure-pipelines/templates/osx/pack.signed/step2-signpayload.yml delete mode 100644 .azure-pipelines/templates/osx/pack.signed/step3-pack.yml delete mode 100644 .azure-pipelines/templates/osx/pack.signed/step4-signpack.yml delete mode 100644 .azure-pipelines/templates/osx/pack.signed/step5-dist.yml delete mode 100644 .azure-pipelines/templates/osx/pack.unsigned.yml delete mode 100644 .azure-pipelines/templates/windows/compile.signed.yml delete mode 100644 .azure-pipelines/templates/windows/compile.yml delete mode 100644 .azure-pipelines/templates/windows/pack.yml diff --git a/.azure-pipelines/continuous-integration.yml b/.azure-pipelines/continuous-integration.yml deleted file mode 100644 index cd9b304a0..000000000 --- a/.azure-pipelines/continuous-integration.yml +++ /dev/null @@ -1,32 +0,0 @@ -trigger: - - main - -variables: - configuration: Release - winImage: vs2017-win2016 - osxImage: macos-latest - -jobs: -- job: windows - displayName: Windows - pool: - vmImage: $(winImage) - steps: - - template: templates/windows/compile.yml - - template: templates/windows/pack.yml - -- job: osx - displayName: macOS - pool: - vmImage: $(osxImage) - steps: - - template: templates/osx/compile.yml - - template: templates/osx/pack.unsigned.yml - -- job: ubuntu1804_x86_64 - displayName: Ubuntu 18.04 LTS x86_64 - pool: - vmImage: ubuntu-18.04 - steps: - - template: templates/linux/compile.yml - - template: templates/linux/pack.unsigned.yml diff --git a/.azure-pipelines/pull-request.yml b/.azure-pipelines/pull-request.yml deleted file mode 100644 index e24d3d6e1..000000000 --- a/.azure-pipelines/pull-request.yml +++ /dev/null @@ -1,33 +0,0 @@ -pr: - - main - - release - -variables: - configuration: Release - winImage: vs2017-win2016 - osxImage: macos-latest - -jobs: -- job: windows - displayName: Windows - pool: - vmImage: $(winImage) - steps: - - template: templates/windows/compile.yml - - template: templates/windows/pack.yml - -- job: osx - displayName: macOS - pool: - vmImage: $(osxImage) - steps: - - template: templates/osx/compile.yml - - template: templates/osx/pack.unsigned.yml - -- job: ubuntu1804_x86_64 - displayName: Ubuntu 18.04 LTS x86_64 - pool: - vmImage: ubuntu-18.04 - steps: - - template: templates/linux/compile.yml - - template: templates/linux/pack.unsigned.yml diff --git a/.azure-pipelines/release.yml b/.azure-pipelines/release.yml deleted file mode 100644 index 934942932..000000000 --- a/.azure-pipelines/release.yml +++ /dev/null @@ -1,69 +0,0 @@ -trigger: - - release - -variables: - configuration: Release - signPool: MSEngSS-MicroBuild2019-1ES - winImage: vs2017-win2016 - osxImage: macos-latest - -jobs: -- job: windows - displayName: Windows - pool: - name: $(signPool) - steps: - - template: templates/windows/compile.signed.yml - - template: templates/windows/pack.yml - -- job: osx_step1 - displayName: macOS (Build & Layout) - pool: - vmImage: $(osxImage) - steps: - - template: templates/osx/compile.yml - - template: templates/osx/pack.signed/step1-layout.yml - -- job: osx_step2 - displayName: macOS (Sign payload) - dependsOn: osx_step1 - condition: succeeded() - pool: - name: $(signPool) - steps: - - template: templates/osx/pack.signed/step2-signpayload.yml - -- job: osx_step3 - displayName: macOS (Pack) - dependsOn: osx_step2 - condition: succeeded() - pool: - vmImage: $(osxImage) - steps: - - template: templates/osx/pack.signed/step3-pack.yml - -- job: osx_step4 - displayName: macOS (Sign package) - dependsOn: osx_step3 - condition: succeeded() - pool: - name: $(signPool) - steps: - - template: templates/osx/pack.signed/step4-signpack.yml - -- job: osx_step5 - displayName: macOS (Prepare for distribution) - dependsOn: osx_step4 - condition: succeeded() - pool: - vmImage: $(osxImage) - steps: - - template: templates/osx/pack.signed/step5-dist.yml - -- job: ubuntu1804_x86_64 - displayName: Ubuntu 18.04 LTS x86_64 - pool: - vmImage: ubuntu-18.04 - steps: - - template: templates/linux/compile.yml - - template: templates/linux/pack.unsigned.yml diff --git a/.azure-pipelines/templates/linux/compile.yml b/.azure-pipelines/templates/linux/compile.yml deleted file mode 100644 index a45ab6b30..000000000 --- a/.azure-pipelines/templates/linux/compile.yml +++ /dev/null @@ -1,22 +0,0 @@ -steps: - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - task: DotNetCoreCLI@2 - displayName: Compile common code - inputs: - command: build - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Linux$(configuration)' - - - task: DotNetCoreCLI@2 - displayName: Run common unit tests - inputs: - command: test - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Linux$(configuration)' - publishTestResults: true - testRunTitle: 'Unit tests (Linux)' diff --git a/.azure-pipelines/templates/linux/pack.unsigned.yml b/.azure-pipelines/templates/linux/pack.unsigned.yml deleted file mode 100644 index 08f9ccffd..000000000 --- a/.azure-pipelines/templates/linux/pack.unsigned.yml +++ /dev/null @@ -1,12 +0,0 @@ -steps: - - script: | - mkdir -p "$(Build.StagingDirectory)/publish/" - cp "out/linux/Packaging.Linux/tar/$(configuration)/"*.tar.gz "$(Build.StagingDirectory)/publish/" - cp "out/linux/Packaging.Linux/deb/$(configuration)/"*.deb "$(Build.StagingDirectory)/publish/" - displayName: Prepare final build artifacts - - - task: PublishPipelineArtifact@0 - displayName: Publish unsigned installer artifacts - inputs: - artifactName: 'Installer.Linux.Unsigned' - targetPath: '$(Build.StagingDirectory)/publish' diff --git a/.azure-pipelines/templates/osx/compile.yml b/.azure-pipelines/templates/osx/compile.yml deleted file mode 100644 index d480a9213..000000000 --- a/.azure-pipelines/templates/osx/compile.yml +++ /dev/null @@ -1,22 +0,0 @@ -steps: - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - task: DotNetCoreCLI@2 - displayName: Compile common code and macOS Helpers - inputs: - command: build - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Mac$(configuration)' - - - task: DotNetCoreCLI@2 - displayName: Run common unit tests - inputs: - command: test - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Mac$(configuration)' - publishTestResults: true - testRunTitle: 'Unit tests (macOS)' diff --git a/.azure-pipelines/templates/osx/pack.signed/step1-layout.yml b/.azure-pipelines/templates/osx/pack.signed/step1-layout.yml deleted file mode 100644 index cb93812b6..000000000 --- a/.azure-pipelines/templates/osx/pack.signed/step1-layout.yml +++ /dev/null @@ -1,15 +0,0 @@ -steps: - - script: src/osx/Installer.Mac/layout.sh --configuration='$(configuration)' --output='$(Build.StagingDirectory)/payload' --symbol-output='$(Build.StagingDirectory)/symbols' - displayName: Layout installer payload - - - task: PublishPipelineArtifact@0 - displayName: Upload unsigned payload - inputs: - artifactName: 'tmp.macpayload_unsigned' - targetPath: '$(Build.StagingDirectory)/payload' - - - task: PublishPipelineArtifact@0 - displayName: Upload symbols - inputs: - artifactName: 'tmp.macsymbols' - targetPath: '$(Build.StagingDirectory)/symbols' diff --git a/.azure-pipelines/templates/osx/pack.signed/step2-signpayload.yml b/.azure-pipelines/templates/osx/pack.signed/step2-signpayload.yml deleted file mode 100644 index 01439a347..000000000 --- a/.azure-pipelines/templates/osx/pack.signed/step2-signpayload.yml +++ /dev/null @@ -1,48 +0,0 @@ -steps: - - task: NuGetAuthenticate@0 - displayName: Authenticate to MicroBuild NuGet feed - inputs: - nuGetServiceConnections: 'MicroBuild Toolset Nuget Feed (Read)' - - - task: ms-vseng.MicroBuildTasks.30666190-6959-11e5-9f96-f56098202fef.MicroBuildSigningPlugin@3 - displayName: Install signing plugin - inputs: - signType: '$(SignType)' - - - task: DownloadPipelineArtifact@1 - displayName: Download unsigned payload - inputs: - buildType: 'current' - artifactName: 'tmp.macpayload_unsigned' - downloadPath: '$(Build.StagingDirectory)\payload' - - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - task: NuGetToolInstaller@0 - displayName: Install NuGet tool >=4.3.0 - inputs: - versionSpec: '>=4.3.0' - - # Must use the NuGet & MSBuild toolchain here rather than `dotnet` - # because the signing tasks target the netfx MSBuild runtime only. - - task: NuGetCommand@2 - displayName: Restore MicroBuild packages - inputs: - command: restore - restoreSolution: 'src\osx\SignFiles.Mac\SignFiles.Mac.csproj' - - - task: MSBuild@1 - displayName: Sign payload - inputs: - solution: 'src\osx\SignFiles.Mac\SignFiles.Mac.csproj' - msbuildArguments: '/p:RootDir="$(Build.StagingDirectory)\payload"' - - - task: PublishPipelineArtifact@0 - displayName: Upload signed payload - inputs: - artifactName: 'tmp.macpayload_signed' - targetPath: '$(Build.StagingDirectory)\payload' diff --git a/.azure-pipelines/templates/osx/pack.signed/step3-pack.yml b/.azure-pipelines/templates/osx/pack.signed/step3-pack.yml deleted file mode 100644 index 897aca172..000000000 --- a/.azure-pipelines/templates/osx/pack.signed/step3-pack.yml +++ /dev/null @@ -1,31 +0,0 @@ -steps: - - task: DownloadPipelineArtifact@1 - displayName: Download signed payload - inputs: - buildType: 'current' - artifactName: 'tmp.macpayload_signed' - downloadPath: '$(Build.StagingDirectory)/payload' - - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - script: dotnet tool install --global nbgv - displayName: Install Nerdbank.GitVersioning tool - - - script: nbgv cloud --common-vars - displayName: Set version variables - - - script: src/osx/Installer.Mac/pack.sh --payload='$(Build.StagingDirectory)/payload' --version='$(GitBuildVersionSimple)' --output='$(Build.StagingDirectory)/components/com.microsoft.gitcredentialmanager.component.pkg' - displayName: Create component package - - - script: src/osx/Installer.Mac/dist.sh --package-path='$(Build.StagingDirectory)/components' --version='$(GitBuildVersionSimple)' --output='$(Build.StagingDirectory)/pkg/gcmcore-osx-$(GitBuildVersionSimple).pkg' || exit 1 - displayName: Create product archive - - - task: PublishPipelineArtifact@0 - displayName: Upload unsigned package - inputs: - artifactName: 'tmp.macinstaller_unsigned' - targetPath: '$(Build.StagingDirectory)/pkg/gcmcore-osx-$(GitBuildVersionSimple).pkg' diff --git a/.azure-pipelines/templates/osx/pack.signed/step4-signpack.yml b/.azure-pipelines/templates/osx/pack.signed/step4-signpack.yml deleted file mode 100644 index 0a7e05d6d..000000000 --- a/.azure-pipelines/templates/osx/pack.signed/step4-signpack.yml +++ /dev/null @@ -1,42 +0,0 @@ -steps: - - task: NuGetAuthenticate@0 - displayName: Authenticate to MicroBuild NuGet feed - inputs: - nuGetServiceConnections: 'MicroBuild Toolset Nuget Feed (Read)' - - - task: ms-vseng.MicroBuildTasks.30666190-6959-11e5-9f96-f56098202fef.MicroBuildSigningPlugin@3 - displayName: Install signing plugin - inputs: - signType: '$(SignType)' - - - task: DownloadPipelineArtifact@1 - displayName: Download unsigned package - inputs: - buildType: 'current' - artifactName: 'tmp.macinstaller_unsigned' - downloadPath: '$(Build.StagingDirectory)\pkg' - - - powershell: | - $dir="$(Build.StagingDirectory)\pkg" - Compress-Archive -Path $dir\*.pkg $dir\gcmcorepkg.zip - Remove-Item $dir\*.pkg - displayName: 'Zip package file for signing' - - - task: ms-vseng.MicroBuildTasks.7973a23b-33e3-4b00-a7d9-c06d90f8297f.MicroBuildSignMacFiles@1 - displayName: Sign package - inputs: - SigningTarget: '$(Build.StagingDirectory)\pkg\gcmcorepkg.zip' - SigningCert: 8003 - condition: and(succeeded(), ne(variables['SignType'], 'test')) - - - powershell: | - $dir="$(Build.StagingDirectory)\pkg" - Expand-Archive -LiteralPath $dir\gcmcorepkg.zip -DestinationPath $dir -Force - Remove-Item $dir\gcmcorepkg.zip -Force - displayName: 'Unzip signed package file' - - - task: PublishPipelineArtifact@0 - displayName: Upload signed installer - inputs: - artifactName: 'tmp.macinstaller_signed' - targetPath: '$(Build.StagingDirectory)\pkg' diff --git a/.azure-pipelines/templates/osx/pack.signed/step5-dist.yml b/.azure-pipelines/templates/osx/pack.signed/step5-dist.yml deleted file mode 100644 index 31a4cbcc7..000000000 --- a/.azure-pipelines/templates/osx/pack.signed/step5-dist.yml +++ /dev/null @@ -1,63 +0,0 @@ -steps: - - task: DownloadPipelineArtifact@1 - displayName: Download signed installer - inputs: - buildType: 'current' - artifactName: 'tmp.macinstaller_signed' - downloadPath: '$(Build.StagingDirectory)/pkg' - - - task: DownloadPipelineArtifact@1 - displayName: Download signed payload - inputs: - buildType: 'current' - artifactName: 'tmp.macpayload_signed' - downloadPath: '$(Build.StagingDirectory)/payload' - - - task: DownloadPipelineArtifact@1 - displayName: Download symbols - inputs: - buildType: 'current' - artifactName: 'tmp.macsymbols' - downloadPath: '$(Build.StagingDirectory)/symbols' - - # Skip notarization until we can preserve the hardened runtime bit and sign the .NET runtime bits - # Tracked: https://github.com/microsoft/Git-Credential-Manager-Core/issues/108 - #- script: src/osx/SignFiles.Mac/notarize-pkg.sh -id "$(AppleId)" -p "$(AppleIdPassword)" -pkg "$(Build.StagingDirectory)"/pkg/*.pkg - # displayName: Notarize and staple installer package - - - script: | - mkdir -p "$(Build.StagingDirectory)/publish/payload" "$(Build.StagingDirectory)/publish/payload.sym" - cp -f "$(Build.StagingDirectory)"/pkg/*.pkg "$(Build.StagingDirectory)/publish/" - cp -Rf "$(Build.StagingDirectory)/payload/" "$(Build.StagingDirectory)/publish/payload/" - cp -Rf "$(Build.StagingDirectory)/symbols/" "$(Build.StagingDirectory)/publish/payload.sym/" - displayName: Prepare final build artifacts - - - script: dotnet tool install --global nbgv - displayName: Install Nerdbank.GitVersioning tool - - - script: nbgv cloud --common-vars - displayName: Set version variables - - - task: ArchiveFiles@2 - displayName: Create payload archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)/publish/payload/' - includeRootFolder: false - archiveType: 'tar' - archiveFile: '$(Build.StagingDirectory)/publish/gcmcore-osx-$(GitBuildVersionSimple).tar.gz' - replaceExistingArchive: true - - - task: ArchiveFiles@2 - displayName: Create symbol archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)/publish/payload.sym/' - includeRootFolder: false - archiveType: 'tar' - archiveFile: '$(Build.StagingDirectory)/publish/symbols-osx.tar.gz' - replaceExistingArchive: true - - - task: PublishPipelineArtifact@0 - displayName: Publish signed installer artifacts - inputs: - artifactName: 'Installer.Mac.Signed' - targetPath: '$(Build.StagingDirectory)/publish' diff --git a/.azure-pipelines/templates/osx/pack.unsigned.yml b/.azure-pipelines/templates/osx/pack.unsigned.yml deleted file mode 100644 index e225d31ef..000000000 --- a/.azure-pipelines/templates/osx/pack.unsigned.yml +++ /dev/null @@ -1,34 +0,0 @@ -steps: - - script: | - cp -R "out/osx/Installer.Mac/pkg/$(configuration)" "$(Build.StagingDirectory)/publish/" - displayName: Prepare final build artifacts - - - script: dotnet tool install --global nbgv - displayName: Install Nerdbank.GitVersioning tool - - - script: nbgv cloud --common-vars - displayName: Set version variables - - - task: ArchiveFiles@2 - displayName: Create payload archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)/publish/payload' - includeRootFolder: false - archiveType: 'tar' - archiveFile: '$(Build.StagingDirectory)/publish/gcmcore-osx-$(GitBuildVersionSimple).tar.gz' - replaceExistingArchive: true - - - task: ArchiveFiles@2 - displayName: Create symbol archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)/publish/payload.sym/' - includeRootFolder: false - archiveType: 'tar' - archiveFile: '$(Build.StagingDirectory)/publish/symbols-osx.tar.gz' - replaceExistingArchive: true - - - task: PublishPipelineArtifact@0 - displayName: Publish unsigned installer artifacts - inputs: - artifactName: 'Installer.Mac.Unsigned' - targetPath: '$(Build.StagingDirectory)/publish' diff --git a/.azure-pipelines/templates/windows/compile.signed.yml b/.azure-pipelines/templates/windows/compile.signed.yml deleted file mode 100644 index ab2afefaf..000000000 --- a/.azure-pipelines/templates/windows/compile.signed.yml +++ /dev/null @@ -1,46 +0,0 @@ -steps: - - task: NuGetAuthenticate@0 - displayName: Authenticate to MicroBuild NuGet feed - inputs: - nuGetServiceConnections: 'MicroBuild Toolset Nuget Feed (Read)' - - - task: ms-vseng.MicroBuildTasks.30666190-6959-11e5-9f96-f56098202fef.MicroBuildSigningPlugin@3 - displayName: Install signing plugin - condition: and(succeeded(), eq(variables['SignType'], 'real')) - inputs: - signType: '$(SignType)' - - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - task: NuGetToolInstaller@0 - displayName: Install NuGet tool >=4.3.0 - inputs: - versionSpec: '>=4.3.0' - - # Must use the NuGet & MSBuild toolchain here rather than `dotnet` - # because the signing tasks target the netfx MSBuild runtime only. - - task: NuGetCommand@2 - displayName: Restore packages - inputs: - command: restore - restoreSolution: 'Git-Credential-Manager.sln' - configuration: 'Windows$(configuration)' - - - task: MSBuild@1 - displayName: Compile common code and Windows helpers - inputs: - solution: 'Git-Credential-Manager.sln' - configuration: 'Windows$(configuration)' - - - task: VSTest@2 - displayName: Run common unit tests - inputs: - testAssemblyVer2: | - out\shared\*.Tests\bin\**\*.Tests.dll - configuration: 'Windows$(configuration)' - otherConsoleOptions: '/Framework:.NETCoreApp,Version=2.1' - testRunTitle: 'Unit tests (Windows)' diff --git a/.azure-pipelines/templates/windows/compile.yml b/.azure-pipelines/templates/windows/compile.yml deleted file mode 100644 index 48d664869..000000000 --- a/.azure-pipelines/templates/windows/compile.yml +++ /dev/null @@ -1,29 +0,0 @@ -steps: - - task: UseDotNet@2 - displayName: Use .NET SDK 6.0.201 - inputs: - packageType: sdk - version: 6.0.201 - - - task: DotNetCoreCLI@2 - displayName: Restore packages - inputs: - command: restore - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Windows$(configuration)' - - - task: DotNetCoreCLI@2 - displayName: Compile common code and Windows Helpers - inputs: - command: build - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Windows$(configuration)' - - - task: DotNetCoreCLI@2 - displayName: Run common unit tests - inputs: - command: test - projects: 'Git-Credential-Manager.sln' - arguments: '--configuration=Mac$(configuration)' - publishTestResults: true - testRunTitle: 'Unit tests (Windows)' diff --git a/.azure-pipelines/templates/windows/pack.yml b/.azure-pipelines/templates/windows/pack.yml deleted file mode 100644 index c6e6fde63..000000000 --- a/.azure-pipelines/templates/windows/pack.yml +++ /dev/null @@ -1,45 +0,0 @@ -steps: - - script: dotnet tool install --tool-path .tools nbgv - displayName: Install Nerdbank.GitVersioning tool - - - script: .tools\nbgv cloud --common-vars - displayName: Set version variables - - - script: | - xcopy "out\windows\Installer.Windows\bin\$(configuration)\net472" "$(Build.StagingDirectory)\publish\" - xcopy "out\windows\Payload.Windows\bin\$(configuration)\net472\win-x86" "$(Build.StagingDirectory)\publish\payload\" - mkdir "$(Build.StagingDirectory)\publish\payload.sym\" - move "$(Build.StagingDirectory)\publish\payload\*.pdb" "$(Build.StagingDirectory)\publish\payload.sym\" - displayName: Prepare final build artifacts - - - task: ArchiveFiles@2 - displayName: Create payload archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)\publish\payload\' - includeRootFolder: false - archiveType: 'zip' - archiveFile: '$(Build.StagingDirectory)\publish\gcmcore-win-x86-$(GitBuildVersionSimple).zip' - replaceExistingArchive: true - - - task: ArchiveFiles@2 - displayName: Create symbol archive - inputs: - rootFolderOrFile: '$(Build.StagingDirectory)\publish\payload.sym\' - includeRootFolder: false - archiveType: 'zip' - archiveFile: '$(Build.StagingDirectory)\publish\symbols-win-x86.zip' - replaceExistingArchive: true - - - task: PublishPipelineArtifact@0 - displayName: Publish unsigned installer artifacts - condition: and(succeeded(), ne(variables['SignType'], 'real')) - inputs: - artifactName: 'Installer.Windows.Unsigned' - targetPath: '$(Build.StagingDirectory)\publish' - - - task: PublishPipelineArtifact@0 - displayName: Publish signed installer artifacts - condition: and(succeeded(), eq(variables['SignType'], 'real')) - inputs: - artifactName: 'Installer.Windows.Signed' - targetPath: '$(Build.StagingDirectory)\publish' From 86a1ad5c7af88ea5118e19a837b2d2067b84f676 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 May 2022 20:31:20 +0000 Subject: [PATCH 49/83] build(deps): bump actions/github-script from 4 to 6 Bumps [actions/github-script](https://github.com/actions/github-script) from 4 to 6. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1a601debc..c5e8a4144 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -478,7 +478,7 @@ jobs: Compress-Archive -Path win-sign/signed-payload/* win-x86-payload-and-symbols/gcm-win-x86-$env:GitBuildVersionSimple.zip Compress-Archive -Path win-sign/src/windows/Installer.Windows/symbols/* win-x86-payload-and-symbols/gcm-win-x86-$env:GitBuildVersionSimple-symbols.zip - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 with: script: | const fs = require('fs'); From 5617e32b84f404100bcb97620119019fe53a3a99 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Fri, 27 May 2022 13:38:45 -0700 Subject: [PATCH 50/83] fixup! fixup! Add install from source instructions --- docs/linux-fromsrc-uninstall.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/linux-fromsrc-uninstall.md b/docs/linux-fromsrc-uninstall.md index 79c959932..878528804 100644 --- a/docs/linux-fromsrc-uninstall.md +++ b/docs/linux-fromsrc-uninstall.md @@ -2,7 +2,7 @@ These instructions will guide you in removing GCM after running the [install from source script](../src/linux/Packaging.Linux/install-from-source.sh) on your Linux distribution. -:siren: PROCEED WITH CAUTION :siren: +:rotating_light: PROCEED WITH CAUTION :rotating_light: For completeness, we provide uninstall instructions for _the GCM application, the GCM repo, and the maximum number of dependencies*_ for all distributions. This repo and these dependencies may or may not have already been present on your system when you ran the install from source script, and uninstalling them could impact other programs and/or your normal workflows. Please keep this in mind when following the instructions below. From bb94c4f1be1ed579185a90b5b1e7fde9323b07dc Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 30 May 2022 12:05:36 +0100 Subject: [PATCH 51/83] bitbucket: add unit test for GetCredAsync helper cmdline Add unit tests for the BitbucketAuthentication command line for UI helpers. --- .../BitbucketAuthenticationTest.cs | 112 ++++++++++++++++++ .../BitbucketAuthentication.cs | 2 +- .../Atlassian.Bitbucket/InternalsVisibleTo.cs | 3 + .../Core/Authentication/AuthenticationBase.cs | 2 +- src/shared/Core/InternalsVisibleTo.cs | 1 + 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/shared/Atlassian.Bitbucket/InternalsVisibleTo.cs diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs index 708d1205a..0606c8111 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs @@ -1,6 +1,10 @@ using System; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; +using GitCredentialManager; using GitCredentialManager.Tests.Objects; +using Moq; using Xunit; namespace Atlassian.Bitbucket.Tests @@ -118,5 +122,113 @@ public async Task BitbucketAuthentication_ShowOAuthRequiredPromptAsync_SucceedsA Assert.Equal($"Your account has two-factor authentication enabled.{Environment.NewLine}" + $"To continue you must complete authentication in your web browser.{Environment.NewLine}", context.Terminal.Messages[0].Item1); } + + [Fact] + public async Task BitbucketAuthentication_GetCredentialsAsync_AllModes_NoUser_BBCloud_HelperCmdLine() + { + var targetUri = new Uri("https://bitbucket.org"); + + var helperPath = "/usr/bin/test-helper"; + var expectedUserName = "jsquire"; + var expectedPassword = "password"; + var resultDict = new Dictionary + { + ["username"] = expectedUserName, + ["password"] = expectedPassword + }; + + string expectedArgs = $"userpass --show-oauth"; + + var context = new TestCommandContext(); + context.SessionManager.IsDesktopSession = true; // Enable OAuth and UI helper selection + + var authMock = new Mock(context) { CallBase = true }; + authMock.Setup(x => x.TryFindHelperExecutablePath(out helperPath)) + .Returns(true); + authMock.Setup(x => x.InvokeHelperAsync(It.IsAny(), It.IsAny(), null, CancellationToken.None)) + .ReturnsAsync(resultDict); + + BitbucketAuthentication auth = authMock.Object; + CredentialsPromptResult result = await auth.GetCredentialsAsync(targetUri, null, AuthenticationModes.All); + + Assert.Equal(AuthenticationModes.Basic, result.AuthenticationMode); + Assert.Equal(result.Credential.Account, expectedUserName); + Assert.Equal(result.Credential.Password, expectedPassword); + + authMock.Verify(x => x.InvokeHelperAsync(helperPath, expectedArgs, null, CancellationToken.None), + Times.Once); + } + + [Fact] + public async Task BitbucketAuthentication_GetCredentialsAsync_BasicOnly_User_BBCloud_HelperCmdLine() + { + var targetUri = new Uri("https://bitbucket.org"); + + var helperPath = "/usr/bin/test-helper"; + var expectedUserName = "jsquire"; + var expectedPassword = "password"; + var resultDict = new Dictionary + { + ["username"] = expectedUserName, + ["password"] = expectedPassword + }; + + string expectedArgs = $"userpass --username {expectedUserName}"; + + var context = new TestCommandContext(); + context.SessionManager.IsDesktopSession = true; // Enable UI helper selection + + var authMock = new Mock(context) { CallBase = true }; + authMock.Setup(x => x.TryFindHelperExecutablePath(out helperPath)) + .Returns(true); + authMock.Setup(x => x.InvokeHelperAsync(It.IsAny(), It.IsAny(), null, CancellationToken.None)) + .ReturnsAsync(resultDict); + + BitbucketAuthentication auth = authMock.Object; + CredentialsPromptResult result = await auth.GetCredentialsAsync(targetUri, expectedUserName, AuthenticationModes.Basic); + + Assert.Equal(AuthenticationModes.Basic, result.AuthenticationMode); + Assert.Equal(result.Credential.Account, expectedUserName); + Assert.Equal(result.Credential.Password, expectedPassword); + + authMock.Verify(x => x.InvokeHelperAsync(helperPath, expectedArgs, null, CancellationToken.None), + Times.Once); + } + + [Fact] + public async Task BitbucketAuthentication_GetCredentialsAsync_AllModes_NoUser_BBServerDC_HelperCmdLine() + { + var targetUri = new Uri("https://example.com/bitbucket"); + + var helperPath = "/usr/bin/test-helper"; + var expectedUserName = "jsquire"; + var expectedPassword = "password"; + var resultDict = new Dictionary + { + ["username"] = expectedUserName, + ["password"] = expectedPassword + }; + + string expectedArgs = $"userpass --url {targetUri} --show-oauth"; + + var context = new TestCommandContext(); + context.SessionManager.IsDesktopSession = true; // Enable OAuth and UI helper selection + + var authMock = new Mock(context) { CallBase = true }; + authMock.Setup(x => x.TryFindHelperExecutablePath(out helperPath)) + .Returns(true); + authMock.Setup(x => x.InvokeHelperAsync(It.IsAny(), It.IsAny(), null, CancellationToken.None)) + .ReturnsAsync(resultDict); + + BitbucketAuthentication auth = authMock.Object; + CredentialsPromptResult result = await auth.GetCredentialsAsync(targetUri, null, AuthenticationModes.All); + + Assert.Equal(AuthenticationModes.Basic, result.AuthenticationMode); + Assert.Equal(result.Credential.Account, expectedUserName); + Assert.Equal(result.Credential.Password, expectedPassword); + + authMock.Verify(x => x.InvokeHelperAsync(helperPath, expectedArgs, null, CancellationToken.None), + Times.Once); + } } } diff --git a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs index 25a10647a..9d3ff0d54 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs @@ -245,7 +245,7 @@ public async Task RefreshOAuthCredentialsAsync(string refresh #region Private Methods - private bool TryFindHelperExecutablePath(out string path) + protected internal virtual bool TryFindHelperExecutablePath(out string path) { return TryFindHelperExecutablePath( BitbucketConstants.EnvironmentVariables.AuthenticationHelper, diff --git a/src/shared/Atlassian.Bitbucket/InternalsVisibleTo.cs b/src/shared/Atlassian.Bitbucket/InternalsVisibleTo.cs new file mode 100644 index 000000000..11a8ae4a8 --- /dev/null +++ b/src/shared/Atlassian.Bitbucket/InternalsVisibleTo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Atlassian.Bitbucket.Tests")] diff --git a/src/shared/Core/Authentication/AuthenticationBase.cs b/src/shared/Core/Authentication/AuthenticationBase.cs index 467a9fffb..fdbe75a11 100644 --- a/src/shared/Core/Authentication/AuthenticationBase.cs +++ b/src/shared/Core/Authentication/AuthenticationBase.cs @@ -25,7 +25,7 @@ protected Task> InvokeHelperAsync(string path, strin return InvokeHelperAsync(path, args, null, CancellationToken.None); } - internal protected virtual async Task> InvokeHelperAsync(string path, string args, + protected internal virtual async Task> InvokeHelperAsync(string path, string args, IDictionary standardInput, CancellationToken ct) { var procStartInfo = new ProcessStartInfo(path) diff --git a/src/shared/Core/InternalsVisibleTo.cs b/src/shared/Core/InternalsVisibleTo.cs index 3b65c60e6..e0a0c782f 100644 --- a/src/shared/Core/InternalsVisibleTo.cs +++ b/src/shared/Core/InternalsVisibleTo.cs @@ -2,3 +2,4 @@ [assembly: InternalsVisibleTo("Core.Tests")] [assembly: InternalsVisibleTo("GitHub.Tests")] +[assembly: InternalsVisibleTo("Atlassian.Bitbucket.Tests")] From b9c3f410a16ea09d9af8b4cb03c2cd2eff1723de Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 30 May 2022 12:12:53 +0100 Subject: [PATCH 52/83] bitbucket: add tests for IsBitbucketOrg method Add test for Bitbucket Cloud hostname detection method. --- .../BitbucketHostProviderTest.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 6afc52f45..800b58d06 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -21,6 +21,58 @@ public class BitbucketHostProviderTest private Mock bitbucketAuthentication = new Mock(MockBehavior.Strict); private Mock bitbucketApi = new Mock(MockBehavior.Strict); + [Theory] + [InlineData(null, false)] + [InlineData("", false)] + [InlineData(" ", false)] + [InlineData("bitbucket.org", true)] + [InlineData("BITBUCKET.ORG", true)] + [InlineData("BiTbUcKeT.OrG", true)] + [InlineData("bitbucket.example.com", false)] + [InlineData("bitbucket.example.org", false)] + [InlineData("bitbucket.org.com", false)] + [InlineData("bitbucket.org.org", false)] + public void BitbucketHostProvider_IsBitbucketOrg_StringHost(string str, bool expected) + { + bool actual = BitbucketHostProvider.IsBitbucketOrg(str); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData("http://bitbucket.org", true)] + [InlineData("https://bitbucket.org", true)] + [InlineData("http://bitbucket.org/path", true)] + [InlineData("https://bitbucket.org/path", true)] + [InlineData("http://BITBUCKET.ORG", true)] + [InlineData("https://BITBUCKET.ORG", true)] + [InlineData("http://BITBUCKET.ORG/PATH", true)] + [InlineData("https://BITBUCKET.ORG/PATH", true)] + [InlineData("http://BiTbUcKeT.OrG", true)] + [InlineData("https://BiTbUcKeT.OrG", true)] + [InlineData("http://BiTbUcKeT.OrG/pAtH", true)] + [InlineData("https://BiTbUcKeT.OrG/pAtH", true)] + [InlineData("http://bitbucket.example.com", false)] + [InlineData("https://bitbucket.example.com", false)] + [InlineData("http://bitbucket.example.com/path", false)] + [InlineData("https://bitbucket.example.com/path", false)] + [InlineData("http://bitbucket.example.org", false)] + [InlineData("https://bitbucket.example.org", false)] + [InlineData("http://bitbucket.example.org/path", false)] + [InlineData("https://bitbucket.example.org/path", false)] + [InlineData("http://bitbucket.org.com", false)] + [InlineData("https://bitbucket.org.com", false)] + [InlineData("http://bitbucket.org.com/path", false)] + [InlineData("https://bitbucket.org.com/path", false)] + [InlineData("http://bitbucket.org.org", false)] + [InlineData("https://bitbucket.org.org", false)] + [InlineData("http://bitbucket.org.org/path", false)] + [InlineData("https://bitbucket.org.org/path", false)] + public void BitbucketHostProvider_IsBitbucketOrg_Uri(string str, bool expected) + { + bool actual = BitbucketHostProvider.IsBitbucketOrg(new Uri(str)); + Assert.Equal(expected, actual); + } + [Theory] [InlineData("https", null, false)] // We report that we support unencrypted HTTP here so that we can fail and From f1a1ae52df6bc675ffff9fd59a02a5ff6cb92cf5 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 31 May 2022 14:43:05 +0100 Subject: [PATCH 53/83] environment: manually scan $PATH on POSIX systems Because the `which` command is not always located in `/usr/bin` on all POSIX systems, we cannot directly call `/usr/bin/which` to do program location for us. Oh the irony.. We might be able to use `env` to locate `which`, but again the `env` utility isn't always found in the same place, so we're stuck. Instead we now manually scan the $PATH variable directories looking for the program we need to find, in the same way we do on Windows (for different reasons). This should also be slightly faster as you'd hope .NET's String.Split method and lstat calls are faster than fork/exec-ing another executable? --- src/shared/Core/EnvironmentBase.cs | 35 ++++++++++++++++-- .../Core/Interop/Posix/PosixEnvironment.cs | 36 ------------------- .../Interop/Windows/WindowsEnvironment.cs | 22 ------------ 3 files changed, 33 insertions(+), 60 deletions(-) diff --git a/src/shared/Core/EnvironmentBase.cs b/src/shared/Core/EnvironmentBase.cs index 5ca12ee6b..d2e710e8c 100644 --- a/src/shared/Core/EnvironmentBase.cs +++ b/src/shared/Core/EnvironmentBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; namespace GitCredentialManager @@ -89,8 +90,6 @@ public bool IsDirectoryOnPath(string directoryPath) protected abstract string[] SplitPathVariable(string value); - public abstract bool TryLocateExecutable(string program, out string path); - public virtual Process CreateProcess(string path, string args, bool useShellExecute, string workingDirectory) { var psi = new ProcessStartInfo(path, args) @@ -104,6 +103,38 @@ public virtual Process CreateProcess(string path, string args, bool useShellExec return new Process { StartInfo = psi }; } + + public bool TryLocateExecutable(string program, out string path) + { + // On UNIX-like systems we would normally use the "which" utility to locate a program, + // but since distributions don't always place "which" in a consistent location we cannot + // find it! Oh the irony.. + // We could also try using "env" to then locate "which", but the same problem exists in + // that "env" isn't always in a standard location. + // + // On Windows we should avoid using the equivalent utility "where.exe" because this will + // include the current working directory in the search, and we don't want this. + // + // The upshot of the above means we cannot use either of "which" or "where.exe" and must + // instead manually scan the PATH variable looking for the program. + // At least both Windows and UNIX use the same name for the $PATH or %PATH% variable! + if (Variables.TryGetValue("PATH", out string pathValue)) + { + string[] paths = SplitPathVariable(pathValue); + foreach (var basePath in paths) + { + string candidatePath = Path.Combine(basePath, program); + if (FileSystem.FileExists(candidatePath)) + { + path = candidatePath; + return true; + } + } + } + + path = null; + return false; + } } public static class EnvironmentExtensions diff --git a/src/shared/Core/Interop/Posix/PosixEnvironment.cs b/src/shared/Core/Interop/Posix/PosixEnvironment.cs index 8c4e4b4f1..021d76a58 100644 --- a/src/shared/Core/Interop/Posix/PosixEnvironment.cs +++ b/src/shared/Core/Interop/Posix/PosixEnvironment.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; namespace GitCredentialManager.Interop.Posix { @@ -29,40 +27,6 @@ protected override string[] SplitPathVariable(string value) return value.Split(':'); } - public override bool TryLocateExecutable(string program, out string path) - { - // The "which" utility scans over the PATH and does not include the current working directory - // (unlike the equivalent "where.exe" on Windows), which is exactly what we want. Let's use it. - const string whichPath = "/usr/bin/which"; - var psi = new ProcessStartInfo(whichPath, program) - { - UseShellExecute = false, - RedirectStandardOutput = true - }; - - using (var where = new Process {StartInfo = psi}) - { - where.Start(); - where.WaitForExit(); - - switch (where.ExitCode) - { - case 0: // found - string stdout = where.StandardOutput.ReadToEnd(); - string[] results = stdout.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries); - path = results.First(); - return true; - - case 1: // not found - path = null; - return false; - - default: - throw new Exception($"Unknown error locating '{program}' using {whichPath}. Exit code: {where.ExitCode}."); - } - } - } - #endregion private static IReadOnlyDictionary GetCurrentVariables() diff --git a/src/shared/Core/Interop/Windows/WindowsEnvironment.cs b/src/shared/Core/Interop/Windows/WindowsEnvironment.cs index 918579d10..c438582c9 100644 --- a/src/shared/Core/Interop/Windows/WindowsEnvironment.cs +++ b/src/shared/Core/Interop/Windows/WindowsEnvironment.cs @@ -67,28 +67,6 @@ public override void RemoveDirectoryFromPath(string directoryPath, EnvironmentVa } } - public override bool TryLocateExecutable(string program, out string path) - { - // Don't use "where.exe" on Windows as this includes the current working directory - // and we don't want to enumerate this location; only the PATH. - if (Variables.TryGetValue("PATH", out string pathValue)) - { - string[] paths = SplitPathVariable(pathValue); - foreach (var basePath in paths) - { - string candidatePath = Path.Combine(basePath, program); - if (FileSystem.FileExists(candidatePath)) - { - path = candidatePath; - return true; - } - } - } - - path = null; - return false; - } - public override Process CreateProcess(string path, string args, bool useShellExecute, string workingDirectory) { // If we're asked to start a WSL executable we must launch via the wsl.exe command tool From d20bd0bda9c96e81ab409a49732382200dcd5fbf Mon Sep 17 00:00:00 2001 From: Samuel Lee <56448320+samuel-lee-msft@users.noreply.github.com> Date: Tue, 31 May 2022 17:58:44 +0100 Subject: [PATCH 54/83] Update architecture.md Fix various typos --- docs/architecture.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index eee92e3e3..7790dfc8c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -31,13 +31,13 @@ | | | | | | +-v---v----v--------------v------------+ +-v-----------------v----------------+ | | | | -| Core <--+ Core.UI | +| Core <--+ Core.UI | | | | | +--------------------------------------+ +------------------------------------+ ``` Git Credential Manager (GCM) is built to be Git host and platform/OS -agonstic. Most of the shared logic (command execution, the abstract platform +agnostic. Most of the shared logic (command execution, the abstract platform subsystems, etc) can be found in the `Core` class library (C#). The library targets .NET Standard as well as .NET Framework. @@ -74,7 +74,7 @@ the shared, core binaries shell out to. Currently the Bitbucket and GitHub providers each have a WPF (Windows only) helper executable that shows authentication prompts and messages. -The `Microsoft.Git.CredentialHelper.UI` project is a WPF (Windows only) assembly +The `Core.UI` project is a WPF (Windows only) assembly that contains common WPF components and styles that are shared between provider helpers on Windows. @@ -163,7 +163,7 @@ appropriate host provider. The default registry implementation select the a host provider by asking each registered provider in turn if they understand the request. The provider selection can be overridden by the user via the [`credential.provider`](configuration.md#credentialprovider) or [`GCM_PROVIDER`](environment.md#GCM_PROVIDER) -configuration and environment variable respectively (3)). +configuration and environment variable respectively (3). The `Get|Store|EraseCommand`s call the corresponding `Get|Store|EraseCredentialAsync` methods on the `IHostProvider`, passing the From e284ef4dc61118aacd06975e5da1db7302c578c9 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Tue, 31 May 2022 14:02:09 -0700 Subject: [PATCH 55/83] fixup! Web browser and PAT support for GitLab. --- docs/gitlab.md | 2 +- src/shared/GitLab/GitLabHostProvider.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/gitlab.md b/docs/gitlab.md index 0d876d514..94065398e 100644 --- a/docs/gitlab.md +++ b/docs/gitlab.md @@ -6,7 +6,7 @@ Git Credential Manager supports [gitlab.com](https://gitlab.com) out the box. To use on another instance, eg. `https://gitlab.example.com` requires setup and configuration: -1. [Create an OAuth application](https://docs.gitlab.com/ee/integration/oauth_provider.html). This can be at the user, group or instance level. Specify a name and use a redirect URI of `http://127.0.0.1/`. _Unselect_ the 'Confidential' option, and ensure the 'Expire access tokens' option is selected. Set the scope to 'write_repository'. +1. [Create an OAuth application](https://docs.gitlab.com/ee/integration/oauth_provider.html). This can be at the user, group or instance level. Specify a name and use a redirect URI of `http://127.0.0.1/`. _Unselect_ the 'Confidential' option, and ensure the 'Expire access tokens' option is selected. Set the 'write_repository' and 'read_repository' scopes. 1. Copy the application ID and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientId ` 1. Copy the application secret and configure `git config --global credential.https://gitlab.example.com.GitLabDevClientSecret ` 1. Configure authentication modes to include 'browser' `git config --global credential.https://gitlab.example.com.gitLabAuthModes browser` diff --git a/src/shared/GitLab/GitLabHostProvider.cs b/src/shared/GitLab/GitLabHostProvider.cs index 5aca828c7..2836f41c6 100644 --- a/src/shared/GitLab/GitLabHostProvider.cs +++ b/src/shared/GitLab/GitLabHostProvider.cs @@ -13,6 +13,7 @@ public class GitLabHostProvider : HostProvider private static readonly string[] GitLabOAuthScopes = { "write_repository", + "read_repository" }; private readonly IGitLabAuthentication _gitLabAuth; From e62b8dff918aa1a538e7a2b86931de6b59cf2a1e Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 31 May 2022 14:54:55 +0100 Subject: [PATCH 56/83] environment: add test for PosixEnv.TryLocateExec --- src/shared/Core.Tests/EnvironmentTests.cs | 92 +++++++++++++++---- .../Core/Interop/Posix/PosixEnvironment.cs | 9 +- 2 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/shared/Core.Tests/EnvironmentTests.cs b/src/shared/Core.Tests/EnvironmentTests.cs index f48060f14..d7a910733 100644 --- a/src/shared/Core.Tests/EnvironmentTests.cs +++ b/src/shared/Core.Tests/EnvironmentTests.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using GitCredentialManager.Interop.Posix; using GitCredentialManager.Interop.Windows; using GitCredentialManager.Tests.Objects; using Xunit; @@ -7,62 +9,116 @@ namespace GitCredentialManager.Tests { public class EnvironmentTests { + private const string WindowsPathVar = @"C:\Users\john.doe\bin;C:\Windows\system32;C:\Windows"; + private const string WindowsExecName = "foo.exe"; + private const string PosixPathVar = "/home/john.doe/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"; + private const string PosixExecName = "foo"; + [PlatformFact(Platforms.Windows)] public void WindowsEnvironment_TryLocateExecutable_NotExists_ReturnFalse() { - string pathVar = @"C:\Users\john.doe\bin;C:\Windows\system32;C:\Windows"; - string execName = "foo.exe"; var fs = new TestFileSystem(); - var envars = new Dictionary {["PATH"] = pathVar}; + var envars = new Dictionary {["PATH"] = WindowsPathVar}; var env = new WindowsEnvironment(fs, envars); - bool actualResult = env.TryLocateExecutable(execName, out string actualPath); + bool actualResult = env.TryLocateExecutable(WindowsExecName, out string actualPath); Assert.False(actualResult); Assert.Null(actualPath); } [PlatformFact(Platforms.Windows)] - public void WindowsEnvironment_TryLocateExecutable_Windows_Exists_ReturnTrueAndPath() + public void WindowsEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() { - string pathVar = @"C:\Users\john.doe\bin;C:\Windows\system32;C:\Windows"; - string execName = "foo.exe"; string expectedPath = @"C:\Windows\system32\foo.exe"; var fs = new TestFileSystem { Files = new Dictionary { - [@"C:\Windows\system32\foo.exe"] = new byte[0], + [expectedPath] = Array.Empty() } }; - var envars = new Dictionary {["PATH"] = pathVar}; + var envars = new Dictionary {["PATH"] = WindowsPathVar}; var env = new WindowsEnvironment(fs, envars); - bool actualResult = env.TryLocateExecutable(execName, out string actualPath); + bool actualResult = env.TryLocateExecutable(WindowsExecName, out string actualPath); Assert.True(actualResult); Assert.Equal(expectedPath, actualPath); } [PlatformFact(Platforms.Windows)] - public void WindowsEnvironment_TryLocateExecutable_Windows_ExistsMultiple_ReturnTrueAndFirstPath() + public void WindowsEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFirstPath() { - string pathVar = @"C:\Users\john.doe\bin;C:\Windows\system32;C:\Windows"; - string execName = "foo.exe"; string expectedPath = @"C:\Users\john.doe\bin\foo.exe"; var fs = new TestFileSystem { Files = new Dictionary { - [@"C:\Users\john.doe\bin\foo.exe"] = new byte[0], - [@"C:\Windows\system32\foo.exe"] = new byte[0], - [@"C:\Windows\foo.exe"] = new byte[0], + [expectedPath] = Array.Empty(), + [@"C:\Windows\system32\foo.exe"] = Array.Empty(), + [@"C:\Windows\foo.exe"] = Array.Empty(), } }; - var envars = new Dictionary {["PATH"] = pathVar}; + var envars = new Dictionary {["PATH"] = WindowsPathVar}; var env = new WindowsEnvironment(fs, envars); - bool actualResult = env.TryLocateExecutable(execName, out string actualPath); + bool actualResult = env.TryLocateExecutable(WindowsExecName, out string actualPath); + + Assert.True(actualResult); + Assert.Equal(expectedPath, actualPath); + } + + [PlatformFact(Platforms.Posix)] + public void PosixEnvironment_TryLocateExecutable_NotExists_ReturnFalse() + { + var fs = new TestFileSystem(); + var envars = new Dictionary {["PATH"] = PosixPathVar}; + var env = new PosixEnvironment(fs, envars); + + bool actualResult = env.TryLocateExecutable(PosixExecName, out string actualPath); + + Assert.False(actualResult); + Assert.Null(actualPath); + } + + [PlatformFact(Platforms.Posix)] + public void PosixEnvironment_TryLocateExecutable_Exists_ReturnTrueAndPath() + { + string expectedPath = "/usr/local/bin/foo"; + var fs = new TestFileSystem + { + Files = new Dictionary + { + [expectedPath] = Array.Empty(), + } + }; + var envars = new Dictionary {["PATH"] = PosixPathVar}; + var env = new PosixEnvironment(fs, envars); + + bool actualResult = env.TryLocateExecutable(PosixExecName, out string actualPath); + + Assert.True(actualResult); + Assert.Equal(expectedPath, actualPath); + } + + [PlatformFact(Platforms.Posix)] + public void PosixEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFirstPath() + { + string expectedPath = "/home/john.doe/bin/foo"; + var fs = new TestFileSystem + { + Files = new Dictionary + { + [expectedPath] = Array.Empty(), + ["/usr/local/bin/foo"] = Array.Empty(), + ["/bin/foo"] = Array.Empty(), + } + }; + var envars = new Dictionary {["PATH"] = PosixPathVar}; + var env = new PosixEnvironment(fs, envars); + + bool actualResult = env.TryLocateExecutable(PosixExecName, out string actualPath); Assert.True(actualResult); Assert.Equal(expectedPath, actualPath); diff --git a/src/shared/Core/Interop/Posix/PosixEnvironment.cs b/src/shared/Core/Interop/Posix/PosixEnvironment.cs index 021d76a58..da2e76c72 100644 --- a/src/shared/Core/Interop/Posix/PosixEnvironment.cs +++ b/src/shared/Core/Interop/Posix/PosixEnvironment.cs @@ -5,9 +5,14 @@ namespace GitCredentialManager.Interop.Posix { public class PosixEnvironment : EnvironmentBase { - public PosixEnvironment(IFileSystem fileSystem) : base(fileSystem) + public PosixEnvironment(IFileSystem fileSystem) + : this(fileSystem, GetCurrentVariables()) { } + + internal PosixEnvironment(IFileSystem fileSystem, IReadOnlyDictionary variables) + : base(fileSystem) { - Variables = GetCurrentVariables(); + EnsureArgument.NotNull(variables, nameof(variables)); + Variables = variables; } #region EnvironmentBase From 47df2011e59f85a8450e9306a8165aadbb3e7e2e Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Wed, 1 Jun 2022 09:29:36 -0700 Subject: [PATCH 57/83] docs: FAQ on revoking GitLab OAuth Application Add FAQ entry detailing how to revoke/re-authorize a GitLab OAuth Application's access. This is needed when the application is updated, e.g. when new scopes are added to it. --- docs/faq.md | 14 ++++++++++++++ docs/img/gitlab-oauthapp-revoke.png | Bin 0 -> 142186 bytes docs/img/gitlab-oauthapp-revoked.png | Bin 0 -> 45535 bytes 3 files changed, 14 insertions(+) create mode 100644 docs/img/gitlab-oauthapp-revoke.png create mode 100644 docs/img/gitlab-oauthapp-revoked.png diff --git a/docs/faq.md b/docs/faq.md index a67b3c119..b61d43d0e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -150,3 +150,17 @@ After revoking access, any tokens created by GCM will be invalidated and can no ### I used the install from source script to install GCM on my Linux distribution. Now how can I uninstall GCM and its dependencies? Please see full instructions [here](./linux-fromsrc-uninstall.md). + +### How do I revoke access for a GitLab OAuth application? + +There are some scenarios (e.g. updated scopes) for which you will need to manually revoke and re-authorize access for a GitLab OAuth application. You can do so by: + +1. Navigating to [the **Applications** page within your **User Settings**](https://gitlab.com/-/profile/applications). +2. Scrolling to **Authorized applications**. +3. Clicking the **Revoke** button next to the name of the application for which you would like to revoke access (Git Credential Manager is used here for demonstration purposes). + + ![Button to revoke GitLab OAuth Application access](./img/gitlab-oauthapp-revoke.png) +4. Waiting for a notification stating **The application was revoked access**. + + ![Notifaction of successful revocation](./img/gitlab-oauthapp-revoked.png) +5. Re-authorizing the application with the new scope (GCM should automatically initiate this flow for you next time access is requested). diff --git a/docs/img/gitlab-oauthapp-revoke.png b/docs/img/gitlab-oauthapp-revoke.png new file mode 100644 index 0000000000000000000000000000000000000000..261fff96a297416d8c06d00617d6886c643753fd GIT binary patch literal 142186 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 a@le;4y%)!5p~V#7-<8XTnw9E~;r|OqjQ_g; literal 0 HcmV?d00001 diff --git a/docs/img/gitlab-oauthapp-revoked.png b/docs/img/gitlab-oauthapp-revoked.png new file mode 100644 index 0000000000000000000000000000000000000000..f478c152eb916e7d4414a2b7684343ec2c216cbf GIT binary patch literal 45535 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 literal 0 HcmV?d00001 From 110f69b720851a72a9c9c6790144f4001e051002 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Wed, 1 Jun 2022 21:30:07 -0700 Subject: [PATCH 58/83] fixup! release: publish draft release to GitHub --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c5e8a4144..e15d88394 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -492,7 +492,7 @@ jobs: // Create the release var tagName = `v${version}`; - var createdRelease = await github.repos.createRelease({ + var createdRelease = await github.rest.repos.createRelease({ ...releaseMetadata, draft: true, tag_name: tagName, @@ -509,7 +509,7 @@ jobs: }) .map(async (file) => { var filePath = path.join(directory, file); - github.repos.uploadReleaseAsset({ + github.rest.repos.uploadReleaseAsset({ ...releaseMetadata, name: file, headers: { From 5a8ba50a3fc58c87b7eef40c4d0023b1b591bf41 Mon Sep 17 00:00:00 2001 From: miya_789 <31382715+miya789@users.noreply.github.com> Date: Tue, 7 Jun 2022 21:56:08 +0900 Subject: [PATCH 59/83] credentialstore: remove windows Co-authored-by: Johannes Schindelin Co-authored-by: Lessley Dennington --- docs/credstores.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/credstores.md b/docs/credstores.md index 3e4a232f2..bb206e647 100644 --- a/docs/credstores.md +++ b/docs/credstores.md @@ -178,7 +178,7 @@ TTY device path, as returned by the `tty` utility. ## Git's built-in [credential cache](https://git-scm.com/docs/git-credential-cache) -**Available on:** _Windows, macOS, Linux_ +**Available on:** _macOS, Linux_ ```shell export GCM_CREDENTIAL_STORE=cache From c0fbe95dbdf21a83427ae8758a913d851ad2e6e1 Mon Sep 17 00:00:00 2001 From: miya_789 <31382715+miya789@users.noreply.github.com> Date: Thu, 9 Jun 2022 08:25:35 +0900 Subject: [PATCH 60/83] credentialstore: add error about cache windows Co-authored-by: Lessley Dennington --- src/shared/Core/CredentialStore.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/shared/Core/CredentialStore.cs b/src/shared/Core/CredentialStore.cs index 812c301ee..bf8c0be47 100644 --- a/src/shared/Core/CredentialStore.cs +++ b/src/shared/Core/CredentialStore.cs @@ -152,8 +152,11 @@ private static void AppendAvailableStoreList(StringBuilder sb) Environment.NewLine, StoreNames.Gpg); } - sb.AppendFormat(" {1,-13} : Git's in-memory credential cache{0}", - Environment.NewLine, StoreNames.Cache); + if (!PlatformUtils.IsWindows()) + { + sb.AppendFormat(" {1,-13} : Git's in-memory credential cache{0}", + Environment.NewLine, StoreNames.Cache); + } sb.AppendFormat(" {1,-13} : store credentials in plain-text files (UNSECURE){0}", Environment.NewLine, StoreNames.Plaintext); @@ -286,6 +289,15 @@ private void ValidateGpgPass(out string storeRoot, out string execPath) private void ValidateCredentialCache(out string options) { + if (PlatformUtils.IsWindows()) + { + throw new Exception( + $"Can not use the '{StoreNames.Cache}' credential store on Windows due to lack of UNIX socket support in Git for Windows." + + Environment.NewLine + + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." + ); + } + // allow for --timeout and other options if (!_context.Settings.TryGetSetting( Constants.EnvironmentVariables.GcmCredCacheOptions, From 3eb7bd776e7c206fe230bf23cc83c861676832dd Mon Sep 17 00:00:00 2001 From: buchwasa <17461354+buchwasa@users.noreply.github.com> Date: Tue, 22 Mar 2022 21:42:31 -0400 Subject: [PATCH 61/83] dependencies: update Microsoft.NET.Test.Sdk and Avalonia The upcoming specification of a macOS runtime led to the need to update the Microsoft.NET.Test.Sdk package. The old version, when combined with this specification, caused dependent packages to be downgraded, which resulted in NuGet errors. Upgrading to the latest version resolved this issue. Additionally, Avalonia has been upgraded to the latest version, which was necessitated by the upcoming changes to support osx-arm64. --- .../Atlassian.Bitbucket.Tests.csproj | 2 +- src/shared/Core.Tests/Core.Tests.csproj | 2 +- src/shared/Core.UI.Avalonia/Core.UI.Avalonia.csproj | 6 +++--- src/shared/GitHub.Tests/GitHub.Tests.csproj | 2 +- src/shared/GitLab.Tests/GitLab.Tests.csproj | 2 +- .../Microsoft.AzureRepos.Tests.csproj | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj index 61f8f2ae5..18d7f90d7 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj +++ b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/src/shared/Core.Tests/Core.Tests.csproj b/src/shared/Core.Tests/Core.Tests.csproj index 6028211f9..0bc07acd2 100644 --- a/src/shared/Core.Tests/Core.Tests.csproj +++ b/src/shared/Core.Tests/Core.Tests.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/src/shared/Core.UI.Avalonia/Core.UI.Avalonia.csproj b/src/shared/Core.UI.Avalonia/Core.UI.Avalonia.csproj index 766c921af..a7ade3aaa 100644 --- a/src/shared/Core.UI.Avalonia/Core.UI.Avalonia.csproj +++ b/src/shared/Core.UI.Avalonia/Core.UI.Avalonia.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/src/shared/GitHub.Tests/GitHub.Tests.csproj b/src/shared/GitHub.Tests/GitHub.Tests.csproj index 3caa998ed..13408d24f 100644 --- a/src/shared/GitHub.Tests/GitHub.Tests.csproj +++ b/src/shared/GitHub.Tests/GitHub.Tests.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/src/shared/GitLab.Tests/GitLab.Tests.csproj b/src/shared/GitLab.Tests/GitLab.Tests.csproj index 341b7bc51..3212501c7 100644 --- a/src/shared/GitLab.Tests/GitLab.Tests.csproj +++ b/src/shared/GitLab.Tests/GitLab.Tests.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj index cb620ba3b..f10e3ddda 100644 --- a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj +++ b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 7c4cde460f2259c69ea545b3641ef196a723350d Mon Sep 17 00:00:00 2001 From: Matt Cooper Date: Wed, 16 Feb 2022 09:33:04 -0500 Subject: [PATCH 62/83] docs: fix rotten links --- docs/configuration.md | 2 +- docs/environment.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 06a46eb5a..e295c68d7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -520,7 +520,7 @@ Value|Description `pat` _(default)_|Azure DevOps personal access tokens `oauth`|Microsoft identity OAuth tokens (AAD or MSA tokens) -More information about Azure Access tokens can be found [here](azrepos-azuretokens.md). +More information about Azure Access tokens can be found [here](azrepos-users-and-tokens.md). #### Example diff --git a/docs/environment.md b/docs/environment.md index 1089c071a..18cfa4774 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -680,7 +680,7 @@ Value|Description `pat` _(default)_|Azure DevOps personal access tokens `oauth`|Microsoft identity OAuth tokens (AAD or MSA tokens) -More information about Azure Access tokens can be found [here](azrepos-azuretokens.md). +More information about Azure Access tokens can be found [here](azrepos-users-and-tokens.md). #### Windows From b5f7f28489f4e88cb542de8b2767b8796f20852b Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 9 Jun 2022 15:02:50 -0700 Subject: [PATCH 63/83] macos environment: add option to ignore paths Add ability to ignore specified paths when searching the PATH for an executable. --- src/shared/Core/EnvironmentBase.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/shared/Core/EnvironmentBase.cs b/src/shared/Core/EnvironmentBase.cs index d2e710e8c..a2aa36cf2 100644 --- a/src/shared/Core/EnvironmentBase.cs +++ b/src/shared/Core/EnvironmentBase.cs @@ -104,7 +104,12 @@ public virtual Process CreateProcess(string path, string args, bool useShellExec return new Process { StartInfo = psi }; } - public bool TryLocateExecutable(string program, out string path) + public virtual bool TryLocateExecutable(string program, out string path) + { + return TryLocateExecutable(program, null, out path); + } + + internal virtual bool TryLocateExecutable(string program, ICollection pathsToIgnore, out string path) { // On UNIX-like systems we would normally use the "which" utility to locate a program, // but since distributions don't always place "which" in a consistent location we cannot @@ -124,7 +129,8 @@ public bool TryLocateExecutable(string program, out string path) foreach (var basePath in paths) { string candidatePath = Path.Combine(basePath, program); - if (FileSystem.FileExists(candidatePath)) + if (FileSystem.FileExists(candidatePath) && (pathsToIgnore is null || + !pathsToIgnore.Contains(candidatePath, StringComparer.OrdinalIgnoreCase))) { path = candidatePath; return true; From 57a566a4cc5a8143c01062675291e50532f17f0c Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 9 Jun 2022 15:03:07 -0700 Subject: [PATCH 64/83] macos environment: ignore homebrew shim Ignore Homebrew shim to ensure the user's installed version of Git is called during `brew uninstall` (instead of the shim). Note that this involves explicitly passing the HOMEBREW_PREFIX environment variable, since the `sudo -u `/usr/bin/logname` "$GCMBIN" unconfigure` command does not inherit it. --- src/osx/Installer.Mac/uninstall.sh | 2 +- src/shared/Core/CommandContext.cs | 2 +- .../Core/Interop/MacOS/MacOSEnvironment.cs | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/shared/Core/Interop/MacOS/MacOSEnvironment.cs diff --git a/src/osx/Installer.Mac/uninstall.sh b/src/osx/Installer.Mac/uninstall.sh index 989ed9956..f26f2b189 100755 --- a/src/osx/Installer.Mac/uninstall.sh +++ b/src/osx/Installer.Mac/uninstall.sh @@ -12,7 +12,7 @@ fi # Unconfigure (as the current user) echo "Unconfiguring credential helper..." -sudo -u `/usr/bin/logname` "$GCMBIN" unconfigure +sudo -u `/usr/bin/logname` -E "$GCMBIN" unconfigure # Remove symlink if [ -L /usr/local/bin/git-credential-manager-core ] diff --git a/src/shared/Core/CommandContext.cs b/src/shared/Core/CommandContext.cs index 0a52f627a..397d57bbb 100644 --- a/src/shared/Core/CommandContext.cs +++ b/src/shared/Core/CommandContext.cs @@ -107,7 +107,7 @@ public CommandContext(string appPath) FileSystem = new MacOSFileSystem(); SessionManager = new MacOSSessionManager(); SystemPrompts = new MacOSSystemPrompts(); - Environment = new PosixEnvironment(FileSystem); + Environment = new MacOSEnvironment(FileSystem); Terminal = new MacOSTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem, Trace); Git = new GitProcess( diff --git a/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs b/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs new file mode 100644 index 000000000..a29f1f4df --- /dev/null +++ b/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Threading; +using GitCredentialManager.Interop.Posix; + +namespace GitCredentialManager.Interop.MacOS +{ + public class MacOSEnvironment : PosixEnvironment + { + private ICollection _pathsToIgnore; + + public MacOSEnvironment(IFileSystem fileSystem) + : base(fileSystem) { } + + internal MacOSEnvironment(IFileSystem fileSystem, IReadOnlyDictionary variables) + : base(fileSystem) + { + EnsureArgument.NotNull(variables, nameof(variables)); + Variables = variables; + } + + public override bool TryLocateExecutable(string program, out string path) + { + if (_pathsToIgnore is null) + { + _pathsToIgnore = new List(); + if (Variables.TryGetValue("HOMEBREW_PREFIX", out string homebrewPrefix)) + { + string homebrewGit = Path.Combine(homebrewPrefix, "Homebrew/Library/Homebrew/shims/shared/git"); + _pathsToIgnore.Add(homebrewGit); + } + } + return TryLocateExecutable(program, _pathsToIgnore, out path); + } + } +} \ No newline at end of file From f39343b02891e25f053e3ed6defbef0366e09160 Mon Sep 17 00:00:00 2001 From: Lessley Dennington Date: Thu, 9 Jun 2022 15:41:00 -0700 Subject: [PATCH 65/83] macos environment: unit test for ignoring paths Add a unit test to verify ignoring paths when searching the PATH for executables works as expected. --- src/shared/Core.Tests/EnvironmentTests.cs | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/shared/Core.Tests/EnvironmentTests.cs b/src/shared/Core.Tests/EnvironmentTests.cs index d7a910733..9c8eae028 100644 --- a/src/shared/Core.Tests/EnvironmentTests.cs +++ b/src/shared/Core.Tests/EnvironmentTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using GitCredentialManager.Interop.Posix; using GitCredentialManager.Interop.Windows; using GitCredentialManager.Tests.Objects; @@ -123,5 +124,31 @@ public void PosixEnvironment_TryLocateExecutable_ExistsMultiple_ReturnTrueAndFir Assert.True(actualResult); Assert.Equal(expectedPath, actualPath); } + + [PlatformFact(Platforms.MacOS)] + public void MacOSEnvironment_TryLocateExecutable_Paths_Are_Ignored() + { + List pathsToIgnore = new List() + { + "/home/john.doe/bin/foo" + }; + string expectedPath = "/usr/local/bin/foo"; + + var fs = new TestFileSystem + { + Files = new Dictionary + { + [pathsToIgnore.FirstOrDefault()] = Array.Empty(), + [expectedPath] = Array.Empty(), + } + }; + var envars = new Dictionary {["PATH"] = PosixPathVar}; + var env = new PosixEnvironment(fs, envars); + + bool actualResult = env.TryLocateExecutable(PosixExecName, pathsToIgnore, out string actualPath); + + Assert.True(actualResult); + Assert.Equal(expectedPath, actualPath); + } } } From 81501c0585db76ffe4c7babfd47631e38b01af74 Mon Sep 17 00:00:00 2001 From: buchwasa <17461354+buchwasa@users.noreply.github.com> Date: Tue, 22 Mar 2022 21:28:36 -0400 Subject: [PATCH 66/83] macos: build arm-64 Add support for building osx-arm64 in addition to osx-x64 to produce native M1 binaries. --- .github/workflows/release.yml | 57 ++++++++++++++----- src/osx/Installer.Mac/Installer.Mac.csproj | 4 +- src/osx/Installer.Mac/build.sh | 23 +++++++- src/osx/Installer.Mac/dist.sh | 27 ++++++++- ...istribution.xml => distribution.arm64.xml} | 2 +- src/osx/Installer.Mac/distribution.x64.xml | 21 +++++++ src/osx/Installer.Mac/layout.sh | 23 +++++++- .../Atlassian.Bitbucket.UI.Avalonia.csproj | 2 +- .../Git-Credential-Manager.csproj | 2 +- .../GitHub.UI.Avalonia.csproj | 2 +- .../GitLab.UI.Avalonia.csproj | 2 +- 11 files changed, 139 insertions(+), 26 deletions(-) rename src/osx/Installer.Mac/{distribution.xml => distribution.arm64.xml} (93%) create mode 100644 src/osx/Installer.Mac/distribution.x64.xml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e15d88394..db6dc6807 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,9 @@ jobs: osx-build: name: Build macOS runs-on: macos-latest + strategy: + matrix: + runtime: [ osx-x64, osx-arm64 ] steps: - uses: actions/checkout@v3 with: @@ -27,7 +30,9 @@ jobs: - name: Build run: | - dotnet build --configuration=MacRelease + dotnet build src/osx/Installer.Mac/*.csproj \ + --configuration=MacRelease --no-self-contained \ + --runtime=${{ matrix.runtime }} - name: Run macOS unit tests run: | @@ -35,7 +40,9 @@ jobs: - name: Lay out payload and symbols run: | - src/osx/Installer.Mac/layout.sh --configuration=MacRelease --output=payload --symbol-output=symbols + src/osx/Installer.Mac/layout.sh \ + --configuration=MacRelease --output=payload \ + --symbol-output=symbols --runtime=${{ matrix.runtime }} - name: Create keychain env: @@ -58,7 +65,7 @@ jobs: - name: Upload macOS artifacts uses: actions/upload-artifact@v3 with: - name: tmp.osx-build + name: tmp.${{ matrix.runtime }}-build path: | payload symbols @@ -67,6 +74,9 @@ jobs: name: Sign macOS payload # ESRP service requires signing to run on Windows runs-on: windows-latest + strategy: + matrix: + runtime: [ osx-x64, osx-arm64 ] needs: osx-build steps: - name: Check out repository @@ -75,7 +85,7 @@ jobs: - name: Download payload uses: actions/download-artifact@v3 with: - name: tmp.osx-build + name: tmp.${{ matrix.runtime }}-build - name: Zip unsigned payload shell: pwsh @@ -109,7 +119,9 @@ jobs: APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }} APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }} run: | - python .github\run_esrp_signing.py payload $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE --params 'Hardening' '--options=runtime' + python .github\run_esrp_signing.py payload ` + $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE ` + --params 'Hardening' '--options=runtime' - name: Unzip signed payload shell: pwsh @@ -120,13 +132,16 @@ jobs: - name: Upload signed payload uses: actions/upload-artifact@v3 with: - name: osx-payload-sign + name: ${{ matrix.runtime }}-payload-sign path: | signed osx-pack: name: Package macOS payload runs-on: macos-latest + strategy: + matrix: + runtime: [ osx-x64, osx-arm64 ] needs: osx-payload-sign steps: - name: Check out repository @@ -147,20 +162,24 @@ jobs: - name: Download signed payload uses: actions/download-artifact@v3 with: - name: osx-payload-sign + name: ${{ matrix.runtime }}-payload-sign - name: Create component package run: | - src/osx/Installer.Mac/pack.sh --payload=payload --version=$GitBuildVersionSimple --output=components/com.microsoft.gitcredentialmanager.component.pkg + src/osx/Installer.Mac/pack.sh --payload=payload \ + --version=$GitBuildVersionSimple \ + --output=components/com.microsoft.gitcredentialmanager.component.pkg - name: Create product archive run: | - src/osx/Installer.Mac/dist.sh --package-path=components --version=$GitBuildVersionSimple --output=pkg/gcm-osx-x64-$GitBuildVersionSimple.pkg || exit 1 + src/osx/Installer.Mac/dist.sh --package-path=components \ + --version=$GitBuildVersionSimple --runtime=${{ matrix.runtime }} \ + --output=pkg/gcm-${{ matrix.runtime }}-$GitBuildVersionSimple.pkg || exit 1 - name: Upload package uses: actions/upload-artifact@v3 with: - name: tmp.osx-pack + name: tmp.${{ matrix.runtime }}-pack path: | pkg @@ -168,6 +187,9 @@ jobs: name: Sign and notarize macOS package # ESRP service requires signing to run on Windows runs-on: windows-latest + strategy: + matrix: + runtime: [ osx-x64, osx-arm64 ] needs: osx-pack steps: - name: Check out repository @@ -176,7 +198,7 @@ jobs: - name: Download unsigned package uses: actions/download-artifact@v3 with: - name: tmp.osx-pack + name: tmp.${{ matrix.runtime }}-pack path: pkg - name: Zip unsigned package @@ -236,7 +258,7 @@ jobs: - name: Publish signed package uses: actions/upload-artifact@v3 with: - name: osx-sign + name: ${{ matrix.runtime }}-sign path: signed/*.pkg # ================================ @@ -468,8 +490,12 @@ jobs: - name: Archive macOS payload and symbols run: | mkdir osx-payload-and-symbols - tar -C osx-payload-sign -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple.tar.gz . - tar -C tmp.osx-build/symbols -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple-symbols.tar.gz . + + tar -C osx-x64-payload-sign -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple.tar.gz . + tar -C tmp.osx-x64-build/symbols -czf osx-payload-and-symbols/gcm-osx-x64-$GitBuildVersionSimple-symbols.tar.gz . + + tar -C osx-arm64-payload-sign -czf osx-payload-and-symbols/gcm-osx-arm64-$GitBuildVersionSimple.tar.gz . + tar -C tmp.osx-arm64-build/symbols -czf osx-payload-and-symbols/gcm-osx-arm64-$GitBuildVersionSimple-symbols.tar.gz . - name: Archive Windows payload and symbols shell: pwsh @@ -527,7 +553,8 @@ jobs: uploadDirectoryToRelease('win-x86-payload-and-symbols'), // Upload macOS artifacts - uploadDirectoryToRelease('osx-sign'), + uploadDirectoryToRelease('osx-x64-sign'), + uploadDirectoryToRelease('osx-arm64-sign'), uploadDirectoryToRelease('osx-payload-and-symbols'), // Upload Linux artifacts diff --git a/src/osx/Installer.Mac/Installer.Mac.csproj b/src/osx/Installer.Mac/Installer.Mac.csproj index 685862ff5..f42bd3333 100644 --- a/src/osx/Installer.Mac/Installer.Mac.csproj +++ b/src/osx/Installer.Mac/Installer.Mac.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/src/osx/Installer.Mac/build.sh b/src/osx/Installer.Mac/build.sh index 816c621ec..e52419601 100755 --- a/src/osx/Installer.Mac/build.sh +++ b/src/osx/Installer.Mac/build.sh @@ -22,6 +22,10 @@ case "$i" in CONFIGURATION="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift + ;; --version=*) VERSION="${i#*=}" shift # past argument=value @@ -38,6 +42,21 @@ if [ -z "$VERSION" ]; then die "--version was not set" fi +if [ -z "$RUNTIME" ]; then + TEST_RUNTIME=`uname -m` + case $TEST_RUNTIME in + "x86_64") + RUNTIME="osx-x64" + ;; + "arm64") + RUNTIME="osx-arm64" + ;; + *) + die "Unknown runtime '$TEST_RUNTIME'" + ;; + esac +fi + OUTDIR="$INSTALLER_OUT/pkg/$CONFIGURATION" PAYLOAD="$OUTDIR/payload" COMPONENTDIR="$OUTDIR/components" @@ -45,8 +64,8 @@ COMPONENTOUT="$COMPONENTDIR/com.microsoft.gitcredentialmanager.component.pkg" DISTOUT="$OUTDIR/gcm-osx-x64-$VERSION.pkg" # Layout and pack -"$INSTALLER_SRC/layout.sh" --configuration="$CONFIGURATION" --output="$PAYLOAD" || exit 1 +"$INSTALLER_SRC/layout.sh" --configuration="$CONFIGURATION" --output="$PAYLOAD" --runtime="$RUNTIME" || exit 1 "$INSTALLER_SRC/pack.sh" --payload="$PAYLOAD" --version="$VERSION" --output="$COMPONENTOUT" || exit 1 -"$INSTALLER_SRC/dist.sh" --package-path="$COMPONENTDIR" --version="$VERSION" --output="$DISTOUT" || exit 1 +"$INSTALLER_SRC/dist.sh" --package-path="$COMPONENTDIR" --version="$VERSION" --output="$DISTOUT" --runtime="$RUNTIME" || exit 1 echo "Build of Installer.Mac complete." diff --git a/src/osx/Installer.Mac/dist.sh b/src/osx/Installer.Mac/dist.sh index 749231583..c1f5b9328 100755 --- a/src/osx/Installer.Mac/dist.sh +++ b/src/osx/Installer.Mac/dist.sh @@ -11,7 +11,6 @@ SRC="$ROOT/src" OUT="$ROOT/out" INSTALLER_SRC="$SRC/osx/Installer.Mac" RESXPATH="$INSTALLER_SRC/resources" -DISTPATH="$INSTALLER_SRC/distribution.xml" # Product information IDENTIFIER="com.microsoft.gitcredentialmanager.dist" @@ -32,6 +31,10 @@ case "$i" in DISTOUT="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift + ;; *) # unknown option ;; @@ -50,6 +53,28 @@ fi if [ -z "$DISTOUT" ]; then die "--output was not set" fi +if [ -z "$RUNTIME" ]; then + TEST_RUNTIME=`uname -m` + case $TEST_RUNTIME in + "x86_64") + RUNTIME="osx-x64" + ;; + "arm64") + RUNTIME="osx-arm64" + ;; + *) + die "Unknown runtime '$TEST_RUNTIME'" + ;; + esac +fi + +echo "Building for runtime '$RUNTIME'" + +if [ "$RUNTIME" == "osx-x64"]; then + DISTPATH="$INSTALLER_SRC/distribution.x64.xml" +else + DISTPATH="$INSTALLER_SRC/distribution.arm64.xml" +fi # Cleanup any old package if [ -e "$DISTOUT" ]; then diff --git a/src/osx/Installer.Mac/distribution.xml b/src/osx/Installer.Mac/distribution.arm64.xml similarity index 93% rename from src/osx/Installer.Mac/distribution.xml rename to src/osx/Installer.Mac/distribution.arm64.xml index 657397513..531bdbe33 100644 --- a/src/osx/Installer.Mac/distribution.xml +++ b/src/osx/Installer.Mac/distribution.arm64.xml @@ -2,7 +2,7 @@ Git Credential Manager - + diff --git a/src/osx/Installer.Mac/distribution.x64.xml b/src/osx/Installer.Mac/distribution.x64.xml new file mode 100644 index 000000000..45deec220 --- /dev/null +++ b/src/osx/Installer.Mac/distribution.x64.xml @@ -0,0 +1,21 @@ + + + Git Credential Manager + + + + + + + + + + + + + + + + com.microsoft.gitcredentialmanager.component.pkg + + diff --git a/src/osx/Installer.Mac/layout.sh b/src/osx/Installer.Mac/layout.sh index 288216165..b9991713d 100755 --- a/src/osx/Installer.Mac/layout.sh +++ b/src/osx/Installer.Mac/layout.sh @@ -27,7 +27,6 @@ GITLAB_UI_SRC="$SRC/shared/GitLab.UI.Avalonia" # Build parameters FRAMEWORK=net6.0 -RUNTIME=osx-x64 # Parse script arguments for i in "$@" @@ -41,6 +40,10 @@ case "$i" in PAYLOAD="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift # past argument=value + ;; --symbol-output=*) SYMBOLOUT="${i#*=}" ;; @@ -50,6 +53,24 @@ case "$i" in esac done +# Determine a runtime if one was not provided +if [ -z "$RUNTIME" ]; then + TEST_RUNTIME=`uname -m` + case $TEST_RUNTIME in + "x86_64") + RUNTIME="osx-x64" + ;; + "arm64") + RUNTIME="osx-arm64" + ;; + *) + die "Unknown runtime '$TEST_RUNTIME'" + ;; + esac +fi + +echo "Building for runtime '$RUNTIME'" + # Perform pre-execution checks CONFIGURATION="${CONFIGURATION:=Debug}" if [ -z "$PAYLOAD" ]; then diff --git a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Atlassian.Bitbucket.UI.Avalonia.csproj b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Atlassian.Bitbucket.UI.Avalonia.csproj index e1ae6d4af..a9185278a 100644 --- a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Atlassian.Bitbucket.UI.Avalonia.csproj +++ b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Atlassian.Bitbucket.UI.Avalonia.csproj @@ -3,7 +3,7 @@ WinExe net6.0 - osx-x64;linux-x64 + osx-x64;linux-x64;osx-arm64 Atlassian.Bitbucket.UI Atlassian.Bitbucket.UI diff --git a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj index 10f598f61..441ee82bc 100644 --- a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj +++ b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj @@ -4,7 +4,7 @@ Exe net6.0 net472;net6.0 - win-x86;osx-x64;linux-x64 + win-x86;osx-x64;linux-x64;osx-arm64 x86 git-credential-manager-core GitCredentialManager diff --git a/src/shared/GitHub.UI.Avalonia/GitHub.UI.Avalonia.csproj b/src/shared/GitHub.UI.Avalonia/GitHub.UI.Avalonia.csproj index d1e040118..828677fcc 100644 --- a/src/shared/GitHub.UI.Avalonia/GitHub.UI.Avalonia.csproj +++ b/src/shared/GitHub.UI.Avalonia/GitHub.UI.Avalonia.csproj @@ -3,7 +3,7 @@ WinExe net6.0 - osx-x64;linux-x64 + osx-x64;linux-x64;osx-arm64 GitHub.UI GitHub.UI diff --git a/src/shared/GitLab.UI.Avalonia/GitLab.UI.Avalonia.csproj b/src/shared/GitLab.UI.Avalonia/GitLab.UI.Avalonia.csproj index 0a64307ee..26927c272 100644 --- a/src/shared/GitLab.UI.Avalonia/GitLab.UI.Avalonia.csproj +++ b/src/shared/GitLab.UI.Avalonia/GitLab.UI.Avalonia.csproj @@ -3,7 +3,7 @@ WinExe net6.0 - osx-x64;linux-x64 + osx-x64;linux-x64;osx-arm64 GitLab.UI GitLab.UI From 58556d37d178e80e4efeb8077e27d4fc7354d8cc Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 13 Jun 2022 15:28:11 +0100 Subject: [PATCH 67/83] plaintextstore: extract credential enumeration Extract common credential file enumeration from both the Get and Remove methods for the plaintext credential store. --- src/shared/Core/PlaintextCredentialStore.cs | 91 ++++++++------------- 1 file changed, 35 insertions(+), 56 deletions(-) diff --git a/src/shared/Core/PlaintextCredentialStore.cs b/src/shared/Core/PlaintextCredentialStore.cs index b82c6eb63..124320d82 100644 --- a/src/shared/Core/PlaintextCredentialStore.cs +++ b/src/shared/Core/PlaintextCredentialStore.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; namespace GitCredentialManager @@ -22,37 +23,9 @@ public PlaintextCredentialStore(IFileSystem fileSystem, string storeRoot, string protected string Namespace { get; } protected virtual string CredentialFileExtension => ".credential"; - #region ICredentialStore - public ICredential Get(string service, string account) { - string serviceSlug = CreateServiceSlug(service); - string searchPath = Path.Combine(StoreRoot, serviceSlug); - bool anyAccount = string.IsNullOrWhiteSpace(account); - - if (!FileSystem.DirectoryExists(searchPath)) - { - return null; - } - - IEnumerable allFiles = FileSystem.EnumerateFiles(searchPath, $"*{CredentialFileExtension}"); - - foreach (string fullPath in allFiles) - { - string accountFile = Path.GetFileNameWithoutExtension(fullPath); - if (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, accountFile)) - { - // Validate the credential metadata also matches our search - if (TryDeserializeCredential(fullPath, out FileCredential credential) && - StringComparer.OrdinalIgnoreCase.Equals(service, credential.Service) && - (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, credential.Account))) - { - return credential; - } - } - } - - return null; + return Enumerate(service, account).FirstOrDefault(); } public void AddOrUpdate(string service, string account, string secret) @@ -75,39 +48,16 @@ public void AddOrUpdate(string service, string account, string secret) public bool Remove(string service, string account) { - string serviceSlug = CreateServiceSlug(service); - string searchPath = Path.Combine(StoreRoot, serviceSlug); - bool anyAccount = string.IsNullOrWhiteSpace(account); - - if (!FileSystem.DirectoryExists(searchPath)) + foreach (FileCredential credential in Enumerate(service, account)) { - return false; - } - - IEnumerable allFiles = FileSystem.EnumerateFiles(searchPath, $"*{CredentialFileExtension}"); - - foreach (string fullPath in allFiles) - { - string accountFile = Path.GetFileNameWithoutExtension(fullPath); - if (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, accountFile)) - { - // Validate the credential metadata also matches our search - if (TryDeserializeCredential(fullPath, out FileCredential credential) && - StringComparer.OrdinalIgnoreCase.Equals(service, credential.Service) && - (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, credential.Account))) - { - // Delete the credential file - FileSystem.DeleteFile(fullPath); - return true; - } - } + // Only delete the first match + FileSystem.DeleteFile(credential.FullPath); + return true; } return false; } - #endregion - protected virtual bool TryDeserializeCredential(string path, out FileCredential credential) { string text; @@ -162,6 +112,35 @@ protected virtual void SerializeCredential(FileCredential credential) } } + private IEnumerable Enumerate(string service, string account) + { + string serviceSlug = CreateServiceSlug(service); + string searchPath = Path.Combine(StoreRoot, serviceSlug); + bool anyAccount = string.IsNullOrWhiteSpace(account); + + if (!FileSystem.DirectoryExists(searchPath)) + { + yield break; + } + + IEnumerable allFiles = FileSystem.EnumerateFiles(searchPath, $"*{CredentialFileExtension}"); + + foreach (string fullPath in allFiles) + { + string accountFile = Path.GetFileNameWithoutExtension(fullPath); + if (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, accountFile)) + { + // Validate the credential metadata also matches our search + if (TryDeserializeCredential(fullPath, out FileCredential credential) && + StringComparer.OrdinalIgnoreCase.Equals(service, credential.Service) && + (anyAccount || StringComparer.OrdinalIgnoreCase.Equals(account, credential.Account))) + { + yield return credential; + } + } + } + } + /// /// Ensure the store root directory exists. If it does not, create a new directory with /// permissions that only permit the owner to read/write/execute. Permissions on an existing From a7e81cf1162e27548c19df176802cbe57c495a8d Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 13 Jun 2022 15:28:53 +0100 Subject: [PATCH 68/83] plaintextstore: do not write creds if nothing has changed Do not needlessly serialise the credential file again if nothing has changed from an existing credential found. This change also updates derived implementations (DPAPI and GPG). --- src/shared/Core/PlaintextCredentialStore.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shared/Core/PlaintextCredentialStore.cs b/src/shared/Core/PlaintextCredentialStore.cs index 124320d82..0ddd21357 100644 --- a/src/shared/Core/PlaintextCredentialStore.cs +++ b/src/shared/Core/PlaintextCredentialStore.cs @@ -33,6 +33,16 @@ public void AddOrUpdate(string service, string account, string secret) // Ensure the store root exists and permissions are set EnsureStoreRoot(); + FileCredential existingCredential = Enumerate(service, account).FirstOrDefault(); + + // No need to update existing credential if nothing has changed + if (existingCredential != null && + StringComparer.Ordinal.Equals(account, existingCredential.Account) && + StringComparer.Ordinal.Equals(secret, existingCredential.Password)) + { + return; + } + string serviceSlug = CreateServiceSlug(service); string servicePath = Path.Combine(StoreRoot, serviceSlug); From e0218ace4a93dcb152e528b24f600bed0ee8483c Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 13 Jun 2022 15:34:40 +0100 Subject: [PATCH 69/83] wincred: do not write creds if nothing has changed Do no bother writing out credentials if there is already an existing credential for the same account, with the same secret/password value. --- .../Core/Interop/Windows/Native/Advapi32.cs | 12 +++++++++ .../Windows/WindowsCredentialManager.cs | 26 +++++++------------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/shared/Core/Interop/Windows/Native/Advapi32.cs b/src/shared/Core/Interop/Windows/Native/Advapi32.cs index 924eb4349..14d4a3303 100644 --- a/src/shared/Core/Interop/Windows/Native/Advapi32.cs +++ b/src/shared/Core/Interop/Windows/Native/Advapi32.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using System.Text; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace GitCredentialManager.Interop.Windows.Native @@ -93,5 +94,16 @@ public struct Win32Credential public string TargetAlias; [MarshalAs(UnmanagedType.LPWStr)] public string UserName; + + public string GetCredentialBlobAsString() + { + if (CredentialBlobSize != 0 && CredentialBlob != IntPtr.Zero) + { + byte[] passwordBytes = InteropUtils.ToByteArray(CredentialBlob, CredentialBlobSize); + return Encoding.Unicode.GetString(passwordBytes); + } + + return null; + } } } diff --git a/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs b/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs index c9c3dd605..390a79b1f 100644 --- a/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs +++ b/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs @@ -13,8 +13,6 @@ public class WindowsCredentialManager : ICredentialStore private readonly string _namespace; - #region Constructors - /// /// Open the Windows Credential Manager vault for the current user. /// @@ -26,10 +24,6 @@ public WindowsCredentialManager(string @namespace = null) _namespace = @namespace; } - #endregion - - #region ICredentialStore - public ICredential Get(string service, string account) { return Enumerate(service, account).FirstOrDefault(); @@ -66,6 +60,15 @@ public void AddOrUpdate(string service, string account, string secret) // Create new entry with the account in the target name targetName = CreateTargetName(service, account); } + else + { + // No need to write out credential if the account and secret/password are the same + string existingSecret = existingCred.GetCredentialBlobAsString(); + if (StringComparer.Ordinal.Equals(existingSecret, secret)) + { + return; + } + } } byte[] secretBytes = Encoding.Unicode.GetBytes(secret); @@ -129,8 +132,6 @@ public bool Remove(string service, string account) return false; } - #endregion - /// /// Check if we can persist credentials to for the current process and logon session. /// @@ -205,14 +206,7 @@ private IEnumerable Enumerate(string service, string account) private WindowsCredential CreateCredentialFromStructure(Win32Credential credential) { - string password = null; - if (credential.CredentialBlobSize != 0 && credential.CredentialBlob != IntPtr.Zero) - { - byte[] passwordBytes = InteropUtils.ToByteArray( - credential.CredentialBlob, - credential.CredentialBlobSize); - password = Encoding.Unicode.GetString(passwordBytes); - } + string password = credential.GetCredentialBlobAsString(); // Recover the target name we gave from the internal (raw) target name string targetName = credential.TargetName.TrimUntilIndexOf(TargetNameLegacyGenericPrefix); From 43b5c5133780046ed42e94aa7eb9c94fd07afe40 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 13 Jun 2022 15:45:45 +0100 Subject: [PATCH 70/83] osx: only update keychain entries when needed Only update keychain entries when the password/secret is different to what is already stored. --- src/shared/Core/Interop/InteropUtils.cs | 17 +++++++++++++++++ src/shared/Core/Interop/MacOS/MacOSKeychain.cs | 7 +++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/shared/Core/Interop/InteropUtils.cs b/src/shared/Core/Interop/InteropUtils.cs index 9a72e243e..2964fa276 100644 --- a/src/shared/Core/Interop/InteropUtils.cs +++ b/src/shared/Core/Interop/InteropUtils.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Runtime.InteropServices; namespace GitCredentialManager.Interop @@ -11,5 +12,21 @@ public static byte[] ToByteArray(IntPtr ptr, long count) Marshal.Copy(ptr, destination, 0, destination.Length); return destination; } + + public static bool AreEqual(byte[] bytes, IntPtr ptr, uint length) + { + if (bytes.Length == 0 && (ptr == IntPtr.Zero || length == 0)) + { + return true; + } + + if (bytes.Length != length) + { + return false; + } + + byte[] ptrBytes = ToByteArray(ptr, length); + return bytes.SequenceEqual(ptrBytes); + } } } diff --git a/src/shared/Core/Interop/MacOS/MacOSKeychain.cs b/src/shared/Core/Interop/MacOS/MacOSKeychain.cs index 23d992b17..61df622b9 100644 --- a/src/shared/Core/Interop/MacOS/MacOSKeychain.cs +++ b/src/shared/Core/Interop/MacOS/MacOSKeychain.cs @@ -103,7 +103,6 @@ public void AddOrUpdate(string service, string account, string secret) string serviceName = CreateServiceName(service); - uint serviceNameLength = (uint) serviceName.Length; uint accountLength = (uint) (account?.Length ?? 0); @@ -112,12 +111,12 @@ public void AddOrUpdate(string service, string account, string secret) // Check if an entry already exists in the keychain int findResult = SecKeychainFindGenericPassword( IntPtr.Zero, serviceNameLength, serviceName, accountLength, account, - out uint _, out passwordData, out itemRef); + out uint passwordDataLength, out passwordData, out itemRef); switch (findResult) { - // Update existing entry - case OK: + // Update existing entry only if the password/secret is different + case OK when !InteropUtils.AreEqual(secretBytes, passwordData, passwordDataLength): ThrowIfError( SecKeychainItemModifyAttributesAndData(itemRef, IntPtr.Zero, (uint) secretBytes.Length, secretBytes), "Could not update existing item" From 3490948a8c61ad1ab3ca64b17f6faabc2268c59e Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 13 Jun 2022 15:49:05 +0100 Subject: [PATCH 71/83] libsecret: don't write out identical creds Avoid writing out credentials that are the same as an already existing cred. --- .../Core/Interop/Linux/SecretServiceCollection.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shared/Core/Interop/Linux/SecretServiceCollection.cs b/src/shared/Core/Interop/Linux/SecretServiceCollection.cs index ab3063b38..e6a61286a 100644 --- a/src/shared/Core/Interop/Linux/SecretServiceCollection.cs +++ b/src/shared/Core/Interop/Linux/SecretServiceCollection.cs @@ -114,6 +114,16 @@ public unsafe void AddOrUpdate(string service, string account, string secret) SecretValue* secretValue = null; GError *error = null; + // If there is an existing credential that matches the same account and password + // then don't bother writing out anything because they're the same! + ICredential existingCred = Get(service, account); + if (existingCred != null && + StringComparer.Ordinal.Equals(existingCred.Account, account) && + StringComparer.Ordinal.Equals(existingCred.Password, secret)) + { + return; + } + try { SecretService* secService = GetSecretService(); From b64cbc34669ad108a2eb5d2e65b0a10d70d422c0 Mon Sep 17 00:00:00 2001 From: Mike Minns Date: Tue, 14 Jun 2022 16:25:20 +0100 Subject: [PATCH 72/83] issue #722 BitbucketHostProvider: fix runtime exceptions when authentication requests for Bitbucket DC would incorrectly call a Bitbucket Cloud REST API A bug was introduced in commit: 5a2cfd7. Prior to this only authentication requests for Bitbucket Cloud would try and automatically determine if 2FA was required by the current user by calling a Bitbucket Cloud REST API using user provided Basic Auth credentials Commit: 5a2cfd7 removed checking of the current host was Bitbucket Cloud vs DC. This meant the check would be run for Bitbucket Cloud and DC regardless. It would fail for Bitbucket DC The fix is more radical than simply re-instating the check on the type of Bitbucket host. From 1st March 2022 support for using a Bitbucket Cloud user's account password to access REST or Git HTTPS operations has been removed, https://atlassian.community/t5/x/x/ba-p/1948231. As such this automatic test to see if 2FA is required no longer works. Therefore the check against the Bitbucket Cloud REST API has been removed in its entirety --- .../BitbucketHostProviderTest.cs | 26 ++--------- .../BitbucketHostProvider.cs | 45 ++----------------- 2 files changed, 7 insertions(+), 64 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 800b58d06..4e5230c5e 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -219,7 +219,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasic var credential = provider.GetCredentialAsync(input); - VerifyBasicAuthFlowRan(password, true, input, credential, null); + VerifyBasicAuthFlowRan(password, true, input, credential); VerifyOAuthFlowDidNotRun(password, true, input, credential); } @@ -327,7 +327,7 @@ public void BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_Is if (alwaysRefreshCredentialsBool) { - VerifyBasicAuthFlowRan(password, true, input, credential, null); + VerifyBasicAuthFlowRan(password, true, input, credential); } else { @@ -450,21 +450,13 @@ private static InputArguments MockInput(string protocol, string host, string use }); } - private void VerifyBasicAuthFlowRan(string password, bool expected, InputArguments input, Task credential, - string preconfiguredAuthModes) + private void VerifyBasicAuthFlowRan(string password, bool expected, InputArguments input, Task credential) { Assert.Equal(expected, credential != null); var remoteUri = input.GetRemoteUri(); bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - - // check username/password for Bitbucket.org - if ((preconfiguredAuthModes == null && BITBUCKET_DOT_ORG_HOST == remoteUri.Host) - || (preconfiguredAuthModes != null && preconfiguredAuthModes.Contains("oauth"))) - { - bitbucketApi.Verify(m => m.GetUserInformationAsync(input.UserName, password, false), Times.Once); - } } private void VerifyInteractiveBasicAuthFlowRan(string password, InputArguments input, Task credential) @@ -473,12 +465,6 @@ private void VerifyInteractiveBasicAuthFlowRan(string password, InputArguments i // verify users was prompted for username/password credentials bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - - // check username/password for Bitbucket.org - if (BITBUCKET_DOT_ORG_HOST == remoteUri.Host) - { - bitbucketApi.Verify(m => m.GetUserInformationAsync(input.UserName, password, false), Times.Once); - } } private void VerifyBasicAuthFlowNeverRan(string password, InputArguments input, bool storedAccount, @@ -527,13 +513,7 @@ private void VerifyOAuthFlowRan(string password, bool storedAccount, bool expect { // prompt user for basic auth, if basic auth is not excluded bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - - // check if entered Basic Auth credentials work, if basic auth is not excluded - bitbucketApi.Verify(m => m.GetUserInformationAsync(input.UserName, password, false), Times.Once); } - - // Basic Auth 403-ed so push user through OAuth flow - bitbucketAuthentication.Verify(m => m.ShowOAuthRequiredPromptAsync(), Times.Once); } } diff --git a/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs b/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs index e312d8cf7..724498a25 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs @@ -156,28 +156,16 @@ private async Task GetRefreshedCredentials(Uri remoteUri, string us switch (result.AuthenticationMode) { + case AuthenticationModes.Basic: + // Return the valid credential + return result.Credential; + case AuthenticationModes.OAuth: // If the user wants to use OAuth fall through to interactive auth // and avoid the OAuth "continue" confirmation prompt skipOAuthPrompt = true; break; - case AuthenticationModes.Basic: - // We need to check if these user/pass credentials require 2FA - _context.Trace.WriteLine("Checking if two-factor requirements for credentials..."); - - bool requires2Fa = await RequiresTwoFactorAuthenticationAsync(result.Credential); - if (!requires2Fa) - { - _context.Trace.WriteLine("Two-factor authentication not required"); - - // Return the valid credential - return result.Credential; - } - - // 2FA is required; fall through to interactive OAuth flow - break; - default: throw new ArgumentOutOfRangeException( $"Unexpected {nameof(AuthenticationModes)} returned from prompt"); @@ -371,31 +359,6 @@ private async Task ResolveBasicAuthUserNameAsync(string username, string throw new Exception($"Failed to resolve username. HTTP: {result.StatusCode}"); } - private async Task RequiresTwoFactorAuthenticationAsync(ICredential credentials) - { - _context.Trace.WriteLineSecrets($"Check if 2FA is required for credentials ({credentials.Account}/{{0}})...", new object[] { credentials.Password }); - - RestApiResult result = await _bitbucketApi.GetUserInformationAsync( - credentials.Account, credentials.Password, isBearerToken: false); - switch (result.StatusCode) - { - // 2FA may not be required - case HttpStatusCode.OK: - return result.Response.IsTwoFactorAuthenticationEnabled; - - // 2FA is required - case HttpStatusCode.Forbidden: - return true; - - // Incorrect credentials - case HttpStatusCode.Unauthorized: - throw new Exception("Invalid credentials"); - - default: - throw new Exception($"Unknown server response: {result.StatusCode}"); - } - } - private async Task ValidateCredentialsWork(Uri remoteUri, ICredential credentials, AuthenticationModes authModes) { if (credentials is null) From 5e0646b336e62d81d8fb09c063ec8a99bdeb3e73 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 15 Jun 2022 10:21:06 +0100 Subject: [PATCH 73/83] docs: fix incorrect Ubuntu uninstall command Fix the Ubuntu uninstall command which used the wrong package name. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53e8bbda5..e7e4c7472 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ To uninstall: ```shell git-credential-manager-core unconfigure -sudo dpkg -r gcm +sudo dpkg -r gcmcore ``` #### Other distributions From a0a7d948a1c5abd022b8cbd35549c56297e2f7ae Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Thu, 16 Jun 2022 13:32:32 +0100 Subject: [PATCH 74/83] wincred: fix bug in credential matching on port nums Fix a bug whereby we would not correctly match existing credentials when port numbers were used in the search. Additionally, actually now store the non-default port number in the target URI if there is one given. We also now always trim any trailing '/' from the end of the path of a service/target URI. Previously we erronously only trimmed the '/' from a 'pathless' URI, i.e.: https://example.com/ => https://example.com https://example.com/path/ => https://example.com/path/ This is a safe change since the `Enumerate` method that is used by both `Get` and `Remove` already matches _both_ trailing and non-trailing slashes by virtue of creating and comparing components of a `System.Uri` which does normalisation of the path. Both `Get` and `Remove` would act (eventually) to remove any bad credentials stored with a trailing slash, even if new credentials are only written out without the slash. --- .../Windows/WindowsCredentialManagerTests.cs | 71 +++++++++++++++++++ .../Windows/WindowsCredentialManager.cs | 24 +++++-- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs b/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs index 303aa126d..78295276e 100644 --- a/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs +++ b/src/shared/Core.Tests/Interop/Windows/WindowsCredentialManagerTests.cs @@ -1,6 +1,7 @@ using System; using Xunit; using GitCredentialManager.Interop.Windows; +using GitCredentialManager.Interop.Windows.Native; namespace GitCredentialManager.Tests.Interop.Windows { @@ -233,5 +234,75 @@ public void WindowsCredentialManager_RemoveUriUserInfo(string input, string expe string actual = WindowsCredentialManager.RemoveUriUserInfo(input); Assert.Equal(expected, actual); } + + [PlatformTheory(Platforms.Windows)] + [InlineData("https://example.com", null, "https://example.com", "alice", true)] + [InlineData("https://example.com", "alice", "https://example.com", "alice", true)] + [InlineData("https://example.com", null, "https://example.com:443", "alice", true)] + [InlineData("https://example.com", "alice", "https://example.com:443", "alice", true)] + [InlineData("https://example.com:1234", null, "https://example.com:1234", "alice", true)] + [InlineData("https://example.com:1234", "alice", "https://example.com:1234", "alice", true)] + [InlineData("https://example.com", null, "http://example.com", "alice", false)] + [InlineData("https://example.com", "alice", "http://example.com", "alice", false)] + [InlineData("https://example.com", "alice", "http://example.com:443", "alice", false)] + [InlineData("http://example.com:443", "alice", "https://example.com", "alice", false)] + [InlineData("https://example.com", "bob", "https://example.com", "alice", false)] + [InlineData("https://example.com", "bob", "https://bob@example.com", "bob", true)] + [InlineData("https://example.com", "bob", "https://example.com", "bob", true)] + [InlineData("https://example.com", "alice", "https://example.com", "ALICE", false)] // username case sensitive + [InlineData("https://example.com", "alice", "https://EXAMPLE.com", "alice", true)] // host NOT case sensitive + [InlineData("https://example.com/path", "alice", "https://example.com/path", "alice", true)] + [InlineData("https://example.com/path", "alice", "https://example.com/PATH", "alice", true)] // path NOT case sensitive + public void WindowsCredentialManager_IsMatch( + string service, string account, string targetName, string userName, bool expected) + { + string fullTargetName = $"{WindowsCredentialManager.TargetNameLegacyGenericPrefix}{TestNamespace}:{targetName}"; + var win32Cred = new Win32Credential + { + UserName = userName, + TargetName = fullTargetName + }; + + var credManager = new WindowsCredentialManager(TestNamespace); + + bool actual = credManager.IsMatch(service, account, win32Cred); + + Assert.Equal(expected, actual); + } + + [PlatformTheory(Platforms.Windows)] + [InlineData("https://example.com", null, "https://example.com")] + [InlineData("https://example.com", "bob", "https://bob@example.com")] + [InlineData("https://example.com", "bob@id.example.com", "https://bob_id.example.com@example.com")] // @ in user + [InlineData("https://example.com:443", null, "https://example.com")] // default port + [InlineData("https://example.com:1234", null, "https://example.com:1234")] + [InlineData("https://example.com/path", null, "https://example.com/path")] + [InlineData("https://example.com/path/with/more/parts", null, "https://example.com/path/with/more/parts")] + [InlineData("https://example.com/path/trim/", null, "https://example.com/path/trim")] // path trailing slash + [InlineData("https://example.com/", null, "https://example.com")] // no path trailing slash + public void WindowsCredentialManager_CreateTargetName(string service, string account, string expected) + { + string fullExpected = $"{TestNamespace}:{expected}"; + + var credManager = new WindowsCredentialManager(TestNamespace); + + string actual = credManager.CreateTargetName(service, account); + + Assert.Equal(fullExpected, actual); + } + + [PlatformTheory(Platforms.Windows)] + [InlineData(TestNamespace, "https://example.com", null, $"{TestNamespace}:https://example.com")] + [InlineData(null, "https://example.com", null, "https://example.com")] + [InlineData("", "https://example.com", null, "https://example.com")] + [InlineData(" ", "https://example.com", null, "https://example.com")] + public void WindowsCredentialManager_CreateTargetName_Namespace(string @namespace, string service, string account, string expected) + { + var credManager = new WindowsCredentialManager(@namespace); + + string actual = credManager.CreateTargetName(service, account); + + Assert.Equal(expected, actual); + } } } diff --git a/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs b/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs index 390a79b1f..2645ef293 100644 --- a/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs +++ b/src/shared/Core/Interop/Windows/WindowsCredentialManager.cs @@ -9,7 +9,7 @@ namespace GitCredentialManager.Interop.Windows { public class WindowsCredentialManager : ICredentialStore { - private const string TargetNameLegacyGenericPrefix = "LegacyGeneric:target="; + internal const string TargetNameLegacyGenericPrefix = "LegacyGeneric:target="; private readonly string _namespace; @@ -260,7 +260,7 @@ private WindowsCredential CreateCredentialFromStructure(Win32Credential credenti return url; } - private bool IsMatch(string service, string account, Win32Credential credential) + internal /* for testing */ bool IsMatch(string service, string account, Win32Credential credential) { // Match against the username first if (!string.IsNullOrWhiteSpace(account) && @@ -286,6 +286,12 @@ private bool IsMatch(string service, string account, Win32Credential credential) if (Uri.TryCreate(service, UriKind.Absolute, out Uri serviceUri) && Uri.TryCreate(targetName, UriKind.Absolute, out Uri targetUri)) { + // Match scheme/protocol + if (!StringComparer.OrdinalIgnoreCase.Equals(serviceUri.Scheme, targetUri.Scheme)) + { + return false; + } + // Match host name if (!StringComparer.OrdinalIgnoreCase.Equals(serviceUri.Host, targetUri.Host)) { @@ -293,7 +299,7 @@ private bool IsMatch(string service, string account, Win32Credential credential) } // Match port number - if (!serviceUri.IsDefaultPort && serviceUri.Port == targetUri.Port) + if (serviceUri.Port != targetUri.Port) { return false; } @@ -313,7 +319,7 @@ private bool IsMatch(string service, string account, Win32Credential credential) return false; } - private string CreateTargetName(string service, string account) + internal /* for testing */ string CreateTargetName(string service, string account) { var serviceUri = new Uri(service, UriKind.Absolute); var sb = new StringBuilder(); @@ -339,9 +345,15 @@ private string CreateTargetName(string service, string account) sb.Append(serviceUri.Host); } - if (!string.IsNullOrWhiteSpace(serviceUri.AbsolutePath.TrimEnd('/'))) + if (!serviceUri.IsDefaultPort) + { + sb.AppendFormat(":{0}", serviceUri.Port); + } + + string trimmedPath = serviceUri.AbsolutePath.TrimEnd('/'); + if (!string.IsNullOrWhiteSpace(trimmedPath)) { - sb.Append(serviceUri.AbsolutePath); + sb.Append(trimmedPath); } return sb.ToString(); From f45a5057c2a471b5938aa80e566ca5f286d47e90 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jun 2022 10:17:55 +0100 Subject: [PATCH 75/83] bb-test: update tests to await ICredential results --- .../BitbucketHostProviderTest.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 4e5230c5e..40fe7a762 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -138,7 +138,7 @@ public void BitbucketHostProvider_IsSupported_HttpResponseMessage(string header, [Theory] [InlineData("https", DC_SERVER_HOST, "jsquire", "password")] [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredBasicAuthAccount(string protocol, string host, string username,string password) + public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredBasicAuthAccount(string protocol, string host, string username,string password) { InputArguments input = MockInput(protocol, host, username); @@ -149,7 +149,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredBasi var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); //verify bitbucket.org credentials were validated if (BITBUCKET_DOT_ORG_HOST.Equals(host)) @@ -172,7 +172,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredBasi [Theory] // DC/Server does not currently support OAuth [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredOAuthAccount(string protocol, string host, string username,string token) + public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredOAuthAccount(string protocol, string host, string username,string token) { InputArguments input = MockInput(protocol, host, username); @@ -183,7 +183,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredOAut var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); //verify bitbucket.org credentials were validated VerifyValidateOAuthCredentialsRan(); @@ -200,7 +200,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredOAut [InlineData("https", DC_SERVER_HOST, "jsquire", "password")] // cloud [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasicAuthAccount(string protocol, string host, string username, string password) + public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasicAuthAccount(string protocol, string host, string username, string password) { InputArguments input = MockInput(protocol, host, username); @@ -217,7 +217,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasic var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); VerifyBasicAuthFlowRan(password, true, input, credential); @@ -227,7 +227,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasic [Theory] // DC/Server does not currently support OAuth [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_ACCESS_TOKEN)] - public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValid2FAAcccount(string protocol, string host, string username, string password) + public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValid2FAAcccount(string protocol, string host, string username, string password) { var input = MockInput(protocol, host, username); @@ -242,7 +242,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValid2FAAc var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); VerifyOAuthFlowRan(password, false, true, input, credential, null); @@ -254,7 +254,7 @@ public void BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValid2FAAc [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "basic")] [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "oauth")] // Basic Auth works - public void BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsRespected(string protocol, string host, string username, string password, + public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsRespected(string protocol, string host, string username, string password, string preconfiguredAuthModes) { var input = MockInput(protocol, host, username); @@ -271,7 +271,7 @@ public void BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsRespected( var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); Assert.NotNull(credential); @@ -301,7 +301,7 @@ public void BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsRespected( [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "1")] [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "true")] [InlineData("https", DC_SERVER_HOST, "jsquire", "password", null)] - public void BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_IsRespected(string protocol, string host, string username, string password, + public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_IsRespected(string protocol, string host, string username, string password, string alwaysRefreshCredentials) { var input = MockInput(protocol, host, username); @@ -319,7 +319,7 @@ public void BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_Is var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - var credential = provider.GetCredentialAsync(input); + var credential = await provider.GetCredentialAsync(input); var alwaysRefreshCredentialsBool = "1".Equals(alwaysRefreshCredentials) || "on".Equals(alwaysRefreshCredentials) @@ -450,7 +450,7 @@ private static InputArguments MockInput(string protocol, string host, string use }); } - private void VerifyBasicAuthFlowRan(string password, bool expected, InputArguments input, Task credential) + private void VerifyBasicAuthFlowRan(string password, bool expected, InputArguments input, ICredential credential) { Assert.Equal(expected, credential != null); @@ -459,7 +459,7 @@ private void VerifyBasicAuthFlowRan(string password, bool expected, InputArgumen bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); } - private void VerifyInteractiveBasicAuthFlowRan(string password, InputArguments input, Task credential) + private void VerifyInteractiveBasicAuthFlowRan(string password, InputArguments input, ICredential credential) { var remoteUri = input.GetRemoteUri(); @@ -485,14 +485,14 @@ private void VerifyBasicAuthFlowNeverRan(string password, InputArguments input, } } - private void VerifyInteractiveBasicAuthFlowNeverRan(string password, InputArguments input, Task credential) + private void VerifyInteractiveBasicAuthFlowNeverRan(string password, InputArguments input, ICredential credential) { var remoteUri = input.GetRemoteUri(); bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Never); } - private void VerifyOAuthFlowRan(string password, bool storedAccount, bool expected, InputArguments input, Task credential, + private void VerifyOAuthFlowRan(string password, bool storedAccount, bool expected, InputArguments input, ICredential credential, string preconfiguredAuthModes) { Assert.Equal(expected, credential != null); @@ -517,7 +517,7 @@ private void VerifyOAuthFlowRan(string password, bool storedAccount, bool expect } } - private void VerifyInteractiveOAuthFlowRan(string password, InputArguments input, System.Threading.Tasks.Task credential) + private void VerifyInteractiveOAuthFlowRan(string password, InputArguments input, ICredential credential) { var remoteUri = input.GetRemoteUri(); @@ -526,7 +526,7 @@ private void VerifyInteractiveOAuthFlowRan(string password, InputArguments input } - private void VerifyOAuthFlowDidNotRun(string password, bool expected, InputArguments input, System.Threading.Tasks.Task credential) + private void VerifyOAuthFlowDidNotRun(string password, bool expected, InputArguments input, ICredential credential) { Assert.Equal(expected, credential != null); @@ -542,7 +542,7 @@ private void VerifyOAuthFlowDidNotRun(string password, bool expected, InputArgum bitbucketApi.Verify(m => m.GetUserInformationAsync(null, MOCK_ACCESS_TOKEN, true), Times.Never); } - private void VerifyInteractiveOAuthFlowNeverRan(InputArguments input, System.Threading.Tasks.Task credential) + private void VerifyInteractiveOAuthFlowNeverRan(InputArguments input, ICredential credential) { var remoteUri = input.GetRemoteUri(); From 2babadc616cd6b7782f1a6f83012a521bb670952 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jun 2022 14:01:32 +0100 Subject: [PATCH 76/83] bb-test: inline 2FA mocking test helpers Inline some 2FA mock setup helper methods that differ only by a single boolean argument. --- .../BitbucketHostProviderTest.cs | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 40fe7a762..f2acd0da8 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -145,7 +145,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStor var context = new TestCommandContext(); MockStoredAccount(context, input, password); - MockRemoteBasicAuthAccountIsValidNo2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -213,7 +213,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshVali MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); } - MockRemoteBasicAuthAccountIsValidNo2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -236,7 +236,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshVali // user is prompted for basic auth credentials MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); // basic auth credentials are valid but 2FA is ON - MockRemoteBasicAuthAccountIsValidRequires2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); MockRemoteValidRefreshToken(); @@ -266,7 +266,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsResp } MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); - MockRemoteBasicAuthAccountIsValidRequires2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -315,7 +315,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredenti MockStoredAccount(context, input, password); MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); - MockRemoteBasicAuthAccountIsValidNo2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -390,7 +390,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ValidateTargetUriAsyn else { MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); - MockRemoteBasicAuthAccountIsValidRequires2FA(bitbucketApi, input, password); + MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); MockRemoteValidRefreshToken(); bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); bitbucketAuthentication.Setup(m => m.CreateOAuthCredentialsAsync(It.IsAny())).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); @@ -615,25 +615,15 @@ private static void MockUserDoesNotEntersValidBasicCredentials(Mock bitbucketApi, InputArguments input, string password, bool twoFAEnabled) + private static void MockRemoteBasicAuthAccountIsValid(Mock bitbucketApi, InputArguments input, string password, bool twoFactor) { - var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFAEnabled }; + var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFactor }; // Basic bitbucketApi.Setup(x => x.GetUserInformationAsync(input.UserName, password, false)) .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.OK, userInfo)); } - private static void MockRemoteBasicAuthAccountIsValidRequires2FA(Mock bitbucketApi, InputArguments input, string password) - { - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, true); - } - - private static void MockRemoteBasicAuthAccountIsValidNo2FA(Mock bitbucketApi, InputArguments input, string password) - { - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, false); - } - private static void MockRemoteBasicAuthAccountIsInvalid(Mock bitbucketApi, InputArguments input, string password) { var userInfo = new UserInfo(); From 81eccb90bf9952b754488b1f74c088f915f77e5c Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jun 2022 14:04:48 +0100 Subject: [PATCH 77/83] bb-test: remove unused test helpers --- .../BitbucketHostProviderTest.cs | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index f2acd0da8..280ecb505 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -568,40 +568,17 @@ private void VerifyValidateBasicAuthCredentialsRan() bitbucketApi.Verify(m => m.GetUserInformationAsync(It.IsAny(), It.IsAny(), false), Times.Once); } - private void VerifyValidateOAuthCredentialsNeverRan() - { - // never check username/password works - bitbucketApi.Verify(m => m.GetUserInformationAsync(null, It.IsAny(), false), Times.Never); - } - private void VerifyValidateOAuthCredentialsRan() { // check username/password works bitbucketApi.Verify(m => m.GetUserInformationAsync(null, It.IsAny(), true), Times.Once); } - private void MockStoredOAuthAccount(TestCommandContext context, InputArguments input) - { - // refresh token - context.CredentialStore.Add("https://bitbucket.org/refresh_token", new TestCredential(input.Host, input.UserName, MOCK_REFRESH_TOKEN)); - // auth token - context.CredentialStore.Add("https://bitbucket.org", new TestCredential(input.Host, input.UserName, MOCK_ACCESS_TOKEN)); - } - private void MockRemoteValidRefreshToken() { bitbucketAuthentication.Setup(m => m.RefreshOAuthCredentialsAsync(MOCK_REFRESH_TOKEN)).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); } - private static void MockInvalidRemoteBasicAccount(Mock bitbucketApi, Mock bitbucketAuthentication) - { - bitbucketAuthentication.Setup(m => m.GetCredentialsAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.Basic, null)); - - bitbucketApi.Setup(x => x.GetUserInformationAsync(It.IsAny(), It.IsAny(), false)) - .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.Unauthorized)); - - } private static void MockUserEntersValidBasicCredentials(Mock bitbucketAuthentication, InputArguments input, string password) { var remoteUri = input.GetRemoteUri(); @@ -609,12 +586,6 @@ private static void MockUserEntersValidBasicCredentials(Mock bitbucketAuthentication) - { - bitbucketAuthentication.Setup(m => m.GetCredentialsAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.Basic, null)); - } - private static void MockRemoteBasicAuthAccountIsValid(Mock bitbucketApi, InputArguments input, string password, bool twoFactor) { var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFactor }; @@ -624,15 +595,6 @@ private static void MockRemoteBasicAuthAccountIsValid(Mock bi } - private static void MockRemoteBasicAuthAccountIsInvalid(Mock bitbucketApi, InputArguments input, string password) - { - var userInfo = new UserInfo(); - // Basic - bitbucketApi.Setup(x => x.GetUserInformationAsync(input.UserName, password, false)) - .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.Forbidden, userInfo)); - - } - private static void MockRemoteOAuthAccountIsValid(Mock bitbucketApi, InputArguments input, string password, bool twoFAEnabled) { var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFAEnabled }; @@ -648,14 +610,6 @@ private static void MockStoredAccount(TestCommandContext context, InputArguments context.CredentialStore.Add(remoteUrl, new TestCredential(input.Host, input.UserName, password)); } - private static void MockValidStoredOAuthUser(TestCommandContext context, Mock bitbucketApi) - { - var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = false }; - bitbucketApi.Setup(x => x.GetUserInformationAsync("jsquire", "password1", false)) - .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.OK, userInfo)); - context.CredentialStore.Add("https://bitbucket.org", new TestCredential("https://bitbucket.org", "jsquire", "password1")); - } - #endregion } } From 8e143e066759926d016c998b8f534818329d0121 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jun 2022 14:11:58 +0100 Subject: [PATCH 78/83] bb-test: rename test/mock helper methods Rename some of the test/mock helper methods to be a little easier to grok/be shorter. --- .../BitbucketHostProviderTest.cs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 280ecb505..8dbb76fed 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -145,7 +145,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStor var context = new TestCommandContext(); MockStoredAccount(context, input, password); - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -163,7 +163,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStor } // Stored credentials so don't ask for more - VerifyInteractiveBasicAuthFlowNeverRan(password, input, credential); + VerifyInteractiveAuthNeverRan(password, input, credential); // Valid Basic Auth credentials so don't run Oauth VerifyInteractiveOAuthFlowNeverRan(input, credential); @@ -179,7 +179,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStor var context = new TestCommandContext(); MockStoredAccount(context, input, token); - MockRemoteOAuthAccountIsValid(bitbucketApi, input, token, false); + MockRemoteAccessTokenValid(bitbucketApi, input, token, false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -189,7 +189,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStor VerifyValidateOAuthCredentialsRan(); // Stored credentials so don't ask for more - VerifyInteractiveBasicAuthFlowNeverRan(token, input, credential); + VerifyInteractiveAuthNeverRan(token, input, credential); // Valid Basic Auth credentials so don't run Oauth VerifyInteractiveOAuthFlowNeverRan(input, credential); @@ -206,14 +206,14 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshVali var context = new TestCommandContext(); - MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); + MockPromptBasic(bitbucketAuthentication, input, password); if (BITBUCKET_DOT_ORG_HOST.Equals(host)) { - MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); + MockRemoteAccessTokenValid(bitbucketApi, input, password, true); } - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -234,10 +234,10 @@ public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshVali var context = new TestCommandContext(); // user is prompted for basic auth credentials - MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); + MockPromptBasic(bitbucketAuthentication, input, password); // basic auth credentials are valid but 2FA is ON - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); - MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); + MockRemoteAccessTokenValid(bitbucketApi, input, password, true); MockRemoteValidRefreshToken(); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -265,8 +265,8 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsResp context.Environment.Variables.Add(BitbucketConstants.EnvironmentVariables.AuthenticationModes, preconfiguredAuthModes); } - MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); + MockPromptBasic(bitbucketAuthentication, input, password); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -283,7 +283,7 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsResp if (preconfiguredAuthModes.Contains("oauth")) { - VerifyInteractiveBasicAuthFlowNeverRan(password, input, credential); + VerifyInteractiveAuthNeverRan(password, input, credential); VerifyInteractiveOAuthFlowRan(password, input, credential); } } @@ -313,9 +313,9 @@ public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredenti } MockStoredAccount(context, input, password); - MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); - MockRemoteOAuthAccountIsValid(bitbucketApi, input, password, true); - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: false); + MockPromptBasic(bitbucketAuthentication, input, password); + MockRemoteAccessTokenValid(bitbucketApi, input, password, true); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -389,8 +389,8 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ValidateTargetUriAsyn } else { - MockUserEntersValidBasicCredentials(bitbucketAuthentication, input, password); - MockRemoteBasicAuthAccountIsValid(bitbucketApi, input, password, twoFactor: true); + MockPromptBasic(bitbucketAuthentication, input, password); + MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); MockRemoteValidRefreshToken(); bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); bitbucketAuthentication.Setup(m => m.CreateOAuthCredentialsAsync(It.IsAny())).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); @@ -485,7 +485,7 @@ private void VerifyBasicAuthFlowNeverRan(string password, InputArguments input, } } - private void VerifyInteractiveBasicAuthFlowNeverRan(string password, InputArguments input, ICredential credential) + private void VerifyInteractiveAuthNeverRan(string password, InputArguments input, ICredential credential) { var remoteUri = input.GetRemoteUri(); @@ -579,14 +579,14 @@ private void MockRemoteValidRefreshToken() bitbucketAuthentication.Setup(m => m.RefreshOAuthCredentialsAsync(MOCK_REFRESH_TOKEN)).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); } - private static void MockUserEntersValidBasicCredentials(Mock bitbucketAuthentication, InputArguments input, string password) + private static void MockPromptBasic(Mock bitbucketAuthentication, InputArguments input, string password) { var remoteUri = input.GetRemoteUri(); bitbucketAuthentication.Setup(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny())) .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.Basic, new TestCredential(input.Host, input.UserName, password))); } - private static void MockRemoteBasicAuthAccountIsValid(Mock bitbucketApi, InputArguments input, string password, bool twoFactor) + private static void MockRemoteBasicValid(Mock bitbucketApi, InputArguments input, string password, bool twoFactor) { var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFactor }; // Basic @@ -595,7 +595,7 @@ private static void MockRemoteBasicAuthAccountIsValid(Mock bi } - private static void MockRemoteOAuthAccountIsValid(Mock bitbucketApi, InputArguments input, string password, bool twoFAEnabled) + private static void MockRemoteAccessTokenValid(Mock bitbucketApi, InputArguments input, string password, bool twoFAEnabled) { var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFAEnabled }; // OAuth From bf068e1ded25347959ea6ee2dfc1e7d1f398344d Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jun 2022 10:04:32 +0100 Subject: [PATCH 79/83] bitbucket: remove separate OAuth prompt/dialog Remove the separate "OAuth Required" UI prompt in favour of just always showing the "Credentials" prompt, where users can select the OAuth auth mode directly anyway. --- .../BitbucketAuthenticationTest.cs | 15 - .../BitbucketHostProviderTest.cs | 459 +++++++++--------- .../BitbucketAuthentication.cs | 47 +- .../BitbucketHostProvider.cs | 69 +-- 4 files changed, 252 insertions(+), 338 deletions(-) diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs index 0606c8111..9fac31e93 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs @@ -108,21 +108,6 @@ public async Task BitbucketAuthentication_GetCredentialsAsync_All_NoDesktopSessi Assert.Equal(password, result.Credential.Password); } - [Fact] - public async Task BitbucketAuthentication_ShowOAuthRequiredPromptAsync_SucceedsAfterUserInput() - { - var context = new TestCommandContext(); - context.Terminal.Prompts["Press enter to continue..."] = " "; - - var bitbucketAuthentication = new BitbucketAuthentication(context); - - var result = await bitbucketAuthentication.ShowOAuthRequiredPromptAsync(); - - Assert.True(result); - Assert.Equal($"Your account has two-factor authentication enabled.{Environment.NewLine}" + - $"To continue you must complete authentication in your web browser.{Environment.NewLine}", context.Terminal.Messages[0].Item1); - } - [Fact] public async Task BitbucketAuthentication_GetCredentialsAsync_AllModes_NoUser_BBCloud_HelperCmdLine() { diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index 8dbb76fed..f658c4029 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -15,6 +15,8 @@ public class BitbucketHostProviderTest #region Tests private const string MOCK_ACCESS_TOKEN = "at-0987654321"; + private const string MOCK_ACCESS_TOKEN_ALT = "at-onetwothreefour-1234"; + private const string MOCK_EXPIRED_ACCESS_TOKEN = "at-1234567890-expired"; private const string MOCK_REFRESH_TOKEN = "rt-1234567809"; private const string BITBUCKET_DOT_ORG_HOST = "bitbucket.org"; private const string DC_SERVER_HOST = "example.com"; @@ -138,136 +140,189 @@ public void BitbucketHostProvider_IsSupported_HttpResponseMessage(string header, [Theory] [InlineData("https", DC_SERVER_HOST, "jsquire", "password")] [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredBasicAuthAccount(string protocol, string host, string username,string password) + public async Task BitbucketHostProvider_GetCredentialAsync_Valid_Stored_Basic( + string protocol, string host, string username, string password) { InputArguments input = MockInput(protocol, host, username); var context = new TestCommandContext(); MockStoredAccount(context, input, password); - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); + MockRemoteBasicValid(input, password); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); var credential = await provider.GetCredentialAsync(input); - //verify bitbucket.org credentials were validated + Assert.Equal(username, credential.Account); + Assert.Equal(password, credential.Password); + + // Verify bitbucket.org credentials were validated if (BITBUCKET_DOT_ORG_HOST.Equals(host)) { - VerifyValidateBasicAuthCredentialsRan(); + VerifyValidateBasicAuthCredentialsRan(input, password); } else { - //verify DC/Server credentials were not validated + // Verify DC/Server credentials were not validated VerifyValidateBasicAuthCredentialsNeverRan(); } // Stored credentials so don't ask for more - VerifyInteractiveAuthNeverRan(password, input, credential); - - // Valid Basic Auth credentials so don't run Oauth - VerifyInteractiveOAuthFlowNeverRan(input, credential); + VerifyInteractiveAuthNeverRan(); } [Theory] // DC/Server does not currently support OAuth [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForValidStoredOAuthAccount(string protocol, string host, string username,string token) + public async Task BitbucketHostProvider_GetCredentialAsync_Valid_Stored_OAuth( + string protocol, string host, string username, string token) { InputArguments input = MockInput(protocol, host, username); var context = new TestCommandContext(); MockStoredAccount(context, input, token); - MockRemoteAccessTokenValid(bitbucketApi, input, token, false); + MockRemoteAccessTokenValid(input, token); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); var credential = await provider.GetCredentialAsync(input); - //verify bitbucket.org credentials were validated - VerifyValidateOAuthCredentialsRan(); + Assert.Equal(username, credential.Account); + Assert.Equal(token, credential.Password); - // Stored credentials so don't ask for more - VerifyInteractiveAuthNeverRan(token, input, credential); + // Verify bitbucket.org credentials were validated + VerifyValidateAccessTokenRan(input, token); - // Valid Basic Auth credentials so don't run Oauth - VerifyInteractiveOAuthFlowNeverRan(input, credential); + // Stored credentials so don't ask for more + VerifyInteractiveAuthNeverRan(); } [Theory] // DC [InlineData("https", DC_SERVER_HOST, "jsquire", "password")] - // cloud + // Cloud [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValidBasicAuthAccount(string protocol, string host, string username, string password) + public async Task BitbucketHostProvider_GetCredentialAsync_Valid_New_Basic( + string protocol, string host, string username, string password) { InputArguments input = MockInput(protocol, host, username); var context = new TestCommandContext(); - MockPromptBasic(bitbucketAuthentication, input, password); + MockPromptBasic(input, password); + MockRemoteBasicValid(input, password); - if (BITBUCKET_DOT_ORG_HOST.Equals(host)) - { - MockRemoteAccessTokenValid(bitbucketApi, input, password, true); - } + var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); + + var credential = await provider.GetCredentialAsync(input); + + Assert.Equal(username, credential.Account); + Assert.Equal(password, credential.Password); + + VerifyInteractiveAuthRan(input); + } + + [Theory] + // DC/Server does not currently support OAuth + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_REFRESH_TOKEN, MOCK_ACCESS_TOKEN)] + public async Task BitbucketHostProvider_GetCredentialAsync_Valid_New_OAuth( + string protocol, string host, string username, string refreshToken, string accessToken) + { + InputArguments input = MockInput(protocol, host, username); + + var context = new TestCommandContext(); - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); + MockPromptOAuth(input); + MockRemoteOAuthTokenCreate(input, accessToken, refreshToken); + MockRemoteAccessTokenValid(input, accessToken); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); var credential = await provider.GetCredentialAsync(input); - VerifyBasicAuthFlowRan(password, true, input, credential); + Assert.Equal(username, credential.Account); + Assert.Equal(accessToken, credential.Password); - VerifyOAuthFlowDidNotRun(password, true, input, credential); + VerifyInteractiveAuthRan(input); + VerifyOAuthFlowRan(input, accessToken); + VerifyValidateAccessTokenRan(input, accessToken); + VerifyOAuthRefreshTokenStored(context, input, refreshToken); } [Theory] // DC/Server does not currently support OAuth - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_ACCESS_TOKEN)] - public async Task BitbucketHostProvider_GetCredentialAsync_Succeeds_ForFreshValid2FAAcccount(string protocol, string host, string username, string password) + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_REFRESH_TOKEN, MOCK_ACCESS_TOKEN)] + public async Task BitbucketHostProvider_GetCredentialAsync_MissingAT_OAuth_Refresh( + string protocol, string host, string username, string refreshToken, string accessToken) { var input = MockInput(protocol, host, username); var context = new TestCommandContext(); - // user is prompted for basic auth credentials - MockPromptBasic(bitbucketAuthentication, input, password); - // basic auth credentials are valid but 2FA is ON - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); - MockRemoteAccessTokenValid(bitbucketApi, input, password, true); - MockRemoteValidRefreshToken(); + // AT has does not exist, but RT is still valid + MockStoredRefreshToken(context, input, refreshToken); + MockRemoteAccessTokenValid(input, accessToken); + MockRemoteRefreshTokenValid(refreshToken, accessToken); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); var credential = await provider.GetCredentialAsync(input); - VerifyOAuthFlowRan(password, false, true, input, credential, null); + Assert.Equal(username, credential.Account); + Assert.Equal(accessToken, credential.Password); - VerifyBasicAuthFlowNeverRan(password, input, false, null); + VerifyValidateAccessTokenRan(input, accessToken); + VerifyOAuthRefreshRan(refreshToken); + VerifyInteractiveAuthNeverRan(); } [Theory] - // cloud - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "basic")] - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "oauth")] - // Basic Auth works - public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsRespected(string protocol, string host, string username, string password, - string preconfiguredAuthModes) + // DC/Server does not currently support OAuth + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_REFRESH_TOKEN, MOCK_EXPIRED_ACCESS_TOKEN, MOCK_ACCESS_TOKEN)] + public async Task BitbucketHostProvider_GetCredentialAsync_ExpiredAT_OAuth_Refresh( + string protocol, string host, string username, string refreshToken, string expiredAccessToken, string accessToken) { var input = MockInput(protocol, host, username); var context = new TestCommandContext(); - if (preconfiguredAuthModes != null) - { - context.Environment.Variables.Add(BitbucketConstants.EnvironmentVariables.AuthenticationModes, preconfiguredAuthModes); - } - MockPromptBasic(bitbucketAuthentication, input, password); - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); - bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); + // AT exists but has expired, but RT is still valid + MockStoredAccount(context, input, expiredAccessToken); + MockRemoteAccessTokenExpired(input, expiredAccessToken); + + MockStoredRefreshToken(context, input, refreshToken); + MockRemoteAccessTokenValid(input, accessToken); + MockRemoteRefreshTokenValid(refreshToken, accessToken); + + var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); + + var credential = await provider.GetCredentialAsync(input); + + Assert.Equal(username, credential.Account); + Assert.Equal(accessToken, credential.Password); + + VerifyValidateAccessTokenRan(input, accessToken); + VerifyOAuthRefreshRan(refreshToken); + VerifyInteractiveAuthNeverRan(); + } + + [Theory] + // Cloud + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_REFRESH_TOKEN, MOCK_ACCESS_TOKEN)] + public async Task BitbucketHostProvider_GetCredentialAsync_PreconfiguredMode_OAuth_ValidRT_IsRespected( + string protocol, string host, string username, string refreshToken, string accessToken) + { + var input = MockInput(protocol, host, username); + + var context = new TestCommandContext(); + context.Environment.Variables.Add(BitbucketConstants.EnvironmentVariables.AuthenticationModes, "oauth"); + + // We have a stored RT so we can just use that without any prompts + MockStoredRefreshToken(context, input, refreshToken); + MockRemoteAccessTokenValid(input, accessToken); + MockRemoteRefreshTokenValid(refreshToken, accessToken); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); @@ -275,73 +330,72 @@ public async Task BitbucketHostProvider_GetCredentialAsync_ForcedAuthMode_IsResp Assert.NotNull(credential); - if (preconfiguredAuthModes.Contains("basic")) - { - VerifyInteractiveBasicAuthFlowRan(password, input, credential); - VerifyInteractiveOAuthFlowNeverRan(input, credential); - } + VerifyInteractiveAuthNeverRan(); + VerifyOAuthRefreshRan(refreshToken); + } - if (preconfiguredAuthModes.Contains("oauth")) - { - VerifyInteractiveAuthNeverRan(password, input, credential); - VerifyInteractiveOAuthFlowRan(password, input, credential); - } + [Theory] + // DC/Server does not currently support OAuth + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", MOCK_ACCESS_TOKEN, MOCK_ACCESS_TOKEN_ALT, MOCK_REFRESH_TOKEN)] + public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_OAuth_IsRespected( + string protocol, string host, string username, string storedToken, string newToken, string refreshToken) + { + var input = MockInput(protocol, host, username); + + var context = new TestCommandContext(); + context.Environment.Variables.Add( + BitbucketConstants.EnvironmentVariables.AlwaysRefreshCredentials, bool.TrueString); + + // User has stored access token that we shouldn't use - RT should be used to mint new AT + MockStoredAccount(context, input, storedToken); + MockStoredRefreshToken(context, input, refreshToken); + MockRemoteAccessTokenValid(input, newToken); + MockRemoteRefreshTokenValid(refreshToken, newToken); + + var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); + + var credential = await provider.GetCredentialAsync(input); + + Assert.Equal(username, credential.Account); + Assert.Equal(newToken, credential.Password); + + VerifyInteractiveAuthNeverRan(); + VerifyOAuthRefreshRan(refreshToken); } [Theory] - // cloud - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "false")] - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "0")] - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "true")] - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", "1")] - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password", null)] + // Cloud + [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "old-password", "new-password")] // DC - [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "false")] - [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "0")] - [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "1")] - [InlineData("https", DC_SERVER_HOST, "jsquire", "password", "true")] - [InlineData("https", DC_SERVER_HOST, "jsquire", "password", null)] - public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_IsRespected(string protocol, string host, string username, string password, - string alwaysRefreshCredentials) + [InlineData("https", DC_SERVER_HOST, "jsquire", "old-password", "new-password")] + public async Task BitbucketHostProvider_GetCredentialAsync_AlwaysRefreshCredentials_Basic_IsRespected( + string protocol, string host, string username, string storedPassword, string freshPassword) { var input = MockInput(protocol, host, username); var context = new TestCommandContext(); - if (alwaysRefreshCredentials != null) - { - context.Environment.Variables.Add(BitbucketConstants.EnvironmentVariables.AlwaysRefreshCredentials, alwaysRefreshCredentials); - } + context.Environment.Variables.Add( + BitbucketConstants.EnvironmentVariables.AlwaysRefreshCredentials, bool.TrueString); - MockStoredAccount(context, input, password); - MockPromptBasic(bitbucketAuthentication, input, password); - MockRemoteAccessTokenValid(bitbucketApi, input, password, true); - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: false); + // User has stored password that we shouldn't use + MockStoredAccount(context, input, storedPassword); + MockPromptBasic(input, freshPassword); var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); var credential = await provider.GetCredentialAsync(input); - var alwaysRefreshCredentialsBool = "1".Equals(alwaysRefreshCredentials) - || "on".Equals(alwaysRefreshCredentials) - || "true".Equals(alwaysRefreshCredentials) ? true : false; + Assert.Equal(username, credential.Account); + Assert.Equal(freshPassword, credential.Password); - if (alwaysRefreshCredentialsBool) - { - VerifyBasicAuthFlowRan(password, true, input, credential); - } - else - { - VerifyBasicAuthFlowNeverRan(password, input, true, null); - } - - VerifyOAuthFlowDidNotRun(password, true, input, credential); + VerifyInteractiveAuthRan(input); } [Theory] // DC - supports Basic [InlineData("https://example.com", "basic", AuthenticationModes.Basic)] [InlineData("https://example.com", "oauth", AuthenticationModes.Basic)] - // cloud - supports Basic, OAuth + // Cloud - supports Basic, OAuth [InlineData("https://bitbucket.org", "oauth", AuthenticationModes.OAuth)] [InlineData("https://bitbucket.org", "basic", AuthenticationModes.Basic)] [InlineData("https://bitbucket.org", "NOT-A-REAL-VALUE", BitbucketConstants.DotOrgAuthenticationModes)] @@ -354,7 +408,7 @@ public void BitbucketHostProvider_GetSupportedAuthenticationModes(string uriStri { var targetUri = new Uri(uriString); - var context = new TestCommandContext { }; + var context = new TestCommandContext(); if (bitbucketAuthModes != null) { context.Environment.Variables.Add(BitbucketConstants.EnvironmentVariables.AuthenticationModes, bitbucketAuthModes); @@ -367,40 +421,6 @@ public void BitbucketHostProvider_GetSupportedAuthenticationModes(string uriStri Assert.Equal(expectedModes, actualModes); } - [Theory] - // DC - [InlineData("https", DC_SERVER_HOST, "jsquire", "password")] - [InlineData("http", DC_SERVER_HOST, "jsquire", "password")] - // cloud - [InlineData("https", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - [InlineData("http", BITBUCKET_DOT_ORG_HOST, "jsquire", "password")] - public async Task BitbucketHostProvider_GetCredentialAsync_ValidateTargetUriAsync(string protocol, string host, string username, string password) - { - var input = MockInput(protocol, host, username); - - var context = new TestCommandContext(); - - var provider = new BitbucketHostProvider(context, bitbucketAuthentication.Object, bitbucketApi.Object); - - if (protocol.ToLower().Equals("http") && host.ToLower().Equals(BITBUCKET_DOT_ORG_HOST)) - { - // only fail for http://bitbucket.org - await Assert.ThrowsAsync(async () => await provider.GetCredentialAsync(input)); - } - else - { - MockPromptBasic(bitbucketAuthentication, input, password); - MockRemoteBasicValid(bitbucketApi, input, password, twoFactor: true); - MockRemoteValidRefreshToken(); - bitbucketAuthentication.Setup(m => m.ShowOAuthRequiredPromptAsync()).ReturnsAsync(true); - bitbucketAuthentication.Setup(m => m.CreateOAuthCredentialsAsync(It.IsAny())).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); - var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = false }; - bitbucketApi.Setup(x => x.GetUserInformationAsync(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.OK, userInfo)); - - var credential = await provider.GetCredentialAsync(input); - } - } - [Theory] [InlineData("https", DC_SERVER_HOST, "jsquire")] public async Task BitbucketHostProvider_StoreCredentialAsync(string protocol, string host, string username) @@ -440,6 +460,7 @@ public async Task BitbucketHostProvider_EraseCredentialAsync(string protocol, st #endregion #region Test helpers + private static InputArguments MockInput(string protocol, string host, string username) { return new InputArguments(new Dictionary @@ -450,156 +471,102 @@ private static InputArguments MockInput(string protocol, string host, string use }); } - private void VerifyBasicAuthFlowRan(string password, bool expected, InputArguments input, ICredential credential) + private void VerifyOAuthFlowRan(InputArguments input, string token) { - Assert.Equal(expected, credential != null); - var remoteUri = input.GetRemoteUri(); - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - } - - private void VerifyInteractiveBasicAuthFlowRan(string password, InputArguments input, ICredential credential) - { - var remoteUri = input.GetRemoteUri(); + // use refresh token to get new access token and refresh token + bitbucketAuthentication.Verify(m => m.CreateOAuthCredentialsAsync(remoteUri), Times.Once); - // verify users was prompted for username/password credentials - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); + // Check access token works/resolve username + bitbucketApi.Verify(m => m.GetUserInformationAsync(null, token, true), Times.Once); } - private void VerifyBasicAuthFlowNeverRan(string password, InputArguments input, bool storedAccount, - string preconfiguredAuthModes) - { - var remoteUri = input.GetRemoteUri(); - - if (!storedAccount && - (preconfiguredAuthModes == null || preconfiguredAuthModes.Contains("basic")) ) - { - // never prompt the user for basic credentials - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - } - else - { - // never prompt the user for basic credentials - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Never); - } - } - - private void VerifyInteractiveAuthNeverRan(string password, InputArguments input, ICredential credential) - { - var remoteUri = input.GetRemoteUri(); - - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Never); - } - - private void VerifyOAuthFlowRan(string password, bool storedAccount, bool expected, InputArguments input, ICredential credential, - string preconfiguredAuthModes) + private void VerifyValidateBasicAuthCredentialsNeverRan() { - Assert.Equal(expected, credential != null); - - var remoteUri = input.GetRemoteUri(); - - if (storedAccount) - { - // use refresh token to get new access token and refresh token - bitbucketAuthentication.Verify(m => m.RefreshOAuthCredentialsAsync(MOCK_REFRESH_TOKEN), Times.Once); - - // check access token works - bitbucketApi.Verify(m => m.GetUserInformationAsync(null, MOCK_ACCESS_TOKEN, true), Times.Once); - } - else - { - if (preconfiguredAuthModes == null || preconfiguredAuthModes.Contains("basic")) - { - // prompt user for basic auth, if basic auth is not excluded - bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); - } - } + // Never check username/password works + bitbucketApi.Verify(m => m.GetUserInformationAsync(It.IsAny(), It.IsAny(), false), Times.Never); } - private void VerifyInteractiveOAuthFlowRan(string password, InputArguments input, ICredential credential) + private void VerifyValidateBasicAuthCredentialsRan(InputArguments input, string password) { - var remoteUri = input.GetRemoteUri(); - - // Basic Auth 403-ed so push user through OAuth flow - bitbucketAuthentication.Verify(m => m.ShowOAuthRequiredPromptAsync(), Times.Once); - + // Check username/password works + bitbucketApi.Verify(m => m.GetUserInformationAsync(input.UserName, password, false), Times.Once); } - private void VerifyOAuthFlowDidNotRun(string password, bool expected, InputArguments input, ICredential credential) + private void VerifyValidateAccessTokenRan(InputArguments input, string token) { - Assert.Equal(expected, credential != null); - - var remoteUri = input.GetRemoteUri(); - - // never prompt user through OAuth flow - bitbucketAuthentication.Verify(m => m.ShowOAuthRequiredPromptAsync(), Times.Never); - - // Never try to refresh Access Token - bitbucketAuthentication.Verify(m => m.RefreshOAuthCredentialsAsync(It.IsAny()), Times.Never); - - // never check access token works - bitbucketApi.Verify(m => m.GetUserInformationAsync(null, MOCK_ACCESS_TOKEN, true), Times.Never); + // Check tokens works + bitbucketApi.Verify(m => m.GetUserInformationAsync(null, token, true), Times.Once); } - private void VerifyInteractiveOAuthFlowNeverRan(InputArguments input, ICredential credential) + private void VerifyInteractiveAuthRan(InputArguments input) { var remoteUri = input.GetRemoteUri(); - // never prompt user through OAuth flow - bitbucketAuthentication.Verify(m => m.ShowOAuthRequiredPromptAsync(), Times.Never); - - // Never try to refresh Access Token - bitbucketAuthentication.Verify(m => m.RefreshOAuthCredentialsAsync(It.IsAny()), Times.Never); - - // never check access token works - bitbucketApi.Verify(m => m.GetUserInformationAsync(null, MOCK_ACCESS_TOKEN, true), Times.Never); + bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny()), Times.Once); } - private void VerifyValidateBasicAuthCredentialsNeverRan() + private void VerifyInteractiveAuthNeverRan() { - // never check username/password works - bitbucketApi.Verify(m => m.GetUserInformationAsync(It.IsAny(), It.IsAny(), false), Times.Never); + bitbucketAuthentication.Verify(m => m.GetCredentialsAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } - private void VerifyValidateBasicAuthCredentialsRan() + private void VerifyOAuthRefreshRan(string refreshToken) { - // check username/password works - bitbucketApi.Verify(m => m.GetUserInformationAsync(It.IsAny(), It.IsAny(), false), Times.Once); + // Check refresh was called + bitbucketAuthentication.Verify(m => m.RefreshOAuthCredentialsAsync(refreshToken), Times.Once); } - private void VerifyValidateOAuthCredentialsRan() + private void MockRemoteRefreshTokenValid(string refreshToken, string accessToken) { - // check username/password works - bitbucketApi.Verify(m => m.GetUserInformationAsync(null, It.IsAny(), true), Times.Once); + bitbucketAuthentication.Setup(m => m.RefreshOAuthCredentialsAsync(refreshToken)).ReturnsAsync(new OAuth2TokenResult(accessToken, "access_token")); } - private void MockRemoteValidRefreshToken() + private void MockPromptBasic(InputArguments input, string password) { - bitbucketAuthentication.Setup(m => m.RefreshOAuthCredentialsAsync(MOCK_REFRESH_TOKEN)).ReturnsAsync(new OAuth2TokenResult(MOCK_ACCESS_TOKEN, "access_token")); + var remoteUri = input.GetRemoteUri(); + bitbucketAuthentication.Setup(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny())) + .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.Basic, new TestCredential(input.Host, input.UserName, password))); } - private static void MockPromptBasic(Mock bitbucketAuthentication, InputArguments input, string password) + private void MockPromptOAuth(InputArguments input) { var remoteUri = input.GetRemoteUri(); bitbucketAuthentication.Setup(m => m.GetCredentialsAsync(remoteUri, input.UserName, It.IsAny())) - .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.Basic, new TestCredential(input.Host, input.UserName, password))); + .ReturnsAsync(new CredentialsPromptResult(AuthenticationModes.OAuth)); } - private static void MockRemoteBasicValid(Mock bitbucketApi, InputArguments input, string password, bool twoFactor) + private void MockRemoteBasicValid(InputArguments input, string password, bool twoFactor = true) { - var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFactor }; + var userInfo = new UserInfo + { + UserName = input.UserName, + IsTwoFactorAuthenticationEnabled = twoFactor + }; + // Basic bitbucketApi.Setup(x => x.GetUserInformationAsync(input.UserName, password, false)) .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.OK, userInfo)); + } + private void MockRemoteAccessTokenExpired(InputArguments input, string token) + { + // OAuth + bitbucketApi.Setup(x => x.GetUserInformationAsync(null, token, true)) + .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.Unauthorized)); } - private static void MockRemoteAccessTokenValid(Mock bitbucketApi, InputArguments input, string password, bool twoFAEnabled) + private void MockRemoteAccessTokenValid(InputArguments input, string token, bool twoFactor = true) { - var userInfo = new UserInfo() { IsTwoFactorAuthenticationEnabled = twoFAEnabled }; + var userInfo = new UserInfo + { + UserName = input.UserName, + IsTwoFactorAuthenticationEnabled = twoFactor + }; + // OAuth - bitbucketApi.Setup(x => x.GetUserInformationAsync(null, password, true)) + bitbucketApi.Setup(x => x.GetUserInformationAsync(null, token, true)) .ReturnsAsync(new RestApiResult(System.Net.HttpStatusCode.OK, userInfo)); } @@ -610,6 +577,30 @@ private static void MockStoredAccount(TestCommandContext context, InputArguments context.CredentialStore.Add(remoteUrl, new TestCredential(input.Host, input.UserName, password)); } + private static void MockStoredRefreshToken(TestCommandContext context, InputArguments input, string token) + { + var remoteUri = input.GetRemoteUri(); + var refreshService = BitbucketHostProvider.GetRefreshTokenServiceName(remoteUri); + context.CredentialStore.Add(refreshService, new TestCredential(refreshService, input.UserName, token)); + } + + private void MockRemoteOAuthTokenCreate(InputArguments input, string accessToken, string refreshToken) + { + var remoteUri = input.GetRemoteUri(); + bitbucketAuthentication.Setup(x => x.CreateOAuthCredentialsAsync(remoteUri)) + .ReturnsAsync(new OAuth2TokenResult(accessToken, "access_token") { RefreshToken = refreshToken }); + } + + private void VerifyOAuthRefreshTokenStored(TestCommandContext context, InputArguments input, string refreshToken) + { + var remoteUri = input.GetRemoteUri(); + string refreshService = BitbucketHostProvider.GetRefreshTokenServiceName(remoteUri); + bool result = context.CredentialStore.TryGet(refreshService, input.UserName, out var credential); + + Assert.True(result); + Assert.Equal(refreshToken, credential.Password); + } + #endregion } } diff --git a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs index 9d3ff0d54..15d9b10fa 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs @@ -23,7 +23,6 @@ public enum AuthenticationModes public interface IBitbucketAuthentication : IDisposable { Task GetCredentialsAsync(Uri targetUri, string userName, AuthenticationModes modes); - Task ShowOAuthRequiredPromptAsync(); Task CreateOAuthCredentialsAsync(Uri targetUri); Task RefreshOAuthCredentialsAsync(string refreshToken); } @@ -62,8 +61,6 @@ public class BitbucketAuthentication : AuthenticationBase, IBitbucketAuthenticat public BitbucketAuthentication(ICommandContext context) : base(context) { } - #region IBitbucketAuthentication - public async Task GetCredentialsAsync(Uri targetUri, string userName, AuthenticationModes modes) { ThrowIfUserInteractionDisabled(); @@ -104,6 +101,11 @@ public async Task GetCredentialsAsync(Uri targetUri, st cmdArgs.AppendFormat(" --username {0}", QuoteCmdArg(userName)); } + if ((modes & AuthenticationModes.Basic) != 0) + { + cmdArgs.Append(" --show-basic"); + } + if ((modes & AuthenticationModes.OAuth) != 0) { cmdArgs.Append(" --show-oauth"); @@ -187,35 +189,6 @@ public async Task GetCredentialsAsync(Uri targetUri, st } } - public async Task ShowOAuthRequiredPromptAsync() - { - ThrowIfUserInteractionDisabled(); - - // Shell out to the UI helper and show the Bitbucket prompt - if (Context.Settings.IsGuiPromptsEnabled && Context.SessionManager.IsDesktopSession && - TryFindHelperExecutablePath(out string helperPath)) - { - IDictionary output = await InvokeHelperAsync(helperPath, "oauth"); - - if (output.TryGetValue("continue", out string continueStr) && continueStr.IsTruthy()) - { - return true; - } - - return false; - } - else - { - ThrowIfTerminalPromptsDisabled(); - - Context.Terminal.WriteLine($"Your account has two-factor authentication enabled.{Environment.NewLine}" + - $"To continue you must complete authentication in your web browser.{Environment.NewLine}"); - - var _ = Context.Terminal.Prompt("Press enter to continue..."); - return true; - } - } - public async Task CreateOAuthCredentialsAsync(Uri targetUri) { ThrowIfUserInteractionDisabled(); @@ -241,10 +214,6 @@ public async Task RefreshOAuthCredentialsAsync(string refresh return await oauthClient.GetTokenByRefreshTokenAsync(refreshToken, CancellationToken.None); } - #endregion - - #region Private Methods - protected internal virtual bool TryFindHelperExecutablePath(out string path) { return TryFindHelperExecutablePath( @@ -257,15 +226,9 @@ protected internal virtual bool TryFindHelperExecutablePath(out string path) private HttpClient _httpClient; private HttpClient HttpClient => _httpClient ??= Context.HttpClientFactory.CreateClient(); - #endregion - - #region IDisposable - public void Dispose() { _httpClient?.Dispose(); } - - #endregion } } diff --git a/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs b/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs index 724498a25..0db55bd0d 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketHostProvider.cs @@ -135,64 +135,39 @@ private async Task GetRefreshedCredentials(Uri remoteUri, string us if (refreshToken is null) { - _context.Trace.WriteLine($"No stored refresh token found"); + _context.Trace.WriteLine("No stored refresh token found"); // There is no refresh token either because this is a non-2FA enabled account (where OAuth is not // required), or because we previously erased the RT. - bool skipOAuthPrompt = false; + _context.Trace.WriteLine("Prompt for credentials..."); - if (SupportsBasicAuth(authModes)) + var result = await _bitbucketAuth.GetCredentialsAsync(remoteUri, userName, authModes); + if (result is null || result.AuthenticationMode == AuthenticationModes.None) { - _context.Trace.WriteLine("Prompt for credentials..."); - - // We don't have any credentials to use at all! Start with the assumption of no 2FA requirement - // and capture username and password via an interactive prompt. - var result = await _bitbucketAuth.GetCredentialsAsync(remoteUri, userName, authModes); - if (result is null || result.AuthenticationMode == AuthenticationModes.None) - { - _context.Trace.WriteLine("User cancelled credential prompt"); - throw new Exception("User cancelled credential prompt."); - } - - switch (result.AuthenticationMode) - { - case AuthenticationModes.Basic: - // Return the valid credential - return result.Credential; - - case AuthenticationModes.OAuth: - // If the user wants to use OAuth fall through to interactive auth - // and avoid the OAuth "continue" confirmation prompt - skipOAuthPrompt = true; - break; - - default: - throw new ArgumentOutOfRangeException( - $"Unexpected {nameof(AuthenticationModes)} returned from prompt"); - } - - // Fall through to the start of the interactive OAuth authentication flow + _context.Trace.WriteLine("User cancelled credential prompt"); + throw new Exception("User cancelled credential prompt."); } - if (SupportsOAuth(authModes) && !skipOAuthPrompt) + switch (result.AuthenticationMode) { - _context.Trace.WriteLine("Two-factor authentication is required - prompting for auth via OAuth..."); - _context.Trace.WriteLine("Prompt for OAuth..."); - - // Show the 2FA/OAuth authentication required prompt - bool @continue = await _bitbucketAuth.ShowOAuthRequiredPromptAsync(); - if (!@continue) - { - _context.Trace.WriteLine("User cancelled OAuth prompt"); - throw new Exception("User cancelled OAuth authentication."); - } - - // Fall through to the start of the interactive OAuth authentication flow + case AuthenticationModes.Basic: + // Return the valid credential + return result.Credential; + + case AuthenticationModes.OAuth: + // If the user wants to use OAuth fall through to interactive auth + break; + + default: + throw new ArgumentOutOfRangeException( + $"Unexpected {nameof(AuthenticationModes)} returned from prompt"); } + + // Fall through to the start of the interactive OAuth authentication flow } else { - _context.Trace.WriteLineSecrets($"Found stored refresh token: {{0}}", new object[] { refreshToken }); + _context.Trace.WriteLineSecrets("Found stored refresh token: {0}", new object[] { refreshToken }); try { @@ -420,7 +395,7 @@ private static string GetServiceName(Uri remoteUri) return remoteUri.WithoutUserInfo().AbsoluteUri.TrimEnd('/'); } - private static string GetRefreshTokenServiceName(Uri remoteUri) + internal /* for testing */ static string GetRefreshTokenServiceName(Uri remoteUri) { Uri baseUri = remoteUri.WithoutUserInfo(); From dab7930aead58f15d479c5c735739d45994fede3 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 21 Jun 2022 13:14:36 +0100 Subject: [PATCH 80/83] windows: generate app manifests for all exe projects Automatically generate the correct application manifest for Windows executable projects that we produce. The manifests are required on Windows systems newer than Windows 8 to correctly access versioning APIs that will otherwise always report "Windows 8", even on later versions. The manifest we generate states we are compatible with all versions of Windows from 7 to 11 (inclusive). --- Directory.Build.props | 6 ++++ Directory.Build.targets | 27 +++++++++++++++ build/GCM.MSBuild.csproj | 13 ++++++++ build/GCM.tasks | 16 +++++++++ build/GenerateWindowsAppManifest.cs | 51 +++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 Directory.Build.targets create mode 100644 build/GCM.MSBuild.csproj create mode 100644 build/GCM.tasks create mode 100644 build/GenerateWindowsAppManifest.cs diff --git a/Directory.Build.props b/Directory.Build.props index 7f78555c7..3abe378a3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -18,6 +18,12 @@ $(RepoPath)src\ $(RepoPath)out\ $(RepoPath)assets\ + + + <_IsExeProject Condition="'$(OutputType)' == 'Exe' OR '$(OutputType)' == 'WinExe'">true + + + true diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 000000000..3c84f230d --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,27 @@ + + + + + + + + + + $(IntermediateOutputPath)app.manifest + + + + + + + + + + + diff --git a/build/GCM.MSBuild.csproj b/build/GCM.MSBuild.csproj new file mode 100644 index 000000000..7dbe90afe --- /dev/null +++ b/build/GCM.MSBuild.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + false + + + + + + + + diff --git a/build/GCM.tasks b/build/GCM.tasks new file mode 100644 index 000000000..fe7031f34 --- /dev/null +++ b/build/GCM.tasks @@ -0,0 +1,16 @@ + + + <_TaskAssembly>$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll + <_TaskFactory>CodeTaskFactory + + + <_TaskAssembly>$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll + <_TaskFactory>RoslynCodeTaskFactory + + + + + + + + diff --git a/build/GenerateWindowsAppManifest.cs b/build/GenerateWindowsAppManifest.cs new file mode 100644 index 000000000..58a94c5a1 --- /dev/null +++ b/build/GenerateWindowsAppManifest.cs @@ -0,0 +1,51 @@ +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using System.IO; + +namespace GitCredentialManager.MSBuild +{ + public class GenerateWindowsAppManifest : Task + { + [Required] + public string Version { get; set; } + + [Required] + public string ApplicationName { get; set; } + + [Required] + public string OutputFile { get; set; } + + public override bool Execute() + { + Log.LogMessage(MessageImportance.Normal, "Creating application manifest file for '{0}'...", ApplicationName); + + string manifestDirectory = Path.GetDirectoryName(OutputFile); + if (!Directory.Exists(manifestDirectory)) + { + Directory.CreateDirectory(manifestDirectory); + } + + File.WriteAllText( + OutputFile, + $@" + + + + + + + + + + + + + + + +"); + + return true; + } + } +} From d4fcfb7deb76dee17e946e206457111ef426a581 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Fri, 17 Jun 2022 18:22:11 +0100 Subject: [PATCH 81/83] bitbucket: update shared UI helper code for new UI model Update shared UI helper code for Bitbucket to remove the separate OAuth prompt/command, and allow basic authentication (username/password) options to be hidden based on a command-line option. --- .../BitbucketAuthenticationTest.cs | 6 +- .../BitbucketHostProviderTest.cs | 2 +- .../Commands/CredentialsCommand.cs | 49 ++++++++----- .../Commands/OAuthCommand.cs | 46 ------------ .../ViewModels/CredentialsViewModel.cs | 23 ++++-- .../ViewModels/OAuthViewModel.cs | 72 ------------------- .../BitbucketAuthentication.cs | 2 +- 7 files changed, 51 insertions(+), 149 deletions(-) delete mode 100644 src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs delete mode 100644 src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs index 9fac31e93..aace44ad7 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketAuthenticationTest.cs @@ -122,7 +122,7 @@ public async Task BitbucketAuthentication_GetCredentialsAsync_AllModes_NoUser_BB ["password"] = expectedPassword }; - string expectedArgs = $"userpass --show-oauth"; + string expectedArgs = $"prompt --show-basic --show-oauth"; var context = new TestCommandContext(); context.SessionManager.IsDesktopSession = true; // Enable OAuth and UI helper selection @@ -158,7 +158,7 @@ public async Task BitbucketAuthentication_GetCredentialsAsync_BasicOnly_User_BBC ["password"] = expectedPassword }; - string expectedArgs = $"userpass --username {expectedUserName}"; + string expectedArgs = $"prompt --username {expectedUserName} --show-basic"; var context = new TestCommandContext(); context.SessionManager.IsDesktopSession = true; // Enable UI helper selection @@ -194,7 +194,7 @@ public async Task BitbucketAuthentication_GetCredentialsAsync_AllModes_NoUser_BB ["password"] = expectedPassword }; - string expectedArgs = $"userpass --url {targetUri} --show-oauth"; + string expectedArgs = $"prompt --url {targetUri} --show-basic --show-oauth"; var context = new TestCommandContext(); context.SessionManager.IsDesktopSession = true; // Enable OAuth and UI helper selection diff --git a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs index f658c4029..cf8216afc 100644 --- a/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs +++ b/src/shared/Atlassian.Bitbucket.Tests/BitbucketHostProviderTest.cs @@ -475,7 +475,7 @@ private void VerifyOAuthFlowRan(InputArguments input, string token) { var remoteUri = input.GetRemoteUri(); - // use refresh token to get new access token and refresh token + // Get new access token and refresh token bitbucketAuthentication.Verify(m => m.CreateOAuthCredentialsAsync(remoteUri), Times.Once); // Check access token works/resolve username diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs index 009625335..a17bdf5f3 100644 --- a/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs +++ b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs @@ -13,7 +13,7 @@ namespace Atlassian.Bitbucket.UI.Commands public abstract class CredentialsCommand : HelperCommand { protected CredentialsCommand(ICommandContext context) - : base(context, "userpass", "Show authentication prompt.") + : base(context, "prompt", "Show authentication prompt.") { AddOption( new Option("--url", "Bitbucket Server or Data Center URL") @@ -27,40 +27,51 @@ protected CredentialsCommand(ICommandContext context) new Option("--show-oauth", "Show OAuth option.") ); - Handler = CommandHandler.Create(ExecuteAsync); + AddOption( + new Option("--show-basic", "Show username/password option.") + ); + + Handler = CommandHandler.Create(ExecuteAsync); } - private async Task ExecuteAsync(Uri url, string userName, bool showOAuth) + private async Task ExecuteAsync(Uri url, string userName, bool showOAuth, bool showBasic) { var viewModel = new CredentialsViewModel(Context.Environment) { Url = url, UserName = userName, - ShowOAuth = showOAuth + ShowOAuth = showOAuth, + ShowBasic = showBasic }; await ShowAsync(viewModel, CancellationToken.None); - if (!viewModel.WindowResult) + if (!viewModel.WindowResult || viewModel.SelectedMode == AuthenticationModes.None) { throw new Exception("User cancelled dialog."); } - if (viewModel.UseOAuth) + switch (viewModel.SelectedMode) { - WriteResult(new Dictionary - { - ["mode"] = "oauth" - }); - } - else - { - WriteResult(new Dictionary - { - ["mode"] = "basic", - ["username"] = viewModel.UserName, - ["password"] = viewModel.Password, - }); + case AuthenticationModes.OAuth: + WriteResult(new Dictionary + { + ["mode"] = "oauth" + }); + break; + + case AuthenticationModes.Basic: + WriteResult(new Dictionary + { + ["mode"] = "basic", + ["username"] = viewModel.UserName, + ["password"] = viewModel.Password, + }); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(AuthenticationModes), + "Unknown authentication mode", viewModel.SelectedMode.ToString()); } return 0; diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs deleted file mode 100644 index 6203e1c81..000000000 --- a/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Invocation; -using System.Threading; -using System.Threading.Tasks; -using Atlassian.Bitbucket.UI.ViewModels; -using GitCredentialManager; -using GitCredentialManager.UI; - -namespace Atlassian.Bitbucket.UI.Commands -{ - public abstract class OAuthCommand : HelperCommand - { - protected OAuthCommand(ICommandContext context) - : base(context, "oauth", "Show OAuth required prompt.") - { - AddOption( - new Option("--url", "Bitbucket Server or Data Center URL") - ); - - Handler = CommandHandler.Create(ExecuteAsync); - } - - private async Task ExecuteAsync() - { - var viewModel = new OAuthViewModel(Context.Environment); - - await ShowAsync(viewModel, CancellationToken.None); - - if (!viewModel.WindowResult) - { - throw new Exception("User cancelled dialog."); - } - - WriteResult(new Dictionary - { - ["continue"] = "true" - }); - - return 0; - } - - protected abstract Task ShowAsync(OAuthViewModel viewModel, CancellationToken ct); - } -} diff --git a/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs b/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs index 38475e9be..d4e8e51c9 100644 --- a/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs +++ b/src/shared/Atlassian.Bitbucket.UI/ViewModels/CredentialsViewModel.cs @@ -15,6 +15,7 @@ public class CredentialsViewModel : WindowViewModel private string _userName; private string _password; private bool _showOAuth; + private bool _showBasic; public CredentialsViewModel() { @@ -28,7 +29,7 @@ public CredentialsViewModel(IEnvironment environment) _environment = environment; Title = "Connect to Bitbucket"; - LoginCommand = new RelayCommand(Accept, CanLogin); + LoginCommand = new RelayCommand(AcceptBasic, CanLogin); CancelCommand = new RelayCommand(Cancel); OAuthCommand = new RelayCommand(AcceptOAuth, CanAcceptOAuth); ForgotPasswordCommand = new RelayCommand(ForgotPassword); @@ -53,9 +54,15 @@ private bool CanLogin() return !string.IsNullOrWhiteSpace(UserName) && !string.IsNullOrWhiteSpace(Password); } + private void AcceptBasic() + { + SelectedMode = AuthenticationModes.Basic; + Accept(); + } + private void AcceptOAuth() { - UseOAuth = true; + SelectedMode = AuthenticationModes.OAuth; Accept(); } @@ -101,7 +108,7 @@ public string Password } /// - /// Show the direct-to-OAuth button. + /// Show the OAuth option. /// public bool ShowOAuth { @@ -110,14 +117,16 @@ public bool ShowOAuth } /// - /// User indicated a preference to use OAuth authentication over username/password. + /// Show the basic authentication options. /// - public bool UseOAuth + public bool ShowBasic { - get; - private set; + get => _showBasic; + set => SetAndRaisePropertyChanged(ref _showBasic, value); } + public AuthenticationModes SelectedMode { get; private set; } + /// /// Start the process to validate the username/password /// diff --git a/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs b/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs deleted file mode 100644 index a9376a3a2..000000000 --- a/src/shared/Atlassian.Bitbucket.UI/ViewModels/OAuthViewModel.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Windows.Input; -using GitCredentialManager; -using GitCredentialManager.UI; -using GitCredentialManager.UI.ViewModels; - -namespace Atlassian.Bitbucket.UI.ViewModels -{ - public class OAuthViewModel : WindowViewModel - { - private readonly IEnvironment _environment; - - public OAuthViewModel() - { - // Constructor the XAML designer - } - - public OAuthViewModel(IEnvironment environment) - { - EnsureArgument.NotNull(environment, nameof(environment)); - - _environment = environment; - - Title = "OAuth authentication required"; - OkCommand = new RelayCommand(Accept); - CancelCommand = new RelayCommand(Cancel); - LearnMoreCommand = new RelayCommand(LearnMore); - ForgotPasswordCommand = new RelayCommand(ForgotPassword); - SignUpCommand = new RelayCommand(SignUp); - } - - private void LearnMore() - { - // 2FA is not supported on Server/DC so this prompt will never be seen outside of Bitbucket Cloud - BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.TwoFactor); - } - - private void ForgotPassword() - { - BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.PasswordReset); - } - - private void SignUp() - { - BrowserUtils.OpenDefaultBrowser(_environment, BitbucketConstants.HelpUrls.SignUp); - } - - /// - /// Provides a link to Bitbucket OAuth documentation - /// - public ICommand LearnMoreCommand { get; } - - /// - /// Hyperlink to the Bitbucket forgotten password process. - /// - public ICommand ForgotPasswordCommand { get; } - - /// - /// Hyperlink to the Bitbucket sign up process. - /// - public ICommand SignUpCommand { get; } - - /// - /// Run the OAuth dance. - /// - public ICommand OkCommand { get; } - - /// - /// Cancel the authentication attempt. - /// - public ICommand CancelCommand { get; } - } -} diff --git a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs index 15d9b10fa..14e7b3fb1 100644 --- a/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs +++ b/src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs @@ -90,7 +90,7 @@ public async Task GetCredentialsAsync(Uri targetUri, st if (Context.Settings.IsGuiPromptsEnabled && Context.SessionManager.IsDesktopSession && TryFindHelperExecutablePath(out string helperPath)) { - var cmdArgs = new StringBuilder("userpass"); + var cmdArgs = new StringBuilder("prompt"); if (!BitbucketHostProvider.IsBitbucketOrg(targetUri)) { cmdArgs.AppendFormat(" --url {0}", QuoteCmdArg(targetUri.ToString())); From 6ceab40eec2d87513000ed4e563a6069a7b28c88 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Thu, 16 Jun 2022 19:07:12 +0100 Subject: [PATCH 82/83] bb-avnui: update Avalonia-based Bitbucket UI Update the Avalonia-based UI for Bitbucket authentication to use a tabbed interface, showing each authentication mode in a separate tab. The new "credentials" prompt can offer and serve all authentication modes in a simpler way that pushes users who can to authenticate using a more secure method (where we don't capture the user/pass). --- .../Commands/OAuthCommandImpl.cs | 19 ----- .../Controls/TesterWindow.axaml | 24 +++++- .../Controls/TesterWindow.axaml.cs | 19 ++--- .../Program.cs | 1 - .../Views/CredentialsView.axaml | 79 +++++++++++++------ .../Views/CredentialsView.axaml.cs | 21 ++++- .../Views/OAuthView.axaml | 42 ---------- .../Views/OAuthView.axaml.cs | 29 ------- .../Converters/BoolConvertersEx.cs | 3 + 9 files changed, 104 insertions(+), 133 deletions(-) delete mode 100644 src/shared/Atlassian.Bitbucket.UI.Avalonia/Commands/OAuthCommandImpl.cs delete mode 100644 src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/OAuthView.axaml delete mode 100644 src/shared/Atlassian.Bitbucket.UI.Avalonia/Views/OAuthView.axaml.cs diff --git a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Commands/OAuthCommandImpl.cs b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Commands/OAuthCommandImpl.cs deleted file mode 100644 index f3ee88591..000000000 --- a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Commands/OAuthCommandImpl.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Atlassian.Bitbucket.UI.ViewModels; -using Atlassian.Bitbucket.UI.Views; -using GitCredentialManager; -using GitCredentialManager.UI; - -namespace Atlassian.Bitbucket.UI.Commands -{ - public class OAuthCommandImpl : OAuthCommand - { - public OAuthCommandImpl(CommandContext context) : base(context) { } - - protected override Task ShowAsync(OAuthViewModel viewModel, CancellationToken ct) - { - return AvaloniaUi.ShowViewAsync(viewModel, GetParentHandle(), ct); - } - } -} diff --git a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Controls/TesterWindow.axaml b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Controls/TesterWindow.axaml index 86b010696..fca8daf48 100644 --- a/src/shared/Atlassian.Bitbucket.UI.Avalonia/Controls/TesterWindow.axaml +++ b/src/shared/Atlassian.Bitbucket.UI.Avalonia/Controls/TesterWindow.axaml @@ -6,8 +6,24 @@ x:Class="Atlassian.Bitbucket.UI.Controls.TesterWindow" Title="Bitbucket Authentication Dialog Tester" Height="240" Width="420" CanResize="False"> - -

52J(sX9VKic-tM=b_Nf8 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ℜo}!d;E;ZJ0EbP z=uSl6S7$gfbrP=ChotVFoXJF3a(G4V$C7btNZ;~ncOtGvVV}4M5dg${AP5BD33~x! z@J=>@BajgQx=ft1C`DaZ^&nfF0X*gi(#lIm1Ss;K+z&(!Ukf|{VqX?!Rrngb8mIqy zDxH><+ja0-_Z!$k=GSdV+#yJZG6MfG`S^-f_NOl+-a@SOLd&vSMAOB4bXEb6TH{%> z$25;Z3J0LCAga@@eu4;bZdSm1!>0q848}r7PZFRx0NAk#rH{D)^&s2c+4-Zb!($H` z_dluwy!gn(=)LscKFbG&Z{TBu=74oa%E>K*PC->S(|?_+{jlz^rw6G=eq)9YY|Zyuf8&*9A6QsOT4&yD1^r%f2A+~}yeRN2w!XID*XPJiyK-SX*| zXExhIXu#Y(1t32y2s4Fxhk1G>Di@3B2IU2-^x9Xf;unnQSt@$Tl>1a1hk$N`UEV9d z6Pwhp8F7YV7;OvBwjF>yREoHs(o>>21Z6PDO88)H|1nt|f$G&8v+jNa2Q_TMogjm? z*LROVLCDYLtez5qNdNa=!Q1zPML+o4$@6%9TF;so`it<+r=Wxwij(I2NoV`O{{x-< z82onz{S{Ib!?J8bk?+}dQ9BxH$=5EajaBw#-nqXh_r3o}xnDkw7su`RlcIkC^EB%F zTZQH1IuXR9zgetA(2{%otwO-YUebSa6J*EFay-wH(BzR~Y4pn!mL-PwZ``D*BVUau z&sL096MvCkj~IZ)x^wFhzmv~NfGLqs;+e$1DrMUs{16>y3%p%tpDat@ENnzdZ7Gz^ zO(VJK3ary`{JJo2mh=pgwoI!7a0XovJYe$C_D3MXQ@5 zI}&U_DI5k?u2fa!c=AI~5euLado`_*E>@{{2>O>r1H+!d_B(zQzwtm~c9Sk-V1lLU z^%Mg-9f=T#%ydf$eo5orRewM8t&dR7%~dh#D5EWKpWnG>s^fs2R&nh9TmIHp6=clD zPsD0ZGvomji-C6>q#WUJ>-#ogL=^A}64B@Jb)?*LghMq*PF@;JYk!$@734Ssy&_C| z#fEtV7S&M3C&k>uE5=CU&K3gBfY&!5F~s`KtKU0K1@IfaH8`X2aH}%jf)zf#{$NzN z)S#1oxrT$b4P5MRWp7<;Y>Wjf`vix0Dgf)FDT}#_<{vXvrkedR4_GqFD%h$B{62|y z&}acn(kd}dJw*D%CMg{t-T+UnU22wQ1Fi5Ndm^b1r=H& zqJbHOeF9c_jwUl}+ehsR82=Rbryu?q5C8dh!F-_4%5Z{x&M`{0XVfuL?gUQQIFzvK zfy4Qa%lspf7|`?8bmXk?)H)@*dOw!nC>ZaE8GWjgknW2*bS}IXvgc{=(#I!{2OFL> zbSXl^PHkGstZUNc!CRxkJRo|D1}XFL3@l><@iyo*u5!D^7x^KY0%Z zaH+zeYGgI8w<_@4WT9OXU20?$`!;|gU>yU`y2te|1-9Am9I^#QV{23I1dC`&!LZ}n zVSv-RO>SbP6fp++bcf64OF$0Fek!Nl{2v<_9N-(aV87Gh?y_cGEzLnCn61X3YrI z`7G>p1nI+AlO$0s+NBjRv54~{PP1t)j7@l|8!1i;f`AJEtF!=kYS$V*apH3E#K3O! zIp7>gM!vXCjlrIiFHr7NPrblkeP0hzAzfI-qhDCnVqCD&54$GJ0PrB!d%(tv74XK3 zvbhQG!QhuG;P;V548H`A#i4~9uOG4MNH?I}w^!oPa&s`jyMoL<9Vwy1`Th$}moJVY{%0^#y z=4Z#UypV64O!K=2CkG|DTLljr1>mT8HqmhMQ!rzbmIE?KX`EO0^-`d>2e}abd63K1 zZ`m(K1O~=MagkUo3}HtY95C|iqf^FX6t9toCSRImK6a#0VE_tD$@#ntewYpXmrbLv zprvHUIH|0|^12A-qJVJih|+zx8gLfR2;-^ergBymujTs3GwL8RSpt9qzXfMwFfTyF z3c@U;@0D%f^J{593oaPH2(qxMPH?`CdQheN)rB|W!027fn_KPad*B3>Kk4=KN4MG` z6G2uMK#B>F;EvNv)|XdPM2e!X)SxuCp_M7x(5yNOV7Vau(JioG)*lzQhOh$;USYEn z4t1@ZM?WnO#&1I~_`y4{WcjNT8FS>x@ZC#3%AS}$TKJ(QyT8~T!9_Vl7;144yU;5X z95}s6w@u72A`xdk^YarG*C=p;0Au>VCGCgd8znw~{ZEU-qdqRxUeNQs<&PDBJA%(% z3Tf&t_bOR>1ER)!)Pogny3^cZ&;(iWMSYshys<24@c`Yy7;`OR)m# zQZ;WIxC);GeE#2T;$Y-?BlT6f9RUs=D0z#N!~-0>U8S-wR!0={skx?QMLn~lCXs^3 z!fK@>*27zno7{o*!Ek3})6n5PDU+m#b!me1rrLo5Jc}Q zz0Jq7ySqzXJvti?eC+!QvM=K2q3!zq(ih_;m{ndz^d-2qufDMvQNw92-P6nKZwogr z1j3b&_GG6OdJ<^^8JdFOS+{&7Ei(N!&z z+4ntcbLcviIZbn;b$k!lu&r+{93TT368jVnH3cj~FP)=fK}cukEIMIB*_)fMmDX^2 zNfw{+y}j@w(6y?lOXQIr^Xy1Z-v40lJ%gHR+qYjkdZR={L8U~csg!_7QAz|sK#&Ni zfRqS`hzOx~5*s2N1VjXhh=A14J4AX@Kza|oNC||5^tIl2KhOW2ckj>p!=62RGLsns z>sn-TWnI^K9LMimsn;|_lRk53kdzIhWtNbVte`zV@b*ZVmyj_6oukIze5L9Zw|$QO`6S0 zMz@r6RolNkTi>A{^k1*KCZJX;KtGoQ>fcI0 zasMUg5&u8n{{IEQ{r}xv4DfyU-wJ^p88QAf2GZ6yV*Xmk3BZfJO^Iom%~nrc_Nu$H zWy8#mG$cg+kw_xJz)_MLdyU$8T4 z&l(DGq&QZs{`KE$kL&d_lDu-OT8Ev&&)kwuFQ43*-aNtmI{M#>$5ccS|a9X(!1K6_#o_)(-#!t(T!`yS zISKY)CdnsKN$!DAeRIj%wd^N&) zy2YUsu7CWj9=8+$JPwAO4k_Xss@42oU%9j-m-ClyVCP5u#K~nPj<{+6&E48WewdIR zrO%PDFTAFVXx%&+cjbMe&S%bPDa!T|_dT!^`S^@By?KsDo{zsN82^S+seNb-_pkXa zCKd6oO^*5>n_M?4uFYG&)f^M5BoQ`3@ar4sF8*d6B_=Gnop?Um=bts8KcZp#*O!&X z#;4z*}yftJKKk9gE z^@m7Cv7PKD{3gfQ4xPlvT)%K7)?^Z+`~Al8zlDeb|5cSL&_}%rw8IK#?hlM?3$Om# zh1TDMt1@@H_&$@)QWV$3-#TM`h*kI5yVG4x|M8EV{`$xNRS5<-_OaF_bqj-B&s%B9 z*Pi?zestNR!J4}Uzn&2y)f8N+=>La_?O5KHaN(ZwE&e1iX+~yu(Emw4SJ;IUl^yTyRKY0Ca|V4etK;WHXdy0Qd5)$HSvbm}gB4$A`3>b?&8^<(Nq@_8g1F zdt1AS!|Z?4bFoT*l`~;~Q_F+>kl^a@2$#DEAdv5O2Fp+3+32iV2++1DWcnd)UQkQp z7S)=3(BCV}#aaWG)_AWevlwthfa~N63=PbJ)0&g+plCbFcc8QxuIvcehAj_E!gTv7 z8c+?K62yeQ0>ItqN`!CSM5U2$)kLKshKWa+BQzN(Q!>J&EnYF-QpQ2bAecTL)2}EQEk>Zm+0g&Jp z(QH-y&wf838Y;+;2BBb!+7?2(4|{QH)ZJ+kv!WdYzMDPFFJPY0QKMEU6L~9U^+|ek z@lss;wH+Z-{^@+c81t0R?pR`Lg{-=88WrSMG)|!b>{m&CGnAy`wk!qE0=&w7_e{R) zv+8w`;$O+j7jqoMsK`^Y93u9d(gpLkN_Lh>X`JF?UxLX?+D>TBmuz>x)bG6aFKXpp zY-j9m%y(dGKG!Zf8q9-bcz$aT1!cz5#2AxT(CpL(6dN{hD@rBbnasf*sP1M{3D!$@ zJ;w^(bo;X5^Z_^)y`hYDW~{GbcQUCR43ldc_d8Zq8#dmoo`Hj<1Kx$fE_E-rjVQu2 z_ltN;Fc-imuV+z~8KKd@a%vzzzV?f+GupHFnl9|KaFQbn>$!Vv0Nmk&V5iw>)X1u# z?^DX3F)uNBx;y-F&-K@{{Db#=of@e3h1P6?A+WS-^>e3iX*T3g*ykSpsQg!B!e3a! z*8Y*Wa+XhJ?FP9lTg{zOgJYi^XfE%f1rFtb9jLRJ^NKidU^R_erTgbe$&l2BbwJ^? zR6LN4{xdLO@s+X+&%QQ$S?DqmoZRV2v0;Rpb*@b-2XA^}vC}Lt?W+1hBjk!Dp<8?m zL@?J^OR#Ag!u~Dy)jF*{o#%~gmI8Uo*I)txnQDK^e;;mmJc4YWxWD`O#np^OirEIm zyzAzFlG4y&f`JG4x4$Wj2!DW*Yw2Xd>Z$#&smQ|p7hYk(Z6Jk82&J+sHKw1!-%W6Z zoTWZESmvA1I=ymHb#epgY^ibXwh7xFiB`=EZgzGa)Blio2G&f0y+@kuMBvHY1ALg> zoPkwRdO|%qaMnJ!l|)DZmQYzt_{_`QV_4Fy^fo{HyUTt4AfpMV$GJ6SdN%&aTOh;i zS7PuE=2*JGy#Q$kndFv8R=JU2)g=(SwUBK@WmPb{Fkn(J^RX$gR=G(&A5(~F7My$( zuplaOy`Ciw`@mH~t=3+fFsK-;j9^r-klC-X;C zf!P~YA|MawwDchk3V+?bW!lT*s{r09NjLtJbRiwcb!-675)i|VeM+d$McgssZ9g-T z7^avosROzT#CIpQ6#!1GkrU`xb9fvw^iZ`J_!E7Ca?|q(r(;49+YOW#=QOP7h& z?>So49msZ6XO3hg)tjKF;wMk#O~OgdkWZUFNveqUsr4rV0vcfJ>T4(iw_1&7H?0mL zFag);eA$NZtr_TNfbN1yE<`KR&AN8O3&P^@i`#9we4qCRU8=|QR!SLR3UQk57yrP* z@?e3xn)uK2eY#fL358G5%nc)B21U}_Ghto4caiQWv;qIoea1n!Kj*A zzgcbdEP?_fGCZAH!An@yAbE|0?RC-!$Ny2{!>eU*tBMF68-tPPa1u>3}{t7nR(fVFiW zqD$G_NQ2IYW>d@>h26E?Qsv*^-><~DJj5Jkm;{1Y#$b+5)W$w1jn2$Z%Y+EbvTqjV z!^bN6ub329pLO|LLqesH@S@+GW%x72rK)9v9q87rCmh!v6bupDpwb3*O)M~VZB}Ev zBfgn;j@4ehkl>`l_T9Bs3)cSgt;^%*F_iT3S?y>UrO?{l+%#9z%Dq=Yk?=O`lTTc) z(+;L|vQ+PJ_R@A&K=oYR=P`%Izc{e%IS;{34)4E-nFReo`^6Vj3@539m4)r}!WYac z>4z4eq?zIT%H7#Q^d2!>Cu%$Zbp3!o=0JO$xO?sWu{zc;$P&P-)UV$MVs(?yLk1Yk zb$~W8p4Uh9S-%sL+%PNXsyMa$Ch!gfT-8N@BpeFcb8T&X)ddy2=0yy|tepn|ihZY) z38oOU@&^TVih)z-j(9#=-rtE~p1%P-H{_`15KsUIcYenharSE!=R*D%`PSWBoe~!5 zU|erbzXy`n?jx9V$8p@Vfg10f6sU4NSsbrCwenWEuku9u2>O>9LQ+pAuo+wL9?-;x zy@2m>A&@6vtol_=2m@GMS+hoMsY%3u5<#V+Z@KQWVclyuZebHf-bw|EF?~v_V2>OO z&qjD^Qw9@Vy3eWxZQ{-FjQiPvlWfr2)un%Gh z3UW3eY|R+A8xihT03o^=1)78s58748MvPQ%dS|6fFSHGK;{vS%pi^ugUvVWOarh`zhEx{rJ?ewCPMb>&P+I_nW&MF&z*qs&CpkN?1oK^2|IdyH-A!7hPW1KLg~YVatNEoY)V|M{P5&z)I2>-# z(0@-}0cp1kwReon4>F?a5SXQbrs@wt-HVKYC{&QBwSM&WpUg(eNKE4fYVsZN&({H7 zM!_kI8HE!>C~GEk9pxR&9wBrM*UhlF7rc=w!sl_s?-?w%QzUw3KQy%`am2sdGAMEJ zUE!O)-{J_>jjPO&`H_a6a?|6ib_!hUNHa((tMbDllc%*=FtG zfE03hdhL^LCv(8;s_MOI_s70Apl2`Km(kLW zNH$`Uodzg{7&3XNvMQt{0_hu>w~Z<{w3+8MyJpg0kyHM>1a+kzLJyjlh^!LHpwx7& zji4?B{~0vR;)d1u)odR_t;o9)ZuJXX#98|HkE(vGk5UkaYwU)_Ads}CGfJE0oiXZH z9yl?KuG&0*Rs7hw%z&rh8Wc|Fbr|4_WPwt!1R#Mf4_AfkSRlo}= zz;|bBzV1=y=y*e)bSr91Fl%9T&=l@MU{!bC(SB_#+NOHAX0LabR4L_HciuaJy^G992gxNRMXZWIhL)lrP-Oi)6*MtLN;qc3P)7P4sP379Y-n!|1u+7 zv450bfP3N+%uXy|$ngBaTcRm4+JXh!U9zF!mo%nyuV$As&pvc+W5TTgjrie^wN9Jh z^fBgU0D#n0o)FXo64L zq-7m7m{{tZS#CsK2(Xf-?}o)Ak~Qd^ri&W0Z%L4+(TO9)bjC!#eK5P$I6Kv&i`)uJ zleY$?V$!13E1pWFYL?PQUX0+UvOJuB?bhEZS3xmis9?4=Vcr$J{=GGr9U-pUlNh{x zfqpB-S~i*XDxxQ8&7-3JRJUgJ^nHwVT_MDZP&;c~i1$o9mytPk5A%#25z#@(0S{O3 zYBqmTjKm**Yy;N4=HxUvw^#VjhPzFDiuJ^G610RVam>hVz+<0T_-&01WX&wwbblEhHqWdpAxJgWifo9CeX3&nwp4?^7y$&zQs)z0o*N+${}z4 z5jX<)UWe}$roXs}cK9W`Mp#lJsMK%Xhoz8xtB}<35fNB$-B~9xdo7f=m%c$rwgGOl z=ZEJ`w?_w^W4K7B%BcgzF$s`suFs%ik8!bWOiZ^WK}j8fj_L^{FrjlN-#(We_ZFoK zicxDuDvcyH0Atc@*HHIQW)>l+XD3U54H!fL5J~oi*K5Hb@ejWq41*u|8kzyQ-3?UW z#A+f8qyKaJ(+Jqfsf^$Q4eHzDW_4Zx%YoC1_2x^eY;x}e1A^Xy7$Jg5VZb4WHdyL; z;fp^Z{ z1j)nkSs9Dz;SF5Di5TC0%j{(hFl2zUHDtDD#_>29?7Se>gXGixE52oFb-#<1^vKO#q6}^*U+bZuhTiy1r;oQ-5smJLyU z^MdUYan}|>{&}bry$1+Yc>*u|fJzb!}>+(-!v6TN=i& zazgbdr&XtqekI=o*|Vz+1PcB+TT*TJ_dtQGciw7pZ@?}YIX6<=-pTaaNtr(P)RA$9 z?(>sV7XBhJsCS@#1l4Ru4W`)w17BC`4CYM{@egY_d+)*5 z=q+aU@&x6Yb3mtojl4R!9rL^fVMh527wjQSt#bM}l*5z*1JJ_UgpU~P# zYmvwrpFWVL+NDTJlCKAbU|84SHQdN4W^qYFL-b!kh*7YtjtQW5BR2@sCH@OyAb!K8 z!6|@@P`9he0HV&RcQNq;$_5(UTs4f!H)-Pj+aKHE?g30yf&{GufbCS_pR2u#)cW&?-cM|;oihth(9M-Qgk1sb+OR%xmP zQJYYWh(2ep6xAukVbH!a+Y<8{ndiuAf+2A1dAR%(VJ8}s09kK`pN^F;=^zuJ0Csit z1P)}NP*`isnAs-qYXGLf&KWT4dTmH`5PokbvVE$7t??ew%Q)!2@)dHO)b$Jp z><=Y?uagX-80vu?U+K#*H-eX^e-)4cq2sfmelG?u)?s-uxFI%a8S^^+!Kiejh)mL5;;Oc;U%%?(eNY5~d_$?kl2khd2x9SIUfi=d6Dx*7_ zSk)VxC8<8^K5#!e0SQsHL?W4IOa{=4BN*p^DJZ+xtD9+(y;XP#l8oVWvH#exT#I+E z8Biv4|LL{f3~FD6AX%!nPG1d7x!&%Xro4Io7Q2x-a-FPTvO_*U7sOV*y}3#NYu2oZ zSJ(^~-1GW&7+kr2u>hQ@+Xl)Hu{$8}QIRT;E=Uj~?u;xz-vrrYQ5k{9{LiuY;EdQ+ zUI_DuzqQBDLcCEHg{my(NC@iJx2ryUxxfa5CbH+{IbYeTLPkwF5&sxfOY~i9DCxDq zqYXB4JPM}ig}!080@%Uqc@)NS0c=OasS@(}9DIi)>4z_45{_Hz#_J`rSdhIabhlX0`kQrvB^Ee|CDk z`HVf1PP#lRwq;u+EF6EwxgWs5E0Z0E1b*i#Fyg3%1^<mvR(%$ry>lM>t>_MrnQf@t{opy4z_0pp1R#d#l!{O1qWjMC&|4a z8Rgb47O3+D&zQh}o~B}nSYSaBmw=*LNw)owX1wko;5VSzP>vKZ#&u#BH%Gb2M^Bnm zC516^NU$m7cDNaW_yHoF22S+GVWQCc1+%zUp`*K~2k*pLWT!-<0;qnYWu`;?NHbH_$_a5$g)quu>x+5rXjxXoJy1gAtf<(>Ww#jhu@w zbT16DT;z=jm?TeQFa&diq}lfv85XU!lGRL(kBNl@g#)|&ku|7*4Jdn++z4TfkW1ix z#zBG21h8SXtQYOW=nU29FD%7FG21l_8tZ=Ts)TD(%m#vb{fcjz6#nvRO7Vi%xT8@D zdTutR4C9>-)%%45CkWext8a)^1oE7K2C62IdCH)0-!S!=z`&swSzT>hnGA*zIO&+p z1@zrqKw4r`t?1rQ1K9BGZG<5NL$=ROYFObEvIIKMZ=7djugk$qz~_#`7a-yfl<^yy z026wH7(NvKkn5uB8Vl(4G%{+dr|#dt`LGcQ%AKA1Mx;7PNn+BZSg3Fq z(ihLSJ8f^~Ry8WR!Mj1wDJQ0;0m;S?xS;{#5 zi}3cyI{wWRbzC_W-4*uH4QX0(=E26gKr!gv9~bceIg=*1^aL&SI=RYC%q4`S(5qp_ zubKGTOImvN;4%E{t@VY|d_KY|a?gt?6pYaI?_J7tFV@MN+d)kuB$zN7r?&l0c!|Gv#|uB)9Cs;Hg)&c%XucxD?E*< z@53VXHXO}lowv6{W8R`yI9(&+s)InHUAu_n#AuHT5RZQ2=ikz-ws<~DtK zVq3?(A6M=fTFQkL?9o`Z8vK6Du1k4Lgh!Pz`eQ0IH8p!a&m^0o$ZWQfKu)_a%zgYq zD=j92J6dqTE;Jy(K0g2eFoq(`>eHSSqOm?&)}QK1Km;qK|1LXpYwUb7dn zuJ6vfFnQk1?|EwY=+sI&8wYxOsnG7$SxyR6P+g0RTdQ(uPWpod3cVuI79l1b_@lnI z>{Yrz(~vo9f#+tHbK&vm7G}*Gmn-SdF$r*=pDM*rT>Wl<$__dHrrDTg*QcC$p6Mz1 zLotu=nqiAHCOruoN&q(H#@sU}AAVm==uASLO4z=*>2SiV!;y)qo!{JIarbpPe~CA} zy16;aY=`g_89eE&hs0j_8XgYtf%DrpLs7*M+1zsQ-8b>4pdDX==Gq%PFQcWkgeSfG z_FR2U861y`P<@E0XGhPzcBjdQo|3&|+z=sKbG0sF%0C+b{Khu2q**+gu0?VHzt3Km z313NiV|W=p7CaC=V;#IfX%?jt&Sa(Vz#}z3jRt-lYoyr|+vOsEggKHjUps42PSU@a z+ccC5*~_&@DHkt@T^i_$eP?^n9V90>kb#lAtChHrllvddS%J%GIwXSvPZ$ zXFb_eV0o8IxOD^fDdcVT*u7F=4dCk8AtB}b_fx<0T`@0Ttj6YkJ!an;+}R-@cD_Vgo*h>(o7 zr50n+)O)kMrh=%7`zkBSTyO3(^4}rb+mMRj9y;qLyRSLsh^R>OzQaGv-5Tl5S%RpO z0kE=1G;Z{|XtZ^|M=&a4<{(EA}XQpUUs^wO+Ah zV_7M0#Q81np-;i5$^v}3B*!6b-&X9eG!BaJr$Sv=;^S2_TC*@*J-_QMLFn1-i_sDR zQb(H(Y_^Ub>C=ghyfp2UYjqx41|aApH^_GC(b}Vv`nM&Tz9v6q4j|xCiZe#h-Xj)L(p5iLD&s4H>Rkuj)ORLJ zZGU{RHa=fKc#`s5=s{EA%QH_t?o~Z>>#d+`&B6Aay0dAmTE9gCi7`i7Oczy7JD{3* z%}4Cwmc={qtP+E6SdF8OwM{UE;x?jAeY+!DWxfFQWDzqrU#VU+n@buS+QTC|-7CfzBIRp{i>g`}m|z3NDQvn4FX#)2kATwM8MTTNE)yJDCBQ`zxRlU~e*sO#qkB$+Q55Q_hl==g%d#pxIKhF+T@#v_ zWV5d>Jj(C+g@2X;B~MG?s`mNBNefh!=JKJ+v-w1{8V?Fj`g`^qAFD2(QnKuX&0%LZ zh1ZoHsY3%+jOn_YGD;H%YFWdFr`&!Hnj+LsMXS!9eBaz0qjut!#?Eu|rR9qFgZn<- z(44bVX#jtt>cojyHs+a-pyDy#tgvpnNs3+g2Z5p;$A_2hKa^fC#=U=Z;fVBPf~hz6 z2ydVmYiZ_Y(df0?eudR66QT6CqCbBqarq26j1;qow$40iD|Zb~z%P-O*A)XtpT0iU z)KAM)7uZ9r24A{$7gXxU$F$6C)a~>{Q7inUKLxxkc}W=%1us_hs8fY(>&r)Yb~50e z7lLvxRnM1Llb?ouK6Kmk9k@ICxr*h{-4z#t&`>Ga>y-V0N1o*IKZi)swFPKS{lveF_s9 zdN=ia+q%>8>)yCMmR);<^sKbi$nP@j>eQdVo_a4OU1{~Penk4?Q|Nxy+Ym01Ah9|s z5I7p_{zPRzH{U%$Z_FCM=fQ^eOTEzIQmKC(wamgh?Sva~|z z-r!0I_fPzdl`Hy=>kk7Sx(qsELmF@PK=40ghv@Rdmu~!Q^hsBzVI$Py=TCQh=Gx^p zkZJJy==WZB_O~wf$7Zo<+_dZ!*M`LhE4z#i+@}Bfi6I@4wuzQu*xS$d2WF!4&1{52 zglin_eEU|mI8nTiH5~p-M5^UsY^URd?p^FTY;bV*FQs;22ZIn?@prZy$;z9uYIypdK-VI$Ln45 zYdJAtTblNvLqgEyq>>dVKxz)3AU3F4y^{|)v`WoRORJ(zdHT+Po)$uO^bspx^@#UV zy}?XZ0f~8I)IHvn>oEe8PJOO4-lkBoH|4|TI@4?Ueu!Q*rsSAKd&Uh^E!#+FUdiCm zm=kN>+16h3i;E+AbIbaS{Ziy;J@rI1pt}2pV80#e5bE|1TE*k1ap=oD8R^nNlNE)e zZr8zI72^;3{jA10{hr>=tX#;`Q3uN3C=qBonHqjf3pex{P`Dw%&=P{ z?SumnF&s1;ipkH`Q#OA6>e27)tC~e6UnY>xqGRA1K#}Fi;6+IhjGO+Of9^^3YJLzzD)FD>JWahA_ zVFL<3JeP$xZg=m%g;5;Mm6FD{boWoGw!_NawRZMU;|Sem{G z7+|Kf>9&+Cm#mZZg03K{TEk2 z4jCRD7fa;diD>}MdtI7yDK)!)(fd!zogxe;=1(eg-E&rIaMJeNGQ2%^a6>fus&RMLKn6TWF+ZE zaVlwrn88_wAnFv$|7UMsX&jDQ(te_8E&(R5oIge5Qn+rCg23RiNOTSd+kB-h3C3P&vUFUw39tuB*{7&6> z0nbb@HK;CwSY0evmCQeC^nSp*z2&<~$Ff%9_2H0$r;w3H%cpz|P!q#6yn&l1qB7oXW-ZZ}jK<3m3o8yOscd)V|TIF&f;M?-e0kc6_t{qnMEQ`gV!%e24(DgIhhU zyDIrL&Dj8cTKU1{oAijbjH)u9Hk8J9cpuOec&hqh;;kcvrrBW&!E%$qxj6$&ViffQ zAuiqSX>6?p;N6T%I^vK;{t+nTGfSsA1Vd)6f`02X2douFg)Fr`*1~Sot%v75ei@ya ztiYb1`?;E(dXlIuU%m0t*L6J-$nT$Ma&H$p&mFuAT-&Y_6FAN|7E3K@M{~W6L#X9< z`}%>nM{$&+MjuP}oD6KNUe<#u(WMHiF7O9`Xxzk4@d1}3gdReSo*^aYwJbmKaVIv* z$r`>4QO|-!`j+pN=_Y(B2%T%jJ@hji_`wU7!le_ug>mv7caA7=$ zuxkqjKZ0hgDKdr3KU!X4c|;UANX|8z3(-U(^7u3n`D|%RFee|Q4f6kpk$9(0oc?P0 zwDI6g#H4@ad{1rq^Di%aD8vzg+T`6ExpNJ2UL^+0`b}{why+$s1guLdrW4P@{h0Og zX3XXk=i1$qcu;H&vGYp-_0g$qHC>gd=Z~=eeP1A;?AW<*1-2@2QsIkk#o?Tar{hkw zp=^xjyRE4hX6f_vP?CSbnKkuG&)J>rP`(G2nKAcLNXx0ENkPu}b&Q8IPvfm0`72wd zNPAg%|Jo7*=XQFJSw+gV>#Phh$VV(uBLZRtC=2KKUO?C1vsYfX>SQoZ@K2LUjP>NB zdhg=CSExi?kt7{bUeU$UU%0A?0%?7U!ps|`kat2dG>J5x{iQ_Hd?4? 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