Skip to content

Commit 241afed

Browse files
committed
generic-ui: add WPF impl of OAuth and device code
Add the WPF based GUI implementation of the OAuth and device code generic prompts.
1 parent d59cd44 commit 241afed

File tree

9 files changed

+316
-0
lines changed

9 files changed

+316
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
using GitCredentialManager.UI.ViewModels;
4+
using GitCredentialManager.UI.Views;
5+
6+
namespace GitCredentialManager.UI.Commands
7+
{
8+
public class DeviceCodeCommandImpl : DeviceCodeCommand
9+
{
10+
public DeviceCodeCommandImpl(ICommandContext context) : base(context) { }
11+
12+
protected override Task ShowAsync(DeviceCodeViewModel viewModel, CancellationToken ct)
13+
{
14+
return Gui.ShowDialogWindow(viewModel, () => new DeviceCodeView(), GetParentHandle());
15+
}
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
using GitCredentialManager.UI.ViewModels;
4+
using GitCredentialManager.UI.Views;
5+
6+
namespace GitCredentialManager.UI.Commands
7+
{
8+
public class OAuthCommandImpl : OAuthCommand
9+
{
10+
public OAuthCommandImpl(ICommandContext context) : base(context) { }
11+
12+
protected override Task ShowAsync(OAuthViewModel viewModel, CancellationToken ct)
13+
{
14+
return Gui.ShowDialogWindow(viewModel, () => new OAuthView(), GetParentHandle());
15+
}
16+
}
17+
}

src/windows/Git-Credential-Manager.UI.Windows/Controls/TesterWindow.xaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,84 @@
4444
</StackPanel>
4545
</StackPanel>
4646
</TabItem>
47+
48+
<TabItem Header="OAuth">
49+
<StackPanel>
50+
<Grid>
51+
<Grid.RowDefinitions>
52+
<RowDefinition Height="Auto"/>
53+
<RowDefinition Height="Auto"/>
54+
<RowDefinition Height="Auto"/>
55+
<RowDefinition Height="Auto"/>
56+
</Grid.RowDefinitions>
57+
<Grid.ColumnDefinitions>
58+
<ColumnDefinition Width="Auto"/>
59+
<ColumnDefinition Width="*"/>
60+
</Grid.ColumnDefinitions>
61+
<Label Grid.Row="0" Grid.Column="0"
62+
Content="Window Title" />
63+
<TextBox Grid.Row="0" Grid.Column="1"
64+
x:Name="oauthTitle" Text="Git Credential Manager" />
65+
<Label Grid.Row="1" Grid.Column="0"
66+
Content="Description" />
67+
<TextBox Grid.Row="1" Grid.Column="1"
68+
x:Name="oauthDescription" Text="Sign in to 'https://example.com'" />
69+
<Label Grid.Row="2" Grid.Column="0"
70+
Content="Modes" />
71+
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
72+
<CheckBox Content="Browser" x:Name="oauthBrowser" MinWidth="90" IsChecked="True" />
73+
<CheckBox Content="Device Code" x:Name="oauthDeviceCode" MinWidth="80" IsChecked="True" />
74+
</StackPanel>
75+
<Label Grid.Row="3" Grid.Column="0"
76+
Content="Show Logo" />
77+
<CheckBox Grid.Row="3" Grid.Column="1"
78+
x:Name="oauthShowLogo" IsChecked="True" />
79+
</Grid>
80+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
81+
Margin="0,10">
82+
<Button Content="Show" Click="ShowOAuth"
83+
Padding="8,4"/>
84+
</StackPanel>
85+
</StackPanel>
86+
</TabItem>
87+
88+
89+
<TabItem Header="Device Code">
90+
<StackPanel>
91+
<Grid>
92+
<Grid.RowDefinitions>
93+
<RowDefinition Height="Auto"/>
94+
<RowDefinition Height="Auto"/>
95+
<RowDefinition Height="Auto"/>
96+
<RowDefinition Height="Auto"/>
97+
</Grid.RowDefinitions>
98+
<Grid.ColumnDefinitions>
99+
<ColumnDefinition Width="Auto"/>
100+
<ColumnDefinition Width="*"/>
101+
</Grid.ColumnDefinitions>
102+
<Label Grid.Row="0" Grid.Column="0"
103+
Content="Window Title" />
104+
<TextBox Grid.Row="0" Grid.Column="1"
105+
x:Name="deviceTitle" Text="Git Credential Manager" />
106+
<Label Grid.Row="1" Grid.Column="0"
107+
Content="User Code" />
108+
<TextBox Grid.Row="1" Grid.Column="1"
109+
x:Name="deviceUserCode" Text="ABCD-EFGH-1234" />
110+
<Label Grid.Row="2" Grid.Column="0"
111+
Content="Verification URL" />
112+
<TextBox Grid.Row="2" Grid.Column="1"
113+
x:Name="deviceVerificationUrl" Text="https://example.com/signin/device" />
114+
<Label Grid.Row="3" Grid.Column="0"
115+
Content="Show Logo" />
116+
<CheckBox Grid.Row="3" Grid.Column="1"
117+
x:Name="deviceShowLogo" IsChecked="True" />
118+
</Grid>
119+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
120+
Margin="0,10">
121+
<Button Content="Show" Click="ShowDeviceCode"
122+
Padding="8,4"/>
123+
</StackPanel>
124+
</StackPanel>
125+
</TabItem>
47126
</TabControl>
48127
</Window>

src/windows/Git-Credential-Manager.UI.Windows/Controls/TesterWindow.xaml.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,40 @@
11
using System.Windows;
22
using GitCredentialManager.UI.ViewModels;
33
using GitCredentialManager.UI.Views;
4+
using GitCredentialManager.Interop.Linux;
5+
using GitCredentialManager.Interop.MacOS;
6+
using GitCredentialManager.Interop.Posix;
47
using GitCredentialManager.Interop.Windows;
58
using GitCredentialManager.UI.Controls;
69

710
namespace GitCredentialManager.UI.Controls
811
{
912
public partial class TesterWindow : Window
1013
{
14+
private readonly IEnvironment _environment;
15+
1116
public TesterWindow()
1217
{
1318
InitializeComponent();
19+
20+
if (PlatformUtils.IsWindows())
21+
{
22+
_environment = new WindowsEnvironment(new WindowsFileSystem());
23+
}
24+
else
25+
{
26+
IFileSystem fs;
27+
if (PlatformUtils.IsMacOS())
28+
{
29+
fs = new MacOSFileSystem();
30+
}
31+
else
32+
{
33+
fs = new LinuxFileSystem();
34+
}
35+
36+
_environment = new PosixEnvironment(fs);
37+
}
1438
}
1539

1640
private void ShowBasic(object sender, RoutedEventArgs e)
@@ -26,5 +50,34 @@ private void ShowBasic(object sender, RoutedEventArgs e)
2650
var window = new DialogWindow(view) {DataContext = vm};
2751
window.ShowDialog();
2852
}
53+
54+
private void ShowOAuth(object sender, RoutedEventArgs e)
55+
{
56+
var vm = new OAuthViewModel
57+
{
58+
Title = oauthTitle.Text,
59+
Description = oauthDescription.Text,
60+
ShowBrowserLogin = oauthBrowser.IsChecked ?? false,
61+
ShowDeviceCodeLogin = oauthDeviceCode.IsChecked ?? false,
62+
ShowProductHeader = oauthShowLogo.IsChecked ?? false
63+
};
64+
var view = new OAuthView();
65+
var window = new DialogWindow(view) { DataContext = vm };
66+
window.ShowDialog();
67+
}
68+
69+
private void ShowDeviceCode(object sender, RoutedEventArgs e)
70+
{
71+
var vm = new DeviceCodeViewModel(_environment)
72+
{
73+
Title = deviceTitle.Text,
74+
UserCode = deviceUserCode.Text,
75+
VerificationUrl = deviceVerificationUrl.Text,
76+
ShowProductHeader = deviceShowLogo.IsChecked ?? false
77+
};
78+
var view = new DeviceCodeView();
79+
var window = new DialogWindow(view) { DataContext = vm };
80+
window.ShowDialog();
81+
}
2982
}
3083
}

src/windows/Git-Credential-Manager.UI.Windows/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public static async Task Main(string[] args)
2121
}
2222

2323
app.RegisterCommand(new CredentialsCommandImpl(context));
24+
app.RegisterCommand(new OAuthCommandImpl(context));
25+
app.RegisterCommand(new DeviceCodeCommandImpl(context));
2426

2527
int exitCode = app.RunAsync(args)
2628
.ConfigureAwait(false)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<UserControl x:Class="GitCredentialManager.UI.Views.DeviceCodeView"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:viewModels="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=Core.UI"
7+
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcoreuiwpf"
8+
mc:Ignorable="d"
9+
d:DataContext="{d:DesignInstance viewModels:DeviceCodeViewModel}"
10+
d:DesignHeight="300" d:DesignWidth="300">
11+
<UserControl.Resources>
12+
<ResourceDictionary>
13+
<ResourceDictionary.MergedDictionaries>
14+
<ResourceDictionary Source="../Assets/Styles.xaml"/>
15+
</ResourceDictionary.MergedDictionaries>
16+
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
17+
</ResourceDictionary>
18+
</UserControl.Resources>
19+
20+
<DockPanel>
21+
<StackPanel DockPanel.Dock="Top" Margin="10,0,0,10">
22+
<StackPanel Margin="0"
23+
Orientation="Horizontal"
24+
HorizontalAlignment="Center"
25+
Visibility="{Binding ShowProductHeader, Converter={StaticResource BooleanToVisibilityConverter}}">
26+
<Image Source="{StaticResource GcmLogo}"
27+
Height="32" VerticalAlignment="Center"
28+
Margin="0,0,10,0"/>
29+
<TextBlock Text="Git Credential Manager"
30+
VerticalAlignment="Center"
31+
FontSize="18"
32+
FontWeight="Light" />
33+
</StackPanel>
34+
</StackPanel>
35+
36+
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
37+
<TextBlock Text="Visit the URL below, sign in, and enter the following device code to continue."
38+
Margin="0,0,0,20"
39+
TextWrapping="Wrap" TextAlignment="Center" FontSize="14"/>
40+
<TextBox Text="{Binding UserCode}"
41+
Margin="0,0,0,20"
42+
HorizontalAlignment="Center"
43+
FontSize="24"
44+
TextAlignment="Center"
45+
Style="{StaticResource DeviceCodeBox}"/>
46+
<TextBlock FontSize="14"
47+
HorizontalAlignment="Center">
48+
<Hyperlink Command="{Binding VerificationUrlCommand}">
49+
<Run Text="{Binding VerificationUrl}"/>
50+
</Hyperlink>
51+
</TextBlock>
52+
</StackPanel>
53+
</DockPanel>
54+
</UserControl>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Windows.Controls;
3+
using System.Windows.Threading;
4+
5+
namespace GitCredentialManager.UI.Views
6+
{
7+
public partial class DeviceCodeView : UserControl
8+
{
9+
public DeviceCodeView()
10+
{
11+
InitializeComponent();
12+
}
13+
}
14+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<UserControl x:Class="GitCredentialManager.UI.Views.OAuthView"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:viewModels="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=gcmcoreui"
7+
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcoreuiwpf"
8+
xmlns:controls="clr-namespace:GitCredentialManager.UI.Controls"
9+
xmlns:sharedControls="clr-namespace:GitCredentialManager.UI.Controls;assembly=gcmcoreuiwpf"
10+
mc:Ignorable="d"
11+
d:DataContext="{d:DesignInstance viewModels:CredentialsViewModel}"
12+
d:DesignWidth="300">
13+
<UserControl.Resources>
14+
<ResourceDictionary>
15+
<ResourceDictionary.MergedDictionaries>
16+
<ResourceDictionary Source="../Assets/Styles.xaml"/>
17+
</ResourceDictionary.MergedDictionaries>
18+
<converters:NonEmptyStringToVisibleConverter x:Key="NonEmptyStringToVisibleConverter"/>
19+
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
20+
<converters:BooleanOrToVisibilityConverter x:Key="BooleanOrToVisibilityConverter"/>
21+
<converters:BooleanOrConverter x:Key="BooleanOrConverter"/>
22+
<converters:BooleanNotConverter x:Key="BooleanNotConverter"/>
23+
</ResourceDictionary>
24+
</UserControl.Resources>
25+
26+
<DockPanel>
27+
<StackPanel DockPanel.Dock="Top" Margin="10,0,0,10">
28+
<StackPanel Margin="0"
29+
Orientation="Horizontal"
30+
HorizontalAlignment="Center"
31+
Visibility="{Binding ShowProductHeader, Converter={StaticResource BooleanToVisibilityConverter}}">
32+
<Image Source="{StaticResource GcmLogo}"
33+
Height="32" VerticalAlignment="Center"
34+
Margin="0,0,10,0"/>
35+
<TextBlock Text="Git Credential Manager"
36+
VerticalAlignment="Center"
37+
FontSize="18"
38+
FontWeight="Light" />
39+
</StackPanel>
40+
41+
<TextBlock Text="{Binding Description}"
42+
HorizontalAlignment="Center"
43+
FontSize="14"
44+
Margin="0,15,0,15"/>
45+
</StackPanel>
46+
47+
<StackPanel x:Name="oauthPanel"
48+
Margin="0,10">
49+
<Button x:Name="browserButton"
50+
Content="Sign in with your browser"
51+
IsDefault="True"
52+
Command="{Binding SignInBrowserCommand}"
53+
Visibility="{Binding ShowBrowserLogin, Converter={StaticResource BooleanToVisibilityConverter}}"
54+
HorizontalAlignment="Center"
55+
Margin="0,0,0,10"
56+
Style="{StaticResource AccentButton}"/>
57+
<Button x:Name="deviceButton"
58+
Content="Sign in with a code"
59+
IsDefault="{Binding ShowBrowserLogin, Converter={StaticResource BooleanNotConverter}}"
60+
Command="{Binding SignInDeviceCodeCommand}"
61+
Visibility="{Binding ShowDeviceCodeLogin, Converter={StaticResource BooleanToVisibilityConverter}}"
62+
HorizontalAlignment="Center"
63+
Margin="0,10,0,10"/>
64+
</StackPanel>
65+
</DockPanel>
66+
</UserControl>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
using System.Windows.Input;
4+
5+
namespace GitCredentialManager.UI.Views
6+
{
7+
public partial class OAuthView : UserControl
8+
{
9+
public OAuthView()
10+
{
11+
InitializeComponent();
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)