From 7f2893b9d7e5b2c6db7c6efb635d46fd9409a4df Mon Sep 17 00:00:00 2001 From: Travis Person Date: Fri, 18 Sep 2020 00:40:46 +0000 Subject: [PATCH] lotus-shed: add jwt token command --- cmd/lotus-shed/jwt.go | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/cmd/lotus-shed/jwt.go b/cmd/lotus-shed/jwt.go index d37359f71e7..8698e6a5180 100644 --- a/cmd/lotus-shed/jwt.go +++ b/cmd/lotus-shed/jwt.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "crypto/rand" "encoding/hex" "encoding/json" @@ -8,10 +9,12 @@ import ( "io" "io/ioutil" "os" + "strings" "github.com/gbrlsnchs/jwt/v3" "github.com/urfave/cli/v2" + "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules" @@ -24,6 +27,99 @@ var jwtCmd = &cli.Command{ having to run the lotus daemon.`, Subcommands: []*cli.Command{ jwtNewCmd, + jwtTokenCmd, + }, +} + +var jwtTokenCmd = &cli.Command{ + Name: "token", + Usage: "create a token for a given jwt secret", + ArgsUsage: "", + Description: `The jwt tokens have four different levels of permissions that provide some ability + to control access to what methods can be invoked by the holder of the token. + `, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Value: "token", + Usage: "specify a name", + }, + &cli.BoolFlag{ + Name: "read", + Value: false, + Usage: "add read permissions to the token", + }, + &cli.BoolFlag{ + Name: "write", + Value: false, + Usage: "add write permissions to the token", + }, + &cli.BoolFlag{ + Name: "sign", + Value: false, + Usage: "add sign permissions to the token", + }, + &cli.BoolFlag{ + Name: "admin", + Value: false, + Usage: "add admin permissions to the token", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("please specify a name") + } + + inputFile, err := os.Open(cctx.Args().First()) + if err != nil { + return err + } + defer inputFile.Close() //nolint:errcheck + input := bufio.NewReader(inputFile) + + encoded, err := ioutil.ReadAll(input) + if err != nil { + return err + } + + decoded, err := hex.DecodeString(strings.TrimSpace(string(encoded))) + if err != nil { + return err + } + + var keyInfo types.KeyInfo + if err := json.Unmarshal(decoded, &keyInfo); err != nil { + return err + } + + perms := []auth.Permission{} + + if cctx.Bool("read") { + perms = append(perms, apistruct.PermRead) + } + + if cctx.Bool("write") { + perms = append(perms, apistruct.PermWrite) + } + + if cctx.Bool("sign") { + perms = append(perms, apistruct.PermSign) + } + + if cctx.Bool("admin") { + perms = append(perms, apistruct.PermAdmin) + } + + p := modules.JwtPayload{ + Allow: perms, + } + + token, err := jwt.Sign(&p, jwt.NewHS256(keyInfo.PrivateKey)) + if err != nil { + return err + } + + return ioutil.WriteFile(cctx.String("output"), token, 0600) }, }