/ macaroons / auth.go
auth.go
 1  package macaroons
 2  
 3  import (
 4  	"context"
 5  	"encoding/hex"
 6  
 7  	macaroon "gopkg.in/macaroon.v2"
 8  )
 9  
10  // MacaroonCredential wraps a macaroon to implement the
11  // credentials.PerRPCCredentials interface.
12  type MacaroonCredential struct {
13  	*macaroon.Macaroon
14  }
15  
16  // RequireTransportSecurity implements the PerRPCCredentials interface.
17  func (m MacaroonCredential) RequireTransportSecurity() bool {
18  	return true
19  }
20  
21  // GetRequestMetadata implements the PerRPCCredentials interface. This method
22  // is required in order to pass the wrapped macaroon into the gRPC context.
23  // With this, the macaroon will be available within the request handling scope
24  // of the ultimate gRPC server implementation.
25  func (m MacaroonCredential) GetRequestMetadata(ctx context.Context,
26  	uri ...string) (map[string]string, error) {
27  
28  	macBytes, err := m.MarshalBinary()
29  	if err != nil {
30  		return nil, err
31  	}
32  
33  	md := make(map[string]string)
34  	md["macaroon"] = hex.EncodeToString(macBytes)
35  	return md, nil
36  }
37  
38  // NewMacaroonCredential returns a copy of the passed macaroon wrapped in a
39  // MacaroonCredential struct which implements PerRPCCredentials.
40  func NewMacaroonCredential(m *macaroon.Macaroon) (MacaroonCredential, error) {
41  	ms := MacaroonCredential{}
42  
43  	// The macaroon library's Clone() method has a subtle bug that doesn't
44  	// correctly clone all caveats. We need to use our own, safe clone
45  	// function instead.
46  	var err error
47  	ms.Macaroon, err = SafeCopyMacaroon(m)
48  	if err != nil {
49  		return ms, err
50  	}
51  
52  	return ms, nil
53  }