github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/cmd/signerparams_test.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  	"os"
    21  	"path/filepath"
    22  	"testing"
    23  
    24  	"github.com/nats-io/nsc/cmd/store"
    25  
    26  	"github.com/mitchellh/go-homedir"
    27  	"github.com/nats-io/nkeys"
    28  	"github.com/spf13/cobra"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func createSignerCmd(kind nkeys.PrefixByte, allowManaged bool, expected nkeys.KeyPair) *cobra.Command {
    33  	params := signerParamsTest{kind: kind, allowManaged: allowManaged, expected: expected}
    34  	cmd := &cobra.Command{
    35  		Use: "sp",
    36  		RunE: func(cmd *cobra.Command, args []string) error {
    37  			if err := RunAction(cmd, args, &params); err != nil {
    38  				return err
    39  			}
    40  			return nil
    41  		},
    42  	}
    43  	HoistRootFlags(cmd)
    44  	return cmd
    45  }
    46  
    47  type signerParamsTest struct {
    48  	expected     nkeys.KeyPair
    49  	kind         nkeys.PrefixByte
    50  	allowManaged bool
    51  	sp           SignerParams
    52  }
    53  
    54  func (a *signerParamsTest) SetDefaults(ctx ActionCtx) error {
    55  	a.sp.SetDefaults(a.kind, a.allowManaged, ctx)
    56  	return nil
    57  }
    58  
    59  func (a *signerParamsTest) PreInteractive(ctx ActionCtx) error {
    60  	return a.sp.Edit(ctx)
    61  }
    62  
    63  func (a *signerParamsTest) Load(ctx ActionCtx) error {
    64  	return nil
    65  }
    66  
    67  func (a *signerParamsTest) PostInteractive(ctx ActionCtx) error {
    68  	return nil
    69  }
    70  
    71  func (a *signerParamsTest) Validate(ctx ActionCtx) error {
    72  	return a.sp.Resolve(ctx)
    73  }
    74  
    75  func (a *signerParamsTest) Run(ctx ActionCtx) (store.Status, error) {
    76  	if a.expected == nil && a.sp.signerKP != nil {
    77  		d, _ := a.sp.signerKP.Seed()
    78  		return nil, fmt.Errorf("no key expected - found %q", string(d))
    79  	}
    80  	if a.expected != nil && a.sp.signerKP == nil {
    81  		return nil, fmt.Errorf("expected key - none found")
    82  	}
    83  	return nil, nil
    84  }
    85  
    86  func Test_SignerParams(t *testing.T) {
    87  	ts := NewTestStore(t, "test")
    88  	defer ts.Done(t)
    89  
    90  	ts.AddAccount(t, "A")
    91  	akp := ts.GetAccountKey(t, "A")
    92  	require.NotNil(t, akp)
    93  
    94  	tests := CmdTests{
    95  		{createSignerCmd(nkeys.PrefixByteOperator, false, ts.OperatorKey), []string{"sp"}, nil, nil, false},
    96  		{createSignerCmd(nkeys.PrefixByteAccount, false, akp), []string{"sp"}, nil, nil, false},
    97  	}
    98  
    99  	tests.Run(t, "root")
   100  }
   101  
   102  func Test_ManagedSignerParams(t *testing.T) {
   103  	as, m := RunTestAccountServer(t)
   104  	defer as.Close()
   105  
   106  	ts := NewTestStoreWithOperatorJWT(t, string(m["operator"]))
   107  	defer ts.Done(t)
   108  
   109  	require.True(t, ts.Store.IsManaged())
   110  	require.Nil(t, ts.OperatorKey)
   111  
   112  	ts.AddAccount(t, "A")
   113  	akp := ts.GetAccountKey(t, "A")
   114  	require.NotNil(t, akp)
   115  
   116  	tests := CmdTests{
   117  		{createSignerCmd(nkeys.PrefixByteOperator, true, akp), []string{"sp"}, nil, nil, false},
   118  	}
   119  
   120  	tests.Run(t, "root")
   121  }
   122  
   123  func Test_SignerOperator(t *testing.T) {
   124  	ts := NewTestStore(t, "test")
   125  	defer ts.Done(t)
   126  
   127  	dest := filepath.Join(ts.Dir, filepath.Base(ts.OperatorKeyPath))
   128  	require.NoError(t, os.Rename(ts.OperatorKeyPath, dest))
   129  	require.FileExists(t, dest)
   130  
   131  	tests := CmdTests{
   132  		{createSignerCmd(nkeys.PrefixByteOperator, false, nil), []string{"sp"}, nil, nil, true},
   133  		{createSignerCmd(nkeys.PrefixByteOperator, false, ts.OperatorKey), []string{"sp", "-K", dest}, nil, nil, false},
   134  	}
   135  
   136  	tests.Run(t, "root")
   137  }
   138  
   139  func Test_SignerParamsSameDir(t *testing.T) {
   140  	ts := NewTestStore(t, "test")
   141  	defer ts.Done(t)
   142  
   143  	dest := filepath.Join(ts.Dir, filepath.Base(ts.OperatorKeyPath))
   144  	require.NoError(t, os.Rename(ts.OperatorKeyPath, dest))
   145  	require.FileExists(t, dest)
   146  
   147  	cwd, err := os.Getwd()
   148  	require.NoError(t, err)
   149  	require.NoError(t, os.Chdir(ts.Dir))
   150  	_, _, err = ExecuteCmd(createSignerCmd(nkeys.PrefixByteOperator, false, ts.OperatorKey), "-K", filepath.Base(dest))
   151  	require.NoError(t, os.Chdir(cwd))
   152  	require.NoError(t, err)
   153  }
   154  
   155  func Test_SignerParamsRelativePath(t *testing.T) {
   156  	ts := NewTestStore(t, "test")
   157  	defer ts.Done(t)
   158  
   159  	dest := filepath.Join(ts.Dir, filepath.Base(ts.OperatorKeyPath))
   160  	require.NoError(t, os.Rename(ts.OperatorKeyPath, dest))
   161  	require.FileExists(t, dest)
   162  
   163  	cwd, err := os.Getwd()
   164  	require.NoError(t, err)
   165  	require.NoError(t, os.Chdir(ts.StoreDir))
   166  	_, _, err = ExecuteCmd(createSignerCmd(nkeys.PrefixByteOperator, false, ts.OperatorKey), "-K", filepath.Join("../", filepath.Base(dest)))
   167  	require.NoError(t, os.Chdir(cwd))
   168  	require.NoError(t, err)
   169  }
   170  
   171  func Test_SignerParamsPathNotFound(t *testing.T) {
   172  	ts := NewTestStore(t, "test")
   173  	defer ts.Done(t)
   174  
   175  	require.NoError(t, os.Remove(ts.OperatorKeyPath))
   176  	_, _, err := ExecuteCmd(createSignerCmd(nkeys.PrefixByteOperator, false, nil), "-K", ts.OperatorKeyPath)
   177  	require.Error(t, err)
   178  	require.Contains(t, err.Error(), "unable to resolve any of the following signing keys in the keystore")
   179  }
   180  
   181  func Test_SignerParamsHomePath(t *testing.T) {
   182  	ts := NewTestStore(t, "O")
   183  	defer ts.Done(t)
   184  
   185  	home, err := homedir.Dir()
   186  	require.NoError(t, err)
   187  
   188  	// yeap not going to remove it
   189  	tmpdir := filepath.Join(home, ".nsc_unit_test")
   190  	require.NoError(t, MaybeMakeDir(tmpdir))
   191  
   192  	fn := filepath.Join(tmpdir, filepath.Base(ts.OperatorKeyPath))
   193  	require.NoError(t, os.Rename(ts.OperatorKeyPath, fn))
   194  	require.FileExists(t, fn)
   195  
   196  	defer func() {
   197  		if err := os.Remove(fn); err != nil {
   198  			t.Fatal(err)
   199  		}
   200  	}()
   201  
   202  	tfn := AbbrevHomePaths(fn)
   203  	require.Equal(t, "~", tfn[:1])
   204  	_, _, err = ExecuteCmd(createSignerCmd(nkeys.PrefixByteOperator, false, ts.OperatorKey), "-K", tfn)
   205  	require.NoError(t, err)
   206  }
   207  
   208  func Test_SignerParamsSeed(t *testing.T) {
   209  	ts := NewTestStore(t, "O")
   210  	defer ts.Done(t)
   211  
   212  	ts.AddAccount(t, "A")
   213  	s, pk, _ := CreateAccountKey(t)
   214  
   215  	_, stdErr, err := ExecuteCmd(HoistRootFlags(CreateAddUserCmd()), "--name", "a", "-K", string(s))
   216  	require.Error(t, err)
   217  	require.Contains(t, stdErr, "is not in the store")
   218  
   219  	_, _, err = ExecuteCmd(createEditAccount(), "--sk", pk)
   220  	require.NoError(t, err)
   221  
   222  	_, _, err = ExecuteCmd(HoistRootFlags(CreateAddUserCmd()), "--name", "a", "-K", string(s))
   223  	require.NoError(t, err)
   224  }