multi: upgrade macaroons to v2, replace per-method auth with interceptors
This commit reworks the macaroon authentication framework to use the v2 macaroon format and bakery API. It also replaces the code in each RPC method which calls the macaroon verifier with interceptors which call the macaroon verifier instead. In addition, the operation permissions are reworked to fit the new format of "allow" commands (specifically, entity/operation permissions instead of method permissions).
This commit is contained in:
1 parent
20098e8cb3
commit
21c29c33d7
11 files changed
+427
-514
No files matched your search
+11
-29
@@ -3,15 +3,13 @@ package macaroons
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/peer"
|
||||
|
||||
"gopkg.in/macaroon-bakery.v1/bakery"
|
||||
"gopkg.in/macaroon-bakery.v1/bakery/checkers"
|
||||
macaroon "gopkg.in/macaroon.v1"
|
||||
"gopkg.in/macaroon-bakery.v2/bakery"
|
||||
macaroon "gopkg.in/macaroon.v2"
|
||||
)
|
||||
|
||||
// MacaroonCredential wraps a macaroon to implement the
|
||||
@@ -54,13 +52,11 @@ func NewMacaroonCredential(m *macaroon.Macaroon) MacaroonCredential {
|
||||
// bakery service, context, and uri. Within the passed context.Context, we
|
||||
// expect a macaroon to be encoded as request metadata using the key
|
||||
// "macaroon".
|
||||
func ValidateMacaroon(ctx context.Context, method string,
|
||||
svc *bakery.Service) error {
|
||||
func ValidateMacaroon(ctx context.Context, requiredPermissions []bakery.Op,
|
||||
svc *bakery.Bakery) error {
|
||||
|
||||
// Get macaroon bytes from context and unmarshal into macaroon.
|
||||
//
|
||||
// TODO(aakselrod): use FromIncomingContext after grpc update in glide.
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to get metadata from context")
|
||||
}
|
||||
@@ -69,16 +65,6 @@ func ValidateMacaroon(ctx context.Context, method string,
|
||||
len(md["macaroon"]))
|
||||
}
|
||||
|
||||
// Get peer info and extract IP address from it for macaroon check
|
||||
pr, ok := peer.FromContext(ctx)
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to get peer info from context")
|
||||
}
|
||||
peerAddr, _, err := net.SplitHostPort(pr.Addr.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse peer address")
|
||||
}
|
||||
|
||||
// With the macaroon obtained, we'll now decode the hex-string
|
||||
// encoding, then unmarshal it from binary into its concrete struct
|
||||
// representation.
|
||||
@@ -93,12 +79,8 @@ func ValidateMacaroon(ctx context.Context, method string,
|
||||
}
|
||||
|
||||
// Check the method being called against the permitted operation and
|
||||
// the expiration time and return the result.
|
||||
//
|
||||
// TODO(aakselrod): Add more checks as required.
|
||||
return svc.Check(macaroon.Slice{mac}, checkers.New(
|
||||
AllowChecker(method),
|
||||
TimeoutChecker(),
|
||||
IPLockChecker(peerAddr),
|
||||
))
|
||||
// the expiration time and IP address and return the result.
|
||||
authChecker := svc.Checker.Auth(macaroon.Slice{mac})
|
||||
_, err = authChecker.Allow(ctx, requiredPermissions...)
|
||||
return err
|
||||
}
|
||||
Reference in new issue
Block a user