/ macaroons / bake.go
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  }