github.com/kbehouse/nsc@v0.0.6/cmd/signingkeyseditor.go (about) 1 /* 2 * 3 * * Copyright 2018-2019 The NATS Authors 4 * * Licensed under the Apache License, Version 2.0 (the "License"); 5 * * you may not use this file except in compliance with the License. 6 * * You may obtain a copy of the License at 7 * * 8 * * http://www.apache.org/licenses/LICENSE-2.0 9 * * 10 * * Unless required by applicable law or agreed to in writing, software 11 * * distributed under the License is distributed on an "AS IS" BASIS, 12 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * * See the License for the specific language governing permissions and 14 * * limitations under the License. 15 * 16 */ 17 18 package cmd 19 20 import ( 21 "fmt" 22 23 "github.com/kbehouse/nsc/cmd/store" 24 cli "github.com/nats-io/cliprompts/v2" 25 "github.com/nats-io/nkeys" 26 "github.com/spf13/cobra" 27 ) 28 29 type SigningKeysParams struct { 30 flagName string 31 paths []string 32 kind nkeys.PrefixByte 33 } 34 35 func (e *SigningKeysParams) BindFlags(flagName string, shorthand string, kind nkeys.PrefixByte, cmd *cobra.Command) { 36 e.flagName = flagName 37 e.kind = kind 38 cmd.Flags().StringSliceVarP(&e.paths, flagName, shorthand, nil, `signing key or keypath or the value "generate"" to generate a key pair on the fly - comma separated list or option can be specified multiple times`) 39 } 40 41 func (e *SigningKeysParams) valid(s string) error { 42 _, err := e.resolve(s) 43 return err 44 } 45 46 func (e *SigningKeysParams) resolve(s string) (nkeys.KeyPair, error) { 47 if s == "" { 48 return nil, fmt.Errorf("signing key cannot be empty") 49 } 50 if s == "generate" { 51 if kp, err := nkeys.CreatePair(e.kind); err != nil { 52 return nil, err 53 } else if s, err = kp.PublicKey(); err != nil { 54 return nil, err 55 } else if _, err = store.StoreKey(kp); err != nil { 56 return nil, err 57 } 58 } 59 kp, err := store.ResolveKey(s) 60 if err != nil { 61 return nil, err 62 } 63 if kp == nil { 64 return nil, fmt.Errorf("a signing key is required") 65 } 66 if !store.KeyPairTypeOk(e.kind, kp) { 67 return nil, fmt.Errorf("invalid %s signing key %q", e.kind.String(), s) 68 } 69 70 return kp, nil 71 } 72 73 func (e *SigningKeysParams) Valid() error { 74 for _, v := range e.paths { 75 if err := e.valid(v); err != nil { 76 return err 77 } 78 } 79 return nil 80 } 81 82 func (e *SigningKeysParams) PublicKeys() ([]string, error) { 83 var keys []string 84 for _, v := range e.paths { 85 kp, err := e.resolve(v) 86 if err != nil { 87 return nil, err 88 } 89 pk, err := kp.PublicKey() 90 if err != nil { 91 return nil, err 92 } 93 keys = append(keys, pk) 94 } 95 return keys, nil 96 } 97 98 func (e *SigningKeysParams) Edit() error { 99 // verify any keys that were added via flags 100 for i, v := range e.paths { 101 sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), v, cli.Val(e.valid)) 102 if err != nil { 103 return err 104 } 105 e.paths[i] = sv 106 } 107 first := true 108 for { 109 m := "add a signing key" 110 if !first || len(e.paths) > 0 { 111 m = "add another signing key" 112 } 113 first = false 114 115 ok, err := cli.Confirm(m, false) 116 if err != nil { 117 return err 118 } 119 if !ok { 120 break 121 } 122 sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), "", cli.Val(e.valid)) 123 if err != nil { 124 return err 125 } 126 e.paths = append(e.paths, sv) 127 } 128 return nil 129 }