rpcserver+macaroons: extract RawMacaroonFromContext

We'll re-use the code for extracting a macaroon from a request context
later on so we extract it into its own exported function.
This commit is contained in:
Oliver Gugger
2021-08-12 16:07:15 +02:00
parent 29a8661517
commit 96ea4bf05e
2 changed files with 30 additions and 20 deletions

View File

@@ -4,10 +4,8 @@ import (
"context" "context"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/kvdb"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"gopkg.in/macaroon-bakery.v2/bakery" "gopkg.in/macaroon-bakery.v2/bakery"
"gopkg.in/macaroon-bakery.v2/bakery/checkers" "gopkg.in/macaroon-bakery.v2/bakery/checkers"
macaroon "gopkg.in/macaroon.v2" macaroon "gopkg.in/macaroon.v2"
@@ -152,34 +150,31 @@ func (svc *Service) ValidateMacaroon(ctx context.Context,
requiredPermissions []bakery.Op, fullMethod string) error { requiredPermissions []bakery.Op, fullMethod string) error {
// Get macaroon bytes from context and unmarshal into macaroon. // Get macaroon bytes from context and unmarshal into macaroon.
md, ok := metadata.FromIncomingContext(ctx) macHex, err := RawMacaroonFromContext(ctx)
if !ok { if err != nil {
return fmt.Errorf("unable to get metadata from context") return err
} }
if len(md["macaroon"]) != 1 {
return fmt.Errorf("expected 1 macaroon, got %d", // With the macaroon obtained, we'll now decode the hex-string encoding.
len(md["macaroon"])) macBytes, err := hex.DecodeString(macHex)
if err != nil {
return err
} }
return svc.CheckMacAuth( return svc.CheckMacAuth(
ctx, md["macaroon"][0], requiredPermissions, fullMethod, ctx, macBytes, requiredPermissions, fullMethod,
) )
} }
// CheckMacAuth checks that the macaroon is not disobeying any caveats and is // CheckMacAuth checks that the macaroon is not disobeying any caveats and is
// authorized to perform the operation the user wants to perform. // authorized to perform the operation the user wants to perform.
func (svc *Service) CheckMacAuth(ctx context.Context, macStr string, func (svc *Service) CheckMacAuth(ctx context.Context, macBytes []byte,
requiredPermissions []bakery.Op, fullMethod string) error { requiredPermissions []bakery.Op, fullMethod string) error {
// With the macaroon obtained, we'll now decode the hex-string // With the macaroon obtained, we'll now unmarshal it from binary into
// encoding, then unmarshal it from binary into its concrete struct // its concrete struct representation.
// representation.
macBytes, err := hex.DecodeString(macStr)
if err != nil {
return err
}
mac := &macaroon.Macaroon{} mac := &macaroon.Macaroon{}
err = mac.UnmarshalBinary(macBytes) err := mac.UnmarshalBinary(macBytes)
if err != nil { if err != nil {
return err return err
} }
@@ -264,3 +259,19 @@ func (svc *Service) GenerateNewRootKey() error {
func (svc *Service) ChangePassword(oldPw, newPw []byte) error { func (svc *Service) ChangePassword(oldPw, newPw []byte) error {
return svc.rks.ChangePassword(oldPw, newPw) return svc.rks.ChangePassword(oldPw, newPw)
} }
// RawMacaroonFromContext is a helper function that extracts a raw macaroon
// from the given incoming gRPC request context.
func RawMacaroonFromContext(ctx context.Context) (string, error) {
// Get macaroon bytes from context and unmarshal into macaroon.
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return "", fmt.Errorf("unable to get metadata from context")
}
if len(md["macaroon"]) != 1 {
return "", fmt.Errorf("expected 1 macaroon, got %d",
len(md["macaroon"]))
}
return md["macaroon"][0], nil
}

View File

@@ -6995,8 +6995,7 @@ func (r *rpcServer) CheckMacaroonPermissions(ctx context.Context,
} }
err := r.macService.CheckMacAuth( err := r.macService.CheckMacAuth(
ctx, hex.EncodeToString(req.Macaroon), permissions, ctx, req.Macaroon, permissions, req.FullMethod,
req.FullMethod,
) )
if err != nil { if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error()) return nil, status.Error(codes.InvalidArgument, err.Error())