1
0
Форкнуть 0

Add support for adding known ssh hosts

This commit is contained in:
J Wyman ∞ 2017-03-03 18:06:54 -05:00 коммит произвёл J Wyman
Родитель 8f6665c0d6
Коммит a53791601a
11 изменённых файлов: 865 добавлений и 492 удалений

Двоичные данные
Assets/gcm-transparent.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 24 KiB

Двоичные данные
Cli-Askpass/Assets/gcm.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 56 KiB

Двоичные данные
Cli-Askpass/Assets/gcm.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 20 KiB

Просмотреть файл

@ -63,12 +63,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="PassphraseWindow.xaml.cs">
<DependentUpon>PassphraseWindow.xaml</DependentUpon>
<Compile Include="UserPromptDialog.xaml.cs">
<DependentUpon>UserPromptDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PasswordBoxHintAdorner.cs" />
<Compile Include="UserPromptKind.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Alm.Authentication\Microsoft.Alm.Authentication.csproj">
@ -92,11 +93,17 @@
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<Page Include="PassphraseWindow.xaml">
<Page Include="UserPromptDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\gcm.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\gcm.png" />
</ItemGroup>
<Import Project="..\Cli-Shared\Cli-Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

Просмотреть файл

@ -1,339 +0,0 @@
<Window x:Class="Microsoft.Alm.Gui.PassphraseWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Microsoft.Alm.Gui"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Height="280"
ResizeMode="NoResize"
Title="Git Credential Manager for Windows"
Width="420"
WindowStartupLocation="CenterOwner">
<Window.Resources>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:Microsoft.Alm.Gui"
mc:Ignorable="PresentationOptions">
<Color x:Key="BackgroundColor">#FFFFFF</Color>
<Color x:Key="AccentColor">#4EA6EA</Color>
<Color x:Key="ButtonBackgroundHoverColor">#222222</Color>
<Color x:Key="ButtonBorderNormalColor">#666666</Color>
<Color x:Key="ButtonBorderHoverColor">#666666</Color>
<Color x:Key="ButtonBorderFocusedColor">#4EA6EA</Color>
<Color x:Key="NormalColor">#1F1F1F</Color>
<Color x:Key="FadedColor">#D9D9D9</Color>
<sys:Double x:Key="NormalFontSize">16</sys:Double>
<FontFamily x:Key="NormalFontFamily">Segoe UI</FontFamily>
<FontFamily x:Key="LightFontFamily">Segoe UI Light, Segoe UI, Global User Interface</FontFamily>
<FontFamily x:Key="BoldFontFamily">Segoe UI Semibold</FontFamily>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}"/>
<SolidColorBrush x:Key="BackgroundBrush" Color="{StaticResource BackgroundColor}"/>
<SolidColorBrush x:Key="FadedBrush" Color="{StaticResource FadedColor}" />
<SolidColorBrush x:Key="NormalBrush" Color="{StaticResource NormalColor}" />
<Thickness x:Key="DoubleThickness" Bottom="1.75" Left="1.75" Right="1.75" Top="1.75"/>
<Thickness x:Key="NormalThickness" Bottom="1" Left="1" Right="1" Top="1"/>
<Thickness x:Key="NormalMargin" Bottom="0" Left="12" Right="12" Top="0"/>
<Thickness x:Key="FooterMargin" Bottom="6" Left="12" Right="12" Top="0"/>
<Thickness x:Key="ControlPadding" Bottom="6" Left="12" Right="12" Top="6"/>
<Thickness x:Key="TextBoxPadding" Bottom="3" Left="6" Right="6" Top="6"/>
<Style x:Key="ControlStyle" TargetType="Border">
<Setter Property="Background" Value="{StaticResource BackgroundBrush}"/>
</Style>
<Style x:Key="LabelStyle" TargetType="Label">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
<Setter Property="FontFamily" Value="{StaticResource NormalFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource NormalFontSize}"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style.Setters>
</Style>
<Style x:Key="HeaderLabelStyle" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Style.Resources>
<sys:Double x:Key="FontSize">32</sys:Double>
<Thickness x:Key="Margin" Bottom="0" Left="6" Right="6" Top="6"/>
<Thickness x:Key="Padding" Bottom="0" Left="6" Right="6" Top="6"/>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="{StaticResource FontSize}"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Margin" Value="{StaticResource Margin}"/>
<Setter Property="Padding" Value="{StaticResource Padding}"/>
</Style.Setters>
</Style>
<Style x:Key="ResourceGridStyle" TargetType="Grid">
<Style.Resources>
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Margin" Value="{StaticResource NormalMargin}"/>
</Style.Setters>
</Style>
<Style x:Key="FadedLabelStyle" TargetType="Label">
<Setter Property="Foreground" Value="{StaticResource FadedBrush}"/>
<Setter Property="FontFamily" Value="{StaticResource LightFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource NormalFontSize}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Padding" Value="{StaticResource DoubleThickness}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="PassphraseBorderStyle" TargetType="Border">
<Style.Resources>
<Style TargetType="PasswordBox">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
<Setter Property="FontFamily" Value="{StaticResource NormalFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource NormalFontSize}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Padding" Value="{StaticResource TextBoxPadding}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource FadedBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource DoubleThickness}"/>
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="{StaticResource NormalMargin}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style.Setters>
</Style>
<Style x:Key="LearnMoreLinkStyle" TargetType="Button">
<Style.Resources>
<Color x:Key="NormalColor">#1F1FF1</Color>
<Color x:Key="HoverColor">#4040C0</Color>
<sys:Double x:Key="FontSize">12</sys:Double>
<SolidColorBrush x:Key="NormalBrush" Color="{StaticResource NormalColor}" />
<SolidColorBrush x:Key="HoverBrush" Color="{StaticResource HoverColor}" />
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Style.Resources>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Label.IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource HoverBrush}"/>
<Setter Property="TextBlock.TextDecorations" Value="Underline"/>
</Trigger>
<Trigger Property="Label.IsMouseOver" Value="False">
<Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
<Setter Property="TextBlock.TextDecorations" Value="None"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="{StaticResource NormalBrush}"/>
<Setter Property="FontSize" Value="{StaticResource FontSize}"/>
</Style.Setters>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="Margin" Value="{StaticResource FooterMargin}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style x:Key="ActionBarStyle" TargetType="Border">
<Style.Resources>
<Color x:Key="BackgroundColor">#C6C6C6</Color>
<SolidColorBrush x:Key="BackgroundBrush" Color="{StaticResource BackgroundColor}"/>
<sys:Double x:Key="ButtonHeight">23</sys:Double>
<sys:Double x:Key="ButtonWidth">75</sys:Double>
<Thickness x:Key="BorderPadding" Bottom="12" Left="12" Right="12" Top="12"/>
<Thickness x:Key="ButtonPadding" Bottom="3" Left="3" Right="3" Top="3"/>
<Thickness x:Key="ButtonMargin" Bottom="0" Left="6" Right="0" Top="0"/>
<Thickness x:Key="ButtonFocusedPadding" Bottom="1" Left="1" Right="1" Top="1"/>
<SolidColorBrush x:Key="ButtonBackgroundHoverBrush" Color="{StaticResource ButtonBackgroundHoverColor}"/>
<SolidColorBrush x:Key="ButtonBorderNormalBrush" Color="{StaticResource ButtonBorderNormalColor}"/>
<SolidColorBrush x:Key="ButtonBorderHoverBrush" Color="{StaticResource ButtonBorderHoverColor}"/>
<SolidColorBrush x:Key="ButtonBorderFocusedBrush" Color="{StaticResource ButtonBorderFocusedColor}"/>
<Thickness x:Key="BorderFocusedBorderThickness" Bottom="3" Left="3" Right="3" Top="3"/>
<Style TargetType="Button">
<Style.Resources>
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}"/>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderNormalBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource NormalThickness}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="MinHeight" Value="{StaticResource ButtonHeight}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="{StaticResource ButtonPadding}"/>
<Setter Property="Margin" Value="{StaticResource ButtonMargin}"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{StaticResource ButtonWidth}"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderHoverBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="{StaticResource BackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderNormalBrush}"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderFocusedBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource BorderFocusedBorderThickness}"/>
<Setter Property="Padding" Value="{StaticResource ButtonFocusedPadding}"/>
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderNormalBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource NormalThickness}"/>
<Setter Property="Padding" Value="{StaticResource ButtonPadding}"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BackgroundBrush}"/>
<Setter Property="Padding" Value="{StaticResource BorderPadding}"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</Window.Resources>
<Window.Content>
<Border Style="{StaticResource ControlStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Children>
<Label x:Name="HeaderLabel"
Grid.Column="0"
Grid.Row="0"
Style="{StaticResource HeaderLabelStyle}">
<TextBlock Text="Enter Passphrase"/>
</Label>
<Grid x:Name="ResourceGrid"
Grid.Column="0"
Grid.Row="1"
HorizontalAlignment="Center"
Style="{StaticResource ResourceGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Label x:Name="ResourceForLabel"
Grid.Column="0"
Grid.Row="0"
HorizontalContentAlignment="Right">
<TextBlock Text="for: "/>
</Label>
<Label x:Name="ResourceLabel"
Grid.Column="1"
Grid.Row="0"
HorizontalContentAlignment="Left">
<ScrollViewer BorderThickness="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
HorizontalScrollBarVisibility="Hidden"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
VerticalScrollBarVisibility="Disabled">
<TextBlock Text="{Binding Path=Resource}"/>
</ScrollViewer>
</Label>
</Grid.Children>
</Grid>
<Border Grid.Column="0"
Grid.Row="2"
Style="{StaticResource PassphraseBorderStyle}">
<PasswordBox x:Name="PassphrasePasswordBox"
Focusable="True"
TabIndex="0"/>
</Border>
<Button x:Name="LearnMoreLink"
Grid.Column="3"
Grid.Row="3"
Style="{StaticResource LearnMoreLinkStyle}"
Click="MoreInfoLabel_Click"
TabIndex="3">
<Label>
<TextBlock Text="Learn More"/>
</Label>
</Button>
<Border x:Name="ActionBar"
Grid.Column="0"
Grid.Row="4"
Style="{StaticResource ActionBarStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.Children>
<Button x:Name="OkButton"
Click="OkButton_Click"
Grid.Column="1"
Grid.Row="0"
IsDefault="True"
TabIndex="1">
<Label>
<TextBlock Text="OK"/>
</Label>
</Button>
<Button x:Name="CancelButton"
Click="CancelButton_Click"
Grid.Column="2"
Grid.Row="0"
IsCancel="True"
TabIndex="2">
<Label>
<TextBlock Text="Cancel"/>
</Label>
</Button>
</Grid.Children>
</Grid>
</Border>
</Grid.Children>
</Grid>
</Border>
</Window.Content>
</Window>

Просмотреть файл

@ -1,133 +0,0 @@
using System.Windows;
using System.Windows.Input;
namespace Microsoft.Alm.Gui
{
/// <summary>
/// Interaction logic for CredentialControl.xaml
/// </summary>
[System.Runtime.InteropServices.ComVisible(false)]
public partial class PassphraseWindow : Window
{
public const string HintText = "SSH Passphrase";
internal PassphraseWindow(string resource)
{
InitializeComponent();
_resource = resource;
Loaded += OnLoaded;
DataContext = this;
}
public bool Canceled
{
get { return _canceled; }
}
private bool _canceled;
public string Passphrase
{
get { return _passphrase; }
}
private string _passphrase;
public string Resource
{
get { return _resource; }
}
private readonly string _resource;
private PasswordBoxHintAdorner _textboxAdorner;
protected void OnLoaded(object sender, RoutedEventArgs args)
{
var style = Resources["FadedLabelStyle"] as Style;
if (style != null)
{
_textboxAdorner = new PasswordBoxHintAdorner(PassphrasePasswordBox, HintText, style, IsAdornerVisible);
}
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (ReferenceEquals(e, null))
return;
switch (e.Key)
{
case Key.Enter:
Success();
break;
case Key.Escape:
Failure();
break;
default:
base.OnKeyUp(e);
break;
}
}
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
Keyboard.Focus(PassphrasePasswordBox);
}
protected void CancelButton_Click(object sender, RoutedEventArgs e)
{
Failure();
Close();
}
protected void MoreInfoLabel_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
{
FileName = Cli.Program.DefinitionUrlPassphrase,
UseShellExecute = true,
});
}
protected void OkButton_Click(object sender, RoutedEventArgs e)
{
Success();
Close();
}
private void Failure()
{
_canceled = true;
_passphrase = null;
}
private Visibility IsAdornerVisible()
{
return (PassphrasePasswordBox.IsFocused || PassphrasePasswordBox.Password.Length > 0)
? Visibility.Collapsed
: Visibility.Visible;
}
private void Success()
{
string passphrase = PassphrasePasswordBox.Password;
if (string.IsNullOrWhiteSpace(passphrase))
{
_canceled = false;
_passphrase = null;
}
else
{
_canceled = false;
_passphrase = passphrase;
}
}
}
}

Просмотреть файл

@ -41,16 +41,27 @@ namespace Microsoft.Alm.Cli
private static readonly Regex AskCredentialRegex = new Regex(@"(\S+)\s+for\s+['""]([^'""]+)['""]:\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private static readonly Regex AskPassphraseRegex = new Regex(@"Enter\s+passphrase\s*for\s*key\s*['""]([^'""]+)['""]\:\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private static readonly Regex AskPasswordRegex = new Regex(@"(\S+)'s\s+password:\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private static readonly Regex AskAuthenticityRegex = new Regex(@"^\s*The authenticity of host '([^']+)' can't be established.\s+RSA key fingerprint is ([^\s:]+:[^\.]+).", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private static void Askpass(string[] args)
{
if (args == null || args.Length == 0)
throw new ArgumentException("Arguments cannot be empty.");
Gui.UserPromptKind promptKind = Gui.UserPromptKind.SshPassphrase;
Match match;
if ((match = AskPasswordRegex.Match(args[0])).Success
|| (match = AskPassphraseRegex.Match(args[0])).Success)
if ((match = AskPasswordRegex.Match(args[0])).Success)
{
promptKind = Gui.UserPromptKind.CredentialsPassword;
}
else if ((match = AskPassphraseRegex.Match(args[0])).Success)
{
promptKind = Gui.UserPromptKind.SshPassphrase;
}
if (match.Success)
{
Git.Trace.WriteLine("querying for passphrase key.");
if (match.Groups.Count < 2)
@ -62,12 +73,12 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"open dialog for '{resource}'.");
System.Windows.Application application = new System.Windows.Application();
Gui.PassphraseWindow prompt = new Gui.PassphraseWindow(resource);
Gui.UserPromptDialog prompt = new Gui.UserPromptDialog(promptKind, resource);
application.Run(prompt);
if (!prompt.Canceled && !string.IsNullOrEmpty(prompt.Passphrase))
if (!prompt.Failed && !string.IsNullOrEmpty(prompt.Response))
{
string passphase = prompt.Passphrase;
string passphase = prompt.Response;
Git.Trace.WriteLine("passphase acquired.");
@ -197,6 +208,31 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"failed to detect {seeking} in target URL.");
}
if ((match = AskAuthenticityRegex.Match(args[0])).Success)
{
string host = match.Groups[1].Value;
string fingerprint = match.Groups[2].Value;
Git.Trace.WriteLine($"requesting authorization to add {host} ({fingerprint}) to known hosts.");
System.Windows.Application application = new System.Windows.Application();
Gui.UserPromptDialog prompt = new Gui.UserPromptDialog(host, fingerprint);
application.Run(prompt);
if (prompt.Failed)
{
Git.Trace.WriteLine("denied authorization of host.");
Console.Out.Write("no\n");
}
else
{
Git.Trace.WriteLine("approved authorization of host.");
Console.Out.Write("yes\n");
}
return;
}
Git.Trace.WriteLine("failed to acquire credentials.");
}
@ -205,10 +241,10 @@ namespace Microsoft.Alm.Cli
{
EnableDebugTrace();
if (args.Length > 0
&& (String.Equals(args[0], "--help", StringComparison.OrdinalIgnoreCase)
|| String.Equals(args[0], "-h", StringComparison.OrdinalIgnoreCase)
|| args[0].Contains('?')))
if (args.Length == 0
|| String.Equals(args[0], "--help", StringComparison.OrdinalIgnoreCase)
|| String.Equals(args[0], "-h", StringComparison.OrdinalIgnoreCase)
|| String.Equals(args[0], "\\?", StringComparison.Ordinal))
{
PrintHelpMessage();
return;

Просмотреть файл

@ -0,0 +1,447 @@
<Window x:Class="Microsoft.Alm.Gui.UserPromptDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Microsoft.Alm.Gui"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Height="{Binding Path=DesiredHeight, Mode=OneWay}"
Icon="Assets/gcm.ico"
ResizeMode="NoResize"
Title="Git Credential Manager for Windows"
Topmost="True"
Width="{Binding Path=DesiredWidth, Mode=TwoWay}"
WindowStartupLocation="CenterScreen"
WindowStyle="ToolWindow">
<Window.Resources>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:Microsoft.Alm.Gui"
mc:Ignorable="PresentationOptions">
<Color x:Key="ColorBackground">#FFEEEEF2</Color>
<Color x:Key="ColorAccent">#FFF5F5F5</Color>
<Color x:Key="ColorButtonBackgroundHover">#FFFFFFFF</Color>
<Color x:Key="ColorButtonBorderNormal">#FFCCCEDB</Color>
<Color x:Key="ColorButtonBorderHover">#FF007ACC</Color>
<Color x:Key="ColorButtonBorderFocused">#FF4EA6EA</Color>
<Color x:Key="ColorNormal">#1F1F1F</Color>
<Color x:Key="ColorFaded">#FF969696</Color>
<sys:Double x:Key="WidthDouble">6</sys:Double>
<sys:Double x:Key="WidthFine">1</sys:Double>
<sys:Double x:Key="WidthNormal">3</sys:Double>
<sys:Double x:Key="WidthThin">2</sys:Double>
<sys:Double x:Key="FontSizeNormal">12</sys:Double>
<FontFamily x:Key="FontFamilyNormal">Segoe UI</FontFamily>
<FontFamily x:Key="FontFamilyLight">Segoe UI Light, Segoe UI, Global User Interface</FontFamily>
<FontFamily x:Key="FontFamilyBold">Segoe UI Semibold</FontFamily>
<SolidColorBrush x:Key="BrushAccent" Color="{StaticResource ColorAccent}"/>
<SolidColorBrush x:Key="BrushBackground" Color="{StaticResource ColorBackground}"/>
<SolidColorBrush x:Key="BrushFaded" Color="{StaticResource ColorFaded}" />
<SolidColorBrush x:Key="BrushNormal" Color="{StaticResource ColorNormal}" />
<Thickness x:Key="ThicknessDouble"
Bottom="{StaticResource WidthDouble}"
Left="{StaticResource WidthDouble}"
Right="{StaticResource WidthDouble}"
Top="{StaticResource WidthDouble}"/>
<Thickness x:Key="ThicknessMinimal"
Bottom="{StaticResource WidthFine}"
Left="{StaticResource WidthFine}"
Right="{StaticResource WidthFine}"
Top="{StaticResource WidthFine}"/>
<Thickness x:Key="ThicknessNormal"
Bottom="{StaticResource WidthNormal}"
Left="{StaticResource WidthNormal}"
Right="{StaticResource WidthNormal}"
Top="{StaticResource WidthNormal}"/>
<Thickness x:Key="PaddingDialog"
Bottom="{StaticResource WidthNormal}"
Left="{StaticResource WidthDouble}"
Right="{StaticResource WidthDouble}"
Top="{StaticResource WidthNormal}"/>
<Style x:Key="ControlStyle" TargetType="Border">
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource BrushNormal}"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
</Style>
<Style x:Key="DialogStyle" TargetType="Border" BasedOn="{StaticResource ControlStyle}">
<Setter Property="Padding" Value="{StaticResource PaddingDialog}"/>
</Style>
<Style x:Key="LabelStyle" TargetType="Label">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource BrushNormal}"/>
<Setter Property="FontFamily" Value="{StaticResource FontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeNormal}"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style.Setters>
</Style>
<Style x:Key="PromptLabelStyle" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Style.Resources>
<Thickness x:Key="Margin"
Bottom="{StaticResource WidthThin}"
Left="{StaticResource WidthThin}"
Right="{StaticResource WidthThin}"
Top="{StaticResource WidthThin}"/>
<Thickness x:Key="Padding"
Bottom="{StaticResource WidthThin}"
Left="{StaticResource WidthThin}"
Right="{StaticResource WidthThin}"
Top="{StaticResource WidthThin}"/>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="{StaticResource FontSizeNormal}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Margin" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</Style.Setters>
</Style>
<Style x:Key="ResourceGridStyle" TargetType="Grid">
<Style.Resources>
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Margin" Value="0"/>
</Style.Setters>
</Style>
<Style x:Key="FadedLabelStyle" TargetType="Label">
<Setter Property="Foreground" Value="{StaticResource BrushFaded}"/>
<Setter Property="FontFamily" Value="{StaticResource FontFamilyLight}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeNormal}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
</Style>
<Style x:Key="PassphraseBorderStyle" TargetType="Border">
<Style.Resources>
<Style TargetType="PasswordBox">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="{StaticResource BrushNormal}"/>
<Setter Property="FontFamily" Value="{StaticResource FontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeNormal}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource BrushFaded}"/>
<Setter Property="BorderThickness" Value="{StaticResource ThicknessMinimal}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style.Setters>
</Style>
<Style x:Key="LearnMoreLinkStyle" TargetType="Button">
<Style.Resources>
<Color x:Key="ColorNormal">#0078D7</Color>
<Color x:Key="HoverColor">#0078D7</Color>
<sys:Double x:Key="FontSize">12</sys:Double>
<SolidColorBrush x:Key="BrushNormal" Color="{StaticResource ColorNormal}" />
<SolidColorBrush x:Key="HoverBrush" Color="{StaticResource HoverColor}" />
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Style.Resources>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Label.IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource HoverBrush}"/>
<Setter Property="TextBlock.TextDecorations" Value="Underline"/>
</Trigger>
<Trigger Property="Label.IsMouseOver" Value="False">
<Setter Property="Foreground" Value="{StaticResource BrushNormal}"/>
<Setter Property="TextBlock.TextDecorations" Value="None"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="{StaticResource BrushNormal}"/>
<Setter Property="FontSize" Value="{StaticResource FontSize}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style.Setters>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0">
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style x:Key="ActionBarStyle" TargetType="Border">
<Style.Resources>
<Color x:Key="ColorBackground">#00000000</Color>
<SolidColorBrush x:Key="BrushBackground" Color="{StaticResource ColorBackground}"/>
<sys:Double x:Key="ButtonHeight">23</sys:Double>
<sys:Double x:Key="ButtonWidth">75</sys:Double>
<Thickness x:Key="MarginButton" Bottom="0" Left="6" Right="0" Top="0"/>
<SolidColorBrush x:Key="BrushButtonBackgroundHover" Color="{StaticResource ColorButtonBackgroundHover}"/>
<SolidColorBrush x:Key="BrushButtonBorderNormal" Color="{StaticResource ColorButtonBorderNormal}"/>
<SolidColorBrush x:Key="ButtonBorderHoverBrush" Color="{StaticResource ColorButtonBorderHover}"/>
<SolidColorBrush x:Key="BrushButtonBorderFocused" Color="{StaticResource ColorButtonBorderFocused}"/>
<Style TargetType="Button">
<Style.Resources>
<Style TargetType="Label" BasedOn="{StaticResource LabelStyle}">
<Style.Setters>
<Setter Property="Padding" Value="{StaticResource ThicknessMinimal}"/>
</Style.Setters>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorderNormal}"/>
<Setter Property="BorderThickness" Value="{StaticResource ThicknessMinimal}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="MinHeight" Value="{StaticResource ButtonHeight}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{StaticResource ButtonWidth}"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BrushButtonBackgroundHover}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorderHoverBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorderNormal}"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorderFocused}"/>
<Setter Property="BorderThickness" Value="{StaticResource ThicknessMinimal}"/>
<Setter Property="Padding" Value="0"/>
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorderNormal}"/>
<Setter Property="BorderThickness" Value="{StaticResource ThicknessMinimal}"/>
<Setter Property="Padding" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</Style.Setters>
</Style>
<Style x:Key="IconStyle" TargetType="Border">
<Style.Resources>
<sys:Double x:Key="SizeHeight">64</sys:Double>
<sys:Double x:Key="SizeWidth">64</sys:Double>
<Style TargetType="Image">
<Style.Setters>
<Setter Property="Height" Value="{StaticResource SizeHeight}"/>
<Setter Property="Width" Value="{StaticResource SizeWidth}"/>
<Setter Property="Stretch" Value="UniformToFill"/>
</Style.Setters>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="{StaticResource ThicknessNormal}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</Style.Setters>
</Style>
<Style x:Key="ValidateHostStyle" TargetType="StackPanel">
<Style.Resources>
<Thickness x:Key="ThicknessWide"
Bottom="0"
Left="{StaticResource WidthNormal}"
Right="{StaticResource WidthNormal}"
Top="0"/>
<Style TargetType="Label" BasedOn="{StaticResource PromptLabelStyle}">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</Style.Resources>
<Setter Property="Margin" Value="{StaticResource ThicknessWide}"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="{StaticResource BrushBackground}"/>
<Setter Property="Focusable" Value="True"/>
<Setter Property="FontFamily" Value="{StaticResource FontFamilyBold}"/>
<Setter Property="FontSize" Value="{StaticResource FontSizeNormal}"/>
<Setter Property="Padding" Value="{StaticResource ThicknessWide}"/>
<Setter Property="Margin" Value="{StaticResource ThicknessWide}"/>
</Style>
</Style.Resources>
<Style.Setters>
</Style.Setters>
</Style>
</ResourceDictionary>
</Window.Resources>
<Window.Content>
<Border Style="{StaticResource DialogStyle}">
<Border.Padding>
<Thickness Bottom="{StaticResource WidthNormal}"
Left="{StaticResource WidthDouble}"
Right="{StaticResource WidthDouble}"
Top="{StaticResource WidthNormal}"/>
</Border.Padding>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="96"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Children>
<Border x:Name="UserPrompt"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="0">
<ScrollViewer x:Name="PromptLabel"
BorderThickness="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
HorizontalScrollBarVisibility="Hidden"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.Children>
<Label Grid.Column="0"
Grid.Row="0"
Style="{StaticResource PromptLabelStyle}">
<TextBlock Text="{Binding Path=PromptText}" />
</Label>
<Border x:Name="UserInput"
Grid.Column="0"
Grid.Row="1"
Style="{StaticResource PassphraseBorderStyle}">
<PasswordBox x:Name="PassphrasePasswordBox"
Focusable="True"
TabIndex="0"/>
</Border>
<Border x:Name="AdditionalInfoLabel"
Grid.Column="0"
Grid.Row="1"
Visibility="Collapsed">
<StackPanel Orientation="Vertical"
Style="{StaticResource ValidateHostStyle}">
<Label>
<TextBlock Text="{Binding Path=AdditionalInfoText}"/>
</Label>
<TextBlock x:Name="FingerprintTextBlock"
Text="{Binding Path=Fingerprint}">
</TextBlock>
</StackPanel>
</Border>
</Grid.Children>
</Grid>
</ScrollViewer>
</Border>
<Border x:Name="GcmIcon"
Grid.Column="2"
Grid.ColumnSpan="1"
Grid.Row="0"
Grid.RowSpan="1"
Style="{StaticResource IconStyle}">
<Image Source="Assets/Gcm.png"/>
</Border>
<Border x:Name="ActionBar"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="1"
Style="{StaticResource ActionBarStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.Children>
<Button x:Name="LearnMoreLink"
Grid.Column="0"
Grid.Row="0"
Style="{StaticResource LearnMoreLinkStyle}"
Click="MoreInfoLabel_Click"
TabIndex="3">
<Label>
<TextBlock Text="Learn More"/>
</Label>
</Button>
<Button x:Name="PositiveButton"
Click="PositiveButton_Click"
Content="_Ok"
Grid.Column="1"
Grid.Row="0"
IsDefault="True"
TabIndex="1">
</Button>
<Button x:Name="NegativeButton"
Click="NegativeButton_Click"
Content="_Cancel"
Grid.Column="2"
Grid.Row="0"
IsCancel="True"
TabIndex="2">
</Button>
</Grid.Children>
</Grid>
</Border>
</Grid.Children>
</Grid>
</Border>
</Window.Content>
</Window>

Просмотреть файл

@ -0,0 +1,328 @@
/**** Git Credential Manager for Windows ****
*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the """"Software""""), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
**/
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Input;
namespace Microsoft.Alm.Gui
{
/// <summary>
/// Interaction logic for PassphraseWindow.xaml
/// </summary>
[System.Runtime.InteropServices.ComVisible(false)]
public partial class UserPromptDialog : Window
{
public const string HintTextPassphrase = "SSH Passphrase";
public const string HintTextPassword = "Password";
public const string HintTextUsername = "Username";
public const double WindowDefaultHeight = 150.0d;
public const double WindowDefaultWidth = 420.0d;
public const double WindowLargerHeight = 170.0d;
public const double WindowLargerWidth = 480.0d;
private const string AdornerStyleName = "FadedLabelStyle";
private readonly Size DefaultSize = new Size(WindowDefaultWidth, WindowDefaultHeight);
private readonly Size LargerSize = new Size(WindowLargerWidth, WindowLargerHeight);
internal UserPromptDialog(UserPromptKind kind, string resource)
{
if ((kind & ~(UserPromptKind.AuthenticateHost | UserPromptKind.CredentialsPassword | UserPromptKind.CredentialsUsername | UserPromptKind.SshPassphrase)) != 0)
throw new ArgumentOutOfRangeException(nameof(kind));
if (string.IsNullOrWhiteSpace(resource))
throw new ArgumentNullException(nameof(resource));
_kind = kind;
_resource = resource;
var text = new System.Text.StringBuilder("Enter ");
switch (kind)
{
case UserPromptKind.CredentialsPassword:
{
text.Append("Password");
_title = text.ToString();
text.Append(" for ");
}
break;
case UserPromptKind.CredentialsUsername:
{
text.Append("Username");
_title = text.ToString();
text.Append(" for ");
}
break;
case UserPromptKind.SshPassphrase:
{
text.Append("Passphrase");
_title = text.ToString();
text.Append(" for key ");
}
break;
}
_isLarger = false;
text.Append('\'')
.Append(resource)
.Append('\'');
_promptText = text.ToString(); ;
InitializeComponent();
Loaded += OnLoaded;
DataContext = this;
}
internal UserPromptDialog(string hostName, string fingerprint)
{
if (string.IsNullOrWhiteSpace(hostName))
throw new ArgumentNullException(nameof(hostName));
if (string.IsNullOrWhiteSpace(fingerprint))
throw new ArgumentNullException(nameof(fingerprint));
_fingerprint = fingerprint;
_kind = UserPromptKind.AuthenticateHost;
_title = "Validate Host Fingerprint";
_isLarger = true;
_promptText = "Continue connecting to '" + hostName + "'?";
_additionInfoText = "RSA key fingerprint:";
InitializeComponent();
Loaded += OnLoaded;
DataContext = this;
}
private readonly string _additionInfoText;
private readonly string _fingerprint;
private readonly bool _isLarger;
private readonly string _promptText;
private bool _failed;
private readonly UserPromptKind _kind;
private string _response;
private string _resource;
private PasswordBoxHintAdorner _textboxAdorner;
private readonly string _title;
public string AdditionalInfoText
{
get { return _additionInfoText; }
}
public double DesiredHeight
{
get
{
return _isLarger
? LargerSize.Height
: DefaultSize.Height;
}
set { /* nope */ }
}
public double DesiredWidth
{
get
{
return _isLarger
? LargerSize.Width
: DefaultSize.Width;
}
set { /* nope */ }
}
public bool Failed
{
get { return _failed; }
}
public string Fingerprint
{
get { return _fingerprint; }
set { /* nope */ }
}
public UserPromptKind Kind
{
get { return _kind; }
}
public string PromptText
{
get { return _promptText; }
}
public string Response
{
get { return _response; }
}
protected void OnLoaded(object sender, RoutedEventArgs args)
{
string hintText = null;
this.Title = _title;
switch (_kind)
{
case UserPromptKind.AuthenticateHost:
PositiveButton.Content = "_Yes";
NegativeButton.Content = "_No";
AdditionalInfoLabel.Visibility = Visibility.Visible;
break;
case UserPromptKind.CredentialsPassword:
hintText = HintTextPassword;
break;
case UserPromptKind.CredentialsUsername:
hintText = HintTextUsername;
break;
case UserPromptKind.SshPassphrase:
hintText = HintTextPassphrase;
break;
}
LearnMoreLink.Visibility = _kind == UserPromptKind.SshPassphrase
? Visibility.Visible
: Visibility.Collapsed;
this.Topmost = true;
this.BringIntoView();
this.Activate();
if (hintText != null)
{
UserInput.Visibility = Visibility.Visible;
var style = Resources[AdornerStyleName] as Style;
if (style != null)
{
_textboxAdorner = new PasswordBoxHintAdorner(PassphrasePasswordBox, hintText, style, IsAdornerVisible);
}
this.PassphrasePasswordBox.Focus();
}
else
{
UserInput.Visibility = Visibility.Collapsed;
}
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (ReferenceEquals(e, null))
return;
switch (e.Key)
{
case Key.Enter:
Success();
break;
case Key.Escape:
Failure();
break;
default:
base.OnKeyUp(e);
break;
}
}
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
Keyboard.Focus(PassphrasePasswordBox);
}
protected void MoreInfoLabel_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
{
FileName = Cli.Program.DefinitionUrlPassphrase,
UseShellExecute = true,
});
}
protected void NegativeButton_Click(object sender, RoutedEventArgs e)
{
Failure();
Close();
}
protected void PositiveButton_Click(object sender, RoutedEventArgs e)
{
Success();
Close();
}
private void Failure()
{
_failed = true;
_response = null;
}
private Visibility IsAdornerVisible()
{
return (PassphrasePasswordBox.IsFocused || PassphrasePasswordBox.Password.Length > 0)
? Visibility.Collapsed
: Visibility.Visible;
}
private void Success()
{
string passphrase = PassphrasePasswordBox.Password;
if (string.IsNullOrWhiteSpace(passphrase))
{
_failed = false;
_response = null;
}
else
{
_failed = false;
_response = passphrase;
}
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
/**** Git Credential Manager for Windows ****
*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the """"Software""""), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
**/
namespace Microsoft.Alm.Gui
{
public enum UserPromptKind
{
SshPassphrase,
CredentialsUsername,
CredentialsPassword,
AuthenticateHost,
}
}

Просмотреть файл

@ -257,14 +257,6 @@ namespace Microsoft.Alm.Cli
}
}
[Flags]
private enum test
{
A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
}
[STAThread]
private static void Main(string[] args)
{