enhance: GPG signing settings.

* remove gpg format settings from repository's local setting
* add support for X.509 format
* ux style
This commit is contained in:
leo 2024-06-04 10:20:31 +08:00
parent 38fd30d431
commit 4b0af79f73
7 changed files with 37 additions and 72 deletions

View file

@ -2,24 +2,18 @@
namespace SourceGit.Models namespace SourceGit.Models
{ {
public class GPGFormat(string name, string value, string desc) public class GPGFormat(string name, string value, string desc, string program, bool needFindProgram)
{ {
public string Name { get; set; } = name; public string Name { get; set; } = name;
public string Value { get; set; } = value; public string Value { get; set; } = value;
public string Desc { get; set; } = desc; public string Desc { get; set; } = desc;
public string Program { get; set; } = program;
public bool NeedFindProgram { get; set; } = needFindProgram;
public static readonly GPGFormat OPENPGP = new GPGFormat("OPENPGP", "openpgp", "DEFAULT"); public static readonly List<GPGFormat> Supported = [
new GPGFormat("OPENPGP", "openpgp", "DEFAULT", "gpg", true),
public static readonly GPGFormat SSH = new GPGFormat("SSH", "ssh", "Git >= 2.34.0"); new GPGFormat("X.509", "x509", "", "gpgsm", true),
new GPGFormat("SSH", "ssh", "Requires Git >= 2.34.0", "ssh-keygen", false),
public static readonly List<GPGFormat> Supported = new List<GPGFormat>() { ];
OPENPGP,
SSH,
};
public bool Equals(GPGFormat other)
{
return Value == other.Value;
}
} }
} }

View file

@ -314,7 +314,7 @@
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">Commit GPG signing</x:String> <x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">Commit GPG signing</x:String>
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Tag GPG signing</x:String> <x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Tag GPG signing</x:String>
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG Format</x:String> <x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG Format</x:String>
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">Install Path</x:String> <x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">Program Install Path</x:String>
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Input path for installed gpg program</x:String> <x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Input path for installed gpg program</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">User Signing Key</x:String> <x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">User Signing Key</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">User's gpg signing key</x:String> <x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">User's gpg signing key</x:String>

View file

@ -316,9 +316,9 @@
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG签名</x:String> <x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG签名</x:String>
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">启用提交签名</x:String> <x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">启用提交签名</x:String>
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">启用标签签名</x:String> <x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">启用标签签名</x:String>
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG签名格式</x:String> <x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">签名格式</x:String>
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">可执行文件位置</x:String> <x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">签名程序位置</x:String>
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">gpg.exe所在路径</x:String> <x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">签名程序所在路径</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">用户签名KEY</x:String> <x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">用户签名KEY</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">输入签名提交所使用的KEY</x:String> <x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">输入签名提交所使用的KEY</x:String>
<x:String x:Key="Text.Preference.Merger" xml:space="preserve">外部合并工具</x:String> <x:String x:Key="Text.Preference.Merger" xml:space="preserve">外部合并工具</x:String>

View file

@ -17,12 +17,6 @@ namespace SourceGit.ViewModels
set; set;
} }
public Models.GPGFormat GPGFormat
{
get;
set;
}
public bool GPGCommitSigningEnabled public bool GPGCommitSigningEnabled
{ {
get; get;
@ -60,10 +54,6 @@ namespace SourceGit.ViewModels
GPGCommitSigningEnabled = gpgCommitSign == "true"; GPGCommitSigningEnabled = gpgCommitSign == "true";
if (_cached.TryGetValue("tag.gpgSign", out var gpgTagSign)) if (_cached.TryGetValue("tag.gpgSign", out var gpgTagSign))
GPGTagSigningEnabled = gpgTagSign == "true"; GPGTagSigningEnabled = gpgTagSign == "true";
if (_cached.TryGetValue("gpg.format", out var gpgFormat))
GPGFormat = Models.GPGFormat.Supported.Find(x => x.Value == gpgFormat);
else
GPGFormat = Models.GPGFormat.OPENPGP;
if (_cached.TryGetValue("user.signingkey", out var signingKey)) if (_cached.TryGetValue("user.signingkey", out var signingKey))
GPGUserSigningKey = signingKey; GPGUserSigningKey = signingKey;
if (_cached.TryGetValue("http.proxy", out var proxy)) if (_cached.TryGetValue("http.proxy", out var proxy))
@ -78,20 +68,19 @@ namespace SourceGit.ViewModels
SetIfChanged("user.email", UserEmail); SetIfChanged("user.email", UserEmail);
SetIfChanged("commit.gpgsign", GPGCommitSigningEnabled ? "true" : "false"); SetIfChanged("commit.gpgsign", GPGCommitSigningEnabled ? "true" : "false");
SetIfChanged("tag.gpgSign", GPGTagSigningEnabled ? "true" : "false"); SetIfChanged("tag.gpgSign", GPGTagSigningEnabled ? "true" : "false");
SetIfChanged("gpg.format", GPGFormat?.Value, Models.GPGFormat.OPENPGP.Value);
SetIfChanged("user.signingkey", GPGUserSigningKey); SetIfChanged("user.signingkey", GPGUserSigningKey);
SetIfChanged("http.proxy", HttpProxy); SetIfChanged("http.proxy", HttpProxy);
return null; return null;
} }
private void SetIfChanged(string key, string value, string defaultValue = null) private void SetIfChanged(string key, string value)
{ {
bool changed = false; bool changed = false;
if (_cached.TryGetValue(key, out var old)) if (_cached.TryGetValue(key, out var old))
{ {
changed = old != value; changed = old != value;
} }
else if (!string.IsNullOrEmpty(value) && value != defaultValue) else if (!string.IsNullOrEmpty(value))
{ {
changed = true; changed = true;
} }

View file

@ -409,7 +409,7 @@
<ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/> <ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/>
</TabItem.Resources> </TabItem.Resources>
<Grid Margin="8" RowDefinitions="32,32,32,32,32" ColumnDefinitions="Auto,*"> <Grid Margin="8" RowDefinitions="32,Auto,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
Text="{DynamicResource Text.Preference.GPG.Format}" Text="{DynamicResource Text.Preference.GPG.Format}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
@ -419,7 +419,7 @@
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={x:Static m:GPGFormat.Supported}}" ItemsSource="{Binding Source={x:Static m:GPGFormat.Supported}}"
SelectedItem="{Binding #me.GPGFormat, Mode=TwoWay, FallbackValue={x:Static m:GPGFormat.OPENPGP}}"> SelectedItem="{Binding #me.GPGFormat, Mode=TwoWay}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:GPGFormat}"> <DataTemplate x:DataType="{x:Type m:GPGFormat}">
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*">
@ -433,12 +433,14 @@
<TextBlock Grid.Row="1" Grid.Column="0" <TextBlock Grid.Row="1" Grid.Column="0"
Text="{DynamicResource Text.Preference.GPG.Path}" Text="{DynamicResource Text.Preference.GPG.Path}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"
IsVisible="{Binding #me.GPGFormat.NeedFindProgram}"/>
<TextBox Grid.Row="1" Grid.Column="1" <TextBox Grid.Row="1" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}" Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}"
IsEnabled="{Binding #me.GPGFormat, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:GPGFormat.OPENPGP}}"> Watermark="{DynamicResource Text.Preference.GPG.Path.Placeholder}"
IsVisible="{Binding #me.GPGFormat.NeedFindProgram}">
<TextBox.InnerRightContent> <TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable"> <Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/> <Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
@ -67,7 +68,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<Models.GPGFormat> GPGFormatProperty = public static readonly StyledProperty<Models.GPGFormat> GPGFormatProperty =
AvaloniaProperty.Register<Preference, Models.GPGFormat>(nameof(GPGFormat)); AvaloniaProperty.Register<Preference, Models.GPGFormat>(nameof(GPGFormat), Models.GPGFormat.Supported[0]);
public Models.GPGFormat GPGFormat public Models.GPGFormat GPGFormat
{ {
@ -160,10 +161,11 @@ namespace SourceGit.Views
if (config.TryGetValue("tag.gpgSign", out var gpgTagSign)) if (config.TryGetValue("tag.gpgSign", out var gpgTagSign))
EnableGPGTagSigning = (gpgTagSign == "true"); EnableGPGTagSigning = (gpgTagSign == "true");
if (config.TryGetValue("gpg.format", out var gpgFormat)) if (config.TryGetValue("gpg.format", out var gpgFormat))
GPGFormat = Models.GPGFormat.Supported.Find(x => x.Value == gpgFormat); GPGFormat = Models.GPGFormat.Supported.Find(x => x.Value == gpgFormat) ?? Models.GPGFormat.Supported[0];
else
GPGFormat = Models.GPGFormat.OPENPGP; if (GPGFormat.Value == "opengpg" && config.TryGetValue("gpg.program", out var opengpg))
if (config.TryGetValue("gpg.program", out var gpgProgram)) GPGExecutableFile = opengpg;
else if (config.TryGetValue($"gpg.{GPGFormat.Value}.program", out var gpgProgram))
GPGExecutableFile = gpgProgram; GPGExecutableFile = gpgProgram;
ver = new Commands.Version().Query(); ver = new Commands.Version().Query();
@ -187,7 +189,7 @@ namespace SourceGit.Views
var oldEmail = config.TryGetValue("user.email", out var email) ? email : string.Empty; var oldEmail = config.TryGetValue("user.email", out var email) ? email : string.Empty;
var oldGPGSignKey = config.TryGetValue("user.signingkey", out var signingKey) ? signingKey : string.Empty; var oldGPGSignKey = config.TryGetValue("user.signingkey", out var signingKey) ? signingKey : string.Empty;
var oldCRLF = config.TryGetValue("core.autocrlf", out var crlf) ? crlf : string.Empty; var oldCRLF = config.TryGetValue("core.autocrlf", out var crlf) ? crlf : string.Empty;
var oldGPGFormat = config.TryGetValue("gpg.format", out var gpgFormat) ? gpgFormat : Models.GPGFormat.OPENPGP.Value; var oldGPGFormat = config.TryGetValue("gpg.format", out var gpgFormat) ? gpgFormat : "opengpg";
var oldGPGCommitSignEnable = config.TryGetValue("commit.gpgsign", out var gpgCommitSign) ? gpgCommitSign : "false"; var oldGPGCommitSignEnable = config.TryGetValue("commit.gpgsign", out var gpgCommitSign) ? gpgCommitSign : "false";
var oldGPGTagSignEnable = config.TryGetValue("tag.gpgSign", out var gpgTagSign) ? gpgTagSign : "false"; var oldGPGTagSignEnable = config.TryGetValue("tag.gpgSign", out var gpgTagSign) ? gpgTagSign : "false";
var oldGPGExec = config.TryGetValue("gpg.program", out var program) ? program : string.Empty; var oldGPGExec = config.TryGetValue("gpg.program", out var program) ? program : string.Empty;
@ -204,10 +206,10 @@ namespace SourceGit.Views
cmd.Set("commit.gpgsign", EnableGPGCommitSigning ? "true" : "false"); cmd.Set("commit.gpgsign", EnableGPGCommitSigning ? "true" : "false");
if (EnableGPGTagSigning != (oldGPGTagSignEnable == "true")) if (EnableGPGTagSigning != (oldGPGTagSignEnable == "true"))
cmd.Set("tag.gpgSign", EnableGPGTagSigning ? "true" : "false"); cmd.Set("tag.gpgSign", EnableGPGTagSigning ? "true" : "false");
if (GPGFormat != null && GPGFormat.Value != oldGPGFormat) if (GPGFormat.Value != oldGPGFormat)
cmd.Set("gpg.format", GPGFormat.Value); cmd.Set("gpg.format", GPGFormat.Value);
if (GPGExecutableFile != oldGPGExec) if (GPGExecutableFile != oldGPGExec)
cmd.Set("gpg.program", GPGExecutableFile); cmd.Set($"gpg.{GPGFormat.Value}.program", GPGExecutableFile);
Close(); Close();
} }
@ -245,15 +247,13 @@ namespace SourceGit.Views
{ {
var patterns = new List<string>(); var patterns = new List<string>();
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
patterns.Add("gpg.exe"); patterns.Add($"{GPGFormat.Program}.exe");
else if (OperatingSystem.IsLinux())
patterns.AddRange(new string[] { "gpg", "gpg2" });
else else
patterns.Add("gpg"); patterns.Add(GPGFormat.Program);
var options = new FilePickerOpenOptions() var options = new FilePickerOpenOptions()
{ {
FileTypeFilter = [new FilePickerFileType("GPG Executable") { Patterns = patterns }], FileTypeFilter = [new FilePickerFileType("GPG Program") { Patterns = patterns }],
AllowMultiple = false, AllowMultiple = false,
}; };

View file

@ -14,7 +14,7 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Configure}"/> Text="{DynamicResource Text.Configure}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
@ -47,40 +47,20 @@
Text="{Binding HttpProxy, Mode=TwoWay}"/> Text="{Binding HttpProxy, Mode=TwoWay}"/>
<TextBlock Grid.Row="3" Grid.Column="0" <TextBlock Grid.Row="3" Grid.Column="0"
Text="{DynamicResource Text.Preference.GPG.Format}"
HorizontalAlignment="Right"
Margin="0,0,16,0"/>
<ComboBox Grid.Row="3" Grid.Column="1"
MinHeight="28"
Padding="8,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={x:Static m:GPGFormat.Supported}}"
SelectedItem="{Binding GPGFormat, Mode=TwoWay, FallbackValue={x:Static m:GPGFormat.OPENPGP}}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:GPGFormat}">
<Grid ColumnDefinitions="Auto,*">
<TextBlock Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Grid.Column="1" Text="{Binding Desc}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Right"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="4" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Preference.GPG.UserKey}"/> Text="{DynamicResource Text.Preference.GPG.UserKey}"/>
<TextBox Grid.Row="4" Grid.Column="1" <TextBox Grid.Row="3" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}" Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"
Text="{Binding GPGUserSigningKey, Mode=TwoWay}"/> Text="{Binding GPGUserSigningKey, Mode=TwoWay}"/>
<CheckBox Grid.Row="5" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.Preference.GPG.CommitEnabled}" Content="{DynamicResource Text.Preference.GPG.CommitEnabled}"
IsChecked="{Binding GPGCommitSigningEnabled, Mode=TwoWay}"/> IsChecked="{Binding GPGCommitSigningEnabled, Mode=TwoWay}"/>
<CheckBox Grid.Row="6" Grid.Column="1" <CheckBox Grid.Row="5" Grid.Column="1"
Content="{DynamicResource Text.Preference.GPG.TagEnabled}" Content="{DynamicResource Text.Preference.GPG.TagEnabled}"
IsChecked="{Binding GPGTagSigningEnabled, Mode=TwoWay}"/> IsChecked="{Binding GPGTagSigningEnabled, Mode=TwoWay}"/>
</Grid> </Grid>