bake.go
1 package macaroons 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 8 "gopkg.in/macaroon-bakery.v2/bakery" 9 "gopkg.in/macaroon.v2" 10 ) 11 12 // inMemoryRootKeyStore is a simple implementation of bakery.RootKeyStore that 13 // stores a single root key in memory. 14 type inMemoryRootKeyStore struct { 15 rootKey []byte 16 } 17 18 // A compile-time check to ensure that inMemoryRootKeyStore implements 19 // bakery.RootKeyStore. 20 var _ bakery.RootKeyStore = (*inMemoryRootKeyStore)(nil) 21 22 // Get returns the root key for the given id. If the item is not there, it 23 // returns ErrNotFound. 24 func (s *inMemoryRootKeyStore) Get(_ context.Context, id []byte) ([]byte, 25 error) { 26 27 if !bytes.Equal(id, DefaultRootKeyID) { 28 return nil, bakery.ErrNotFound 29 } 30 31 return s.rootKey, nil 32 } 33 34 // RootKey returns the root key to be used for making a new macaroon, and an id 35 // that can be used to look it up later with the Get method. 36 func (s *inMemoryRootKeyStore) RootKey(context.Context) ([]byte, []byte, 37 error) { 38 39 return s.rootKey, DefaultRootKeyID, nil 40 } 41 42 // BakeFromRootKey creates a new macaroon that is derived from the given root 43 // key and permissions. 44 func BakeFromRootKey(rootKey []byte, 45 permissions []bakery.Op) (*macaroon.Macaroon, error) { 46 47 if len(rootKey) != RootKeyLen { 48 return nil, fmt.Errorf("root key must be %d bytes, is %d", 49 RootKeyLen, len(rootKey)) 50 } 51 52 rootKeyStore := &inMemoryRootKeyStore{ 53 rootKey: rootKey, 54 } 55 56 service, err := NewService(rootKeyStore, "lnd", false) 57 if err != nil { 58 return nil, fmt.Errorf("unable to create service: %w", err) 59 } 60 61 ctx := context.Background() 62 mac, err := service.NewMacaroon(ctx, DefaultRootKeyID, permissions...) 63 if err != nil { 64 return nil, fmt.Errorf("unable to create macaroon: %w", err) 65 } 66 67 return mac.M(), nil 68 }