From a27988d8c7f7dbab95edf65da5482aec5d8067e4 Mon Sep 17 00:00:00 2001 From: jwijenbergh Date: Mon, 24 Apr 2023 12:16:29 +0200 Subject: Server: Support unmarshalling server as a string This is for V1 configs --- types/server/server.go | 33 ++++++++++++++++++ types/server/server_test.go | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 types/server/server_test.go (limited to 'types/server') diff --git a/types/server/server.go b/types/server/server.go index aea496d..3bdebe1 100644 --- a/types/server/server.go +++ b/types/server/server.go @@ -2,6 +2,9 @@ package server import ( + "encoding/json" + "fmt" + "github.com/eduvpn/eduvpn-common/types/cookie" "github.com/eduvpn/eduvpn-common/types/protocol" ) @@ -20,6 +23,36 @@ const ( TypeCustom ) +// This is here to support V1 configs which had the server type as a string +func (t *Type) UnmarshalJSON(data []byte) error { + // First try to just unmarshal the type + var num int8 + if err := json.Unmarshal(data, &num); err == nil { + if num < int8(TypeUnknown) || num > int8(TypeCustom) { + return fmt.Errorf("invalid server type: %d", num) + } + *t = Type(num) + return nil + } + + // unmarshal the old way, as a string + var str string + if err := json.Unmarshal(data, &str); err != nil { + return err + } + switch str { + case "secure_internet": + *t = TypeSecureInternet + case "institute_access": + *t = TypeInstituteAccess + case "custom_server": + *t = TypeCustom + default: + return fmt.Errorf("invalid server type: %s", str) + } + return nil +} + // RequiredAskTransition represents the data that is sent when a transition is required to be handled and the go library needs data from the client // This data can be a profile selection or secure internet location selection type RequiredAskTransition struct { diff --git a/types/server/server_test.go b/types/server/server_test.go new file mode 100644 index 0000000..06a6851 --- /dev/null +++ b/types/server/server_test.go @@ -0,0 +1,83 @@ +package server + +import ( + "encoding/json" + "testing" +) + +func errorString(err error) string { + if err == nil { + return "" + } + return err.Error() +} + +func TestServerUnmarshal(t *testing.T) { + cases := []struct{ + want Type + wantErr string + payload string + }{ + { + want: TypeUnknown, + wantErr: "invalid server type: a", + payload: `{"value": "a"}`, + }, + { + want: TypeInstituteAccess, + wantErr: "", + payload: `{"value": "institute_access"}`, + }, + { + want: TypeCustom, + wantErr: "", + payload: `{"value": "custom_server"}`, + }, + { + want: TypeSecureInternet, + wantErr: "", + payload: `{"value": "secure_internet"}`, + }, + { + want: TypeUnknown, + wantErr: "", + payload: `{"value": 0}`, + }, + { + want: TypeInstituteAccess, + wantErr: "", + payload: `{"value": 1}`, + }, + { + want: TypeSecureInternet, + wantErr: "", + payload: `{"value": 2}`, + }, + { + want: TypeCustom, + wantErr: "", + payload: `{"value": 3}`, + }, + // Values that are outside the range will be error checked too + // This is thus even more strict than a regular type unmarshal/marshal + { + want: TypeUnknown, + wantErr: "invalid server type: 25", + payload: `{"value": 25}`, + }, + } + + for _, c := range cases { + var got struct{ + Value Type `json:"value"` + } + err := json.Unmarshal([]byte(c.payload), &got) + if errorString(err) != c.wantErr { + t.Fatalf("server unmarshal error is not equal to want, got: %v, want: %v", err, c.want) + } + if got.Value != c.want { + t.Fatalf("server unmarshal value is not equal to want, got: %v, want: %v", got.Value, c.want) + } + } + +} -- cgit v1.2.3