github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/cmd/store/store_test.go (about) 1 /* 2 * 3 * * Copyright 2018-2019 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 store 19 20 import ( 21 "fmt" 22 "os" 23 "path/filepath" 24 "testing" 25 "time" 26 27 "github.com/nats-io/jwt/v2" 28 "github.com/nats-io/nkeys" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func MakeTempStore(t *testing.T, name string, kp nkeys.KeyPair) *Store { 33 p := MakeTempDir(t) 34 35 var nk *NamedKey 36 if kp != nil { 37 nk = &NamedKey{Name: name, KP: kp} 38 } 39 40 s, err := CreateStore(name, p, nk) 41 require.NoError(t, err) 42 require.NotNil(t, s) 43 return s 44 } 45 46 func MakeTempDir(t *testing.T) string { 47 p, err := os.MkdirTemp("", "store_test") 48 require.NoError(t, err) 49 return p 50 } 51 52 func CreateTestStoreForOperator(t *testing.T, name string, operator nkeys.KeyPair) *Store { 53 s := MakeTempStore(t, name, operator) 54 55 require.NotNil(t, s) 56 require.FileExists(t, filepath.Join(s.Dir, ".nsc")) 57 require.True(t, s.Has("", ".nsc")) 58 59 if operator != nil { 60 tokenName := fmt.Sprintf("%s.jwt", SafeName(name)) 61 require.FileExists(t, filepath.Join(s.Dir, tokenName)) 62 require.True(t, s.Has("", tokenName)) 63 } 64 65 for _, d := range standardDirs { 66 require.DirExists(t, filepath.Join(s.Dir, d)) 67 require.True(t, s.Has(d, "")) 68 } 69 return s 70 } 71 72 func CreateTestStore(t *testing.T, name string) *Store { 73 var kp nkeys.KeyPair 74 _, _, kp = CreateOperatorKey(t) 75 return CreateTestStoreForOperator(t, name, kp) 76 } 77 78 func TestCreateStoreFailsOnNonEmptyDir(t *testing.T) { 79 p := MakeTempDir(t) 80 fp := filepath.Join(p, "test") 81 require.NoError(t, os.WriteFile(fp, []byte("hello"), 0666)) 82 83 _, _, kp := CreateAccountKey(t) 84 _, err := CreateStore("foo", p, &NamedKey{Name: "foo", KP: kp}) 85 require.Error(t, err) 86 } 87 88 func TestUnsupportedKeyType(t *testing.T) { 89 p := MakeTempDir(t) 90 fp := filepath.Join(p, "test") 91 require.NoError(t, os.WriteFile(fp, []byte("hello"), 0666)) 92 93 kp, err := nkeys.CreateServer() 94 require.NoError(t, err) 95 96 _, err = CreateStore("foo", p, &NamedKey{Name: "foo", KP: kp}) 97 require.Error(t, err) 98 } 99 100 func TestOperatorLoadStore(t *testing.T) { 101 s := CreateTestStore(t, "test-account") 102 ss, err := LoadStore(s.Dir) 103 require.NoError(t, err) 104 require.NotNil(t, ss) 105 require.Equal(t, s.Dir, ss.Dir) 106 } 107 108 func TestCreateOperatorStore(t *testing.T) { 109 CreateTestStore(t, "test-operator") 110 } 111 112 func TestWriteFile(t *testing.T) { 113 s := CreateTestStore(t, "test-account") 114 err := s.Write([]byte("foo"), Users, "foo") 115 require.NoError(t, err) 116 117 fp := filepath.Join(s.Dir, Users, "foo") 118 require.FileExists(t, fp) 119 } 120 121 func TestReadFile(t *testing.T) { 122 s := CreateTestStore(t, "test-account") 123 err := s.Write([]byte("foo"), Users, "foo") 124 require.NoError(t, err) 125 126 fp := filepath.Join(s.Dir, Users, "foo") 127 require.FileExists(t, fp) 128 129 d, err := s.Read(Users, "foo") 130 require.NoError(t, err) 131 require.Equal(t, "foo", string(d)) 132 } 133 134 func TestListFiles(t *testing.T) { 135 s := CreateTestStore(t, "test-account") 136 err := s.Write([]byte("foo"), Users, "foo") 137 require.NoError(t, err) 138 139 err = s.Write([]byte("bar"), Users, "bar") 140 require.NoError(t, err) 141 142 infos, err := s.List(Users, "") 143 require.NoError(t, err) 144 145 var names []string 146 for _, i := range infos { 147 names = append(names, i.Name()) 148 } 149 require.ElementsMatch(t, names, []string{"foo", "bar"}) 150 } 151 152 func TestDeleteFile(t *testing.T) { 153 s := CreateTestStore(t, "test-account") 154 err := s.Write([]byte("foo"), Users, "foo") 155 require.NoError(t, err) 156 157 fp := filepath.Join(s.Dir, Users, "foo") 158 require.FileExists(t, fp) 159 160 err = s.Delete(Users, "foo") 161 require.NoError(t, err) 162 require.False(t, s.Has(Users, "foo")) 163 } 164 165 func TestLoadOperator(t *testing.T) { 166 s := CreateTestStore(t, "x") 167 require.True(t, s.Has(JwtName("x"))) 168 c, err := s.LoadRootClaim() 169 require.NoError(t, err) 170 require.NotNil(t, c) 171 } 172 173 func TestStoreOperator(t *testing.T) { 174 _, _, kp := CreateOperatorKey(t) 175 s := CreateTestStoreForOperator(t, "x", kp) 176 c, err := s.LoadClaim("x.jwt") 177 require.NoError(t, err) 178 require.NotNil(t, c) 179 exp := time.Now().Unix() + 5 180 require.Zero(t, c.Expires) 181 182 c.Expires = exp 183 token, err := c.Encode(kp) 184 require.NoError(t, err) 185 186 _, err = s.StoreClaim([]byte(token)) 187 require.NoError(t, err) 188 c, err = s.LoadClaim("x.jwt") 189 require.NoError(t, err) 190 require.Equal(t, c.Expires, exp) 191 } 192 193 func TestStoreAccount(t *testing.T) { 194 _, _, kp := CreateOperatorKey(t) 195 _, apub, _ := CreateAccountKey(t) 196 s := CreateTestStoreForOperator(t, "x", kp) 197 198 c := jwt.NewAccountClaims(apub) 199 c.Name = "foo" 200 cd, err := c.Encode(kp) 201 require.NoError(t, err) 202 _, err = s.StoreClaim([]byte(cd)) 203 require.NoError(t, err) 204 205 gc, err := s.LoadClaim(Accounts, "foo", "foo.jwt") 206 require.NoError(t, err) 207 require.NotNil(t, gc) 208 require.Equal(t, gc.Name, "foo") 209 } 210 211 func TestStoreAccountWithSigningKey(t *testing.T) { 212 _, _, kp := CreateOperatorKey(t) 213 _, apub, _ := CreateAccountKey(t) 214 s := CreateTestStoreForOperator(t, "x", kp) 215 oc, err := s.ReadOperatorClaim() 216 require.NoError(t, err) 217 218 _, spk1, skp1 := CreateOperatorKey(t) 219 _, spk2, _ := CreateOperatorKey(t) 220 oc.SigningKeys.Add(spk1, spk2) 221 cd, err := oc.Encode(kp) 222 require.NoError(t, err) 223 _, err = s.StoreClaim([]byte(cd)) 224 require.NoError(t, err) 225 226 oc, err = s.ReadOperatorClaim() 227 require.NoError(t, err) 228 require.Contains(t, oc.SigningKeys, spk1) 229 require.Contains(t, oc.SigningKeys, spk2) 230 231 c := jwt.NewAccountClaims(apub) 232 c.Name = "foo" 233 cd, err = c.Encode(skp1) 234 require.NoError(t, err) 235 _, err = s.StoreClaim([]byte(cd)) 236 require.NoError(t, err) 237 238 gc, err := s.LoadClaim(Accounts, "foo", "foo.jwt") 239 require.NoError(t, err) 240 require.NotNil(t, gc) 241 require.Equal(t, gc.Name, "foo") 242 require.True(t, oc.DidSign(gc)) 243 } 244 245 func TestStoreUser(t *testing.T) { 246 _, _, kp := CreateOperatorKey(t) 247 _, apub, akp := CreateAccountKey(t) 248 _, upub, _ := CreateUserKey(t) 249 250 s := CreateTestStoreForOperator(t, "x", kp) 251 252 ac := jwt.NewAccountClaims(apub) 253 ac.Name = "foo" 254 cd, err := ac.Encode(kp) 255 require.NoError(t, err) 256 _, err = s.StoreClaim([]byte(cd)) 257 require.NoError(t, err) 258 259 uc := jwt.NewUserClaims(upub) 260 uc.Name = "bar" 261 ud, err := uc.Encode(akp) 262 require.NoError(t, err) 263 264 _, err = s.StoreClaim([]byte(ud)) 265 require.NoError(t, err) 266 267 gc, err := s.LoadClaim(Accounts, "foo", Users, "bar.jwt") 268 require.NoError(t, err) 269 require.NotNil(t, gc) 270 require.Equal(t, gc.Name, "bar") 271 } 272 273 func TestStoreUserWithSigningKeys(t *testing.T) { 274 _, _, kp := CreateOperatorKey(t) 275 _, apub, _ := CreateAccountKey(t) 276 _, spub, sakp := CreateAccountKey(t) 277 _, upub, _ := CreateUserKey(t) 278 279 s := CreateTestStoreForOperator(t, "x", kp) 280 281 ac := jwt.NewAccountClaims(apub) 282 ac.Name = "foo" 283 ac.SigningKeys.Add(spub) 284 cd, err := ac.Encode(kp) 285 require.NoError(t, err) 286 _, err = s.StoreClaim([]byte(cd)) 287 require.NoError(t, err) 288 289 uc := jwt.NewUserClaims(upub) 290 uc.Name = "bar" 291 uc.IssuerAccount = apub 292 ud, err := uc.Encode(sakp) 293 require.NoError(t, err) 294 _, err = s.StoreClaim([]byte(ud)) 295 require.NoError(t, err) 296 297 gc, err := s.LoadClaim(Accounts, "foo", Users, "bar.jwt") 298 require.NoError(t, err) 299 require.NotNil(t, gc) 300 require.Equal(t, gc.Name, "bar") 301 require.True(t, ac.DidSign(uc)) 302 } 303 304 func TestStore_ListSubContainers(t *testing.T) { 305 _, _, kp := CreateOperatorKey(t) 306 _, apub, akp := CreateAccountKey(t) 307 _, upub, _ := CreateUserKey(t) 308 309 s := CreateTestStoreForOperator(t, "store", kp) 310 311 ac := jwt.NewAccountClaims(apub) 312 ac.Name = "foo" 313 cd, err := ac.Encode(kp) 314 require.NoError(t, err) 315 rs, err := s.StoreClaim([]byte(cd)) 316 require.NoError(t, err) 317 require.Nil(t, rs) 318 319 uc := jwt.NewUserClaims(upub) 320 uc.Name = "bar" 321 ud, err := uc.Encode(akp) 322 require.NoError(t, err) 323 324 _, err = s.StoreClaim([]byte(ud)) 325 require.NoError(t, err) 326 327 v, err := s.ListEntries(Accounts, "foo", Users) 328 require.NoError(t, err) 329 require.NotNil(t, v) 330 require.Len(t, v, 1) 331 require.Equal(t, "bar", v[0]) 332 } 333 334 func TestStore_GetAccountKeys(t *testing.T) { 335 _, _, kp := CreateOperatorKey(t) 336 _, apub, _ := CreateAccountKey(t) 337 338 s := CreateTestStoreForOperator(t, "O", kp) 339 340 ctx, err := s.GetContext() 341 require.NoError(t, err) 342 343 keys, err := ctx.GetAccountKeys("A") 344 require.NoError(t, err) 345 require.Nil(t, keys) 346 347 ac := jwt.NewAccountClaims(apub) 348 ac.Name = "A" 349 cd, err := ac.Encode(kp) 350 require.NoError(t, err) 351 rs, err := s.StoreClaim([]byte(cd)) 352 require.NoError(t, err) 353 require.Nil(t, rs) 354 355 keys, err = ctx.GetAccountKeys("A") 356 require.NoError(t, err) 357 require.Len(t, keys, 1) 358 require.Contains(t, keys, apub) 359 360 _, apub2, _ := CreateAccountKey(t) 361 ac.SigningKeys.Add(apub2) 362 cd, err = ac.Encode(kp) 363 require.NoError(t, err) 364 rs, err = s.StoreClaim([]byte(cd)) 365 require.NoError(t, err) 366 require.Nil(t, rs) 367 368 keys, err = ctx.GetAccountKeys("A") 369 require.NoError(t, err) 370 require.Len(t, keys, 2) 371 require.Equal(t, apub, keys[0]) 372 require.Equal(t, apub2, keys[1]) 373 }