diff --git a/crypto/verify.go b/crypto/verify.go
--- a/crypto/verify.go
+++ b/crypto/verify.go
@@ -5,11 +5,9 @@
"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 @@
// 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()))
}
// SSHFingerprint computes the fingerprint of the supplied ssh pubkey.
diff --git a/patchutil/patchutil.go b/patchutil/patchutil.go
--- a/patchutil/patchutil.go
+++ b/patchutil/patchutil.go
@@ -296,7 +296,6 @@
}
nd := types.NiceDiff{}
- nd.Commit.Parent = targetBranch
for _, d := range diffs {
ndiff := types.Diff{}
diff --git a/types/diff.go b/types/diff.go
--- a/types/diff.go
+++ b/types/diff.go
@@ -2,7 +2,6 @@
import (
"github.com/bluekeyes/go-gitdiff/gitdiff"
- "github.com/go-git/go-git/v5/plumbing/object"
)
type DiffOpts struct {
@@ -43,17 +42,8 @@
// 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
--- a/types/repo.go
+++ b/types/repo.go
@@ -8,26 +8,26 @@
)
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 {
diff --git a/appview/commitverify/verify.go b/appview/commitverify/verify.go
--- a/appview/commitverify/verify.go
+++ b/appview/commitverify/verify.go
@@ -3,7 +3,6 @@
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 @@
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 @@
}
// 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
}
@@ -85,34 +76,4 @@
}
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
--- a/appview/pages/pages.go
+++ b/appview/pages/pages.go
@@ -31,7 +31,6 @@
"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 @@
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/repo/index.go b/appview/repo/index.go
--- a/appview/repo/index.go
+++ b/appview/repo/index.go
@@ -122,7 +122,7 @@
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
--- a/appview/repo/log.go
+++ b/appview/repo/log.go
@@ -116,7 +116,7 @@
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 @@
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
--- a/appview/repo/repo_util.go
+++ b/appview/repo/repo_util.go
@@ -8,8 +8,6 @@
"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 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/knotserver/git/diff.go b/knotserver/git/diff.go
--- a/knotserver/git/diff.go
+++ b/knotserver/git/diff.go
@@ -77,23 +77,7 @@
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
--- a/knotserver/xrpc/repo_log.go
+++ b/knotserver/xrpc/repo_log.go
@@ -62,9 +62,14 @@
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/appview/pages/templates/repo/commit.html b/appview/pages/templates/repo/commit.html
--- 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 }}