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