From f596e11b6f2239dfe16e891850c911f68bc75b13 Mon Sep 17 00:00:00 2001 From: Viacheslav Date: Mon, 2 Oct 2023 11:41:04 +0300 Subject: [PATCH] feat(cmd/rpc): add node store flag (#2762) --- cmd/auth.go | 82 +++++++++++++++++++++++---------------------- cmd/celestia/rpc.go | 22 ++++-------- cmd/flags_node.go | 2 +- cmd/rpc.go | 57 +++++++++++++++++++++++++++---- 4 files changed, 101 insertions(+), 62 deletions(-) diff --git a/cmd/auth.go b/cmd/auth.go index eb2000675e..3006526b15 100644 --- a/cmd/auth.go +++ b/cmd/auth.go @@ -25,59 +25,61 @@ func AuthCmd(fsets ...*flag.FlagSet) *cobra.Command { Short: "Signs and outputs a hex-encoded JWT token with the given permissions.", Long: "Signs and outputs a hex-encoded JWT token with the given permissions. NOTE: only use this command when " + "the node has already been initialized and started.", - RunE: newToken, - } + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("must specify permissions") + } + permissions, err := convertToPerms(args[0]) + if err != nil { + return err + } - for _, set := range fsets { - cmd.Flags().AddFlagSet(set) - } - return cmd -} + ks, err := newKeystore(StorePath(cmd.Context())) + if err != nil { + return err -func newToken(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("must specify permissions") - } + } - permissions, err := convertToPerms(args[0]) - if err != nil { - return err - } + key, err := ks.Get(nodemod.SecretName) + if err != nil { + if !errors.Is(err, keystore.ErrNotFound) { + return err + } + key, err = generateNewKey(ks) + if err != nil { + return err + } + } - expanded, err := homedir.Expand(filepath.Clean(StorePath(cmd.Context()))) - if err != nil { - return err - } - ks, err := keystore.NewFSKeystore(filepath.Join(expanded, "keys"), nil) - if err != nil { - return err + token, err := buildJWTToken(key.Body, permissions) + if err != nil { + return err + } + fmt.Printf("%s", token) + return nil + }, } - var key keystore.PrivKey - key, err = ks.Get(nodemod.SecretName) - if err != nil { - if !errors.Is(err, keystore.ErrNotFound) { - return err - } - // otherwise, generate and save new priv key - key, err = generateNewKey(ks) - if err != nil { - return err - } + for _, set := range fsets { + cmd.Flags().AddFlagSet(set) } + return cmd +} - signer, err := jwt.NewHS256(key.Body) +func newKeystore(path string) (keystore.Keystore, error) { + expanded, err := homedir.Expand(filepath.Clean(path)) if err != nil { - return err + return nil, err } + return keystore.NewFSKeystore(filepath.Join(expanded, "keys"), nil) +} - token, err := authtoken.NewSignedJWT(signer, permissions) +func buildJWTToken(body []byte, permissions []auth.Permission) (string, error) { + signer, err := jwt.NewHS256(body) if err != nil { - return err + return "", err } - - fmt.Printf("%s", token) - return nil + return authtoken.NewSignedJWT(signer, permissions) } func generateNewKey(ks keystore.Keystore) (keystore.PrivKey, error) { diff --git a/cmd/celestia/rpc.go b/cmd/celestia/rpc.go index 8cf51fda09..11e96c2e46 100644 --- a/cmd/celestia/rpc.go +++ b/cmd/celestia/rpc.go @@ -12,21 +12,13 @@ import ( ) func init() { - blob.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - das.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - header.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - p2p.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - share.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - state.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - node.Cmd.PersistentFlags().StringVar(cmd.InitURLFlag()) - - blob.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - das.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - header.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - p2p.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - share.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - state.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) - node.Cmd.PersistentFlags().StringVar(cmd.InitAuthTokenFlag()) + blob.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + das.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + header.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + p2p.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + share.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + state.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) + node.Cmd.PersistentFlags().AddFlagSet(cmd.RPCFlags()) rootCmd.AddCommand( blob.Cmd, diff --git a/cmd/flags_node.go b/cmd/flags_node.go index 8c73a06169..fe4981b6c6 100644 --- a/cmd/flags_node.go +++ b/cmd/flags_node.go @@ -15,7 +15,7 @@ import ( "github.com/celestiaorg/celestia-node/nodebuilder/p2p" ) -var ( +const ( nodeStoreFlag = "node.store" nodeConfigFlag = "node.config" ) diff --git a/cmd/rpc.go b/cmd/rpc.go index 513967f0ed..7ea0173795 100644 --- a/cmd/rpc.go +++ b/cmd/rpc.go @@ -3,11 +3,15 @@ package cmd import ( "context" "errors" + "fmt" "os" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" rpc "github.com/celestiaorg/celestia-node/api/rpc/client" + "github.com/celestiaorg/celestia-node/api/rpc/perms" + nodemod "github.com/celestiaorg/celestia-node/nodebuilder/node" ) const ( @@ -21,15 +25,26 @@ var ( authTokenFlag string ) -func InitURLFlag() (*string, string, string, string) { - return &requestURL, "url", defaultRPCAddress, "Request URL" -} +func RPCFlags() *flag.FlagSet { + fset := &flag.FlagSet{} + + fset.StringVar( + &requestURL, + "url", + defaultRPCAddress, + "Request URL", + ) -func InitAuthTokenFlag() (*string, string, string, string) { - return &authTokenFlag, + fset.StringVar( + &authTokenFlag, "token", "", - "Authorization token (if not provided, the " + authEnvKey + " environment variable will be used)" + "Authorization token (if not provided, the "+authEnvKey+" environment variable will be used)", + ) + + storeFlag := NodeFlags().Lookup(nodeStoreFlag) + fset.AddFlag(storeFlag) + return fset } func InitClient(cmd *cobra.Command, _ []string) error { @@ -37,6 +52,18 @@ func InitClient(cmd *cobra.Command, _ []string) error { authTokenFlag = os.Getenv(authEnvKey) } + if authTokenFlag == "" { + storePath := "" + if cmd.Flag(nodeStoreFlag).Changed { + storePath = cmd.Flag(nodeStoreFlag).Value.String() + } + token, err := getToken(storePath) + if err != nil { + return fmt.Errorf("cant get the access to the auth token: %v", err) + } + authTokenFlag = token + } + client, err := rpc.NewClient(cmd.Context(), requestURL, authTokenFlag) if err != nil { return err @@ -47,6 +74,24 @@ func InitClient(cmd *cobra.Command, _ []string) error { return nil } +func getToken(path string) (string, error) { + if path == "" { + return "", errors.New("root directory was not specified") + } + + ks, err := newKeystore(path) + if err != nil { + return "", err + } + + key, err := ks.Get(nodemod.SecretName) + if err != nil { + fmt.Printf("error getting the JWT secret: %v", err) + return "", err + } + return buildJWTToken(key.Body, perms.AllPerms) +} + type rpcClientKey struct{} func ParseClientFromCtx(ctx context.Context) (*rpc.Client, error) {