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

     1  /*
     2   * Copyright 2018-2020 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  	"testing"
    20  	"time"
    21  
    22  	"github.com/nats-io/nkeys"
    23  )
    24  
    25  func TestNewUserClaims(t *testing.T) {
    26  	akp := createAccountNKey(t)
    27  	ukp := createUserNKey(t)
    28  
    29  	uc := NewUserClaims(publicKey(ukp, t))
    30  	uc.Expires = time.Now().Add(time.Duration(time.Hour)).Unix()
    31  	uJwt := encode(uc, akp, t)
    32  
    33  	uc2, err := DecodeUserClaims(uJwt)
    34  	if err != nil {
    35  		t.Fatal("failed to decode uc", 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 TestUserClaimIssuer(t *testing.T) {
    45  	akp := createAccountNKey(t)
    46  	ukp := createUserNKey(t)
    47  
    48  	uc := NewUserClaims(publicKey(ukp, t))
    49  	uc.Expires = time.Now().Add(time.Duration(time.Hour)).Unix()
    50  	uJwt := encode(uc, akp, t)
    51  
    52  	temp, err := DecodeGeneric(uJwt)
    53  	if err != nil {
    54  		t.Fatal("failed to decode", err)
    55  	}
    56  
    57  	type kpInputs struct {
    58  		name string
    59  		kp   nkeys.KeyPair
    60  		ok   bool
    61  	}
    62  
    63  	inputs := []kpInputs{
    64  		{"account", createAccountNKey(t), true},
    65  		{"user", createUserNKey(t), false},
    66  		{"operator", createOperatorNKey(t), false},
    67  		{"server", createServerNKey(t), false},
    68  		{"cluster", createClusterNKey(t), false},
    69  	}
    70  
    71  	for _, i := range inputs {
    72  		bad := encode(temp, i.kp, t)
    73  		_, err = DecodeUserClaims(bad)
    74  		if i.ok && err != nil {
    75  			t.Fatalf("unexpected error for %q: %v", i.name, err)
    76  		}
    77  		if !i.ok && err == nil {
    78  			t.Logf("should have failed to decode user signed by %q", i.name)
    79  			t.Fail()
    80  		}
    81  	}
    82  }
    83  
    84  func TestUserSubjects(t *testing.T) {
    85  	type kpInputs struct {
    86  		name string
    87  		kp   nkeys.KeyPair
    88  		ok   bool
    89  	}
    90  
    91  	inputs := []kpInputs{
    92  		{"account", createAccountNKey(t), false},
    93  		{"cluster", createClusterNKey(t), false},
    94  		{"operator", createOperatorNKey(t), false},
    95  		{"server", createServerNKey(t), false},
    96  		{"user", createUserNKey(t), true},
    97  	}
    98  
    99  	for _, i := range inputs {
   100  		c := NewUserClaims(publicKey(i.kp, t))
   101  		_, err := c.Encode(createAccountNKey(t))
   102  		if i.ok && err != nil {
   103  			t.Fatalf("unexpected error for %q: %v", i.name, err)
   104  		}
   105  		if !i.ok && err == nil {
   106  			t.Logf("should have failed to encode user with with %q subject", i.name)
   107  			t.Fail()
   108  		}
   109  	}
   110  }
   111  
   112  func TestNewNilUserClaim(t *testing.T) {
   113  	v := NewUserClaims("")
   114  	if v != nil {
   115  		t.Fatal("expected nil user claim")
   116  	}
   117  }
   118  
   119  func TestUserType(t *testing.T) {
   120  	c := NewUserClaims(publicKey(createUserNKey(t), t))
   121  	s := encode(c, createAccountNKey(t), t)
   122  	u, err := DecodeUserClaims(s)
   123  	if err != nil {
   124  		t.Fatalf("failed to decode user claim: %v", err)
   125  	}
   126  
   127  	if UserClaim != u.Type {
   128  		t.Fatalf("user type is unexpected %q", u.Type)
   129  	}
   130  }
   131  
   132  func TestSubjects(t *testing.T) {
   133  	s := StringList{}
   134  	if len(s) != 0 {
   135  		t.Fatalf("expected len 0")
   136  	}
   137  	if s.Contains("a") {
   138  		t.Fatalf("didn't expect 'a'")
   139  	}
   140  	s.Add("a")
   141  	if !s.Contains("a") {
   142  		t.Fatalf("expected 'a'")
   143  	}
   144  	s.Remove("a")
   145  	if s.Contains("a") {
   146  		t.Fatalf("didn't expect 'a' after removing")
   147  	}
   148  }
   149  
   150  func TestUserValidation(t *testing.T) {
   151  	ukp := createUserNKey(t)
   152  
   153  	uc := NewUserClaims(publicKey(ukp, t))
   154  	uc.Permissions.Pub.Allow.Add("a")
   155  	uc.Permissions.Pub.Deny.Add("b")
   156  	uc.Permissions.Sub.Allow.Add("a")
   157  	uc.Permissions.Sub.Deny.Add("b")
   158  	uc.Permissions.Resp = &ResponsePermission{
   159  		MaxMsgs: 10,
   160  		Expires: 50 * time.Minute,
   161  	}
   162  	uc.Limits.Max = 10
   163  	uc.Limits.Payload = 10
   164  	uc.Limits.Src = "192.0.2.0/24"
   165  	uc.Limits.Times = []TimeRange{
   166  		{
   167  			Start: "01:15:00",
   168  			End:   "03:15:00",
   169  		},
   170  		{
   171  			Start: "06:15:00",
   172  			End:   "09:15:00",
   173  		},
   174  	}
   175  
   176  	vr := CreateValidationResults()
   177  	uc.Validate(vr)
   178  
   179  	if !vr.IsEmpty() {
   180  		t.Error("valid user permissions should be valid")
   181  	}
   182  	uc.Limits.Max = -1
   183  	vr = CreateValidationResults()
   184  	uc.Validate(vr)
   185  
   186  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   187  		t.Error("bad limit should be invalid")
   188  	}
   189  
   190  	uc.Limits.Max = 10
   191  	uc.Limits.Payload = -1
   192  	vr = CreateValidationResults()
   193  	uc.Validate(vr)
   194  
   195  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   196  		t.Error("bad limit should be invalid")
   197  	}
   198  
   199  	uc.Limits.Payload = 10
   200  	uc.Limits.Src = "hello world"
   201  	vr = CreateValidationResults()
   202  	uc.Validate(vr)
   203  
   204  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   205  		t.Error("bad limit should be invalid")
   206  	}
   207  
   208  	uc.Limits.Payload = 10
   209  	uc.Limits.Src = "hello world"
   210  	vr = CreateValidationResults()
   211  	uc.Validate(vr)
   212  
   213  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   214  		t.Error("bad limit should be invalid")
   215  	}
   216  
   217  	tr := TimeRange{
   218  		Start: "hello",
   219  		End:   "03:15:00",
   220  	}
   221  	uc.Limits.Src = "192.0.2.0/24"
   222  	uc.Limits.Times = append(uc.Limits.Times, tr)
   223  	vr = CreateValidationResults()
   224  	uc.Validate(vr)
   225  
   226  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   227  		t.Error("bad limit should be invalid")
   228  	}
   229  
   230  	uc.Limits.Times = []TimeRange{}
   231  	uc.Permissions.Pub.Allow.Add("bad subject")
   232  	vr = CreateValidationResults()
   233  	uc.Validate(vr)
   234  
   235  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   236  		t.Error("bad permission should be invalid")
   237  	}
   238  
   239  	uc.Permissions.Pub.Allow.Remove("bad subject")
   240  	uc.Permissions.Sub.Allow.Add("bad subject")
   241  	vr = CreateValidationResults()
   242  	uc.Validate(vr)
   243  
   244  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   245  		t.Error("bad permission should be invalid")
   246  	}
   247  
   248  	uc.Permissions.Sub.Allow.Remove("bad subject")
   249  	uc.Permissions.Pub.Deny.Add("bad subject")
   250  	vr = CreateValidationResults()
   251  	uc.Validate(vr)
   252  
   253  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   254  		t.Error("bad permission should be invalid")
   255  	}
   256  
   257  	uc.Permissions.Pub.Deny.Remove("bad subject")
   258  	uc.Permissions.Sub.Deny.Add("bad subject")
   259  	vr = CreateValidationResults()
   260  	uc.Validate(vr)
   261  
   262  	if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) {
   263  		t.Error("bad permission should be invalid")
   264  	}
   265  }
   266  
   267  func TestUserAccountID(t *testing.T) {
   268  	akp := createAccountNKey(t)
   269  	apk := publicKey(akp, t)
   270  	a2kp := createAccountNKey(t)
   271  	ac := NewAccountClaims(apk)
   272  	ac.SigningKeys.Add(publicKey(a2kp, t))
   273  
   274  	token, err := ac.Encode(akp)
   275  	if err != nil {
   276  		t.Fatal(err)
   277  	}
   278  	ac, err = DecodeAccountClaims(token)
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  
   283  	uc := NewUserClaims(publicKey(createUserNKey(t), t))
   284  	uc.IssuerAccount = apk
   285  	userToken, err := uc.Encode(a2kp)
   286  	if err != nil {
   287  		t.Fatal(err)
   288  	}
   289  
   290  	uc, err = DecodeUserClaims(userToken)
   291  	if err != nil {
   292  		t.Fatal(err)
   293  	}
   294  
   295  	if uc.IssuerAccount != apk {
   296  		t.Fatalf("expected AccountID to be set to %s - got %s", apk, uc.IssuerAccount)
   297  	}
   298  
   299  	signed := ac.DidSign(uc)
   300  	if !signed {
   301  		t.Fatal("expected user signed by account")
   302  	}
   303  }
   304  
   305  func TestUserAccountIDValidation(t *testing.T) {
   306  	uc := NewUserClaims(publicKey(createUserNKey(t), t))
   307  	uc.IssuerAccount = publicKey(createAccountNKey(t), t)
   308  	var vr ValidationResults
   309  	uc.Validate(&vr)
   310  	if len(vr.Issues) != 0 {
   311  		t.Fatal("expected no issues")
   312  	}
   313  
   314  	uc.IssuerAccount = publicKey(createUserNKey(t), t)
   315  	uc.Validate(&vr)
   316  	if len(vr.Issues) != 1 {
   317  		t.Fatal("expected validation issues")
   318  	}
   319  }
   320  
   321  func TestSourceNetworkValidation(t *testing.T) {
   322  	ukp := createUserNKey(t)
   323  	uc := NewUserClaims(publicKey(ukp, t))
   324  
   325  	uc.Limits.Src = "192.0.2.0/24"
   326  	vr := CreateValidationResults()
   327  	uc.Validate(vr)
   328  
   329  	if !vr.IsEmpty() {
   330  		t.Error("limits should be valid")
   331  	}
   332  
   333  	uc.Limits.Src = "192.0.2.1/1"
   334  	vr = CreateValidationResults()
   335  	uc.Validate(vr)
   336  
   337  	if !vr.IsEmpty() {
   338  		t.Error("limits should be valid")
   339  	}
   340  
   341  	uc.Limits.Src = "192.0.2.0/24,2001:db8:a0b:12f0::1/32"
   342  	vr = CreateValidationResults()
   343  	uc.Validate(vr)
   344  
   345  	if !vr.IsEmpty() {
   346  		t.Error("limits should be valid")
   347  	}
   348  
   349  	uc.Limits.Src = "192.0.2.0/24 ,\t2001:db8:a0b:12f0::1/32 , 192.168.1.1/1"
   350  	vr = CreateValidationResults()
   351  	uc.Validate(vr)
   352  
   353  	if !vr.IsEmpty() {
   354  		t.Error("limits should be valid")
   355  	}
   356  
   357  	uc.Limits.Src = "foo"
   358  	vr = CreateValidationResults()
   359  	uc.Validate(vr)
   360  
   361  	if vr.IsEmpty() || len(vr.Issues) != 1 {
   362  		t.Error("limits should be invalid")
   363  	}
   364  
   365  	uc.Limits.Src = "192.0.2.0/24,foo"
   366  	vr = CreateValidationResults()
   367  	uc.Validate(vr)
   368  
   369  	if vr.IsEmpty() || len(vr.Issues) != 1 {
   370  		t.Error("limits should be invalid")
   371  	}
   372  
   373  	uc.Limits.Src = "bloo,foo"
   374  	vr = CreateValidationResults()
   375  	uc.Validate(vr)
   376  
   377  	if vr.IsEmpty() || len(vr.Issues) != 2 {
   378  		t.Error("limits should be invalid")
   379  	}
   380  }
   381  
   382  func TestUserClaimRevocation(t *testing.T) {
   383  	akp := createAccountNKey(t)
   384  	apk := publicKey(akp, t)
   385  	account := NewAccountClaims(apk)
   386  
   387  	u := publicKey(createUserNKey(t), t)
   388  	aminAgo := time.Now().Add(-time.Minute)
   389  	if account.Revocations.IsRevoked(u, aminAgo) {
   390  		t.Fatal("shouldn't be revoked")
   391  	}
   392  	account.RevokeAt(u, aminAgo)
   393  	if !account.Revocations.IsRevoked(u, aminAgo) {
   394  		t.Fatal("should be revoked")
   395  	}
   396  
   397  	u2 := publicKey(createUserNKey(t), t)
   398  	if account.Revocations.IsRevoked(u2, aminAgo) {
   399  		t.Fatal("should not be revoked")
   400  	}
   401  	account.RevokeAt("*", aminAgo)
   402  	if !account.Revocations.IsRevoked(u2, time.Now().Add(-time.Hour)) {
   403  		t.Fatal("should be revoked")
   404  	}
   405  
   406  	vr := ValidationResults{}
   407  	account.Validate(&vr)
   408  	if !vr.IsEmpty() {
   409  		t.Fatal("account validation shouldn't have failed")
   410  	}
   411  }