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 }