forked from tangled.org/core
this repo has no description
at oplog 3.9 kB view raw
1package repo 2 3import ( 4 "context" 5 "crypto/rand" 6 "fmt" 7 "log" 8 "math/big" 9 10 "github.com/go-git/go-git/v5/plumbing/object" 11 "tangled.sh/tangled.sh/core/appview/db" 12 "tangled.sh/tangled.sh/core/crypto" 13 "tangled.sh/tangled.sh/core/types" 14) 15 16func uniqueEmails(commits []*object.Commit) []string { 17 emails := make(map[string]struct{}) 18 for _, commit := range commits { 19 if commit.Author.Email != "" { 20 emails[commit.Author.Email] = struct{}{} 21 } 22 if commit.Committer.Email != "" { 23 emails[commit.Committer.Email] = struct{}{} 24 } 25 } 26 var uniqueEmails []string 27 for email := range emails { 28 uniqueEmails = append(uniqueEmails, email) 29 } 30 return uniqueEmails 31} 32 33func balanceIndexItems(commitCount, branchCount, tagCount, fileCount int) (commitsTrunc int, branchesTrunc int, tagsTrunc int) { 34 if commitCount == 0 && tagCount == 0 && branchCount == 0 { 35 return 36 } 37 38 // typically 1 item on right side = 2 files in height 39 availableSpace := fileCount / 2 40 41 // clamp tagcount 42 if tagCount > 0 { 43 tagsTrunc = 1 44 availableSpace -= 1 // an extra subtracted for headers etc. 45 } 46 47 // clamp branchcount 48 if branchCount > 0 { 49 branchesTrunc = min(max(branchCount, 1), 3) 50 availableSpace -= branchesTrunc // an extra subtracted for headers etc. 51 } 52 53 // show 54 if commitCount > 0 { 55 commitsTrunc = max(availableSpace, 3) 56 } 57 58 return 59} 60 61// emailToDidOrHandle takes an emailToDidMap from db.GetEmailToDid 62// and resolves all dids to handles and returns a new map[string]string 63func emailToDidOrHandle(r *Repo, emailToDidMap map[string]string) map[string]string { 64 if emailToDidMap == nil { 65 return nil 66 } 67 68 var dids []string 69 for _, v := range emailToDidMap { 70 dids = append(dids, v) 71 } 72 resolvedIdents := r.idResolver.ResolveIdents(context.Background(), dids) 73 74 didHandleMap := make(map[string]string) 75 for _, identity := range resolvedIdents { 76 if !identity.Handle.IsInvalidHandle() { 77 didHandleMap[identity.DID.String()] = fmt.Sprintf("@%s", identity.Handle.String()) 78 } else { 79 didHandleMap[identity.DID.String()] = identity.DID.String() 80 } 81 } 82 83 // Create map of email to didOrHandle for commit display 84 emailToDidOrHandle := make(map[string]string) 85 for email, did := range emailToDidMap { 86 if didOrHandle, ok := didHandleMap[did]; ok { 87 emailToDidOrHandle[email] = didOrHandle 88 } 89 } 90 91 return emailToDidOrHandle 92} 93 94func verifiedObjectCommits(r *Repo, emailToDid map[string]string, commits []*object.Commit) (map[string]bool, error) { 95 ndCommits := []types.NiceDiff{} 96 for _, commit := range commits { 97 ndCommits = append(ndCommits, types.ObjectCommitToNiceDiff(commit)) 98 } 99 return verifiedCommits(r, emailToDid, ndCommits) 100} 101 102func verifiedCommits(r *Repo, emailToDid map[string]string, ndCommits []types.NiceDiff) (map[string]bool, error) { 103 hashToVerified := make(map[string]bool) 104 105 didPubkeyCache := make(map[string][]db.PublicKey) 106 107 for _, commit := range ndCommits { 108 c := commit.Commit 109 110 committerEmail := c.Committer.Email 111 if did, exists := emailToDid[committerEmail]; exists { 112 // check if we've already fetched public keys for this did 113 pubKeys, ok := didPubkeyCache[did] 114 if !ok { 115 // fetch and cache public keys 116 keys, err := db.GetPublicKeysForDid(r.db, did) 117 if err != nil { 118 log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 119 continue 120 } 121 pubKeys = keys 122 didPubkeyCache[did] = pubKeys 123 } 124 125 verified := false 126 127 // try to verify with any associated pubkeys 128 for _, pk := range pubKeys { 129 if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { 130 verified = true 131 break 132 } 133 } 134 135 hashToVerified[c.This] = verified 136 } 137 } 138 139 return hashToVerified, nil 140} 141 142func randomString(n int) string { 143 const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 144 result := make([]byte, n) 145 146 for i := 0; i < n; i++ { 147 n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) 148 result[i] = letters[n.Int64()] 149 } 150 151 return string(result) 152}