From 4b2f4481715e949863953f3c043e6129439483dd Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 5 Nov 2024 09:49:04 +0000 Subject: [PATCH 1/5] update castle sdk remove deprecated fields --- client.go | 23 ++++++++++++++++++----- model.go | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/client.go b/client.go index 5d9cebd..e036a4e 100644 --- a/client.go +++ b/client.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "net/http" + "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -71,14 +72,19 @@ func (c *Castle) Filter(ctx context.Context, req *Request) (RecommendedAction, e if req.Context == nil { return RecommendedActionNone, errors.New("request.Context cannot be nil") } - r := &castleAPIRequest{ + user_params := UserParams{ + Email: req.User.Email, + Username: req.User.Name, + } + r := &castleFilterAPIRequest{ Type: req.Event.EventType, Name: req.Event.Name, Status: req.Event.EventStatus, RequestToken: req.Context.RequestToken, - User: req.User, + Params: user_params, Context: req.Context, Properties: req.Properties, + CreatedAt: time.Now(), } return c.sendCall(ctx, r, FilterEndpoint) } @@ -92,7 +98,7 @@ func (c *Castle) Risk(ctx context.Context, req *Request) (RecommendedAction, err if req.Context == nil { return RecommendedActionNone, errors.New("request.Context cannot be nil") } - r := &castleAPIRequest{ + r := &castleRiskAPIRequest{ Type: req.Event.EventType, Name: req.Event.Name, Status: req.Event.EventStatus, @@ -100,11 +106,12 @@ func (c *Castle) Risk(ctx context.Context, req *Request) (RecommendedAction, err User: req.User, Context: req.Context, Properties: req.Properties, + CreatedAt: time.Now(), } return c.sendCall(ctx, r, RiskEndpoint) } -func (c *Castle) sendCall(ctx context.Context, r *castleAPIRequest, url string) (_ RecommendedAction, err error) { +func (c *Castle) sendCall(ctx context.Context, r castleAPIRequest, url string) (_ RecommendedAction, err error) { defer func() { if !c.metricsEnabled { return @@ -118,7 +125,13 @@ func (c *Castle) sendCall(ctx context.Context, r *castleAPIRequest, url string) }() b := new(bytes.Buffer) - err = json.NewEncoder(b).Encode(r) + + switch request := r.(type) { + case *castleRiskAPIRequest: + err = json.NewEncoder(b).Encode(request) + case *castleFilterAPIRequest: + err = json.NewEncoder(b).Encode(request) + } if err != nil { return RecommendedActionNone, err } diff --git a/model.go b/model.go index 3ef63d2..6fdafed 100644 --- a/model.go +++ b/model.go @@ -1,5 +1,7 @@ package castle +import "time" + type Event struct { EventType EventType EventStatus EventStatus @@ -68,7 +70,32 @@ type User struct { Traits map[string]string `json:"traits,omitempty"` } -type castleAPIRequest struct { +type UserParams struct { + Email string `json:"email,omitempty"` + Phone string `json:"phone,omitempty"` + Username string `json:"username,omitempty"` +} + +type castleAPIRequest interface { + GetEventType() EventType +} + +type castleFilterAPIRequest struct { + Type EventType `json:"type"` + Name string `json:"name,omitempty"` + Status EventStatus `json:"status"` + RequestToken string `json:"request_token"` + Params UserParams `json:"params"` + Context *Context `json:"context"` + Properties map[string]string `json:"properties,omitempty"` + CreatedAt time.Time `json:"created_at"` +} + +func (r *castleFilterAPIRequest) GetEventType() EventType { + return r.Type +} + +type castleRiskAPIRequest struct { Type EventType `json:"type"` Name string `json:"name,omitempty"` Status EventStatus `json:"status"` @@ -76,6 +103,11 @@ type castleAPIRequest struct { User User `json:"user"` Context *Context `json:"context"` Properties map[string]string `json:"properties,omitempty"` + CreatedAt time.Time `json:"created_at"` +} + +func (r *castleRiskAPIRequest) GetEventType() EventType { + return r.Type } type castleAPIResponse struct { From 473d7f18c532d4b586bd73d2cc709f8553bc9c09 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 5 Nov 2024 14:18:17 +0000 Subject: [PATCH 2/5] tests pass --- client.go | 1 + client_test.go | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index e036a4e..b1e2d64 100644 --- a/client.go +++ b/client.go @@ -10,6 +10,7 @@ import ( "net/http" "time" + "github.com/davecgh/go-spew/spew" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) diff --git a/client_test.go b/client_test.go index a0942ef..b5cb7c5 100644 --- a/client_test.go +++ b/client_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "testing" + "github.com/davecgh/go-spew/spew" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -32,6 +33,7 @@ func configureRequest(httpReq *http.Request) *castle.Request { }, User: castle.User{ ID: "user-id", + Email: "user@test.com", Traits: map[string]string{"trait1": "traitValue1"}, }, Properties: map[string]string{"prop1": "propValue1"}, @@ -150,7 +152,7 @@ func TestCastle_Filter(t *testing.T) { Type castle.EventType `json:"type"` Status castle.EventStatus `json:"status"` RequestToken string `json:"request_token"` - User castle.User `json:"user"` + Params castle.UserParams `json:"params"` Context *castle.Context `json:"context"` Properties map[string]string `json:"properties"` } @@ -164,13 +166,13 @@ func TestCastle_Filter(t *testing.T) { assert.True(t, ok) err = json.NewDecoder(r.Body).Decode(reqData) + spew.Dump(reqData) require.NoError(t, err) assert.Equal(t, castle.EventTypeLogin, reqData.Type) assert.Equal(t, castle.EventStatusSucceeded, reqData.Status) - assert.Equal(t, "user-id", reqData.User.ID) + assert.Equal(t, "user@test.com", reqData.Params.Email) assert.Equal(t, map[string]string{"prop1": "propValue1"}, reqData.Properties) - assert.Equal(t, map[string]string{"trait1": "traitValue1"}, reqData.User.Traits) assert.Equal(t, castle.FromHTTPRequest(httpReq), reqData.Context) executed = true From cb9ed0b81dc5cf7868cc5789e627a2567863839d Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 5 Nov 2024 15:04:44 +0000 Subject: [PATCH 3/5] remove spew --- client.go | 1 - client_test.go | 1 - 2 files changed, 2 deletions(-) diff --git a/client.go b/client.go index b1e2d64..e036a4e 100644 --- a/client.go +++ b/client.go @@ -10,7 +10,6 @@ import ( "net/http" "time" - "github.com/davecgh/go-spew/spew" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) diff --git a/client_test.go b/client_test.go index b5cb7c5..a422a2c 100644 --- a/client_test.go +++ b/client_test.go @@ -166,7 +166,6 @@ func TestCastle_Filter(t *testing.T) { assert.True(t, ok) err = json.NewDecoder(r.Body).Decode(reqData) - spew.Dump(reqData) require.NoError(t, err) assert.Equal(t, castle.EventTypeLogin, reqData.Type) From 0ee71f47e6ef17544807008c2c98d50f0eff7803 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 5 Nov 2024 15:15:03 +0000 Subject: [PATCH 4/5] lint fix --- client_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/client_test.go b/client_test.go index a422a2c..9154bdc 100644 --- a/client_test.go +++ b/client_test.go @@ -7,7 +7,6 @@ import ( "net/http/httptest" "testing" - "github.com/davecgh/go-spew/spew" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" From 6f902ad2deee61be39afdc5b33b8f6c98dc9a569 Mon Sep 17 00:00:00 2001 From: James Tait Date: Tue, 5 Nov 2024 16:26:16 +0000 Subject: [PATCH 5/5] demo generics --- client.go | 17 ++++++----------- model.go | 14 +++----------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/client.go b/client.go index e036a4e..886cb23 100644 --- a/client.go +++ b/client.go @@ -76,7 +76,7 @@ func (c *Castle) Filter(ctx context.Context, req *Request) (RecommendedAction, e Email: req.User.Email, Username: req.User.Name, } - r := &castleFilterAPIRequest{ + r := &FilterRequest{ Type: req.Event.EventType, Name: req.Event.Name, Status: req.Event.EventStatus, @@ -86,7 +86,7 @@ func (c *Castle) Filter(ctx context.Context, req *Request) (RecommendedAction, e Properties: req.Properties, CreatedAt: time.Now(), } - return c.sendCall(ctx, r, FilterEndpoint) + return sendCall(ctx, c, r, FilterEndpoint) } // Risk sends a risk request to castle.io @@ -98,7 +98,7 @@ func (c *Castle) Risk(ctx context.Context, req *Request) (RecommendedAction, err if req.Context == nil { return RecommendedActionNone, errors.New("request.Context cannot be nil") } - r := &castleRiskAPIRequest{ + r := &RiskRequest{ Type: req.Event.EventType, Name: req.Event.Name, Status: req.Event.EventStatus, @@ -108,10 +108,10 @@ func (c *Castle) Risk(ctx context.Context, req *Request) (RecommendedAction, err Properties: req.Properties, CreatedAt: time.Now(), } - return c.sendCall(ctx, r, RiskEndpoint) + return sendCall(ctx, c, r, RiskEndpoint) } -func (c *Castle) sendCall(ctx context.Context, r castleAPIRequest, url string) (_ RecommendedAction, err error) { +func sendCall[Req castleAPIRequest](ctx context.Context, c *Castle, r Req, url string) (_ RecommendedAction, err error) { defer func() { if !c.metricsEnabled { return @@ -126,12 +126,7 @@ func (c *Castle) sendCall(ctx context.Context, r castleAPIRequest, url string) ( b := new(bytes.Buffer) - switch request := r.(type) { - case *castleRiskAPIRequest: - err = json.NewEncoder(b).Encode(request) - case *castleFilterAPIRequest: - err = json.NewEncoder(b).Encode(request) - } + err = json.NewEncoder(b).Encode(r) if err != nil { return RecommendedActionNone, err } diff --git a/model.go b/model.go index 6fdafed..c0410e0 100644 --- a/model.go +++ b/model.go @@ -77,10 +77,10 @@ type UserParams struct { } type castleAPIRequest interface { - GetEventType() EventType + *FilterRequest | *RiskRequest } -type castleFilterAPIRequest struct { +type FilterRequest struct { Type EventType `json:"type"` Name string `json:"name,omitempty"` Status EventStatus `json:"status"` @@ -91,11 +91,7 @@ type castleFilterAPIRequest struct { CreatedAt time.Time `json:"created_at"` } -func (r *castleFilterAPIRequest) GetEventType() EventType { - return r.Type -} - -type castleRiskAPIRequest struct { +type RiskRequest struct { Type EventType `json:"type"` Name string `json:"name,omitempty"` Status EventStatus `json:"status"` @@ -106,10 +102,6 @@ type castleRiskAPIRequest struct { CreatedAt time.Time `json:"created_at"` } -func (r *castleRiskAPIRequest) GetEventType() EventType { - return r.Type -} - type castleAPIResponse struct { Type string `json:"type"` Message string `json:"message"`