Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion models/asymkey/gpg_key_commit_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
37 changes: 37 additions & 0 deletions models/asymkey/key_display.go
Original file line number Diff line number Diff line change
@@ -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)"
}
11 changes: 11 additions & 0 deletions modules/git/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 2 additions & 1 deletion routers/web/repo/issue_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
21 changes: 11 additions & 10 deletions services/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -99,7 +100,7 @@ type CommitFormOptions struct {
UserCanPush bool
RequireSigned bool
WillSign bool
SigningKey *git.SigningKey
SigningKeyFormDisplay string
WontSignReason string
CanCreatePullRequest bool
CanCreateBasePullRequest bool
Expand Down Expand Up @@ -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)
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/commit_sign_badge.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 -}}
Expand Down Expand Up @@ -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 -}}
Expand Down
8 changes: 5 additions & 3 deletions templates/repo/editor/commit_form.tmpl
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<div class="commit-form-wrapper">
{{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}}
<div class="commit-form avatar-content-left-arrow">
<h3>{{- if .CommitFormOptions.WillSign}}
<span title="{{ctx.Locale.Tr "repo.signing.will_sign" .CommitFormOptions.SigningKey}}">{{svg "octicon-lock" 24}}</span>
<h3>
{{- 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"}}
{{- else}}
<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"}}
{{- end}}</h3>
{{- end}}
</h3>
<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>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/issue/view_content/pull_merge_box.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
{{if .WillSign}}
<div class="item">
{{svg "octicon-lock" 16 "text green"}}
{{ctx.Locale.Tr "repo.signing.will_sign" .SigningKey}}
{{ctx.Locale.Tr "repo.signing.will_sign" .SigningKeyMergeDisplay}}
</div>
{{else if .IsSigned}}
<div class="item">
Expand Down