github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/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/spf13/cobra"
    15  
    16  	"github.com/iotexproject/iotex-core/ioctl/cmd/account"
    17  	"github.com/iotexproject/iotex-core/ioctl/cmd/action"
    18  	"github.com/iotexproject/iotex-core/ioctl/config"
    19  	"github.com/iotexproject/iotex-core/ioctl/flag"
    20  	"github.com/iotexproject/iotex-core/ioctl/output"
    21  )
    22  
    23  // Multi-language support
    24  var (
    25  	_signCmdShorts = map[config.Language]string{
    26  		config.English: "Sign Json Web Token on IoTeX blockchain",
    27  		config.Chinese: "签发IoTeX区块链上的JWT",
    28  	}
    29  	_signCmdUses = map[config.Language]string{
    30  		config.English: "sign [-s SIGNER] [-P PASSWORD] [-y] --with-arguments [INVOKE_INPUT]",
    31  		config.Chinese: "sign [-s 签署人] [-P 密码] [-y] --with-arguments [输入]",
    32  	}
    33  )
    34  
    35  // _jwtSignCmd represents the jwt sign command
    36  var _jwtSignCmd = &cobra.Command{
    37  	Use:   config.TranslateInLang(_signCmdUses, config.UILanguage),
    38  	Short: config.TranslateInLang(_signCmdShorts, config.UILanguage),
    39  	Args:  cobra.ExactArgs(0),
    40  	RunE: func(cmd *cobra.Command, args []string) error {
    41  		cmd.SilenceUsage = true
    42  		return output.PrintError(jwtSign())
    43  	},
    44  }
    45  
    46  func jwtSign() error {
    47  	arg := flag.WithArgumentsFlag.Value().(string)
    48  	if arg == "" {
    49  		arg = "{}"
    50  	}
    51  
    52  	var (
    53  		input map[string]string
    54  		exp   int64
    55  		err   error
    56  	)
    57  	if err = json.Unmarshal([]byte(arg), &input); err != nil {
    58  		return output.NewError(output.SerializationError, "failed to unmarshal arguments", err)
    59  	}
    60  	if input["exp"] != "" {
    61  		exp, err = strconv.ParseInt(input["exp"], 10, 64)
    62  		if err != nil {
    63  			return output.NewError(output.SerializationError, "invalid expire time", err)
    64  		}
    65  	} else {
    66  		input["exp"] = "0"
    67  	}
    68  
    69  	signer, err := action.Signer()
    70  	if err != nil {
    71  		return output.NewError(output.AddressError, "failed to get signer address", err)
    72  	}
    73  	prvKey, err := account.PrivateKeyFromSigner(signer, "")
    74  	if err != nil {
    75  		return err
    76  	}
    77  	pubKey := prvKey.PublicKey()
    78  	addr := pubKey.Address()
    79  
    80  	// sign JWT
    81  	now := time.Now().Unix()
    82  	jwtString, err := jwt.SignJWT(now, exp, input["sub"], input["scope"], prvKey)
    83  	if err != nil {
    84  		return output.NewError(output.CryptoError, "failed to sign JWT token", err)
    85  	}
    86  	prvKey.Zero()
    87  
    88  	// format output
    89  	input["iat"] = strconv.FormatInt(now, 10)
    90  	input["iss"] = "0x" + pubKey.HexString()
    91  	out := "JWT token: " + jwtString + "\n\n"
    92  	out += "signed by:\n"
    93  	out += "{\n"
    94  	out += "  address: " + addr.String() + "\n"
    95  	out += "  public key: " + input["iss"] + "\n"
    96  	out += "}\n"
    97  	out += "with following claims:\n"
    98  	out += output.JSONString(input)
    99  	output.PrintResult(out)
   100  	return nil
   101  }