diff --git a/Git-Credential-Manager.sln b/Git-Credential-Manager.sln index 26793a007..c41f97745 100644 --- a/Git-Credential-Manager.sln +++ b/Git-Credential-Manager.sln @@ -73,6 +73,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Packaging.Linux", "src\linu EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linux", "linux", "{8F9D7E67-7DD7-4E32-9134-423281AF00E9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.UI", "src\shared\GitHub.UI\GitHub.UI.csproj", "{B5F00B46-FE93-45F2-B283-52B74B3E13B9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Atlassian.Bitbucket.UI", "src\shared\Atlassian.Bitbucket.UI\Atlassian.Bitbucket.UI.csproj", "{EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Git.CredentialManager.UI", "src\shared\Microsoft.Git.CredentialManager.UI\Microsoft.Git.CredentialManager.UI.csproj", "{001846B0-462B-4A27-90CD-2435D4C0F680}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -315,6 +321,54 @@ Global {AD2A935F-3720-4802-8119-6A9B35B254DF}.WindowsDebug|Any CPU.ActiveCfg = Debug|Any CPU {AD2A935F-3720-4802-8119-6A9B35B254DF}.WindowsRelease|Any CPU.ActiveCfg = Release|Any CPU {AD2A935F-3720-4802-8119-6A9B35B254DF}.LinuxRelease|Any CPU.Build.0 = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.MacDebug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.MacDebug|Any CPU.Build.0 = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.MacRelease|Any CPU.ActiveCfg = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.MacRelease|Any CPU.Build.0 = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.Release|Any CPU.Build.0 = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.WindowsDebug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.WindowsDebug|Any CPU.Build.0 = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.WindowsRelease|Any CPU.ActiveCfg = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.WindowsRelease|Any CPU.Build.0 = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.LinuxDebug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.LinuxDebug|Any CPU.Build.0 = Debug|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.LinuxRelease|Any CPU.ActiveCfg = Release|Any CPU + {B5F00B46-FE93-45F2-B283-52B74B3E13B9}.LinuxRelease|Any CPU.Build.0 = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.MacDebug|Any CPU.ActiveCfg = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.MacDebug|Any CPU.Build.0 = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.MacRelease|Any CPU.ActiveCfg = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.MacRelease|Any CPU.Build.0 = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.Release|Any CPU.Build.0 = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.WindowsDebug|Any CPU.ActiveCfg = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.WindowsDebug|Any CPU.Build.0 = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.WindowsRelease|Any CPU.ActiveCfg = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.WindowsRelease|Any CPU.Build.0 = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.LinuxDebug|Any CPU.ActiveCfg = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.LinuxDebug|Any CPU.Build.0 = Debug|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.LinuxRelease|Any CPU.ActiveCfg = Release|Any CPU + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA}.LinuxRelease|Any CPU.Build.0 = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.Debug|Any CPU.Build.0 = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.MacDebug|Any CPU.ActiveCfg = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.MacDebug|Any CPU.Build.0 = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.MacRelease|Any CPU.ActiveCfg = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.MacRelease|Any CPU.Build.0 = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.Release|Any CPU.ActiveCfg = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.Release|Any CPU.Build.0 = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.WindowsDebug|Any CPU.ActiveCfg = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.WindowsDebug|Any CPU.Build.0 = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.WindowsRelease|Any CPU.ActiveCfg = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.WindowsRelease|Any CPU.Build.0 = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.LinuxDebug|Any CPU.ActiveCfg = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.LinuxDebug|Any CPU.Build.0 = Debug|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.LinuxRelease|Any CPU.ActiveCfg = Release|Any CPU + {001846B0-462B-4A27-90CD-2435D4C0F680}.LinuxRelease|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -341,6 +395,9 @@ Global {D34D31DF-B44A-45D3-9B39-73573077BAE0} = {66722747-1B61-40E4-A89B-1AC8E6D62EA9} {8F9D7E67-7DD7-4E32-9134-423281AF00E9} = {A7FC1234-95E3-4496-B5F7-4306F41E6A0E} {AD2A935F-3720-4802-8119-6A9B35B254DF} = {8F9D7E67-7DD7-4E32-9134-423281AF00E9} + {B5F00B46-FE93-45F2-B283-52B74B3E13B9} = {D5277A0E-997E-453A-8CB9-4EFCC8B16A29} + {EB1AA840-6FFF-4464-A9B2-0AEA36F615EA} = {D5277A0E-997E-453A-8CB9-4EFCC8B16A29} + {001846B0-462B-4A27-90CD-2435D4C0F680} = {D5277A0E-997E-453A-8CB9-4EFCC8B16A29} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0EF9FC65-E6BA-45D4-A455-262A9EA4366B} diff --git a/assets/gcm.xaml b/assets/gcm.xaml new file mode 100644 index 000000000..31afc3ca2 --- /dev/null +++ b/assets/gcm.xaml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/linux/Packaging.Linux/build.sh b/src/linux/Packaging.Linux/build.sh index 374bd04bb..f1c74732c 100755 --- a/src/linux/Packaging.Linux/build.sh +++ b/src/linux/Packaging.Linux/build.sh @@ -44,6 +44,8 @@ ROOT="$( cd "$THISDIR"/../../.. ; pwd -P )" SRC="$ROOT/src" OUT="$ROOT/out" GCM_SRC="$SRC/shared/Git-Credential-Manager" +BITBUCKET_UI_SRC="$SRC/shared/Atlassian.Bitbucket.UI" +GITHUB_UI_SRC="$SRC/shared/GitHub.UI" PROJ_OUT="$OUT/linux/Packaging.Linux" # Build parameters @@ -94,8 +96,26 @@ dotnet publish "$GCM_SRC" \ --configuration="$CONFIGURATION" \ --framework="$FRAMEWORK" \ --runtime="$RUNTIME" \ - --self-contained=true \ - "/p:PublishSingleFile=True" \ + --self-contained=true \ + -p:PublishSingleFile=true \ + --output="$(make_absolute "$PAYLOAD")" || exit 1 + +echo "Publishing Bitbucket UI helper..." +dotnet publish "$BITBUCKET_UI_SRC" \ + --configuration="$CONFIGURATION" \ + --framework="$FRAMEWORK" \ + --runtime="$RUNTIME" \ + --self-contained=true \ + -p:PublishSingleFile=true \ + --output="$(make_absolute "$PAYLOAD")" || exit 1 + +echo "Publishing GitHub UI helper..." +dotnet publish "$GITHUB_UI_SRC" \ + --configuration="$CONFIGURATION" \ + --framework="$FRAMEWORK" \ + --runtime="$RUNTIME" \ + --self-contained=true \ + -p:PublishSingleFile=true \ --output="$(make_absolute "$PAYLOAD")" || exit 1 # Collect symbols diff --git a/src/osx/Installer.Mac/Installer.Mac.csproj b/src/osx/Installer.Mac/Installer.Mac.csproj index b6ceb7de0..cd23e4176 100644 --- a/src/osx/Installer.Mac/Installer.Mac.csproj +++ b/src/osx/Installer.Mac/Installer.Mac.csproj @@ -13,6 +13,8 @@ + + diff --git a/src/osx/Installer.Mac/layout.sh b/src/osx/Installer.Mac/layout.sh index 2f1f7f9f3..9d4493e66 100755 --- a/src/osx/Installer.Mac/layout.sh +++ b/src/osx/Installer.Mac/layout.sh @@ -21,6 +21,8 @@ SRC="$ROOT/src" OUT="$ROOT/out" INSTALLER_SRC="$SRC/osx/Installer.Mac" GCM_SRC="$SRC/shared/Git-Credential-Manager" +BITBUCKET_UI_SRC="$SRC/shared/Atlassian.Bitbucket.UI" +GITHUB_UI_SRC="$SRC/shared/GitHub.UI" # Build parameters FRAMEWORK=net5.0 @@ -77,6 +79,20 @@ dotnet publish "$GCM_SRC" \ --runtime="$RUNTIME" \ --output="$(make_absolute "$PAYLOAD")" || exit 1 +echo "Publishing Bitbucket UI helper..." +dotnet publish "$BITBUCKET_UI_SRC" \ + --configuration="$CONFIGURATION" \ + --framework="$FRAMEWORK" \ + --runtime="$RUNTIME" \ + --output="$(make_absolute "$PAYLOAD")" || exit 1 + +echo "Publishing GitHub UI helper..." +dotnet publish "$GITHUB_UI_SRC" \ + --configuration="$CONFIGURATION" \ + --framework="$FRAMEWORK" \ + --runtime="$RUNTIME" \ + --output="$(make_absolute "$PAYLOAD")" || exit 1 + # Collect symbols echo "Collecting managed symbols..." mv "$PAYLOAD"/*.pdb "$SYMBOLOUT" || exit 1 diff --git a/src/osx/SignFiles.Mac/SignFiles.Mac.csproj b/src/osx/SignFiles.Mac/SignFiles.Mac.csproj index a29cd8c7f..45454fc7a 100644 --- a/src/osx/SignFiles.Mac/SignFiles.Mac.csproj +++ b/src/osx/SignFiles.Mac/SignFiles.Mac.csproj @@ -20,15 +20,20 @@ Microsoft400 false + $(OutDir)\git-credential-manager-core; + $(OutDir)\GitHub.UI; + $(OutDir)\Atlassian.Bitbucket.UI;"> false diff --git a/src/shared/Atlassian.Bitbucket.UI/Assets/atlassian-logo.png b/src/shared/Atlassian.Bitbucket.UI/Assets/atlassian-logo.png new file mode 100644 index 000000000..6226f936d Binary files /dev/null and b/src/shared/Atlassian.Bitbucket.UI/Assets/atlassian-logo.png differ diff --git a/src/shared/Atlassian.Bitbucket.UI/Atlassian.Bitbucket.UI.csproj b/src/shared/Atlassian.Bitbucket.UI/Atlassian.Bitbucket.UI.csproj new file mode 100644 index 000000000..ea9086bd1 --- /dev/null +++ b/src/shared/Atlassian.Bitbucket.UI/Atlassian.Bitbucket.UI.csproj @@ -0,0 +1,22 @@ + + + + WinExe + net5.0 + osx-x64;linux-x64 + + + + + + + + + + TesterWindow.axaml + Code + + + + + diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs new file mode 100644 index 000000000..957d19de3 --- /dev/null +++ b/src/shared/Atlassian.Bitbucket.UI/Commands/CredentialsCommand.cs @@ -0,0 +1,49 @@ +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 Atlassian.Bitbucket.UI.Views; +using Microsoft.Git.CredentialManager; +using Microsoft.Git.CredentialManager.UI; + +namespace Atlassian.Bitbucket.UI.Commands +{ + internal class CredentialsCommand : HelperCommand + { + public CredentialsCommand(CommandContext context) + : base(context, "userpass", "Show authentication prompt.") + { + AddOption( + new Option("--username", "Username or email.") + ); + + Handler = CommandHandler.Create(ExecuteAsync); + } + + private async Task ExecuteAsync(string userName) + { + var viewModel = new CredentialsViewModel(Context.Environment) + { + UserName = userName + }; + + await AvaloniaUi.ShowViewAsync(viewModel, GetParentHandle(), CancellationToken.None); + + if (!viewModel.WindowResult) + { + throw new Exception("User cancelled dialog."); + } + + WriteResult(new Dictionary + { + ["username"] = viewModel.UserName, + ["password"] = viewModel.Password, + }); + + return 0; + } + } +} diff --git a/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs b/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs new file mode 100644 index 000000000..6776f5aa5 --- /dev/null +++ b/src/shared/Atlassian.Bitbucket.UI/Commands/OAuthCommand.cs @@ -0,0 +1,40 @@ +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 Atlassian.Bitbucket.UI.Views; +using Microsoft.Git.CredentialManager; +using Microsoft.Git.CredentialManager.UI; + +namespace Atlassian.Bitbucket.UI.Commands +{ + internal class OAuthCommand : HelperCommand + { + public OAuthCommand(CommandContext context) + : base(context, "oauth", "Show OAuth required prompt.") + { + Handler = CommandHandler.Create(ExecuteAsync); + } + + private async Task ExecuteAsync() + { + var viewModel = new OAuthViewModel(Context.Environment); + await AvaloniaUi.ShowViewAsync(viewModel, GetParentHandle(), CancellationToken.None); + + if (!viewModel.WindowResult) + { + throw new Exception("User cancelled dialog."); + } + + WriteResult(new Dictionary + { + ["continue"] = "true" + }); + + return 0; + } + } +} diff --git a/src/shared/Atlassian.Bitbucket.UI/Controls/TesterWindow.axaml b/src/shared/Atlassian.Bitbucket.UI/Controls/TesterWindow.axaml new file mode 100644 index 000000000..86b010696 --- /dev/null +++ b/src/shared/Atlassian.Bitbucket.UI/Controls/TesterWindow.axaml @@ -0,0 +1,13 @@ + + +