From 56d765a46b709f6104937bf18cd5df3c1eed395c Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Thu, 28 Dec 2023 17:37:31 +0100 Subject: [PATCH] shamir_threshold is an integer. Signed-off-by: Felix Fontein --- stores/dotenv/store.go | 5 ++++- stores/flatten.go | 22 +++++++++++++++++++++- stores/flatten_test.go | 25 ++++++++++++++++++++++++- stores/ini/store.go | 5 ++++- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/stores/dotenv/store.go b/stores/dotenv/store.go index 58d7c6d53..9433322ee 100644 --- a/stores/dotenv/store.go +++ b/stores/dotenv/store.go @@ -49,7 +49,10 @@ func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) { } stores.DecodeNewLines(mdMap) - stores.DecodeNonStrings(mdMap) + err = stores.DecodeNonStrings(mdMap) + if err != nil { + return sops.Tree{}, err + } metadata, err := stores.UnflattenMetadata(mdMap) if err != nil { return sops.Tree{}, err diff --git a/stores/flatten.go b/stores/flatten.go index c894e6e29..fe6e981fd 100644 --- a/stores/flatten.go +++ b/stores/flatten.go @@ -236,13 +236,28 @@ func EncodeNewLines(m map[string]interface{}) { } // DecodeNonStrings will look for known metadata keys that are not strings and decode to the appropriate type -func DecodeNonStrings(m map[string]interface{}) { +func DecodeNonStrings(m map[string]interface{}) error { if v, ok := m["mac_only_encrypted"]; ok { m["mac_only_encrypted"] = false if v == "true" { m["mac_only_encrypted"] = true } } + if v, ok := m["shamir_threshold"]; ok { + switch val := v.(type) { + case string: + vInt, err := strconv.Atoi(val) + if err != nil { + return fmt.Errorf("shamir_threshold is not an integer: %s", err.Error()) + } + m["shamir_threshold"] = vInt + case int: + m["shamir_threshold"] = val + default: + return fmt.Errorf("shamir_threshold is neither a string nor an integer, but %T", val) + } + } + return nil } // EncodeNonStrings will look for known metadata keys that are not strings and will encode it to strings @@ -255,4 +270,9 @@ func EncodeNonStrings(m map[string]interface{}) { } } } + if v, found := m["shamir_threshold"]; found { + if vInt, ok := v.(int); ok { + m["shamir_threshold"] = fmt.Sprintf("%d", vInt) + } + } } diff --git a/stores/flatten_test.go b/stores/flatten_test.go index 4d11dd1ad..6c75da3d1 100644 --- a/stores/flatten_test.go +++ b/stores/flatten_test.go @@ -222,14 +222,35 @@ func TestDecodeNonStrings(t *testing.T) { {map[string]interface{}{"mac_only_encrypted": "false"}, map[string]interface{}{"mac_only_encrypted": false}}, {map[string]interface{}{"mac_only_encrypted": "true"}, map[string]interface{}{"mac_only_encrypted": true}}, {map[string]interface{}{"mac_only_encrypted": "something-else"}, map[string]interface{}{"mac_only_encrypted": false}}, + {map[string]interface{}{"shamir_threshold": "2"}, map[string]interface{}{"shamir_threshold": 2}}, + {map[string]interface{}{"shamir_threshold": "002"}, map[string]interface{}{"shamir_threshold": 2}}, + {map[string]interface{}{"shamir_threshold": "123"}, map[string]interface{}{"shamir_threshold": 123}}, + {map[string]interface{}{"shamir_threshold": 123}, map[string]interface{}{"shamir_threshold": 123}}, } for _, tt := range tests { - DecodeNonStrings(tt.input) + err := DecodeNonStrings(tt.input) + assert.Nil(t, err) assert.Equal(t, tt.want, tt.input) } } +func TestDecodeNonStringsErrors(t *testing.T) { + tests := []struct { + input map[string]interface{} + want string + }{ + {map[string]interface{}{"shamir_threshold": "foo"}, "shamir_threshold is not an integer: strconv.Atoi: parsing \"foo\": invalid syntax"}, + {map[string]interface{}{"shamir_threshold": true}, "shamir_threshold is neither a string nor an integer, but bool"}, + } + + for _, tt := range tests { + err := DecodeNonStrings(tt.input) + assert.NotNil(t, err) + assert.Equal(t, tt.want, err.Error()) + } +} + func TestEncodeNonStrings(t *testing.T) { tests := []struct { input map[string]interface{} @@ -237,6 +258,8 @@ func TestEncodeNonStrings(t *testing.T) { }{ {map[string]interface{}{"mac_only_encrypted": false}, map[string]interface{}{"mac_only_encrypted": "false"}}, {map[string]interface{}{"mac_only_encrypted": true}, map[string]interface{}{"mac_only_encrypted": "true"}}, + {map[string]interface{}{"shamir_threshold": 2}, map[string]interface{}{"shamir_threshold": "2"}}, + {map[string]interface{}{"shamir_threshold": 123}, map[string]interface{}{"shamir_threshold": "123"}}, } for _, tt := range tests { diff --git a/stores/ini/store.go b/stores/ini/store.go index 12bd17ce1..dd1a77c63 100644 --- a/stores/ini/store.go +++ b/stores/ini/store.go @@ -188,7 +188,10 @@ func (store *Store) iniSectionToMetadata(sopsSection *ini.Section) (stores.Metad metadataHash[k] = v } stores.DecodeNewLines(metadataHash) - stores.DecodeNonStrings(metadataHash) + err := stores.DecodeNonStrings(metadataHash) + if err != nil { + return stores.Metadata{}, err + } return stores.UnflattenMetadata(metadataHash) }