github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/teams/box_public_summary.go (about) 1 package teams 2 3 import ( 4 "crypto/sha256" 5 "encoding/base64" 6 "encoding/hex" 7 8 "github.com/keybase/client/go/protocol/keybase1" 9 "github.com/keybase/go-codec/codec" 10 ) 11 12 type boxPublicSummaryTable map[keybase1.UID]keybase1.Seqno 13 14 type boxPublicSummary struct { 15 table boxPublicSummaryTable 16 encoded []byte 17 } 18 19 func newBoxPublicSummary(d map[keybase1.UserVersion]keybase1.PerUserKey) (*boxPublicSummary, error) { 20 table := make(boxPublicSummaryTable, len(d)) 21 for uv, puk := range d { 22 q, found := table[uv.Uid] 23 if !found || q < puk.Seqno { 24 table[uv.Uid] = puk.Seqno 25 } 26 } 27 return newBoxPublicSummaryFromTable(table) 28 } 29 30 // encode only ever gets called with the boxPublicSummary is being constructed. This means 31 // we don't allow mutation. Thus, we just encode it once, since if ever canonical encoding 32 // stops working, it won't matter, we'll still get consistent results. 33 func newBoxPublicSummaryFromTable(table boxPublicSummaryTable) (*boxPublicSummary, error) { 34 ret := boxPublicSummary{ 35 table: table, 36 } 37 err := ret.encode() 38 if err != nil { 39 return nil, err 40 } 41 return &ret, nil 42 } 43 44 func (b *boxPublicSummary) encode() error { 45 var mh codec.MsgpackHandle 46 mh.WriteExt = true 47 mh.Canonical = true 48 err := codec.NewEncoderBytes(&b.encoded, &mh).Encode(b.table) 49 return err 50 } 51 52 func (b boxPublicSummary) Hash() []byte { 53 ret := sha256.Sum256(b.encoded) 54 return ret[:] 55 } 56 57 func (b boxPublicSummary) HashHexEncoded() string { 58 tmp := b.Hash() 59 return hex.EncodeToString(tmp) 60 } 61 62 func (b boxPublicSummary) EncodeToString() string { 63 return base64.StdEncoding.EncodeToString(b.encoded) 64 } 65 66 func (b boxPublicSummary) IsEmpty() bool { 67 return len(b.table) == 0 68 }