1
1
mirror of https://github.com/go-gitea/gitea synced 2025-09-13 12:18:13 +00:00

Fix SSH signing key path will be displayed in the pull request UI (#35381)

Closes #35361

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
ChristopherHX
2025-09-12 05:00:18 +02:00
committed by GitHub
parent 16e1207449
commit 84812e42df
8 changed files with 70 additions and 18 deletions

View File

@@ -25,7 +25,7 @@ type CommitVerification struct {
SigningUser *user_model.User // if Verified, then SigningUser is non-nil SigningUser *user_model.User // if Verified, then SigningUser is non-nil
CommittingUser *user_model.User // if Verified, then CommittingUser is non-nil CommittingUser *user_model.User // if Verified, then CommittingUser is non-nil
SigningEmail string SigningEmail string
SigningKey *GPGKey SigningKey *GPGKey // FIXME: need to refactor it to a new name like "SigningGPGKey", it is also used in some templates
SigningSSHKey *PublicKey SigningSSHKey *PublicKey
TrustStatus string TrustStatus string
} }

View File

@@ -0,0 +1,37 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package asymkey
import (
"os"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
func GetDisplaySigningKey(key *git.SigningKey) string {
if key == nil || key.Format == "" {
return ""
}
switch key.Format {
case git.SigningKeyFormatOpenPGP:
return key.KeyID
case git.SigningKeyFormatSSH:
content, err := os.ReadFile(key.KeyID)
if err != nil {
log.Error("Unable to read SSH key %s: %v", key.KeyID, err)
return "(Unable to read SSH key)"
}
display, err := CalcFingerprint(string(content))
if err != nil {
log.Error("Unable to calculate fingerprint for SSH key %s: %v", key.KeyID, err)
return "(Unable to calculate fingerprint for SSH key)"
}
return display
}
setting.PanicInDevOrTesting("Unknown signing key format: %s", key.Format)
return "(Unknown key format)"
}

View File

@@ -3,13 +3,24 @@
package git package git
import "code.gitea.io/gitea/modules/setting"
// Based on https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat // Based on https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat
const ( const (
SigningKeyFormatOpenPGP = "openpgp" // for GPG keys, the expected default of git cli SigningKeyFormatOpenPGP = "openpgp" // for GPG keys, the expected default of git cli
SigningKeyFormatSSH = "ssh" SigningKeyFormatSSH = "ssh"
) )
// SigningKey represents an instance key info which will be used to sign git commits.
// FIXME: need to refactor it to a new name, this name conflicts with the variable names for "asymkey.GPGKey" in many places.
type SigningKey struct { type SigningKey struct {
KeyID string KeyID string
Format string Format string
} }
func (s *SigningKey) String() string {
// Do not expose KeyID
// In case the key is a file path and the struct is rendered in a template, then the server path will be exposed.
setting.PanicInDevOrTesting("don't call SigningKey.String() - it exposes the KeyID which might be a local file path")
return "SigningKey:" + s.Format
}

View File

@@ -12,6 +12,7 @@ import (
"strconv" "strconv"
activities_model "code.gitea.io/gitea/models/activities" activities_model "code.gitea.io/gitea/models/activities"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
@@ -494,7 +495,7 @@ func preparePullViewSigning(ctx *context.Context, issue *issues_model.Issue) {
if ctx.Doer != nil { if ctx.Doer != nil {
sign, key, _, err := asymkey_service.SignMerge(ctx, pull, ctx.Doer, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitHeadRefName()) sign, key, _, err := asymkey_service.SignMerge(ctx, pull, ctx.Doer, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitHeadRefName())
ctx.Data["WillSign"] = sign ctx.Data["WillSign"] = sign
ctx.Data["SigningKey"] = key ctx.Data["SigningKeyMergeDisplay"] = asymkey_model.GetDisplaySigningKey(key)
if err != nil { if err != nil {
if asymkey_service.IsErrWontSign(err) { if asymkey_service.IsErrWontSign(err) {
ctx.Data["WontSignReason"] = err.(*asymkey_service.ErrWontSign).Reason ctx.Data["WontSignReason"] = err.(*asymkey_service.ErrWontSign).Reason

View File

@@ -14,6 +14,7 @@ import (
"path" "path"
"strings" "strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
@@ -99,7 +100,7 @@ type CommitFormOptions struct {
UserCanPush bool UserCanPush bool
RequireSigned bool RequireSigned bool
WillSign bool WillSign bool
SigningKey *git.SigningKey SigningKeyFormDisplay string
WontSignReason string WontSignReason string
CanCreatePullRequest bool CanCreatePullRequest bool
CanCreateBasePullRequest bool CanCreateBasePullRequest bool
@@ -139,7 +140,7 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r
protectionRequireSigned = protectedBranch.RequireSignedCommits protectionRequireSigned = protectedBranch.RequireSignedCommits
} }
willSign, signKeyID, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String()) willSign, signKey, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String())
wontSignReason := "" wontSignReason := ""
if asymkey_service.IsErrWontSign(err) { if asymkey_service.IsErrWontSign(err) {
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason) wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason)
@@ -156,14 +157,14 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r
canCreatePullRequest := targetRepo.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest canCreatePullRequest := targetRepo.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest
opts := &CommitFormOptions{ opts := &CommitFormOptions{
TargetRepo: targetRepo, TargetRepo: targetRepo,
WillSubmitToFork: submitToForkedRepo, WillSubmitToFork: submitToForkedRepo,
CanCommitToBranch: canCommitToBranch, CanCommitToBranch: canCommitToBranch,
UserCanPush: canPushWithProtection, UserCanPush: canPushWithProtection,
RequireSigned: protectionRequireSigned, RequireSigned: protectionRequireSigned,
WillSign: willSign, WillSign: willSign,
SigningKey: signKeyID, SigningKeyFormDisplay: asymkey_model.GetDisplaySigningKey(signKey),
WontSignReason: wontSignReason, WontSignReason: wontSignReason,
CanCreatePullRequest: canCreatePullRequest, CanCreatePullRequest: canCreatePullRequest,
CanCreateBasePullRequest: canCreateBasePullRequest, CanCreateBasePullRequest: canCreateBasePullRequest,

View File

@@ -8,7 +8,7 @@ so this template should be kept as small as possbile, DO NOT put large component
*/}} */}}
{{- $commit := $.Commit -}} {{- $commit := $.Commit -}}
{{- $commitBaseLink := $.CommitBaseLink -}} {{- $commitBaseLink := $.CommitBaseLink -}}
{{- $verification := $.CommitSignVerification -}} {{- $verification := $.CommitSignVerification -}}{{- /* asymkey.CommitVerification */ -}}
{{- $extraClass := "" -}} {{- $extraClass := "" -}}
{{- $verified := false -}} {{- $verified := false -}}
@@ -50,7 +50,7 @@ so this template should be kept as small as possbile, DO NOT put large component
{{- if $verification.SigningSSHKey -}} {{- if $verification.SigningSSHKey -}}
{{- $msgSigningKey = print (ctx.Locale.Tr "repo.commits.ssh_key_fingerprint") ": " $verification.SigningSSHKey.Fingerprint -}} {{- $msgSigningKey = print (ctx.Locale.Tr "repo.commits.ssh_key_fingerprint") ": " $verification.SigningSSHKey.Fingerprint -}}
{{- else if $verification.SigningKey -}} {{- else if $verification.SigningKey -}}{{- /* asymkey.GPGKey */ -}}
{{- $msgSigningKey = print (ctx.Locale.Tr "repo.commits.gpg_key_id") ": " $verification.SigningKey.PaddedKeyID -}} {{- $msgSigningKey = print (ctx.Locale.Tr "repo.commits.gpg_key_id") ": " $verification.SigningKey.PaddedKeyID -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}

View File

@@ -1,13 +1,15 @@
<div class="commit-form-wrapper"> <div class="commit-form-wrapper">
{{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}} {{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}}
<div class="commit-form avatar-content-left-arrow"> <div class="commit-form avatar-content-left-arrow">
<h3>{{- if .CommitFormOptions.WillSign}} <h3>
<span title="{{ctx.Locale.Tr "repo.signing.will_sign" .CommitFormOptions.SigningKey}}">{{svg "octicon-lock" 24}}</span> {{- if .CommitFormOptions.WillSign}}
<span data-tooltip-content="{{ctx.Locale.Tr "repo.signing.will_sign" .CommitFormOptions.SigningKeyFormDisplay}}">{{svg "octicon-lock" 24}}</span>
{{ctx.Locale.Tr "repo.editor.commit_signed_changes"}} {{ctx.Locale.Tr "repo.editor.commit_signed_changes"}}
{{- else}} {{- else}}
<span title="{{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .CommitFormOptions.WontSignReason)}}">{{svg "octicon-unlock" 24}}</span> <span title="{{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .CommitFormOptions.WontSignReason)}}">{{svg "octicon-unlock" 24}}</span>
{{ctx.Locale.Tr "repo.editor.commit_changes"}} {{ctx.Locale.Tr "repo.editor.commit_changes"}}
{{- end}}</h3> {{- end}}
</h3>
<div class="field"> <div class="field">
<input name="commit_summary" maxlength="100" placeholder="{{if .PageIsDelete}}{{ctx.Locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{ctx.Locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.add_tmpl"}}{{else if .PageIsPatch}}{{ctx.Locale.Tr "repo.editor.patch"}}{{else}}{{ctx.Locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus> <input name="commit_summary" maxlength="100" placeholder="{{if .PageIsDelete}}{{ctx.Locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{ctx.Locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.add_tmpl"}}{{else if .PageIsPatch}}{{ctx.Locale.Tr "repo.editor.patch"}}{{else}}{{ctx.Locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus>
</div> </div>

View File

@@ -188,7 +188,7 @@
{{if .WillSign}} {{if .WillSign}}
<div class="item"> <div class="item">
{{svg "octicon-lock" 16 "text green"}} {{svg "octicon-lock" 16 "text green"}}
{{ctx.Locale.Tr "repo.signing.will_sign" .SigningKey}} {{ctx.Locale.Tr "repo.signing.will_sign" .SigningKeyMergeDisplay}}
</div> </div>
{{else if .IsSigned}} {{else if .IsSigned}}
<div class="item"> <div class="item">