github.com/kbehouse/nsc@v0.0.6/cmd/pubkeyparams.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  	"fmt"
    20  
    21  	"github.com/kbehouse/nsc/cmd/store"
    22  	cli "github.com/nats-io/cliprompts/v2"
    23  	"github.com/nats-io/jwt"
    24  	"github.com/nats-io/nkeys"
    25  	"github.com/spf13/cobra"
    26  )
    27  
    28  type PubKeyChoice struct {
    29  	Label string
    30  	Key   string
    31  }
    32  
    33  type PubKeyParams struct {
    34  	flagName      string
    35  	kind          nkeys.PrefixByte
    36  	publicKey     string
    37  	AllowWildcard bool
    38  }
    39  
    40  type accountRef string
    41  
    42  func (l *accountRef) Set(val string) error {
    43  	if val == "*" || nkeys.IsValidPublicKey(val) {
    44  		*l = accountRef(val)
    45  	} else if s, err := GetConfig().LoadStore(GetConfig().Operator); err != nil {
    46  		return err
    47  	} else if claim, err := s.ReadAccountClaim(val); err != nil {
    48  		return err
    49  	} else {
    50  		*l = accountRef(claim.Subject)
    51  	}
    52  	return nil
    53  }
    54  
    55  func (l *accountRef) String() string {
    56  	return string(*l)
    57  }
    58  
    59  func (t *accountRef) Type() string {
    60  	return "account-ref"
    61  }
    62  
    63  func (e *PubKeyParams) BindFlags(flagName string, shorthand string, kind nkeys.PrefixByte, cmd *cobra.Command) {
    64  	e.flagName = flagName
    65  	e.kind = kind
    66  	if kind == nkeys.PrefixByteAccount {
    67  		cmd.Flags().VarP((*accountRef)(&e.publicKey), flagName, shorthand, "")
    68  	} else {
    69  		cmd.Flags().StringVarP(&e.publicKey, flagName, shorthand, "", flagName)
    70  	}
    71  }
    72  
    73  func (e *PubKeyParams) valid(s string) error {
    74  	if s == "" {
    75  		return fmt.Errorf("%s cannot be empty", e.flagName)
    76  	}
    77  	if e.AllowWildcard && s == jwt.All {
    78  		return nil
    79  	}
    80  
    81  	if !store.IsPublicKey(e.kind, s) {
    82  		return fmt.Errorf("%s is not a valid %q public key", e.publicKey, e.kind.String())
    83  	}
    84  
    85  	return nil
    86  }
    87  
    88  func (e *PubKeyParams) Valid() error {
    89  	return e.valid(e.publicKey)
    90  }
    91  
    92  func (e *PubKeyParams) Select(label string, choices ...PubKeyChoice) error {
    93  	var labels []string
    94  	for _, c := range choices {
    95  		labels = append(labels, c.Label)
    96  	}
    97  	sel, err := cli.Select(label, "", labels)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	if sel == -1 {
   102  		return fmt.Errorf("nothing selected")
   103  	}
   104  	e.publicKey = choices[sel].Key
   105  	return nil
   106  }
   107  
   108  func (e *PubKeyParams) Edit() error {
   109  	m := fmt.Sprintf("%s public key", e.flagName)
   110  	if e.AllowWildcard {
   111  		m = fmt.Sprintf("%s or '*' to match any %s", m, e.flagName)
   112  	}
   113  	sv, err := cli.Prompt(m, e.publicKey, cli.Val(e.valid))
   114  	if err != nil {
   115  		return err
   116  	}
   117  	e.publicKey = sv
   118  	return nil
   119  }