github.com/nats-io/nsc/v2@v2.8.7-0.20240307184528-efd7023c6896/cmd/describejwt.go (about) 1 /* 2 * Copyright 2018-2020 The NATS Authors 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package cmd 17 18 import ( 19 "errors" 20 "fmt" 21 22 cli "github.com/nats-io/cliprompts/v2" 23 "github.com/nats-io/jwt/v2" 24 "github.com/nats-io/nsc/v2/cmd/store" 25 "github.com/spf13/cobra" 26 ) 27 28 func createDescribeJwtCmd() *cobra.Command { 29 var params DescribeFile 30 var cmd = &cobra.Command{ 31 Use: "jwt", 32 Short: "Describe a jwt/creds file", 33 Args: MaxArgs(0), 34 Example: fmt.Sprintf(`%s describe jwt -f pathorurl`, GetToolName()), 35 SilenceUsage: true, 36 RunE: func(cmd *cobra.Command, args []string) error { 37 if err := RunStoreLessAction(cmd, args, ¶ms); err != nil { 38 return err 39 } 40 return nil 41 }, 42 } 43 cmd.Flags().StringVarP(¶ms.outputFile, "output-file", "o", "--", "output file, '--' is stdout") 44 cmd.Flags().StringVarP(¶ms.file, "file", "f", "", "a token file or url to a token file") 45 46 return cmd 47 } 48 49 func init() { 50 describeCmd.AddCommand(createDescribeJwtCmd()) 51 } 52 53 type DescribeFile struct { 54 file string 55 kind jwt.ClaimType 56 outputFile string 57 token string 58 } 59 60 func (p *DescribeFile) SetDefaults(ctx ActionCtx) error { 61 return nil 62 } 63 64 func (p *DescribeFile) PreInteractive(ctx ActionCtx) error { 65 var err error 66 p.file, err = cli.Prompt("token file or url", p.file) 67 return err 68 } 69 70 func (p *DescribeFile) Load(ctx ActionCtx) error { 71 if p.file == "" { 72 ctx.CurrentCmd().SilenceErrors = false 73 ctx.CurrentCmd().SilenceUsage = false 74 return errors.New("file is required") 75 } 76 if d, err := LoadFromFileOrURL(p.file); err == nil { 77 p.token, err = jwt.ParseDecoratedJWT(d) 78 if err != nil { 79 return err 80 } 81 gc, err := jwt.DecodeGeneric(p.token) 82 if err != nil { 83 return err 84 } 85 p.kind = gc.ClaimType() 86 } 87 return nil 88 } 89 90 func (p *DescribeFile) PostInteractive(ctx ActionCtx) error { 91 return nil 92 } 93 94 func (p *DescribeFile) Validate(ctx ActionCtx) error { 95 return nil 96 } 97 98 func (p *DescribeFile) handleRaw() (store.Status, error) { 99 var err error 100 var raw []byte 101 if Json || JsonPath != "" { 102 raw, err = bodyAsJson([]byte(p.token)) 103 if err != nil { 104 return nil, err 105 } 106 if JsonPath != "" { 107 raw, err = GetField(raw, JsonPath) 108 if err != nil { 109 return nil, err 110 } 111 } 112 } 113 raw = append(raw, '\n') 114 if err := Write(p.outputFile, raw); err != nil { 115 return nil, err 116 } 117 var s store.Status 118 if !IsStdOut(p.outputFile) { 119 k := "description" 120 if Raw { 121 k = "jwt" 122 } 123 s = store.OKStatus("wrote jwt %s to %#q", k, AbbrevHomePaths(p.outputFile)) 124 } 125 return s, nil 126 } 127 128 func (p *DescribeFile) Run(ctx ActionCtx) (store.Status, error) { 129 if Json || Raw || JsonPath != "" { 130 return p.handleRaw() 131 } 132 133 var describer Describer 134 switch p.kind { 135 case jwt.AccountClaim: 136 ac, err := jwt.DecodeAccountClaims(p.token) 137 if err != nil { 138 return nil, err 139 } 140 describer = NewAccountDescriber(*ac) 141 case jwt.ActivationClaim: 142 ac, err := jwt.DecodeActivationClaims(p.token) 143 if err != nil { 144 return nil, err 145 } 146 describer = NewActivationDescriber(*ac) 147 case jwt.UserClaim: 148 uc, err := jwt.DecodeUserClaims(p.token) 149 if err != nil { 150 return nil, err 151 } 152 describer = NewUserDescriber(*uc) 153 case jwt.OperatorClaim: 154 oc, err := jwt.DecodeOperatorClaims(p.token) 155 if err != nil { 156 return nil, err 157 } 158 describer = NewOperatorDescriber(*oc) 159 } 160 161 if describer == nil { 162 return nil, fmt.Errorf("describer for %q is not implemented", p.kind) 163 } 164 165 if err := Write(p.outputFile, []byte(describer.Describe())); err != nil { 166 return nil, err 167 } 168 var s store.Status 169 if !IsStdOut(p.outputFile) { 170 s = store.OKStatus("wrote account description to %#q", AbbrevHomePaths(p.outputFile)) 171 } 172 return s, nil 173 }