github.com/nats-io/nsc/v2@v2.8.7-0.20240307184528-efd7023c6896/cmd/expirations_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  	"testing"
    21  	"time"
    22  
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func Test_ExpirationsNone(t *testing.T) {
    27  	ts := NewTestStore(t, "O")
    28  	defer ts.Done(t)
    29  
    30  	ts.AddAccount(t, "A")
    31  	ts.AddUser(t, "A", "U")
    32  
    33  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
    34  	require.NoError(t, err)
    35  
    36  	var expirations ExpirationReportJSON
    37  	err = json.Unmarshal([]byte(stdout), &expirations)
    38  	require.NoError(t, err)
    39  	_, err = time.Parse(time.RFC3339, expirations.ExpirationThreshold)
    40  	require.NoError(t, err)
    41  	require.Len(t, expirations.Report, 4)
    42  }
    43  
    44  func Test_ExpirationsOperator(t *testing.T) {
    45  	ts := NewTestStore(t, "O")
    46  	defer ts.Done(t)
    47  
    48  	oc, err := ts.Store.ReadOperatorClaim()
    49  	require.NoError(t, err)
    50  	// an hour ago
    51  	oc.Expires = time.Now().Add(-time.Hour).UTC().Unix()
    52  	token, err := oc.Encode(ts.OperatorKey)
    53  	require.NoError(t, err)
    54  	err = ts.Store.StoreRaw([]byte(token))
    55  	require.NoError(t, err)
    56  
    57  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
    58  	require.NoError(t, err)
    59  
    60  	var expirations ExpirationReportJSON
    61  	err = json.Unmarshal([]byte(stdout), &expirations)
    62  	require.NoError(t, err)
    63  	require.Len(t, expirations.Report, 1)
    64  	require.True(t, expirations.Report[0].Expired)
    65  }
    66  
    67  func Test_ExpirationAccount(t *testing.T) {
    68  	ts := NewTestStore(t, "O")
    69  	defer ts.Done(t)
    70  
    71  	ts.AddAccount(t, "A")
    72  	ac, err := ts.Store.ReadAccountClaim("A")
    73  	require.NoError(t, err)
    74  	ac.Expires = time.Now().Add(-time.Minute).UTC().Unix()
    75  	token, err := ac.Encode(ts.GetAccountKey(t, "A"))
    76  	require.NoError(t, err)
    77  	err = ts.Store.StoreRaw([]byte(token))
    78  	require.NoError(t, err)
    79  
    80  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
    81  	require.NoError(t, err)
    82  
    83  	var expirations ExpirationReportJSON
    84  	err = json.Unmarshal([]byte(stdout), &expirations)
    85  	require.NoError(t, err)
    86  	require.Len(t, expirations.Report, 2)
    87  	require.False(t, expirations.Report[0].Expired)
    88  	require.True(t, expirations.Report[1].Expired)
    89  }
    90  
    91  func Test_ExpirationUser(t *testing.T) {
    92  	ts := NewTestStore(t, "O")
    93  	defer ts.Done(t)
    94  
    95  	ts.AddAccount(t, "A")
    96  	ts.AddUser(t, "A", "U")
    97  	uc, err := ts.Store.ReadUserClaim("A", "U")
    98  	require.NoError(t, err)
    99  	uc.Expires = time.Now().Add(-time.Minute).UTC().Unix()
   100  	token, err := uc.Encode(ts.GetAccountKey(t, "A"))
   101  	require.NoError(t, err)
   102  	err = ts.Store.StoreRaw([]byte(token))
   103  	require.NoError(t, err)
   104  
   105  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
   106  	require.NoError(t, err)
   107  
   108  	var expirations ExpirationReportJSON
   109  	err = json.Unmarshal([]byte(stdout), &expirations)
   110  	require.NoError(t, err)
   111  	require.Len(t, expirations.Report, 4)
   112  	require.False(t, expirations.Report[0].Expired)
   113  	require.False(t, expirations.Report[1].Expired)
   114  	require.True(t, expirations.Report[2].Expired)
   115  	// we didn't update the creds
   116  	require.False(t, expirations.Report[3].Expired)
   117  }
   118  
   119  func Test_ExpiresSoonOperator(t *testing.T) {
   120  	ts := NewTestStore(t, "O")
   121  	defer ts.Done(t)
   122  
   123  	oc, err := ts.Store.ReadOperatorClaim()
   124  	require.NoError(t, err)
   125  	// an hour ago
   126  	oc.Expires = time.Now().Add(time.Hour * 24 * 7).UTC().Unix()
   127  	token, err := oc.Encode(ts.OperatorKey)
   128  	require.NoError(t, err)
   129  	err = ts.Store.StoreRaw([]byte(token))
   130  	require.NoError(t, err)
   131  
   132  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
   133  	require.NoError(t, err)
   134  
   135  	var expirations ExpirationReportJSON
   136  	err = json.Unmarshal([]byte(stdout), &expirations)
   137  	require.NoError(t, err)
   138  	require.Len(t, expirations.Report, 1)
   139  	require.False(t, expirations.Report[0].Expired)
   140  	require.True(t, expirations.Report[0].ExpiresSoon)
   141  }
   142  
   143  func Test_ExpiresSoonAccount(t *testing.T) {
   144  	ts := NewTestStore(t, "O")
   145  	defer ts.Done(t)
   146  
   147  	ts.AddAccount(t, "A")
   148  	ac, err := ts.Store.ReadAccountClaim("A")
   149  	require.NoError(t, err)
   150  	ac.Expires = time.Now().Add(time.Minute * 2).UTC().Unix()
   151  	token, err := ac.Encode(ts.GetAccountKey(t, "A"))
   152  	require.NoError(t, err)
   153  	err = ts.Store.StoreRaw([]byte(token))
   154  	require.NoError(t, err)
   155  
   156  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
   157  	require.NoError(t, err)
   158  
   159  	var expirations ExpirationReportJSON
   160  	err = json.Unmarshal([]byte(stdout), &expirations)
   161  	require.NoError(t, err)
   162  	require.Len(t, expirations.Report, 2)
   163  	require.False(t, expirations.Report[0].Expired)
   164  	require.False(t, expirations.Report[1].Expired)
   165  	require.True(t, expirations.Report[1].ExpiresSoon)
   166  }
   167  
   168  func Test_ExpiresSoonUser(t *testing.T) {
   169  	ts := NewTestStore(t, "O")
   170  	defer ts.Done(t)
   171  
   172  	ts.AddAccount(t, "A")
   173  	ts.AddUser(t, "A", "U")
   174  	uc, err := ts.Store.ReadUserClaim("A", "U")
   175  	require.NoError(t, err)
   176  	uc.Expires = time.Now().Add(time.Hour).UTC().Unix()
   177  	token, err := uc.Encode(ts.GetAccountKey(t, "A"))
   178  	require.NoError(t, err)
   179  	err = ts.Store.StoreRaw([]byte(token))
   180  	require.NoError(t, err)
   181  
   182  	creds, err := GenerateConfig(ts.Store, "A", "U", ts.GetUserKey(t, "A", "U"))
   183  	require.NoError(t, err)
   184  	_, err = ts.KeyStore.MaybeStoreUserCreds("A", "U", creds)
   185  	require.NoError(t, err)
   186  
   187  	stdout, _, err := ExecuteCmd(createExpirationsCommand(), "--json")
   188  	require.NoError(t, err)
   189  
   190  	var expirations ExpirationReportJSON
   191  	err = json.Unmarshal([]byte(stdout), &expirations)
   192  	require.NoError(t, err)
   193  	require.Len(t, expirations.Report, 4)
   194  	require.False(t, expirations.Report[0].Expired)
   195  	require.False(t, expirations.Report[1].Expired)
   196  	require.False(t, expirations.Report[2].Expired)
   197  	require.True(t, expirations.Report[2].ExpiresSoon)
   198  	require.False(t, expirations.Report[3].Expired)
   199  	require.True(t, expirations.Report[3].ExpiresSoon)
   200  	require.False(t, expirations.Report[3].Expired)
   201  
   202  	stdout, _, err = ExecuteCmd(createExpirationsCommand(), "--skip", "--json")
   203  	require.NoError(t, err)
   204  	err = json.Unmarshal([]byte(stdout), &expirations)
   205  	require.NoError(t, err)
   206  	require.Len(t, expirations.Report, 2)
   207  	require.Equal(t, expirations.Report[0].ID, uc.Subject)
   208  	require.True(t, expirations.Report[0].ExpiresSoon)
   209  	require.False(t, expirations.Report[0].Expired)
   210  	require.Equal(t, expirations.Report[1].ID, uc.Subject)
   211  	require.True(t, expirations.Report[1].ExpiresSoon)
   212  	require.False(t, expirations.Report[1].Expired)
   213  }
   214  
   215  func Test_ExpirationsTable(t *testing.T) {
   216  	ts := NewTestStore(t, "O")
   217  	defer ts.Done(t)
   218  
   219  	ts.AddAccount(t, "A")
   220  	ts.AddUser(t, "A", "U")
   221  	uc, err := ts.Store.ReadUserClaim("A", "U")
   222  	require.NoError(t, err)
   223  	uc.Expires = time.Now().Add(time.Hour).UTC().Unix()
   224  	token, err := uc.Encode(ts.GetAccountKey(t, "A"))
   225  	require.NoError(t, err)
   226  	err = ts.Store.StoreRaw([]byte(token))
   227  	require.NoError(t, err)
   228  
   229  	_, stderr, err := ExecuteCmd(createExpirationsCommand())
   230  	require.NoError(t, err)
   231  
   232  	require.Contains(t, stderr, "| O")
   233  	require.Contains(t, stderr, "| O/A")
   234  	require.Contains(t, stderr, "| Soon    | O/A/U")
   235  	require.Contains(t, stderr, "In 59 Minutes |")
   236  	require.Contains(t, stderr, "creds/O/A/U.creds")
   237  }