github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/jwt/jwtsign.go (about)

     1  // Copyright (c) 2022 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package jwt
     7  
     8  import (
     9  	"encoding/json"
    10  	"strconv"
    11  	"time"
    12  
    13  	"github.com/iotexproject/iotex-antenna-go/v2/jwt"
    14  	"github.com/pkg/errors"
    15  	"github.com/spf13/cobra"
    16  
    17  	"github.com/iotexproject/iotex-core/ioctl"
    18  	"github.com/iotexproject/iotex-core/ioctl/config"
    19  	"github.com/iotexproject/iotex-core/ioctl/flag"
    20  	"github.com/iotexproject/iotex-core/ioctl/newcmd/account"
    21  	"github.com/iotexproject/iotex-core/ioctl/newcmd/action"
    22  )
    23  
    24  // Multi-language support
    25  var (
    26  	_signCmdShorts = map[config.Language]string{
    27  		config.English: "Sign Json Web Token on IoTeX blockchain",
    28  		config.Chinese: "签发IoTeX区块链上的JWT",
    29  	}
    30  	_signCmdUses = map[config.Language]string{
    31  		config.English: "sign [-s SIGNER] [-P PASSWORD] [-y] --with-arguments [INVOKE_INPUT]",
    32  		config.Chinese: "sign [-s 签署人] [-P 密码] [-y] --with-arguments [输入]",
    33  	}
    34  )
    35  
    36  // NewJwtSignCmd represents the jwt sign command
    37  func NewJwtSignCmd(client ioctl.Client) *cobra.Command {
    38  	use, _ := client.SelectTranslation(_signCmdUses)
    39  	short, _ := client.SelectTranslation(_signCmdShorts)
    40  
    41  	cmd := &cobra.Command{
    42  		Use:   use,
    43  		Short: short,
    44  		Args:  cobra.ExactArgs(0),
    45  		RunE: func(cmd *cobra.Command, args []string) error {
    46  			cmd.SilenceUsage = true
    47  
    48  			var (
    49  				input struct {
    50  					Exp   string `json:"exp,omitempty"`
    51  					Sub   string `json:"sub,omitempty"`
    52  					Scope string `json:"scope,omitempty"`
    53  					Iat   string `json:"iat,omitempty"`
    54  					Iss   string `json:"iss,omitempty"`
    55  				}
    56  				exp int64
    57  				err error
    58  			)
    59  
    60  			arg := flag.WithArgumentsFlag.Value().(string)
    61  			if arg == "" {
    62  				arg = "{}"
    63  			}
    64  			if err = json.Unmarshal([]byte(arg), &input); err != nil {
    65  				return errors.Wrap(err, "failed to unmarshal arguments")
    66  			}
    67  			if input.Exp != "" {
    68  				exp, err = strconv.ParseInt(input.Exp, 10, 64)
    69  				if err != nil {
    70  					return errors.Wrap(err, "invalid expire time")
    71  				}
    72  			} else {
    73  				input.Exp = "0"
    74  			}
    75  
    76  			signer, err := cmd.Flags().GetString("signer")
    77  			if err != nil {
    78  				return errors.Wrap(err, "failed to get flag signer")
    79  			}
    80  			signer, err = action.Signer(client, signer)
    81  			if err != nil {
    82  				return errors.Wrap(err, "failed to get signer address")
    83  			}
    84  			prvKey, err := account.PrivateKeyFromSigner(client, cmd, signer, "")
    85  			if err != nil {
    86  				return err
    87  			}
    88  			pubKey := prvKey.PublicKey()
    89  			addr := pubKey.Address()
    90  
    91  			// sign JWT
    92  			now := time.Now().Unix()
    93  			jwtString, err := jwt.SignJWT(now, exp, input.Sub, input.Scope, prvKey)
    94  			if err != nil {
    95  				return errors.Wrap(err, "failed to sign JWT token")
    96  			}
    97  			prvKey.Zero()
    98  
    99  			// format output
   100  			input.Iat = strconv.FormatInt(now, 10)
   101  			input.Iss = "0x" + pubKey.HexString()
   102  			byteAsJSON, err := json.MarshalIndent(input, "", "  ")
   103  			if err != nil {
   104  				return err
   105  			}
   106  			cmd.Printf("JWT token: %s\n\n"+
   107  				"signed by:\n"+
   108  				"{\n"+
   109  				"  address: %s\n"+
   110  				"  public key: %s\n"+
   111  				"}\n"+
   112  				"with following claims:\n"+
   113  				"%s\n",
   114  				jwtString, addr.String(), input.Iss, string(byteAsJSON))
   115  			return nil
   116  		},
   117  	}
   118  	action.RegisterWriteCommand(client, cmd)
   119  	flag.WithArgumentsFlag.RegisterCommand(cmd)
   120  	return cmd
   121  }