forked from tangled.org/core
this repo has no description
1package commitverify 2 3import ( 4 "fmt" 5 "log" 6 7 "github.com/go-git/go-git/v5/plumbing/object" 8 "tangled.sh/tangled.sh/core/appview/db" 9 "tangled.sh/tangled.sh/core/crypto" 10 "tangled.sh/tangled.sh/core/types" 11) 12 13type verifiedCommit struct { 14 fingerprint string 15 hash string 16} 17 18type VerifiedCommits map[verifiedCommit]struct{} 19 20func (vcs VerifiedCommits) IsVerified(hash string) bool { 21 for vc := range vcs { 22 if vc.hash == hash { 23 return true 24 } 25 } 26 return false 27} 28 29func (vcs VerifiedCommits) Fingerprint(hash string) string { 30 for vc := range vcs { 31 if vc.hash == hash { 32 return vc.fingerprint 33 } 34 } 35 return "" 36} 37 38func GetVerifiedObjectCommits(e db.Execer, emailToDid map[string]string, commits []*object.Commit) (VerifiedCommits, error) { 39 ndCommits := []types.NiceDiff{} 40 for _, commit := range commits { 41 ndCommits = append(ndCommits, ObjectCommitToNiceDiff(commit)) 42 } 43 return GetVerifiedCommits(e, emailToDid, ndCommits) 44} 45 46func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.NiceDiff) (VerifiedCommits, error) { 47 vcs := VerifiedCommits{} 48 49 didPubkeyCache := make(map[string][]db.PublicKey) 50 51 for _, commit := range ndCommits { 52 c := commit.Commit 53 54 committerEmail := c.Committer.Email 55 if did, exists := emailToDid[committerEmail]; exists { 56 // check if we've already fetched public keys for this did 57 pubKeys, ok := didPubkeyCache[did] 58 if !ok { 59 // fetch and cache public keys 60 keys, err := db.GetPublicKeysForDid(e, did) 61 if err != nil { 62 log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 63 continue 64 } 65 pubKeys = keys 66 didPubkeyCache[did] = pubKeys 67 } 68 69 // try to verify with any associated pubkeys 70 for _, pk := range pubKeys { 71 if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { 72 73 fp, err := crypto.SSHFingerprint(pk.Key) 74 if err != nil { 75 log.Println("error computing ssh fingerprint:", err) 76 } 77 fmt.Println(fp) 78 79 vc := verifiedCommit{fingerprint: fp, hash: c.This} 80 vcs[vc] = struct{}{} 81 break 82 } 83 } 84 85 } 86 } 87 88 return vcs, nil 89} 90 91// ObjectCommitToNiceDiff is a compatibility function to convert a 92// commit object into a NiceDiff structure. 93func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff { 94 var niceDiff types.NiceDiff 95 96 // set commit information 97 niceDiff.Commit.Message = c.Message 98 niceDiff.Commit.Author = c.Author 99 niceDiff.Commit.This = c.Hash.String() 100 niceDiff.Commit.Committer = c.Committer 101 niceDiff.Commit.Tree = c.TreeHash.String() 102 niceDiff.Commit.PGPSignature = c.PGPSignature 103 104 changeId, ok := c.ExtraHeaders["change-id"] 105 if ok { 106 niceDiff.Commit.ChangedId = string(changeId) 107 } 108 109 // set parent hash if available 110 if len(c.ParentHashes) > 0 { 111 niceDiff.Commit.Parent = c.ParentHashes[0].String() 112 } 113 114 // XXX: Stats and Diff fields are typically populated 115 // after fetching the actual diff information, which isn't 116 // directly available in the commit object itself. 117 118 return niceDiff 119}