forked from tangled.org/core
this repo has no description
1package commitverify 2 3import ( 4 "log" 5 6 "github.com/go-git/go-git/v5/plumbing/object" 7 "tangled.org/core/appview/db" 8 "tangled.org/core/appview/models" 9 "tangled.org/core/crypto" 10 "tangled.org/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][]models.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 78 vc := verifiedCommit{fingerprint: fp, hash: c.This} 79 vcs[vc] = struct{}{} 80 break 81 } 82 } 83 84 } 85 } 86 87 return vcs, nil 88} 89 90// ObjectCommitToNiceDiff is a compatibility function to convert a 91// commit object into a NiceDiff structure. 92func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff { 93 var niceDiff types.NiceDiff 94 95 // set commit information 96 niceDiff.Commit.Message = c.Message 97 niceDiff.Commit.Author = c.Author 98 niceDiff.Commit.This = c.Hash.String() 99 niceDiff.Commit.Committer = c.Committer 100 niceDiff.Commit.Tree = c.TreeHash.String() 101 niceDiff.Commit.PGPSignature = c.PGPSignature 102 103 changeId, ok := c.ExtraHeaders["change-id"] 104 if ok { 105 niceDiff.Commit.ChangedId = string(changeId) 106 } 107 108 // set parent hash if available 109 if len(c.ParentHashes) > 0 { 110 niceDiff.Commit.Parent = c.ParentHashes[0].String() 111 } 112 113 // XXX: Stats and Diff fields are typically populated 114 // after fetching the actual diff information, which isn't 115 // directly available in the commit object itself. 116 117 return niceDiff 118}