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 16c4f87f..6394a9e2 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..5217500d 100644
--- a/appview/repo/repo_util.go
+++ b/appview/repo/repo_util.go
@@ -8,8 +8,6 @@ import (
"tangled.org/core/appview/db"
"tangled.org/core/appview/models"
"tangled.org/core/types"
-
- "github.com/go-git/go-git/v5/plumbing/object"
)
func sortFiles(files []types.NiceTree) {
@@ -42,7 +40,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 {