Skip to content

Commit 9c4e9bc

Browse files
authored
[jwk] Add a Set() method to jwk.Set (#503)
* [jwk] Add a Set() method to jwk.Set * Appease linter
1 parent 1a1ea73 commit 9c4e9bc

3 files changed

Lines changed: 70 additions & 3 deletions

File tree

jwk/interface.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ const (
5757
type Set interface {
5858
// Add adds the specified key. If the key already exists in the set, it is
5959
// not added.
60+
// This method will be renamed to `AddKey(Key)` in a future major release.
6061
Add(Key) bool
6162

6263
// Clear resets the list of keys associated with this set, emptying the
6364
// internal list of `jwk.Key`s
65+
// This method will be changed in the future to clear all contents in the
66+
// `jwk.Set` instead of just the keys.
6467
Clear()
6568

6669
// Get returns the key at index `idx`. If the index is out of range,
@@ -69,11 +72,23 @@ type Set interface {
6972
Get(int) (Key, bool)
7073

7174
// Field returns the value of a private field in the key set.
75+
//
7276
// For the purposes of a key set, any field other than the "keys" field is
73-
// considered to be a private field.
77+
// considered to be a private field. In other words, you cannot use this
78+
// method to directly access the list of keys in the set
79+
//
7480
// This method will be renamed to `Get(string)` in a future major release.
7581
Field(string) (interface{}, bool)
7682

83+
// Set sets the value of a single field.
84+
//
85+
// This method, which takes an `interface{}`, exists because
86+
// these objects can contain extra _arbitrary_ fields that users can
87+
// specify, and there is no way of knowing what type they could be.
88+
Set(string, interface{}) error
89+
90+
// Remove removes the field associated with the specified key.
91+
// There is no way to remove the `kty` (key type). You will ALWAYS be left with one field in a jwk.Key.
7792
// Index returns the index where the given key exists, -1 otherwise
7893
Index(Key) int
7994

jwk/jwk_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,4 +1769,37 @@ func TestSetWithPrivateParams(t *testing.T) {
17691769
check(t, js)
17701770
})
17711771
})
1772+
t.Run("Set private parameters", func(t *testing.T) {
1773+
set := jwk.NewSet()
1774+
if !assert.NoError(t, set.Set(`renewal_kid`, `foo`), `set.Set should succeed`) {
1775+
return
1776+
}
1777+
1778+
v, ok := set.Field(`renewal_kid`)
1779+
if !assert.True(t, ok, `set.Get("renewal_kid") should succeed`) {
1780+
return
1781+
}
1782+
1783+
if !assert.Equal(t, `foo`, v, `set.Get("renewal_kid") should return "foo"`) {
1784+
return
1785+
}
1786+
1787+
if !assert.Error(t, set.Set(`keys`, []string{"foo"}), `set.Set should fail`) {
1788+
return
1789+
}
1790+
1791+
k, err := jwk.New([]byte("foobar"))
1792+
if !assert.NoError(t, err, `jwk.New should succeed`) {
1793+
return
1794+
}
1795+
keys := []jwk.Key{k}
1796+
1797+
if !assert.NoError(t, set.Set(`keys`, keys), `set.Set should succeed`) {
1798+
return
1799+
}
1800+
1801+
if !assert.Equal(t, set.Len(), 1, `set should have 1 key`) {
1802+
return
1803+
}
1804+
})
17721805
}

jwk/set.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,32 @@ import (
1212
"github.com/pkg/errors"
1313
)
1414

15+
const keysKey = `keys` // appease linter
16+
1517
// NewSet creates and empty `jwk.Set` object
1618
func NewSet() Set {
1719
return &set{
1820
privateParams: make(map[string]interface{}),
1921
}
2022
}
2123

24+
func (s *set) Set(n string, v interface{}) error {
25+
s.mu.RLock()
26+
defer s.mu.RUnlock()
27+
28+
if n == keysKey {
29+
vl, ok := v.([]Key)
30+
if !ok {
31+
return errors.Errorf(`value for field "keys" must be []jwk.Key`)
32+
}
33+
s.keys = vl
34+
return nil
35+
}
36+
37+
s.privateParams[n] = v
38+
return nil
39+
}
40+
2241
func (s *set) Field(n string) (interface{}, bool) {
2342
s.mu.RLock()
2443
defer s.mu.RUnlock()
@@ -126,7 +145,7 @@ func (s *set) MarshalJSON() ([]byte, error) {
126145
defer pool.ReleaseBytesBuffer(buf)
127146
enc := json.NewEncoder(buf)
128147

129-
fields := []string{`keys`}
148+
fields := []string{keysKey}
130149
for k := range s.privateParams {
131150
fields = append(fields, k)
132151
}
@@ -138,7 +157,7 @@ func (s *set) MarshalJSON() ([]byte, error) {
138157
buf.WriteByte(',')
139158
}
140159
fmt.Fprintf(buf, `%q:`, field)
141-
if field != `keys` {
160+
if field != keysKey {
142161
if err := enc.Encode(s.privateParams[field]); err != nil {
143162
return nil, errors.Wrapf(err, `failed to marshal field %q`, field)
144163
}

0 commit comments

Comments
 (0)