diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index b85374e0735..375b703f7b3 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -25,7 +25,7 @@ type CommitVerification struct { SigningUser *user_model.User // if Verified, then SigningUser is non-nil CommittingUser *user_model.User // if Verified, then CommittingUser is non-nil 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 TrustStatus string } diff --git a/models/asymkey/key_display.go b/models/asymkey/key_display.go new file mode 100644 index 00000000000..ee17553b5b4 --- /dev/null +++ b/models/asymkey/key_display.go @@ -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)" +} diff --git a/modules/git/key.go b/modules/git/key.go index 2513c048b7c..8c14742f34a 100644 --- a/modules/git/key.go +++ b/modules/git/key.go @@ -3,13 +3,24 @@ package git +import "code.gitea.io/gitea/modules/setting" + // Based on https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat const ( SigningKeyFormatOpenPGP = "openpgp" // for GPG keys, the expected default of git cli 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 { KeyID 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 +} diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index d0064e763ef..d9f6c33e3fb 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -12,6 +12,7 @@ import ( "strconv" activities_model "code.gitea.io/gitea/models/activities" + asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" 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 { sign, key, _, err := asymkey_service.SignMerge(ctx, pull, ctx.Doer, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitHeadRefName()) ctx.Data["WillSign"] = sign - ctx.Data["SigningKey"] = key + ctx.Data["SigningKeyMergeDisplay"] = asymkey_model.GetDisplaySigningKey(key) if err != nil { if asymkey_service.IsErrWontSign(err) { ctx.Data["WontSignReason"] = err.(*asymkey_service.ErrWontSign).Reason diff --git a/services/context/repo.go b/services/context/repo.go index afc6de9b166..04ddba70fe0 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -14,6 +14,7 @@ import ( "path" "strings" + asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" @@ -99,7 +100,7 @@ type CommitFormOptions struct { UserCanPush bool RequireSigned bool WillSign bool - SigningKey *git.SigningKey + SigningKeyFormDisplay string WontSignReason string CanCreatePullRequest bool CanCreateBasePullRequest bool @@ -139,7 +140,7 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r 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 := "" if asymkey_service.IsErrWontSign(err) { 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 opts := &CommitFormOptions{ - TargetRepo: targetRepo, - WillSubmitToFork: submitToForkedRepo, - CanCommitToBranch: canCommitToBranch, - UserCanPush: canPushWithProtection, - RequireSigned: protectionRequireSigned, - WillSign: willSign, - SigningKey: signKeyID, - WontSignReason: wontSignReason, + TargetRepo: targetRepo, + WillSubmitToFork: submitToForkedRepo, + CanCommitToBranch: canCommitToBranch, + UserCanPush: canPushWithProtection, + RequireSigned: protectionRequireSigned, + WillSign: willSign, + SigningKeyFormDisplay: asymkey_model.GetDisplaySigningKey(signKey), + WontSignReason: wontSignReason, CanCreatePullRequest: canCreatePullRequest, CanCreateBasePullRequest: canCreateBasePullRequest, diff --git a/templates/repo/commit_sign_badge.tmpl b/templates/repo/commit_sign_badge.tmpl index 02089d7a4c3..895d0fa0627 100644 --- a/templates/repo/commit_sign_badge.tmpl +++ b/templates/repo/commit_sign_badge.tmpl @@ -8,7 +8,7 @@ so this template should be kept as small as possbile, DO NOT put large component */}} {{- $commit := $.Commit -}} {{- $commitBaseLink := $.CommitBaseLink -}} -{{- $verification := $.CommitSignVerification -}} +{{- $verification := $.CommitSignVerification -}}{{- /* asymkey.CommitVerification */ -}} {{- $extraClass := "" -}} {{- $verified := false -}} @@ -50,7 +50,7 @@ so this template should be kept as small as possbile, DO NOT put large component {{- if $verification.SigningSSHKey -}} {{- $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 -}} {{- end -}} {{- end -}} diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index 3e4482f9e2f..10872f8af74 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -1,13 +1,15 @@
{{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}}
-

{{- if .CommitFormOptions.WillSign}} - {{svg "octicon-lock" 24}} +

+ {{- if .CommitFormOptions.WillSign}} + {{svg "octicon-lock" 24}} {{ctx.Locale.Tr "repo.editor.commit_signed_changes"}} {{- else}} {{svg "octicon-unlock" 24}} {{ctx.Locale.Tr "repo.editor.commit_changes"}} - {{- end}}

+ {{- end}} +
diff --git a/templates/repo/issue/view_content/pull_merge_box.tmpl b/templates/repo/issue/view_content/pull_merge_box.tmpl index 113bfb732ec..b0ac24c9f6c 100644 --- a/templates/repo/issue/view_content/pull_merge_box.tmpl +++ b/templates/repo/issue/view_content/pull_merge_box.tmpl @@ -188,7 +188,7 @@ {{if .WillSign}}
{{svg "octicon-lock" 16 "text green"}} - {{ctx.Locale.Tr "repo.signing.will_sign" .SigningKey}} + {{ctx.Locale.Tr "repo.signing.will_sign" .SigningKeyMergeDisplay}}
{{else if .IsSigned}}