mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-25 16:23:49 +02:00
cmd/lncli: extract macaroon caveat flags
As a preparation for re-using the macaroon caveat/constraints CLI flags, we extract the parsing and adding of those constraints into its own function.
This commit is contained in:
parent
7106ea59db
commit
f4e1f60e4d
@ -19,12 +19,36 @@ import (
|
|||||||
"gopkg.in/macaroon.v2"
|
"gopkg.in/macaroon.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
macTimeoutFlag = cli.Uint64Flag{
|
||||||
|
Name: "timeout",
|
||||||
|
Usage: "the number of seconds the macaroon will be " +
|
||||||
|
"valid before it times out",
|
||||||
|
}
|
||||||
|
macIPAddressFlag = cli.StringFlag{
|
||||||
|
Name: "ip_address",
|
||||||
|
Usage: "the IP address the macaroon will be bound to",
|
||||||
|
}
|
||||||
|
macCustomCaveatNameFlag = cli.StringFlag{
|
||||||
|
Name: "custom_caveat_name",
|
||||||
|
Usage: "the name of the custom caveat to add",
|
||||||
|
}
|
||||||
|
macCustomCaveatConditionFlag = cli.StringFlag{
|
||||||
|
Name: "custom_caveat_condition",
|
||||||
|
Usage: "the condition of the custom caveat to add, can be " +
|
||||||
|
"empty if custom caveat doesn't need a value",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
var bakeMacaroonCommand = cli.Command{
|
var bakeMacaroonCommand = cli.Command{
|
||||||
Name: "bakemacaroon",
|
Name: "bakemacaroon",
|
||||||
Category: "Macaroons",
|
Category: "Macaroons",
|
||||||
Usage: "Bakes a new macaroon with the provided list of permissions " +
|
Usage: "Bakes a new macaroon with the provided list of permissions " +
|
||||||
"and restrictions.",
|
"and restrictions.",
|
||||||
ArgsUsage: "[--save_to=] [--timeout=] [--ip_address=] [--allow_external_permissions] permissions...",
|
ArgsUsage: "[--save_to=] [--timeout=] [--ip_address=] " +
|
||||||
|
"[--custom_caveat_name= [--custom_caveat_condition=]] " +
|
||||||
|
"[--root_key_id=] [--allow_external_permissions] " +
|
||||||
|
"permissions...",
|
||||||
Description: `
|
Description: `
|
||||||
Bake a new macaroon that grants the provided permissions and
|
Bake a new macaroon that grants the provided permissions and
|
||||||
optionally adds restrictions (timeout, IP address) to it.
|
optionally adds restrictions (timeout, IP address) to it.
|
||||||
@ -57,32 +81,19 @@ var bakeMacaroonCommand = cli.Command{
|
|||||||
Usage: "save the created macaroon to this file " +
|
Usage: "save the created macaroon to this file " +
|
||||||
"using the default binary format",
|
"using the default binary format",
|
||||||
},
|
},
|
||||||
|
macTimeoutFlag,
|
||||||
|
macIPAddressFlag,
|
||||||
|
macCustomCaveatNameFlag,
|
||||||
|
macCustomCaveatConditionFlag,
|
||||||
cli.Uint64Flag{
|
cli.Uint64Flag{
|
||||||
Name: "timeout",
|
Name: "root_key_id",
|
||||||
Usage: "the number of seconds the macaroon will be " +
|
Usage: "the numerical root key ID used to create the " +
|
||||||
"valid before it times out",
|
"macaroon",
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "ip_address",
|
|
||||||
Usage: "the IP address the macaroon will be bound to",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "custom_caveat_name",
|
|
||||||
Usage: "the name of the custom caveat to add",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "custom_caveat_condition",
|
|
||||||
Usage: "the condition of the custom caveat to add, " +
|
|
||||||
"can be empty if custom caveat doesn't need " +
|
|
||||||
"a value",
|
|
||||||
},
|
|
||||||
cli.Uint64Flag{
|
|
||||||
Name: "root_key_id",
|
|
||||||
Usage: "the numerical root key ID used to create the macaroon",
|
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "allow_external_permissions",
|
Name: "allow_external_permissions",
|
||||||
Usage: "whether permissions lnd is not familiar with are allowed",
|
Usage: "whether permissions lnd is not familiar with " +
|
||||||
|
"are allowed",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: actionDecorator(bakeMacaroon),
|
Action: actionDecorator(bakeMacaroon),
|
||||||
@ -101,10 +112,6 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
savePath string
|
savePath string
|
||||||
timeout int64
|
|
||||||
ipAddress net.IP
|
|
||||||
customCaveatName string
|
|
||||||
customCaveatCond string
|
|
||||||
rootKeyID uint64
|
rootKeyID uint64
|
||||||
parsedPermissions []*lnrpc.MacaroonPermission
|
parsedPermissions []*lnrpc.MacaroonPermission
|
||||||
err error
|
err error
|
||||||
@ -114,47 +121,6 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
savePath = lncfg.CleanAndExpandPath(ctx.String("save_to"))
|
savePath = lncfg.CleanAndExpandPath(ctx.String("save_to"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsSet("timeout") {
|
|
||||||
timeout = ctx.Int64("timeout")
|
|
||||||
if timeout <= 0 {
|
|
||||||
return fmt.Errorf("timeout must be greater than 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.IsSet("ip_address") {
|
|
||||||
ipAddress = net.ParseIP(ctx.String("ip_address"))
|
|
||||||
if ipAddress == nil {
|
|
||||||
return fmt.Errorf("unable to parse ip_address: %s",
|
|
||||||
ctx.String("ip_address"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.IsSet("custom_caveat_name") {
|
|
||||||
customCaveatName = ctx.String("custom_caveat_name")
|
|
||||||
if containsWhiteSpace(customCaveatName) {
|
|
||||||
return fmt.Errorf("unexpected white space found in " +
|
|
||||||
"custom caveat name")
|
|
||||||
}
|
|
||||||
if customCaveatName == "" {
|
|
||||||
return fmt.Errorf("invalid custom caveat name")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.IsSet("custom_caveat_condition") {
|
|
||||||
customCaveatCond = ctx.String("custom_caveat_condition")
|
|
||||||
if containsWhiteSpace(customCaveatCond) {
|
|
||||||
return fmt.Errorf("unexpected white space found in " +
|
|
||||||
"custom caveat condition")
|
|
||||||
}
|
|
||||||
if customCaveatCond == "" {
|
|
||||||
return fmt.Errorf("invalid custom caveat condition")
|
|
||||||
}
|
|
||||||
if customCaveatCond != "" && customCaveatName == "" {
|
|
||||||
return fmt.Errorf("cannot set custom caveat " +
|
|
||||||
"condition without custom caveat name")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.IsSet("root_key_id") {
|
if ctx.IsSet("root_key_id") {
|
||||||
rootKeyID = ctx.Uint64("root_key_id")
|
rootKeyID = ctx.Uint64("root_key_id")
|
||||||
}
|
}
|
||||||
@ -213,32 +179,7 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
|
|
||||||
// Now apply the desired constraints to the macaroon. This will always
|
// Now apply the desired constraints to the macaroon. This will always
|
||||||
// create a new macaroon object, even if no constraints are added.
|
// create a new macaroon object, even if no constraints are added.
|
||||||
macConstraints := make([]macaroons.Constraint, 0)
|
constrainedMac, err := applyMacaroonConstraints(ctx, unmarshalMac)
|
||||||
if timeout > 0 {
|
|
||||||
macConstraints = append(
|
|
||||||
macConstraints, macaroons.TimeoutConstraint(timeout),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if ipAddress != nil {
|
|
||||||
macConstraints = append(
|
|
||||||
macConstraints,
|
|
||||||
macaroons.IPLockConstraint(ipAddress.String()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The custom caveat condition is optional, it could just be a marker
|
|
||||||
// tag in the macaroon with just a name. The interceptor itself doesn't
|
|
||||||
// care about the value anyway.
|
|
||||||
if customCaveatName != "" {
|
|
||||||
macConstraints = append(
|
|
||||||
macConstraints, macaroons.CustomConstraint(
|
|
||||||
customCaveatName, customCaveatCond,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
constrainedMac, err := macaroons.AddConstraints(
|
|
||||||
unmarshalMac, macConstraints...,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -470,6 +411,81 @@ func printMacaroon(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applyMacaroonConstraints parses and applies all currently supported macaroon
|
||||||
|
// condition flags from the command line to the given macaroon and returns a new
|
||||||
|
// macaroon instance.
|
||||||
|
func applyMacaroonConstraints(ctx *cli.Context,
|
||||||
|
mac *macaroon.Macaroon) (*macaroon.Macaroon, error) {
|
||||||
|
|
||||||
|
macConstraints := make([]macaroons.Constraint, 0)
|
||||||
|
|
||||||
|
if ctx.IsSet(macTimeoutFlag.Name) {
|
||||||
|
timeout := ctx.Int64(macTimeoutFlag.Name)
|
||||||
|
if timeout <= 0 {
|
||||||
|
return nil, fmt.Errorf("timeout must be greater than 0")
|
||||||
|
}
|
||||||
|
macConstraints = append(
|
||||||
|
macConstraints, macaroons.TimeoutConstraint(timeout),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet(macIPAddressFlag.Name) {
|
||||||
|
ipAddress := net.ParseIP(ctx.String(macIPAddressFlag.Name))
|
||||||
|
if ipAddress == nil {
|
||||||
|
return nil, fmt.Errorf("unable to parse ip_address: %s",
|
||||||
|
ctx.String("ip_address"))
|
||||||
|
}
|
||||||
|
|
||||||
|
macConstraints = append(
|
||||||
|
macConstraints,
|
||||||
|
macaroons.IPLockConstraint(ipAddress.String()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet(macCustomCaveatNameFlag.Name) {
|
||||||
|
customCaveatName := ctx.String(macCustomCaveatNameFlag.Name)
|
||||||
|
if containsWhiteSpace(customCaveatName) {
|
||||||
|
return nil, fmt.Errorf("unexpected white space found " +
|
||||||
|
"in custom caveat name")
|
||||||
|
}
|
||||||
|
if customCaveatName == "" {
|
||||||
|
return nil, fmt.Errorf("invalid custom caveat name")
|
||||||
|
}
|
||||||
|
|
||||||
|
var customCaveatCond string
|
||||||
|
if ctx.IsSet(macCustomCaveatConditionFlag.Name) {
|
||||||
|
customCaveatCond = ctx.String(
|
||||||
|
macCustomCaveatConditionFlag.Name,
|
||||||
|
)
|
||||||
|
if containsWhiteSpace(customCaveatCond) {
|
||||||
|
return nil, fmt.Errorf("unexpected white " +
|
||||||
|
"space found in custom caveat " +
|
||||||
|
"condition")
|
||||||
|
}
|
||||||
|
if customCaveatCond == "" {
|
||||||
|
return nil, fmt.Errorf("invalid custom " +
|
||||||
|
"caveat condition")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The custom caveat condition is optional, it could just be a
|
||||||
|
// marker tag in the macaroon with just a name. The interceptor
|
||||||
|
// itself doesn't care about the value anyway.
|
||||||
|
macConstraints = append(
|
||||||
|
macConstraints, macaroons.CustomConstraint(
|
||||||
|
customCaveatName, customCaveatCond,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
constrainedMac, err := macaroons.AddConstraints(mac, macConstraints...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error adding constraints: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return constrainedMac, nil
|
||||||
|
}
|
||||||
|
|
||||||
// containsWhiteSpace returns true if the given string contains any character
|
// containsWhiteSpace returns true if the given string contains any character
|
||||||
// that is considered to be a white space or non-printable character such as
|
// that is considered to be a white space or non-printable character such as
|
||||||
// space, tabulator, newline, carriage return and some more exotic ones.
|
// space, tabulator, newline, carriage return and some more exotic ones.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user