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

     1  /*
     2   * Copyright 2018-2023 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  	"encoding/json"
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/nats-io/jwt/v2"
    27  
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestDescribeUser_Single(t *testing.T) {
    32  	ts := NewTestStore(t, "operator")
    33  	defer ts.Done(t)
    34  
    35  	ts.AddAccount(t, "A")
    36  	ts.AddUser(t, "A", "a")
    37  
    38  	pub := ts.GetUserPublicKey(t, "A", "a")
    39  	apub := ts.GetAccountPublicKey(t, "A")
    40  
    41  	stdout, _, err := ExecuteCmd(createDescribeUserCmd())
    42  	require.NoError(t, err)
    43  	// account A public key
    44  	require.Contains(t, stdout, apub)
    45  	// operator public key
    46  	require.Contains(t, stdout, pub)
    47  	// name for the account
    48  	require.Contains(t, stdout, " a ")
    49  }
    50  
    51  func TestDescribeUserRaw(t *testing.T) {
    52  	ts := NewTestStore(t, "operator")
    53  	defer ts.Done(t)
    54  
    55  	ts.AddAccount(t, "A")
    56  	ts.AddUser(t, "A", "U")
    57  
    58  	Raw = true
    59  	stdout, _, err := ExecuteCmd(createDescribeUserCmd())
    60  	require.NoError(t, err)
    61  
    62  	uc, err := jwt.DecodeUserClaims(stdout)
    63  	require.NoError(t, err)
    64  
    65  	require.NotNil(t, uc)
    66  	require.Equal(t, "U", uc.Name)
    67  }
    68  
    69  func TestDescribeUser_Multiple(t *testing.T) {
    70  	ts := NewTestStore(t, "operator")
    71  	defer ts.Done(t)
    72  
    73  	ts.AddAccount(t, "A")
    74  	ts.AddUser(t, "A", "a")
    75  	ts.AddUser(t, "A", "b")
    76  
    77  	_, stderr, err := ExecuteCmd(createDescribeUserCmd())
    78  	require.Error(t, err)
    79  	require.Contains(t, stderr, "user is required")
    80  }
    81  
    82  func TestDescribeUser_MultipleWithContext(t *testing.T) {
    83  	ts := NewTestStore(t, "operator")
    84  	defer ts.Done(t)
    85  
    86  	ts.AddAccount(t, "A")
    87  	ts.AddUser(t, "A", "a")
    88  	ts.AddAccount(t, "B")
    89  	ts.AddUser(t, "B", "b")
    90  
    91  	err := GetConfig().SetAccount("B")
    92  	require.NoError(t, err)
    93  
    94  	apub := ts.GetAccountPublicKey(t, "B")
    95  
    96  	pub := ts.GetUserPublicKey(t, "B", "b")
    97  
    98  	stdout, _, err := ExecuteCmd(createDescribeUserCmd())
    99  	require.NoError(t, err)
   100  	require.Contains(t, stdout, apub)
   101  	require.Contains(t, stdout, pub)
   102  	require.Contains(t, stdout, " b ")
   103  }
   104  
   105  func TestDescribeUser_MultipleWithFlag(t *testing.T) {
   106  	ts := NewTestStore(t, "operator")
   107  	defer ts.Done(t)
   108  
   109  	ts.AddAccount(t, "A")
   110  	ts.AddAccount(t, "B")
   111  	ts.AddUser(t, "B", "b")
   112  	ts.AddUser(t, "B", "bb")
   113  
   114  	_, stderr, err := ExecuteCmd(createDescribeUserCmd(), "--account", "B")
   115  	require.Error(t, err)
   116  	require.Contains(t, stderr, "user is required")
   117  
   118  	apub := ts.GetAccountPublicKey(t, "B")
   119  
   120  	pub := ts.GetUserPublicKey(t, "B", "bb")
   121  
   122  	stdout, _, err := ExecuteCmd(createDescribeUserCmd(), "--account", "B", "--name", "bb")
   123  	require.NoError(t, err)
   124  	require.Contains(t, stdout, apub)
   125  	require.Contains(t, stdout, pub)
   126  	require.Contains(t, stdout, " bb ")
   127  }
   128  
   129  func TestDescribeUser_MultipleWithBadUser(t *testing.T) {
   130  	ts := NewTestStore(t, "operator")
   131  	defer ts.Done(t)
   132  
   133  	ts.AddAccount(t, "A")
   134  	ts.AddAccount(t, "B")
   135  	ts.AddUser(t, "B", "b")
   136  
   137  	_, _, err := ExecuteCmd(createDescribeUserCmd(), "--account", "A")
   138  	require.Error(t, err)
   139  
   140  	_, _, err = ExecuteCmd(createDescribeUserCmd(), "--account", "B", "--name", "a")
   141  	require.Error(t, err)
   142  
   143  	_, _, err = ExecuteCmd(createDescribeUserCmd(), "--account", "B", "--name", "b")
   144  	require.NoError(t, err)
   145  }
   146  
   147  func TestDescribeUser_Interactive(t *testing.T) {
   148  	ts := NewTestStore(t, "operator")
   149  	defer ts.Done(t)
   150  
   151  	ts.AddAccount(t, "A")
   152  	ts.AddAccount(t, "B")
   153  	ts.AddUser(t, "B", "bb")
   154  
   155  	_, _, err := ExecuteInteractiveCmd(createDescribeUserCmd(), []interface{}{1, 0})
   156  	require.NoError(t, err)
   157  }
   158  
   159  func TestDescribeUser_Account(t *testing.T) {
   160  	ts := NewTestStore(t, "operator")
   161  	defer ts.Done(t)
   162  
   163  	ts.AddAccount(t, "A")
   164  	_, pub, kp := CreateAccountKey(t)
   165  	_, _, err := ExecuteCmd(createEditAccount(), "--name", "A", "--sk", pub)
   166  	require.NoError(t, err)
   167  
   168  	// signed with default account key
   169  	ts.AddUser(t, "A", "aa")
   170  	stdout, _, err := ExecuteCmd(createDescribeUserCmd(), "--account", "A", "--name", "aa")
   171  	require.NoError(t, err)
   172  	require.NotContains(t, stdout, "Issuer Account")
   173  
   174  	// signed with a signing key
   175  	ts.AddUserWithSigner(t, "A", "bb", kp)
   176  	require.NoError(t, err)
   177  	stdout, _, err = ExecuteCmd(createDescribeUserCmd(), "--account", "A", "--name", "bb")
   178  	require.NoError(t, err)
   179  	require.Contains(t, stdout, "Issuer Account")
   180  }
   181  
   182  func TestDescribeRawUser(t *testing.T) {
   183  	ts := NewTestStore(t, "operator")
   184  	defer ts.Done(t)
   185  
   186  	ts.AddAccount(t, "A")
   187  	_, pub, kp := CreateAccountKey(t)
   188  	_, _, err := ExecuteCmd(createEditAccount(), "--name", "A", "--sk", pub)
   189  	require.NoError(t, err)
   190  
   191  	// signed with default account key
   192  	ts.AddUser(t, "A", "aa")
   193  	stdout, _, err := ExecuteCmd(createDescribeUserCmd(), "--account", "A", "--name", "aa")
   194  	require.NoError(t, err)
   195  	require.NotContains(t, stdout, "Issuer Account")
   196  
   197  	// signed with a signing key
   198  	ts.AddUserWithSigner(t, "A", "bb", kp)
   199  	require.NoError(t, err)
   200  	stdout, _, err = ExecuteCmd(createDescribeUserCmd(), "--account", "A", "--name", "bb")
   201  	require.NoError(t, err)
   202  	require.Contains(t, stdout, "Issuer Account")
   203  }
   204  
   205  func TestDescribeUser_Json(t *testing.T) {
   206  	ts := NewTestStore(t, "O")
   207  	defer ts.Done(t)
   208  
   209  	ts.AddAccount(t, "A")
   210  	ts.AddUser(t, "A", "aa")
   211  
   212  	out, _, err := ExecuteCmd(rootCmd, "describe", "user", "--json")
   213  	require.NoError(t, err)
   214  	m := make(map[string]interface{})
   215  	err = json.Unmarshal([]byte(out), &m)
   216  	require.NoError(t, err)
   217  	uc, err := ts.Store.ReadUserClaim("A", "aa")
   218  	require.NoError(t, err)
   219  	require.NotNil(t, uc)
   220  	require.Equal(t, uc.Subject, m["sub"])
   221  }
   222  
   223  func TestDescribeUser_JsonPath(t *testing.T) {
   224  	ts := NewTestStore(t, "O")
   225  	defer ts.Done(t)
   226  
   227  	ts.AddAccount(t, "A")
   228  	ts.AddUser(t, "A", "aa")
   229  
   230  	out, _, err := ExecuteCmd(rootCmd, "describe", "user", "--field", "sub")
   231  	require.NoError(t, err)
   232  	uc, err := ts.Store.ReadUserClaim("A", "aa")
   233  	require.NoError(t, err)
   234  	require.Equal(t, fmt.Sprintf("\"%s\"\n", uc.Subject), out)
   235  }
   236  
   237  func TestDescribeUser_Times(t *testing.T) {
   238  	ts := NewTestStore(t, "operator")
   239  	defer ts.Done(t)
   240  
   241  	ts.AddAccount(t, "A")
   242  	ts.AddUser(t, "A", "aa")
   243  	_, _, err := ExecuteCmd(createEditUserCmd(), "--time", "16:04:05-17:04:09")
   244  	require.NoError(t, err)
   245  
   246  	stdout, _, err := ExecuteCmd(createDescribeUserCmd(), "--account", "A", "--name", "aa")
   247  	require.NoError(t, err)
   248  	require.Contains(t, stdout, "16:04:05-17:04:09")
   249  }
   250  
   251  func TestDescribeUser_Output(t *testing.T) {
   252  	ts := NewTestStore(t, "O")
   253  	defer ts.Done(t)
   254  
   255  	ts.AddAccount(t, "A")
   256  	ts.AddUser(t, "A", "aa")
   257  
   258  	p := filepath.Join(ts.Dir, "aa.json")
   259  	_, _, err := ExecuteCmd(rootCmd, "describe", "user", "-a", "A", "--json", "--output-file", p)
   260  	require.NoError(t, err)
   261  	data, err := os.ReadFile(p)
   262  	require.NoError(t, err)
   263  	uc := jwt.UserClaims{}
   264  	require.NoError(t, json.Unmarshal(data, &uc))
   265  	require.Equal(t, "aa", uc.Name)
   266  
   267  	p = filepath.Join(ts.Dir, "aa.txt")
   268  	_, _, err = ExecuteCmd(rootCmd, "describe", "user", "-a", "A", "--output-file", p)
   269  	require.NoError(t, err)
   270  	data, err = os.ReadFile(p)
   271  	require.NoError(t, err)
   272  	strings.Contains(string(data), "User Details")
   273  
   274  	p = filepath.Join(ts.Dir, "aa.jwt")
   275  	_, _, err = ExecuteCmd(rootCmd, "describe", "user", "-a", "A", "--raw", "--output-file", p)
   276  	require.NoError(t, err)
   277  	data, err = os.ReadFile(p)
   278  	require.NoError(t, err)
   279  	require.Contains(t, string(data), "-----BEGIN NATS USER JWT-----\ney")
   280  }