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