github.com/nats-io/nsc/v2@v2.8.7-0.20240307184528-efd7023c6896/cmd/pubkeyparams.go (about)

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