github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/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/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.>", 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.>", 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 }