From 7c8f656205aa055f89ace757a23ce3ca64bc644a Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Fri, 5 Dec 2025 04:12:11 +0000 Subject: [PATCH] types,appview,knotserver: replace object.Commit with types.Commit Change-Id: prmwsnqlovmkuprpwwxzmkpzropxmyvq Signed-off-by: oppiliappan --- appview/commitverify/verify.go | 51 +++--------------------- appview/pages/pages.go | 3 +- appview/pages/templates/repo/commit.html | 2 +- appview/repo/index.go | 2 +- appview/repo/log.go | 4 +- appview/repo/repo_util.go | 3 +- crypto/verify.go | 35 +--------------- knotserver/git/diff.go | 18 +-------- knotserver/xrpc/repo_log.go | 7 +++- patchutil/patchutil.go | 1 - types/diff.go | 14 +------ types/repo.go | 34 ++++++++-------- 12 files changed, 40 insertions(+), 134 deletions(-) diff --git a/appview/commitverify/verify.go b/appview/commitverify/verify.go index 3c04495d..bff8efde 100644 --- a/appview/commitverify/verify.go +++ b/appview/commitverify/verify.go @@ -3,7 +3,6 @@ package commitverify import ( "log" - "github.com/go-git/go-git/v5/plumbing/object" "tangled.org/core/appview/db" "tangled.org/core/appview/models" "tangled.org/core/crypto" @@ -35,23 +34,13 @@ func (vcs VerifiedCommits) Fingerprint(hash string) string { return "" } -func GetVerifiedObjectCommits(e db.Execer, emailToDid map[string]string, commits []*object.Commit) (VerifiedCommits, error) { - ndCommits := []types.NiceDiff{} - for _, commit := range commits { - ndCommits = append(ndCommits, ObjectCommitToNiceDiff(commit)) - } - return GetVerifiedCommits(e, emailToDid, ndCommits) -} - -func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.NiceDiff) (VerifiedCommits, error) { +func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.Commit) (VerifiedCommits, error) { vcs := VerifiedCommits{} didPubkeyCache := make(map[string][]models.PublicKey) for _, commit := range ndCommits { - c := commit.Commit - - committerEmail := c.Committer.Email + committerEmail := commit.Committer.Email if did, exists := emailToDid[committerEmail]; exists { // check if we've already fetched public keys for this did pubKeys, ok := didPubkeyCache[did] @@ -67,15 +56,17 @@ func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []t } // try to verify with any associated pubkeys + payload := commit.Payload() + signature := commit.PGPSignature for _, pk := range pubKeys { - if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { + if _, ok := crypto.VerifySignature([]byte(pk.Key), []byte(signature), []byte(payload)); ok { fp, err := crypto.SSHFingerprint(pk.Key) if err != nil { log.Println("error computing ssh fingerprint:", err) } - vc := verifiedCommit{fingerprint: fp, hash: c.This} + vc := verifiedCommit{fingerprint: fp, hash: commit.This} vcs[vc] = struct{}{} break } @@ -86,33 +77,3 @@ func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []t return vcs, nil } - -// ObjectCommitToNiceDiff is a compatibility function to convert a -// commit object into a NiceDiff structure. -func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff { - var niceDiff types.NiceDiff - - // set commit information - niceDiff.Commit.Message = c.Message - niceDiff.Commit.Author = c.Author - niceDiff.Commit.This = c.Hash.String() - niceDiff.Commit.Committer = c.Committer - niceDiff.Commit.Tree = c.TreeHash.String() - niceDiff.Commit.PGPSignature = c.PGPSignature - - changeId, ok := c.ExtraHeaders["change-id"] - if ok { - niceDiff.Commit.ChangedId = string(changeId) - } - - // set parent hash if available - if len(c.ParentHashes) > 0 { - niceDiff.Commit.Parent = c.ParentHashes[0].String() - } - - // XXX: Stats and Diff fields are typically populated - // after fetching the actual diff information, which isn't - // directly available in the commit object itself. - - return niceDiff -} diff --git a/appview/pages/pages.go b/appview/pages/pages.go index 1965ecae..145362c9 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -31,7 +31,6 @@ import ( "github.com/bluesky-social/indigo/atproto/identity" "github.com/bluesky-social/indigo/atproto/syntax" "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" ) //go:embed templates/* static legal @@ -649,7 +648,7 @@ type RepoIndexParams struct { RepoInfo repoinfo.RepoInfo Active string TagMap map[string][]string - CommitsTrunc []*object.Commit + CommitsTrunc []types.Commit TagsTrunc []*types.TagReference BranchesTrunc []types.Branch // ForkInfo *types.ForkInfo diff --git a/appview/pages/templates/repo/commit.html b/appview/pages/templates/repo/commit.html index 3ce4902c..d1a2e5f3 100644 --- a/appview/pages/templates/repo/commit.html +++ b/appview/pages/templates/repo/commit.html @@ -35,7 +35,7 @@ {{ end }} - {{ template "repo/fragments/time" $commit.Author.When }} + {{ template "repo/fragments/time" $commit.Committer.When }} {{ slice $commit.This 0 8 }} diff --git a/appview/repo/index.go b/appview/repo/index.go index 8954494f..726e9dd0 100644 --- a/appview/repo/index.go +++ b/appview/repo/index.go @@ -122,7 +122,7 @@ func (rp *Repo) Index(w http.ResponseWriter, r *http.Request) { l.Error("failed to get email to did map", "err", err) } - vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, commitsTrunc) + vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, commitsTrunc) if err != nil { l.Error("failed to GetVerifiedObjectCommits", "err", err) } diff --git a/appview/repo/log.go b/appview/repo/log.go index 9607a902..ef4d9e62 100644 --- a/appview/repo/log.go +++ b/appview/repo/log.go @@ -116,7 +116,7 @@ func (rp *Repo) Log(w http.ResponseWriter, r *http.Request) { l.Error("failed to fetch email to did mapping", "err", err) } - vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, xrpcResp.Commits) + vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, xrpcResp.Commits) if err != nil { l.Error("failed to GetVerifiedObjectCommits", "err", err) } @@ -192,7 +192,7 @@ func (rp *Repo) Commit(w http.ResponseWriter, r *http.Request) { l.Error("failed to get email to did mapping", "err", err) } - vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, []types.NiceDiff{*result.Diff}) + vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, []types.Commit{result.Diff.Commit}) if err != nil { l.Error("failed to GetVerifiedCommits", "err", err) } diff --git a/appview/repo/repo_util.go b/appview/repo/repo_util.go index f585a3a5..b6a9507a 100644 --- a/appview/repo/repo_util.go +++ b/appview/repo/repo_util.go @@ -1,6 +1,7 @@ package repo import ( + "regexp" "slices" "sort" "strings" @@ -42,7 +43,7 @@ func sortBranches(branches []types.Branch) { }) } -func uniqueEmails(commits []*object.Commit) []string { +func uniqueEmails(commits []types.Commit) []string { emails := make(map[string]struct{}) for _, commit := range commits { if commit.Author.Email != "" { diff --git a/crypto/verify.go b/crypto/verify.go index a87b2888..a5c014c0 100644 --- a/crypto/verify.go +++ b/crypto/verify.go @@ -5,11 +5,9 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "strings" "github.com/hiddeco/sshsig" "golang.org/x/crypto/ssh" - "tangled.org/core/types" ) func VerifySignature(pubKey, signature, payload []byte) (error, bool) { @@ -28,39 +26,8 @@ func VerifySignature(pubKey, signature, payload []byte) (error, bool) { // multiple algorithms but sha-512 is most secure, and git's ssh signing defaults // to sha-512 for all key types anyway. err = sshsig.Verify(buf, sig, pub, sshsig.HashSHA512, "git") - return err, err == nil -} - -// VerifyCommitSignature reconstructs the payload used to sign a commit. This is -// essentially the git cat-file output but without the gpgsig header. -// -// Caveats: signature verification will fail on commits with more than one parent, -// i.e. merge commits, because types.NiceDiff doesn't carry more than one Parent field -// and we are unable to reconstruct the payload correctly. -// -// Ideally this should directly operate on an *object.Commit. -func VerifyCommitSignature(pubKey string, commit types.NiceDiff) (error, bool) { - signature := commit.Commit.PGPSignature - - author := bytes.NewBuffer([]byte{}) - committer := bytes.NewBuffer([]byte{}) - commit.Commit.Author.Encode(author) - commit.Commit.Committer.Encode(committer) - - payload := strings.Builder{} - fmt.Fprintf(&payload, "tree %s\n", commit.Commit.Tree) - if commit.Commit.Parent != "" { - fmt.Fprintf(&payload, "parent %s\n", commit.Commit.Parent) - } - fmt.Fprintf(&payload, "author %s\n", author.String()) - fmt.Fprintf(&payload, "committer %s\n", committer.String()) - if commit.Commit.ChangedId != "" { - fmt.Fprintf(&payload, "change-id %s\n", commit.Commit.ChangedId) - } - fmt.Fprintf(&payload, "\n%s", commit.Commit.Message) - - return VerifySignature([]byte(pubKey), []byte(signature), []byte(payload.String())) + return err, err == nil } // SSHFingerprint computes the fingerprint of the supplied ssh pubkey. diff --git a/knotserver/git/diff.go b/knotserver/git/diff.go index 6f538fce..ef9a40e1 100644 --- a/knotserver/git/diff.go +++ b/knotserver/git/diff.go @@ -77,23 +77,7 @@ func (g *GitRepo) Diff() (*types.NiceDiff, error) { nd.Diff = append(nd.Diff, ndiff) } - nd.Stat.FilesChanged = len(diffs) - nd.Commit.This = c.Hash.String() - nd.Commit.PGPSignature = c.PGPSignature - nd.Commit.Committer = c.Committer - nd.Commit.Tree = c.TreeHash.String() - - if parent.Hash.IsZero() { - nd.Commit.Parent = "" - } else { - nd.Commit.Parent = parent.Hash.String() - } - nd.Commit.Author = c.Author - nd.Commit.Message = c.Message - - if v, ok := c.ExtraHeaders["change-id"]; ok { - nd.Commit.ChangedId = string(v) - } + nd.Commit.FromGoGitCommit(c) return &nd, nil } diff --git a/knotserver/xrpc/repo_log.go b/knotserver/xrpc/repo_log.go index da182148..30220e34 100644 --- a/knotserver/xrpc/repo_log.go +++ b/knotserver/xrpc/repo_log.go @@ -62,9 +62,14 @@ func (x *Xrpc) RepoLog(w http.ResponseWriter, r *http.Request) { return } + tcommits := make([]types.Commit, len(commits)) + for i, c := range commits { + tcommits[i].FromGoGitCommit(c) + } + // Create response using existing types.RepoLogResponse response := types.RepoLogResponse{ - Commits: commits, + Commits: tcommits, Ref: ref, Page: (offset / limit) + 1, PerPage: limit, diff --git a/patchutil/patchutil.go b/patchutil/patchutil.go index 584f1aeb..046eeddf 100644 --- a/patchutil/patchutil.go +++ b/patchutil/patchutil.go @@ -296,7 +296,6 @@ func AsNiceDiff(patch, targetBranch string) types.NiceDiff { } nd := types.NiceDiff{} - nd.Commit.Parent = targetBranch for _, d := range diffs { ndiff := types.Diff{} diff --git a/types/diff.go b/types/diff.go index 12ecd9e7..8cdea07c 100644 --- a/types/diff.go +++ b/types/diff.go @@ -2,7 +2,6 @@ package types import ( "github.com/bluekeyes/go-gitdiff/gitdiff" - "github.com/go-git/go-git/v5/plumbing/object" ) type DiffOpts struct { @@ -43,17 +42,8 @@ func (d *Diff) Stats() DiffStat { // A nicer git diff representation. type NiceDiff struct { - Commit struct { - Message string `json:"message"` - Author object.Signature `json:"author"` - This string `json:"this"` - Parent string `json:"parent"` - PGPSignature string `json:"pgp_signature"` - Committer object.Signature `json:"committer"` - Tree string `json:"tree"` - ChangedId string `json:"change_id"` - } `json:"commit"` - Stat struct { + Commit Commit `json:"commit"` + Stat struct { FilesChanged int `json:"files_changed"` Insertions int `json:"insertions"` Deletions int `json:"deletions"` diff --git a/types/repo.go b/types/repo.go index 8e664959..ebb20732 100644 --- a/types/repo.go +++ b/types/repo.go @@ -8,26 +8,26 @@ import ( ) type RepoIndexResponse struct { - IsEmpty bool `json:"is_empty"` - Ref string `json:"ref,omitempty"` - Readme string `json:"readme,omitempty"` - ReadmeFileName string `json:"readme_file_name,omitempty"` - Commits []*object.Commit `json:"commits,omitempty"` - Description string `json:"description,omitempty"` - Files []NiceTree `json:"files,omitempty"` - Branches []Branch `json:"branches,omitempty"` - Tags []*TagReference `json:"tags,omitempty"` - TotalCommits int `json:"total_commits,omitempty"` + IsEmpty bool `json:"is_empty"` + Ref string `json:"ref,omitempty"` + Readme string `json:"readme,omitempty"` + ReadmeFileName string `json:"readme_file_name,omitempty"` + Commits []Commit `json:"commits,omitempty"` + Description string `json:"description,omitempty"` + Files []NiceTree `json:"files,omitempty"` + Branches []Branch `json:"branches,omitempty"` + Tags []*TagReference `json:"tags,omitempty"` + TotalCommits int `json:"total_commits,omitempty"` } type RepoLogResponse struct { - Commits []*object.Commit `json:"commits,omitempty"` - Ref string `json:"ref,omitempty"` - Description string `json:"description,omitempty"` - Log bool `json:"log,omitempty"` - Total int `json:"total,omitempty"` - Page int `json:"page,omitempty"` - PerPage int `json:"per_page,omitempty"` + Commits []Commit `json:"commits,omitempty"` + Ref string `json:"ref,omitempty"` + Description string `json:"description,omitempty"` + Log bool `json:"log,omitempty"` + Total int `json:"total,omitempty"` + Page int `json:"page,omitempty"` + PerPage int `json:"per_page,omitempty"` } type RepoCommitResponse struct { -- 2.43.0