github.com/nats-io/jwt/v2@v2.5.6/v1compat/operator_claims_test.go (about)

     1  /*
     2   * Copyright 2018 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 jwt
    17  
    18  import (
    19  	"fmt"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/nats-io/nkeys"
    24  )
    25  
    26  func TestNewOperatorClaims(t *testing.T) {
    27  	ckp := createOperatorNKey(t)
    28  
    29  	uc := NewOperatorClaims(publicKey(ckp, t))
    30  	uc.Expires = time.Now().Add(time.Duration(time.Hour)).Unix()
    31  	uJwt := encode(uc, ckp, t)
    32  
    33  	uc2, err := DecodeOperatorClaims(uJwt)
    34  	if err != nil {
    35  		t.Fatal("failed to decode", err)
    36  	}
    37  
    38  	AssertEquals(uc.String(), uc2.String(), t)
    39  
    40  	AssertEquals(uc.Claims() != nil, true, t)
    41  	AssertEquals(uc.Payload() != nil, true, t)
    42  }
    43  
    44  func TestOperatorSubjects(t *testing.T) {
    45  	type kpInputs struct {
    46  		name string
    47  		kp   nkeys.KeyPair
    48  		ok   bool
    49  	}
    50  
    51  	inputs := []kpInputs{
    52  		{"account", createAccountNKey(t), false},
    53  		{"cluster", createClusterNKey(t), false},
    54  		{"operator", createOperatorNKey(t), true},
    55  		{"server", createServerNKey(t), false},
    56  		{"user", createUserNKey(t), false},
    57  	}
    58  
    59  	for _, i := range inputs {
    60  		c := NewOperatorClaims(publicKey(i.kp, t))
    61  		_, err := c.Encode(createOperatorNKey(t))
    62  		if i.ok && err != nil {
    63  			t.Fatalf("unexpected error for %q: %v", i.name, err)
    64  		}
    65  		if !i.ok && err == nil {
    66  			t.Logf("should have failed to encode server with with %q subject", i.name)
    67  			t.Fail()
    68  		}
    69  	}
    70  }
    71  
    72  func TestInvalidOperatorClaimIssuer(t *testing.T) {
    73  	akp := createOperatorNKey(t)
    74  	ac := NewOperatorClaims(publicKey(akp, t))
    75  	ac.Expires = time.Now().Add(time.Duration(time.Hour)).Unix()
    76  	aJwt := encode(ac, akp, t)
    77  
    78  	temp, err := DecodeGeneric(aJwt)
    79  	if err != nil {
    80  		t.Fatal("failed to decode", err)
    81  	}
    82  
    83  	type kpInputs struct {
    84  		name string
    85  		kp   nkeys.KeyPair
    86  		ok   bool
    87  	}
    88  
    89  	inputs := []kpInputs{
    90  		{"account", createAccountNKey(t), false},
    91  		{"user", createUserNKey(t), false},
    92  		{"operator", createOperatorNKey(t), true},
    93  		{"server", createServerNKey(t), false},
    94  		{"cluster", createClusterNKey(t), false},
    95  	}
    96  
    97  	for _, i := range inputs {
    98  		bad := encode(temp, i.kp, t)
    99  		_, err = DecodeOperatorClaims(bad)
   100  		if i.ok && err != nil {
   101  			t.Fatalf("unexpected error for %q: %v", i.name, err)
   102  		}
   103  		if !i.ok && err == nil {
   104  			t.Logf("should have failed to decode account signed by %q", i.name)
   105  			t.Fail()
   106  		}
   107  	}
   108  }
   109  
   110  func TestNewNilOperatorClaims(t *testing.T) {
   111  	v := NewOperatorClaims("")
   112  	if v != nil {
   113  		t.Fatal("expected nil user claim")
   114  	}
   115  }
   116  
   117  func TestOperatorType(t *testing.T) {
   118  	c := NewOperatorClaims(publicKey(createOperatorNKey(t), t))
   119  	s := encode(c, createOperatorNKey(t), t)
   120  	u, err := DecodeOperatorClaims(s)
   121  	if err != nil {
   122  		t.Fatalf("failed to decode operator claim: %v", err)
   123  	}
   124  
   125  	if OperatorClaim != u.Type {
   126  		t.Fatalf("type is unexpected %q (wanted operator)", u.Type)
   127  	}
   128  
   129  }
   130  
   131  func TestSigningKeyValidation(t *testing.T) {
   132  	ckp := createOperatorNKey(t)
   133  	ckp2 := createOperatorNKey(t)
   134  
   135  	uc := NewOperatorClaims(publicKey(ckp, t))
   136  	uc.Expires = time.Now().Add(time.Duration(time.Hour)).Unix()
   137  	uc.AddSigningKey(publicKey(ckp2, t))
   138  	uJwt := encode(uc, ckp, t)
   139  
   140  	uc2, err := DecodeOperatorClaims(uJwt)
   141  	if err != nil {
   142  		t.Fatal("failed to decode", err)
   143  	}
   144  
   145  	AssertEquals(len(uc2.SigningKeys), 1, t)
   146  	AssertEquals(uc2.SigningKeys[0] == publicKey(ckp2, t), true, t)
   147  
   148  	vr := &ValidationResults{}
   149  	uc.Validate(vr)
   150  
   151  	if len(vr.Issues) != 0 {
   152  		t.Fatal("valid operator key should have no validation issues")
   153  	}
   154  
   155  	uc.AddSigningKey("") // add an invalid one
   156  
   157  	vr = &ValidationResults{}
   158  	uc.Validate(vr)
   159  	if len(vr.Issues) != 0 {
   160  		t.Fatal("should not be able to add empty values")
   161  	}
   162  }
   163  
   164  func TestSignedBy(t *testing.T) {
   165  	ckp := createOperatorNKey(t)
   166  	ckp2 := createOperatorNKey(t)
   167  
   168  	uc := NewOperatorClaims(publicKey(ckp, t))
   169  	uc2 := NewOperatorClaims(publicKey(ckp2, t))
   170  
   171  	akp := createAccountNKey(t)
   172  	ac := NewAccountClaims(publicKey(akp, t))
   173  	enc, err := ac.Encode(ckp) // sign with the operator key
   174  	if err != nil {
   175  		t.Fatal("failed to encode", err)
   176  	}
   177  	ac, err = DecodeAccountClaims(enc)
   178  	if err != nil {
   179  		t.Fatal("failed to decode", err)
   180  	}
   181  
   182  	AssertEquals(uc.DidSign(ac), true, t)
   183  	AssertEquals(uc2.DidSign(ac), false, t)
   184  
   185  	enc, err = ac.Encode(ckp2) // sign with the other operator key
   186  	if err != nil {
   187  		t.Fatal("failed to encode", err)
   188  	}
   189  	ac, err = DecodeAccountClaims(enc)
   190  	if err != nil {
   191  		t.Fatal("failed to decode", err)
   192  	}
   193  
   194  	AssertEquals(uc.DidSign(ac), false, t) // no signing key
   195  	AssertEquals(uc2.DidSign(ac), true, t) // actual key
   196  	uc.AddSigningKey(publicKey(ckp2, t))
   197  	AssertEquals(uc.DidSign(ac), true, t) // signing key
   198  
   199  	clusterKey := createClusterNKey(t)
   200  	clusterClaims := NewClusterClaims(publicKey(clusterKey, t))
   201  	enc, err = clusterClaims.Encode(ckp2) // sign with the operator key
   202  	if err != nil {
   203  		t.Fatal("failed to encode", err)
   204  	}
   205  	clusterClaims, err = DecodeClusterClaims(enc)
   206  	if err != nil {
   207  		t.Fatal("failed to decode", err)
   208  	}
   209  
   210  	AssertEquals(uc.DidSign(clusterClaims), true, t)  // signing key
   211  	AssertEquals(uc2.DidSign(clusterClaims), true, t) // actual key
   212  }
   213  
   214  func testAccountWithAccountServerURL(t *testing.T, u string) error {
   215  	kp := createOperatorNKey(t)
   216  	pk := publicKey(kp, t)
   217  	oc := NewOperatorClaims(pk)
   218  	oc.AccountServerURL = u
   219  
   220  	s, err := oc.Encode(kp)
   221  	if err != nil {
   222  		return err
   223  	}
   224  	oc, err = DecodeOperatorClaims(s)
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  	AssertEquals(oc.AccountServerURL, u, t)
   229  	vr := ValidationResults{}
   230  	oc.Validate(&vr)
   231  	if !vr.IsEmpty() {
   232  		errs := vr.Errors()
   233  		return errs[0]
   234  	}
   235  	return nil
   236  }
   237  
   238  func Test_SystemAccount(t *testing.T) {
   239  	operatorWithSystemAcc := func(t *testing.T, u string) error {
   240  		kp := createOperatorNKey(t)
   241  		pk := publicKey(kp, t)
   242  		oc := NewOperatorClaims(pk)
   243  		oc.SystemAccount = u
   244  		s, err := oc.Encode(kp)
   245  		if err != nil {
   246  			return err
   247  		}
   248  		oc, err = DecodeOperatorClaims(s)
   249  		if err != nil {
   250  			t.Fatal(err)
   251  		}
   252  		AssertEquals(oc.SystemAccount, u, t)
   253  		vr := ValidationResults{}
   254  		oc.Validate(&vr)
   255  		if !vr.IsEmpty() {
   256  			return fmt.Errorf("%s", vr.Errors()[0])
   257  		}
   258  		return nil
   259  	}
   260  	var asuTests = []struct {
   261  		accKey     string
   262  		shouldFail bool
   263  	}{
   264  		{"", false},
   265  		{"x", true},
   266  		{"ADZ547B24WHPLWOK7TMLNBSA7FQFXR6UM2NZ4HHNIB7RDFVZQFOZ4GQQ", false},
   267  		{"ADZ547B24WHPLWOK7TMLNBSA7FQFXR6UM2NZ4HHNIB7RDFVZQFOZ4777", true},
   268  	}
   269  	for i, tt := range asuTests {
   270  		err := operatorWithSystemAcc(t, tt.accKey)
   271  		if err != nil && tt.shouldFail == false {
   272  			t.Fatalf("expected not to fail: %v", err)
   273  		} else if err == nil && tt.shouldFail {
   274  			t.Fatalf("test %s expected to fail but didn't", asuTests[i].accKey)
   275  		}
   276  	}
   277  }
   278  
   279  func Test_AccountServerURL(t *testing.T) {
   280  	var asuTests = []struct {
   281  		u          string
   282  		shouldFail bool
   283  	}{
   284  		{"", false},
   285  		{"HTTP://foo.bar.com", false},
   286  		{"http://foo.bar.com/foo/bar", false},
   287  		{"http://user:pass@foo.bar.com/foo/bar", false},
   288  		{"https://foo.bar.com", false},
   289  		{"nats://foo.bar.com", false},
   290  		{"/hello", true},
   291  	}
   292  
   293  	for i, tt := range asuTests {
   294  		err := testAccountWithAccountServerURL(t, tt.u)
   295  		if err != nil && tt.shouldFail == false {
   296  			t.Fatalf("expected not to fail: %v", err)
   297  		} else if err == nil && tt.shouldFail {
   298  			t.Fatalf("test %s expected to fail but didn't", asuTests[i].u)
   299  		}
   300  	}
   301  }
   302  
   303  func testOperatorWithOperatorServiceURL(t *testing.T, u string) error {
   304  	kp := createOperatorNKey(t)
   305  	pk := publicKey(kp, t)
   306  	oc := NewOperatorClaims(pk)
   307  	oc.OperatorServiceURLs.Add(u)
   308  
   309  	s, err := oc.Encode(kp)
   310  	if err != nil {
   311  		return err
   312  	}
   313  	oc, err = DecodeOperatorClaims(s)
   314  	if err != nil {
   315  		t.Fatal(err)
   316  	}
   317  	if u != "" {
   318  		AssertEquals(oc.OperatorServiceURLs[0], u, t)
   319  	}
   320  	vr := ValidationResults{}
   321  	oc.Validate(&vr)
   322  	if !vr.IsEmpty() {
   323  		errs := vr.Errors()
   324  		return errs[0]
   325  	}
   326  	return nil
   327  }
   328  
   329  func Test_OperatorServiceURL(t *testing.T) {
   330  	var asuTests = []struct {
   331  		u          string
   332  		shouldFail bool
   333  	}{
   334  		{"", false},
   335  		{"HTTP://foo.bar.com", true},
   336  		{"http://foo.bar.com/foo/bar", true},
   337  		{"nats://user:pass@foo.bar.com", true},
   338  		{"NATS://user:pass@foo.bar.com", true},
   339  		{"NATS://user@foo.bar.com", true},
   340  		{"nats://foo.bar.com/path", true},
   341  		{"tls://foo.bar.com/path", true},
   342  		{"/hello", true},
   343  		{"NATS://foo.bar.com", false},
   344  		{"TLS://foo.bar.com", false},
   345  		{"nats://foo.bar.com", false},
   346  		{"tls://foo.bar.com", false},
   347  	}
   348  
   349  	for i, tt := range asuTests {
   350  		err := testOperatorWithOperatorServiceURL(t, tt.u)
   351  		if err != nil && tt.shouldFail == false {
   352  			t.Fatalf("expected not to fail: %v", err)
   353  		} else if err == nil && tt.shouldFail {
   354  			t.Fatalf("test %s expected to fail but didn't", asuTests[i].u)
   355  		}
   356  	}
   357  
   358  	// now test all of them in a single jwt
   359  	kp := createOperatorNKey(t)
   360  	pk := publicKey(kp, t)
   361  	oc := NewOperatorClaims(pk)
   362  
   363  	encoded := 0
   364  	shouldFail := 0
   365  	for _, v := range asuTests {
   366  		oc.OperatorServiceURLs.Add(v.u)
   367  		// list won't encode empty strings
   368  		if v.u != "" {
   369  			encoded++
   370  		}
   371  		if v.shouldFail {
   372  			shouldFail++
   373  		}
   374  	}
   375  
   376  	s, err := oc.Encode(kp)
   377  	if err != nil {
   378  		t.Fatal(err)
   379  	}
   380  	oc, err = DecodeOperatorClaims(s)
   381  	if err != nil {
   382  		t.Fatal(err)
   383  	}
   384  
   385  	AssertEquals(len(oc.OperatorServiceURLs), encoded, t)
   386  
   387  	vr := ValidationResults{}
   388  	oc.Validate(&vr)
   389  	if vr.IsEmpty() {
   390  		t.Fatal("should have had errors")
   391  	}
   392  
   393  	errs := vr.Errors()
   394  	AssertEquals(len(errs), shouldFail, t)
   395  }
   396  
   397  func Test_ForwardCompatibility(t *testing.T) {
   398  	newOp := `eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJTSUYyR0ZRSEhWWUtDQlZYRklYUURYV1FCQUcyWEw3SVZLVVJZT0ZTWlhVT0tTRUpLWDdBIiwiaWF0IjoxNTkwNTI0NTAwLCJpc3MiOiJPQlQ2REtGSzQ2STM3TjdCUkwyUkpMVVJLWUdSQTZBWVJQREFISFFFQUFBR05ZWExNR1JEUEtMQyIsInN1YiI6Ik9CVDZES0ZLNDZJMzdON0JSTDJSSkxVUktZR1JBNkFZUlBEQUhIUUVBQUFHTllYTE1HUkRQS0xDIiwibmF0cyI6eyJ0YWdzIjpbIm9uZSIsInR3byIsInRocmVlIl0sInR5cGUiOiJvcGVyYXRvciIsInZlcnNpb24iOjJ9fQ.u6JFiISIh2o-CWxktfEw3binmCLhLaFVMyuIa2HNo_x_6EGWVPVICVWc_MOLFS-6Nm17Cj4SmOh3zUtlTRkfDA`
   399  	if _, err := DecodeOperatorClaims(newOp); err == nil {
   400  		t.Fatal("Expected error")
   401  	} else if err.Error() != `more recent jwt version` {
   402  		t.Fatal("Expected different error, got: ", err)
   403  	}
   404  }