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

     1  /*
     2   *
     3   *  * Copyright 2018-2020 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  	"encoding/json"
    22  	"fmt"
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	"github.com/nats-io/jwt/v2"
    27  	"github.com/nats-io/nsc/v2/cmd/store"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestDescribe(t *testing.T) {
    32  	ts := NewTestStore(t, "test")
    33  	defer ts.Done(t)
    34  
    35  	_, serr, err := ExecuteCmd(createDescribeJwtCmd())
    36  	require.Error(t, err)
    37  	require.Contains(t, serr, "file is required")
    38  }
    39  
    40  func TestDescribe_Operator(t *testing.T) {
    41  	ts := NewTestStore(t, "O")
    42  	defer ts.Done(t)
    43  
    44  	pub := ts.GetOperatorPublicKey(t)
    45  
    46  	fp := filepath.Join(ts.GetStoresRoot(), "O", "O.jwt")
    47  	out, _, err := ExecuteCmd(createDescribeJwtCmd(), "--file", fp)
    48  	require.NoError(t, err)
    49  	require.Contains(t, out, pub)
    50  }
    51  
    52  func TestDescribe_Interactive(t *testing.T) {
    53  	ts := NewTestStore(t, "O")
    54  	defer ts.Done(t)
    55  
    56  	ts.AddAccount(t, "A")
    57  	pub := ts.GetAccountPublicKey(t, "A")
    58  
    59  	fp := filepath.Join(ts.GetStoresRoot(), "O", store.Accounts, "A", "A.jwt")
    60  
    61  	out, _, err := ExecuteInteractiveCmd(createDescribeJwtCmd(), []interface{}{fp})
    62  	require.NoError(t, err)
    63  	require.Contains(t, out, pub)
    64  }
    65  
    66  func TestDescribe_Account(t *testing.T) {
    67  	ts := NewTestStore(t, "O")
    68  	defer ts.Done(t)
    69  
    70  	ts.AddAccount(t, "A")
    71  	pub := ts.GetAccountPublicKey(t, "A")
    72  
    73  	fp := filepath.Join(ts.GetStoresRoot(), "O", store.Accounts, "A", "A.jwt")
    74  	out, _, err := ExecuteCmd(createDescribeJwtCmd(), "--file", fp)
    75  	require.NoError(t, err)
    76  	require.Contains(t, out, pub)
    77  }
    78  
    79  func TestDescribe_User(t *testing.T) {
    80  	ts := NewTestStore(t, "O")
    81  	defer ts.Done(t)
    82  
    83  	ts.AddAccount(t, "A")
    84  	ts.AddUser(t, "A", "a")
    85  	pub := ts.GetUserPublicKey(t, "A", "a")
    86  
    87  	fp := filepath.Join(ts.GetStoresRoot(), "O", store.Accounts, "A", store.Users, "a.jwt")
    88  	out, _, err := ExecuteCmd(createDescribeJwtCmd(), "--file", fp)
    89  	require.NoError(t, err)
    90  	require.Contains(t, out, pub)
    91  }
    92  
    93  func TestDescribe_Activation(t *testing.T) {
    94  	ts := NewTestStore(t, "O")
    95  	defer ts.Done(t)
    96  
    97  	ts.AddAccount(t, "A")
    98  	ts.AddAccount(t, "B")
    99  
   100  	ts.AddExport(t, "A", jwt.Stream, "AA.>", 0, false)
   101  
   102  	token := ts.GenerateActivation(t, "A", "AA.>", "B")
   103  	tp := filepath.Join(ts.Dir, "token.jwt")
   104  	require.NoError(t, Write(tp, []byte(token)))
   105  
   106  	out, _, err := ExecuteCmd(createDescribeJwtCmd(), "--file", tp)
   107  	require.NoError(t, err)
   108  	require.Contains(t, out, "AA.>")
   109  
   110  	act, err := jwt.DecodeActivationClaims(token)
   111  	require.NoError(t, err)
   112  
   113  	hash, err := act.HashID()
   114  	require.NoError(t, err)
   115  	require.Contains(t, out, hash)
   116  }
   117  
   118  func TestDescribe_ActivationWithSigner(t *testing.T) {
   119  	ts := NewTestStore(t, "O")
   120  	defer ts.Done(t)
   121  
   122  	ts.AddAccount(t, "A")
   123  	ts.AddAccount(t, "B")
   124  
   125  	// generate an export, normally signed by the account
   126  	ts.AddExport(t, "A", jwt.Stream, "AA.>", 0, false)
   127  	token := ts.GenerateActivation(t, "A", "AA.>", "B")
   128  	tp := filepath.Join(ts.Dir, "token.jwt")
   129  	require.NoError(t, Write(tp, []byte(token)))
   130  	// verify that issuer account is not present
   131  	out, _, err := ExecuteCmd(createDescribeJwtCmd(), "--file", tp)
   132  	require.NoError(t, err)
   133  	require.NotContains(t, out, "Issuer Account")
   134  	// modify the account to have a signing key
   135  	_, pk, kp := CreateAccountKey(t)
   136  	_, _, err = ExecuteCmd(createEditAccount(), "-n", "A", "--sk", pk)
   137  	require.NoError(t, err)
   138  	// generate an export using the account signing key
   139  	token = ts.GenerateActivationWithSigner(t, "A", "AA.>", "B", kp)
   140  	tp2 := filepath.Join(ts.Dir, "token2.jwt")
   141  	require.NoError(t, Write(tp2, []byte(token)))
   142  	// verify that issuer account is present
   143  	out, _, err = ExecuteCmd(createDescribeJwtCmd(), "--file", tp2)
   144  	require.NoError(t, err)
   145  	require.Contains(t, out, "Issuer Account")
   146  }
   147  
   148  func TestDescribeJwt_Json(t *testing.T) {
   149  	ts := NewTestStore(t, "O")
   150  	defer ts.Done(t)
   151  
   152  	ts.AddAccount(t, "A")
   153  	fp := filepath.Join(ts.Store.Dir, "accounts", "A", "A.jwt")
   154  	t.Log(fp)
   155  
   156  	out, _, err := ExecuteCmd(rootCmd, "describe", "jwt", "--json", "--file", fp)
   157  	require.NoError(t, err)
   158  	m := make(map[string]interface{})
   159  	err = json.Unmarshal([]byte(out), &m)
   160  	require.NoError(t, err)
   161  	ac, err := ts.Store.ReadAccountClaim("A")
   162  	require.NoError(t, err)
   163  	require.Equal(t, ac.Subject, m["sub"])
   164  }
   165  
   166  func TestDescribeJwt_JsonPath(t *testing.T) {
   167  	ts := NewTestStore(t, "O")
   168  	defer ts.Done(t)
   169  
   170  	ts.AddAccount(t, "A")
   171  	fp := filepath.Join(ts.Store.Dir, "accounts", "A", "A.jwt")
   172  
   173  	out, _, err := ExecuteCmd(rootCmd, "describe", "jwt", "--json", "--file", fp, "--field", "sub")
   174  	require.NoError(t, err)
   175  	ac, err := ts.Store.ReadAccountClaim("A")
   176  	require.NoError(t, err)
   177  	require.Equal(t, fmt.Sprintf("\"%s\"\n", ac.Subject), out)
   178  }