From f9c7776a413358752942d078361ee8d13f15e2f4 Mon Sep 17 00:00:00 2001 From: Alberto Ricart Date: Wed, 9 Oct 2024 14:35:56 -0500 Subject: [PATCH] Retract case-insensitive tag functionality (#233) * Revert "[CHANGE] Tags are now case-sensitive (#225)" This reverts commit de1f16b5781c771513bdc8de201e86bfa76f0325. * retract 2.7.0 Signed-off-by: Alberto Ricart --------- Signed-off-by: Alberto Ricart --- v2/go.mod | 7 ++- v2/operator_claims_test.go | 5 ++- v2/types.go | 79 +++++++++----------------------- v2/types_test.go | 92 ++++---------------------------------- 4 files changed, 38 insertions(+), 145 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index 63452bd..b0d2610 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -1,9 +1,14 @@ module github.com/nats-io/jwt/v2 -go 1.18 +go 1.22 require github.com/nats-io/nkeys v0.4.7 +retract ( + v2.7.1 // contains retractions only + v2.7.0 // includes case insensitive changes to tags that break jetstream placement +) + require ( golang.org/x/crypto v0.19.0 // indirect golang.org/x/sys v0.17.0 // indirect diff --git a/v2/operator_claims_test.go b/v2/operator_claims_test.go index 04529ae..dcc4d34 100644 --- a/v2/operator_claims_test.go +++ b/v2/operator_claims_test.go @@ -457,9 +457,12 @@ func TestTags(t *testing.T) { if len(oc2.GenericFields.Tags) != 3 { t.Fatal("expected 3 tags") } + for _, v := range oc.GenericFields.Tags { + AssertFalse(v == "TWO", t) + } AssertTrue(oc.GenericFields.Tags.Contains("one"), t) - AssertTrue(oc.GenericFields.Tags.Contains("TWO"), t) + AssertTrue(oc.GenericFields.Tags.Contains("two"), t) AssertTrue(oc.GenericFields.Tags.Contains("three"), t) } diff --git a/v2/types.go b/v2/types.go index f0049ab..d5814db 100644 --- a/v2/types.go +++ b/v2/types.go @@ -1,5 +1,5 @@ /* - * Copyright 2018-2024 The NATS Authors + * Copyright 2018-2019 The NATS Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -427,90 +427,51 @@ type TagList []string // Contains returns true if the list contains the tags func (u *TagList) Contains(p string) bool { - return u.find(p) != -1 -} - -func (u *TagList) Equals(other *TagList) bool { - if len(*u) != len(*other) { - return false - } - for _, v := range *u { - if other.find(v) == -1 { - return false - } - } - return true -} - -func (u *TagList) find(p string) int { - for idx, t := range *u { - if p == t { - return idx + p = strings.ToLower(strings.TrimSpace(p)) + for _, t := range *u { + if t == p { + return true } } - return -1 + return false } // Add appends 1 or more tags to a list func (u *TagList) Add(p ...string) { for _, v := range p { - v = strings.TrimSpace(v) - if v == "" { - continue - } - if !u.Contains(v) { + v = strings.ToLower(strings.TrimSpace(v)) + if !u.Contains(v) && v != "" { *u = append(*u, v) } } } // Remove removes 1 or more tags from a list -func (u *TagList) Remove(p ...string) error { +func (u *TagList) Remove(p ...string) { for _, v := range p { - v = strings.TrimSpace(v) - idx := u.find(v) - if idx != -1 { - a := *u - *u = append(a[:idx], a[idx+1:]...) - } else { - return fmt.Errorf("unable to remove tag: %q - not found", v) + v = strings.ToLower(strings.TrimSpace(v)) + for i, t := range *u { + if t == v { + a := *u + *u = append(a[:i], a[i+1:]...) + break + } } } - return nil } -type CIDRList []string +type CIDRList TagList func (c *CIDRList) Contains(p string) bool { - p = strings.ToLower(strings.TrimSpace(p)) - for _, t := range *c { - if t == p { - return true - } - } - return false + return (*TagList)(c).Contains(p) } func (c *CIDRList) Add(p ...string) { - for _, v := range p { - v = strings.ToLower(strings.TrimSpace(v)) - if !c.Contains(v) && v != "" { - *c = append(*c, v) - } - } + (*TagList)(c).Add(p...) } func (c *CIDRList) Remove(p ...string) { - for _, v := range p { - v = strings.ToLower(strings.TrimSpace(v)) - for i, t := range *c { - if t == v { - a := *c - *c = append(a[:i], a[i+1:]...) - break - } - } - } + (*TagList)(c).Remove(p...) } func (c *CIDRList) Set(values string) { diff --git a/v2/types_test.go b/v2/types_test.go index 9d8a205..34d1fa4 100644 --- a/v2/types_test.go +++ b/v2/types_test.go @@ -1,5 +1,5 @@ /* - * Copyright 2018-2024 The NATS Authors + * Copyright 2018 The NATS Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -117,21 +117,19 @@ func TestTagList(t *testing.T) { tags.Add("one") AssertEquals(true, tags.Contains("one"), t) - AssertEquals(false, tags.Contains("ONE"), t) + AssertEquals(true, tags.Contains("ONE"), t) AssertEquals("one", tags[0], t) tags.Add("TWO") - AssertEquals(false, tags.Contains("two"), t) + AssertEquals(true, tags.Contains("two"), t) AssertEquals(true, tags.Contains("TWO"), t) - AssertEquals("TWO", tags[1], t) + AssertEquals("two", tags[1], t) - err := tags.Remove("ONE") - if err == nil { - t.Fatal("removing tag that doesn't exist should have failed") - } - AssertEquals("one", tags[0], t) - AssertEquals(true, tags.Contains("TWO"), t) + tags.Remove("ONE") + AssertEquals("two", tags[0], t) + AssertEquals(false, tags.Contains("one"), t) + AssertEquals(false, tags.Contains("ONE"), t) } func TestStringList(t *testing.T) { @@ -429,77 +427,3 @@ func TestInvalidInfo(t *testing.T) { } } } - -func TestTagList_CasePreservingContains(t *testing.T) { - type test struct { - v string - a TagList - ok bool - } - - tests := []test{ - {v: "A", a: TagList{}, ok: false}, - {v: "A", a: TagList{"A"}, ok: true}, - {v: "a", a: TagList{"A"}, ok: false}, - {v: "a", a: TagList{"a:hello"}, ok: false}, - {v: "a:a", a: TagList{"a:c"}, ok: false}, - } - - for idx, test := range tests { - found := test.a.Contains(test.v) - if !found && test.ok { - t.Errorf("[%d] expected to contain %q", idx, test.v) - } - } -} - -func TestTagList_Add(t *testing.T) { - type test struct { - v string - a TagList - shouldBe TagList - } - - tests := []test{ - {v: "A", a: TagList{}, shouldBe: TagList{"A"}}, - {v: "A", a: TagList{"A"}, shouldBe: TagList{"A"}}, - {v: "a", a: TagList{"A"}, shouldBe: TagList{"A", "a"}}, - {v: "a", a: TagList{"a:hello"}, shouldBe: TagList{"a", "a:hello"}}, - {v: "a:Hello", a: TagList{"a:hello"}, shouldBe: TagList{"a:hello", "a:Hello"}}, - {v: "a:a", a: TagList{"a:c"}, shouldBe: TagList{"a:a", "a:c"}}, - } - - for idx, test := range tests { - test.a.Add(test.v) - if !test.a.Equals(&test.shouldBe) { - t.Errorf("[%d] expected lists to be equal: %v", idx, test.a) - } - } -} - -func TestTagList_Delete(t *testing.T) { - type test struct { - v string - a TagList - shouldBe TagList - shouldFail bool - } - - tests := []test{ - {v: "A", a: TagList{}, shouldBe: TagList{}, shouldFail: true}, - {v: "A", a: TagList{"A"}, shouldBe: TagList{}}, - {v: "a", a: TagList{"A"}, shouldBe: TagList{"A"}, shouldFail: true}, - {v: "a:Hello", a: TagList{"a:hello"}, shouldBe: TagList{"a:hello"}, shouldFail: true}, - {v: "a:a", a: TagList{"a:A"}, shouldBe: TagList{"a:A"}, shouldFail: true}, - } - - for idx, test := range tests { - err := test.a.Remove(test.v) - if test.shouldFail && err == nil { - t.Fatalf("[%d] expected delete to fail: %v", idx, test.a) - } - if !test.a.Equals(&test.shouldBe) { - t.Fatalf("[%d] expected lists to be equal: %v", idx, test.a) - } - } -}