From 59b03c8f0538d286cb17ac8b854e20cd1226a7a5 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Tue, 14 Dec 2021 09:32:51 -0800
Subject: [PATCH 01/10] Integration Type Handling
---
analytics/event.go | 15 ++++-----
config/accounts.go | 15 ++++-----
config/config.go | 3 ++
endpoints/events/event.go | 13 +++++---
endpoints/events/event_test.go | 22 +++++++++++---
endpoints/events/vtrack.go | 25 +++++++--------
endpoints/events/vtrack_test.go | 4 +--
endpoints/openrtb2/auction.go | 22 ++++++++++++++
endpoints/openrtb2/auction_test.go | 49 ++++++++++++++++++++++++++++++
exchange/events.go | 9 +++---
openrtb_ext/request.go | 1 +
11 files changed, 137 insertions(+), 41 deletions(-)
diff --git a/analytics/event.go b/analytics/event.go
index 5350223d8d1..1683191d322 100644
--- a/analytics/event.go
+++ b/analytics/event.go
@@ -28,11 +28,12 @@ const (
)
type EventRequest struct {
- Type EventType `json:"type,omitempty"`
- Format ResponseFormat `json:"format,omitempty"`
- Analytics Analytics `json:"analytics,omitempty"`
- BidID string `json:"bidid,omitempty"`
- AccountID string `json:"account_id,omitempty"`
- Bidder string `json:"bidder,omitempty"`
- Timestamp int64 `json:"timestamp,omitempty"`
+ Type EventType `json:"type,omitempty"`
+ Format ResponseFormat `json:"format,omitempty"`
+ Analytics Analytics `json:"analytics,omitempty"`
+ BidID string `json:"bidid,omitempty"`
+ AccountID string `json:"account_id,omitempty"`
+ Bidder string `json:"bidder,omitempty"`
+ Timestamp int64 `json:"timestamp,omitempty"`
+ IntegrationType string `json:"integration_type,omitempty"`
}
diff --git a/config/accounts.go b/config/accounts.go
index f7b380fca48..5a6e82dce04 100644
--- a/config/accounts.go
+++ b/config/accounts.go
@@ -13,13 +13,14 @@ const (
// Account represents a publisher account configuration
type Account struct {
- ID string `mapstructure:"id" json:"id"`
- Disabled bool `mapstructure:"disabled" json:"disabled"`
- CacheTTL DefaultTTLs `mapstructure:"cache_ttl" json:"cache_ttl"`
- EventsEnabled bool `mapstructure:"events_enabled" json:"events_enabled"`
- CCPA AccountCCPA `mapstructure:"ccpa" json:"ccpa"`
- GDPR AccountGDPR `mapstructure:"gdpr" json:"gdpr"`
- DebugAllow bool `mapstructure:"debug_allow" json:"debug_allow"`
+ ID string `mapstructure:"id" json:"id"`
+ Disabled bool `mapstructure:"disabled" json:"disabled"`
+ CacheTTL DefaultTTLs `mapstructure:"cache_ttl" json:"cache_ttl"`
+ EventsEnabled bool `mapstructure:"events_enabled" json:"events_enabled"`
+ CCPA AccountCCPA `mapstructure:"ccpa" json:"ccpa"`
+ GDPR AccountGDPR `mapstructure:"gdpr" json:"gdpr"`
+ DebugAllow bool `mapstructure:"debug_allow" json:"debug_allow"`
+ DefaultIntegration string `mapstructure:"default_integration"`
}
// AccountCCPA represents account-specific CCPA configuration
diff --git a/config/config.go b/config/config.go
index 41809aea97f..b5208792ce3 100644
--- a/config/config.go
+++ b/config/config.go
@@ -88,6 +88,8 @@ type Configuration struct {
GenerateBidID bool `mapstructure:"generate_bid_id"`
// GenerateRequestID overrides the bidrequest.id in an AMP Request or an App Stored Request with a generated UUID if set to true. The default is false.
GenerateRequestID bool `mapstructure:"generate_request_id"`
+ // Integration Type value lives in config so that it can be updated from the request, and then passed for the event URL
+ IntegrationType string
}
const MIN_COOKIE_SIZE_BYTES = 500
@@ -970,6 +972,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("auto_gen_source_tid", true)
v.SetDefault("generate_bid_id", false)
v.SetDefault("generate_request_id", false)
+ v.SetDefault("account_defaults.default_integration", "") // Default Integration For Accounts Can Be Set Here
v.SetDefault("request_timeout_headers.request_time_in_queue", "")
v.SetDefault("request_timeout_headers.request_timeout_in_queue", "")
diff --git a/endpoints/events/event.go b/endpoints/events/event.go
index 5974ba9f7d8..64cb3f353a0 100644
--- a/endpoints/events/event.go
+++ b/endpoints/events/event.go
@@ -26,10 +26,11 @@ const (
AccountIdParameter = "a"
// Optional
- BidderParameter = "bidder"
- TimestampParameter = "ts"
- FormatParameter = "f"
- AnalyticsParameter = "x"
+ BidderParameter = "bidder"
+ TimestampParameter = "ts"
+ FormatParameter = "f"
+ AnalyticsParameter = "x"
+ IntegrationTypeParameter = "int"
)
type eventEndpoint struct {
@@ -225,6 +226,10 @@ func optionalParameters(request *analytics.EventRequest) string {
r.Add(AnalyticsParameter, string(analytics.Disabled))
}
+ if request.IntegrationType != "" {
+ r.Add(IntegrationTypeParameter, request.IntegrationType)
+ }
+
opt := r.Encode()
if opt != "" {
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index ba8071843f4..813a5f3200f 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -4,16 +4,17 @@ import (
"context"
"encoding/base64"
"encoding/json"
- "github.com/prebid/prebid-server/analytics"
- "github.com/prebid/prebid-server/config"
- "github.com/prebid/prebid-server/stored_requests"
- "github.com/stretchr/testify/assert"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
+
+ "github.com/prebid/prebid-server/analytics"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/stored_requests"
+ "github.com/stretchr/testify/assert"
)
// Mock Analytics Module
@@ -652,6 +653,19 @@ func TestEventRequestToUrl(t *testing.T) {
},
want: "http://localhost:8000/event?t=win&b=bidid&a=accountId&bidder=bidder&f=i&ts=1234567&x=0",
},
+ "three": {
+ er: &analytics.EventRequest{
+ Type: analytics.Win,
+ BidID: "bidid",
+ AccountID: "accountId",
+ Bidder: "bidder",
+ Timestamp: 1234567,
+ Format: analytics.Image,
+ Analytics: analytics.Disabled,
+ IntegrationType: "integrationType",
+ },
+ want: "http://localhost:8000/event?t=win&b=bidid&a=accountId&bidder=bidder&f=i&int=integrationType&ts=1234567&x=0",
+ },
}
for name, test := range tests {
diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go
index da845162de2..7a685725f41 100644
--- a/endpoints/events/vtrack.go
+++ b/endpoints/events/vtrack.go
@@ -128,15 +128,16 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
}
// GetVastUrlTracking creates a vast url tracking
-func GetVastUrlTracking(externalUrl string, bidid string, bidder string, accountId string, timestamp int64) string {
+func GetVastUrlTracking(externalUrl string, bidid string, bidder string, accountId string, timestamp int64, integrationType string) string {
eventReq := &analytics.EventRequest{
- Type: analytics.Imp,
- BidID: bidid,
- AccountID: accountId,
- Bidder: bidder,
- Timestamp: timestamp,
- Format: analytics.Blank,
+ Type: analytics.Imp,
+ BidID: bidid,
+ AccountID: accountId,
+ Bidder: bidder,
+ Timestamp: timestamp,
+ Format: analytics.Blank,
+ IntegrationType: integrationType,
}
return EventRequestToUrl(externalUrl, eventReq)
@@ -229,7 +230,7 @@ func (v *vtrackEndpoint) cachePutObjects(ctx context.Context, req *BidCacheReque
}
if _, ok := biddersAllowingVastUpdate[c.Bidder]; ok && nc.Data != nil {
- nc.Data = ModifyVastXmlJSON(v.Cfg.ExternalURL, nc.Data, c.BidID, c.Bidder, accountId, c.Timestamp)
+ nc.Data = ModifyVastXmlJSON(v.Cfg.ExternalURL, nc.Data, c.BidID, c.Bidder, accountId, c.Timestamp, v.Cfg.IntegrationType)
}
cacheables = append(cacheables, *nc)
@@ -269,7 +270,7 @@ func getAccountId(httpRequest *http.Request) string {
}
// ModifyVastXmlString rewrites and returns the string vastXML and a flag indicating if it was modified
-func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, timestamp int64) (string, bool) {
+func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, timestamp int64, integrationType string) (string, bool) {
ci := strings.Index(vast, ImpressionCloseTag)
// no impression tag - pass it as it is
@@ -277,7 +278,7 @@ func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, tim
return vast, false
}
- vastUrlTracking := GetVastUrlTracking(externalUrl, bidid, bidder, accountID, timestamp)
+ vastUrlTracking := GetVastUrlTracking(externalUrl, bidid, bidder, accountID, timestamp, integrationType)
impressionUrl := ""
oi := strings.Index(vast, ImpressionOpenTag)
@@ -289,13 +290,13 @@ func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, tim
}
// ModifyVastXmlJSON modifies BidCacheRequest element Vast XML data
-func ModifyVastXmlJSON(externalUrl string, data json.RawMessage, bidid, bidder, accountId string, timestamp int64) json.RawMessage {
+func ModifyVastXmlJSON(externalUrl string, data json.RawMessage, bidid, bidder, accountId string, timestamp int64, integrationType string) json.RawMessage {
var vast string
if err := json.Unmarshal(data, &vast); err != nil {
// failed to decode json, fall back to string
vast = string(data)
}
- vast, ok := ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountId, timestamp)
+ vast, ok := ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountId, timestamp, integrationType)
if !ok {
return data
}
diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go
index 1766f2e2e0d..54c041bde43 100644
--- a/endpoints/events/vtrack_test.go
+++ b/endpoints/events/vtrack_test.go
@@ -633,8 +633,8 @@ func TestShouldRespondWithInternalErrorPbsCacheIsNotConfigured(t *testing.T) {
}
func TestVastUrlShouldReturnExpectedUrl(t *testing.T) {
- url := GetVastUrlTracking("http://external-url", "bidId", "bidder", "accountId", 1000)
- assert.Equal(t, "http://external-url/event?t=imp&b=bidId&a=accountId&bidder=bidder&f=b&ts=1000", url, "Invalid vast url")
+ url := GetVastUrlTracking("http://external-url", "bidId", "bidder", "accountId", 1000, "integrationType")
+ assert.Equal(t, "http://external-url/event?t=imp&b=bidId&a=accountId&bidder=bidder&f=b&int=integrationType&ts=1000", url, "Invalid vast url")
}
func getValidVTrackRequestBody(withImpression bool, withContent bool) (string, error) {
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 8e9725f37f2..cb6bd49af29 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -309,6 +309,13 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request) (req *openrtb_
lmt.ModifyForIOS(req.BidRequest)
+ // Integration Type Handling
+ err = deps.setIntegrationType(req)
+ if err != nil {
+ errs = []error{err}
+ return
+ }
+
errL := deps.validateRequest(req, false)
if len(errL) > 0 {
errs = append(errs, errL...)
@@ -1795,3 +1802,18 @@ func checkIfAppRequest(request []byte) (bool, error) {
}
return false, nil
}
+
+func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper) error {
+ reqExt, err := req.GetRequestExt()
+ if err != nil {
+ return err
+ }
+ reqPrebid := reqExt.GetPrebid()
+ if reqPrebid == nil {
+ reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: deps.cfg.AccountDefaults.DefaultIntegration}
+ reqExt.SetPrebid(reqPrebid)
+ req.RebuildRequest()
+ }
+ deps.cfg.IntegrationType = reqPrebid.Integration
+ return nil
+}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index af68d693243..cc8d026471d 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1386,6 +1386,55 @@ func TestValidateOrFillChannel(t *testing.T) {
}
}
+func TestSetIntegrationType(t *testing.T) {
+ deps := &endpointDeps{
+ fakeUUIDGenerator{},
+ &nobidExchange{},
+ newParamsValidator(t),
+ &mockStoredReqFetcher{},
+ empty_fetcher.EmptyFetcher{},
+ empty_fetcher.EmptyFetcher{},
+ &config.Configuration{MaxRequestSize: maxSize, AccountDefaults: config.Account{DefaultIntegration: "TestDefaultIntegrationType"}},
+ &metricsConfig.NilMetricsEngine{},
+ analyticsConf.NewPBSAnalytics(&config.Analytics{}),
+ map[string]string{},
+ false,
+ []byte{},
+ openrtb_ext.BuildBidderMap(),
+ nil,
+ nil,
+ hardcodedResponseIPValidator{response: true},
+ }
+
+ testCases := []struct {
+ description string
+ givenRequestWrapper *openrtb_ext.RequestWrapper
+ expectedError error
+ expectedIntegrationType string
+ }{
+ {
+ description: "Request has integration type defined, expect that same integration type",
+ givenRequestWrapper: &openrtb_ext.RequestWrapper{
+ BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": "TestIntegrationType"}}`)},
+ },
+ expectedIntegrationType: "TestIntegrationType",
+ },
+ {
+ description: "Request doesn't have request.ext.prebid path, expect default integration value",
+ givenRequestWrapper: &openrtb_ext.RequestWrapper{
+ BidRequest: &openrtb2.BidRequest{Ext: []byte(``)},
+ },
+ expectedIntegrationType: "TestDefaultIntegrationType",
+ },
+ }
+
+ for _, test := range testCases {
+ err := deps.setIntegrationType(test.givenRequestWrapper)
+ assert.Empty(t, err, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, deps.cfg.IntegrationType, "Integration type information isn't correct: %s\n", test.description)
+ }
+}
+
func TestStoredRequestGenerateUuid(t *testing.T) {
uuid := "foo"
diff --git a/exchange/events.go b/exchange/events.go
index bedafddf5a0..4c31f8ddbdb 100644
--- a/exchange/events.go
+++ b/exchange/events.go
@@ -4,11 +4,10 @@ import (
"encoding/json"
"time"
- "github.com/evanphx/json-patch"
+ jsonpatch "github.com/evanphx/json-patch"
"github.com/prebid/prebid-server/analytics"
"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/endpoints/events"
- "github.com/prebid/prebid-server/metrics"
"github.com/prebid/prebid-server/openrtb_ext"
)
@@ -18,7 +17,7 @@ type eventTracking struct {
enabledForAccount bool
enabledForRequest bool
auctionTimestampMs int64
- integration metrics.DemandSource // web app amp
+ integrationType string
bidderInfos config.BidderInfos
externalURL string
}
@@ -30,7 +29,7 @@ func getEventTracking(requestExtPrebid *openrtb_ext.ExtRequestPrebid, ts time.Ti
enabledForAccount: account.EventsEnabled,
enabledForRequest: requestExtPrebid != nil && requestExtPrebid.Events != nil,
auctionTimestampMs: ts.UnixNano() / 1e+6,
- integration: "", // TODO: add integration support, see #1428
+ integrationType: requestExtPrebid.Integration,
bidderInfos: bidderInfos,
externalURL: externalURL,
}
@@ -66,7 +65,7 @@ func (ev *eventTracking) modifyBidVAST(pbsBid *pbsOrtbBid, bidderName openrtb_ex
if len(pbsBid.generatedBidID) > 0 {
bidID = pbsBid.generatedBidID
}
- if newVastXML, ok := events.ModifyVastXmlString(ev.externalURL, vastXML, bidID, bidderName.String(), ev.accountID, ev.auctionTimestampMs); ok {
+ if newVastXML, ok := events.ModifyVastXmlString(ev.externalURL, vastXML, bidID, bidderName.String(), ev.accountID, ev.auctionTimestampMs, ev.integrationType); ok {
bid.AdM = newVastXML
}
}
diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go
index a65e8d3c7b1..60af1b6adc6 100644
--- a/openrtb_ext/request.go
+++ b/openrtb_ext/request.go
@@ -32,6 +32,7 @@ type ExtRequestPrebid struct {
Channel *ExtRequestPrebidChannel `json:"channel,omitempty"`
Data *ExtRequestPrebidData `json:"data,omitempty"`
Debug bool `json:"debug,omitempty"`
+ Integration string `json:"integration,omitempty"`
Events json.RawMessage `json:"events,omitempty"`
SChains []*ExtRequestPrebidSChain `json:"schains,omitempty"`
StoredRequest *ExtStoredRequest `json:"storedrequest,omitempty"`
From 71f7ff527d23d8d10be3f4d53cf3688d1b22ea95 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Mon, 10 Jan 2022 15:50:30 -0800
Subject: [PATCH 02/10] Addressing comments, fixed tests
---
analytics/event.go | 16 ++++++++--------
config/accounts.go | 2 +-
config/config.go | 2 +-
endpoints/events/event.go | 4 ++--
endpoints/events/event_test.go | 18 +++++++++---------
endpoints/events/vtrack.go | 16 ++++++++--------
endpoints/openrtb2/auction.go | 4 +++-
endpoints/openrtb2/auction_test.go | 8 ++++++++
.../invalid-whole/cache-nothing.json | 2 +-
9 files changed, 41 insertions(+), 31 deletions(-)
diff --git a/analytics/event.go b/analytics/event.go
index 1683191d322..56b757693e6 100644
--- a/analytics/event.go
+++ b/analytics/event.go
@@ -28,12 +28,12 @@ const (
)
type EventRequest struct {
- Type EventType `json:"type,omitempty"`
- Format ResponseFormat `json:"format,omitempty"`
- Analytics Analytics `json:"analytics,omitempty"`
- BidID string `json:"bidid,omitempty"`
- AccountID string `json:"account_id,omitempty"`
- Bidder string `json:"bidder,omitempty"`
- Timestamp int64 `json:"timestamp,omitempty"`
- IntegrationType string `json:"integration_type,omitempty"`
+ Type EventType `json:"type,omitempty"`
+ Format ResponseFormat `json:"format,omitempty"`
+ Analytics Analytics `json:"analytics,omitempty"`
+ BidID string `json:"bidid,omitempty"`
+ AccountID string `json:"account_id,omitempty"`
+ Bidder string `json:"bidder,omitempty"`
+ Timestamp int64 `json:"timestamp,omitempty"`
+ Integration string `json:"integration,omitempty"`
}
diff --git a/config/accounts.go b/config/accounts.go
index 5a6e82dce04..dd4d273ebcf 100644
--- a/config/accounts.go
+++ b/config/accounts.go
@@ -20,7 +20,7 @@ type Account struct {
CCPA AccountCCPA `mapstructure:"ccpa" json:"ccpa"`
GDPR AccountGDPR `mapstructure:"gdpr" json:"gdpr"`
DebugAllow bool `mapstructure:"debug_allow" json:"debug_allow"`
- DefaultIntegration string `mapstructure:"default_integration"`
+ DefaultIntegration string `mapstructure:"default_integration" json:"default_integration"`
}
// AccountCCPA represents account-specific CCPA configuration
diff --git a/config/config.go b/config/config.go
index 2ab6cc9ddeb..15276598441 100644
--- a/config/config.go
+++ b/config/config.go
@@ -1003,7 +1003,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("auto_gen_source_tid", true)
v.SetDefault("generate_bid_id", false)
v.SetDefault("generate_request_id", false)
- v.SetDefault("account_defaults.default_integration", "") // Default Integration For Accounts Can Be Set Here
+ v.SetDefault("account_defaults.default_integration", "")
v.SetDefault("request_timeout_headers.request_time_in_queue", "")
v.SetDefault("request_timeout_headers.request_timeout_in_queue", "")
diff --git a/endpoints/events/event.go b/endpoints/events/event.go
index 64cb3f353a0..d187d5fafd1 100644
--- a/endpoints/events/event.go
+++ b/endpoints/events/event.go
@@ -226,8 +226,8 @@ func optionalParameters(request *analytics.EventRequest) string {
r.Add(AnalyticsParameter, string(analytics.Disabled))
}
- if request.IntegrationType != "" {
- r.Add(IntegrationTypeParameter, request.IntegrationType)
+ if request.Integration != "" {
+ r.Add(IntegrationTypeParameter, request.Integration)
}
opt := r.Encode()
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index 813a5f3200f..f8431ad5913 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -655,16 +655,16 @@ func TestEventRequestToUrl(t *testing.T) {
},
"three": {
er: &analytics.EventRequest{
- Type: analytics.Win,
- BidID: "bidid",
- AccountID: "accountId",
- Bidder: "bidder",
- Timestamp: 1234567,
- Format: analytics.Image,
- Analytics: analytics.Disabled,
- IntegrationType: "integrationType",
+ Type: analytics.Win,
+ BidID: "bidid",
+ AccountID: "accountId",
+ Bidder: "bidder",
+ Timestamp: 1234567,
+ Format: analytics.Image,
+ Analytics: analytics.Disabled,
+ Integration: "integration",
},
- want: "http://localhost:8000/event?t=win&b=bidid&a=accountId&bidder=bidder&f=i&int=integrationType&ts=1234567&x=0",
+ want: "http://localhost:8000/event?t=win&b=bidid&a=accountId&bidder=bidder&f=i&int=integration&ts=1234567&x=0",
},
}
diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go
index 7a685725f41..ec9907025b1 100644
--- a/endpoints/events/vtrack.go
+++ b/endpoints/events/vtrack.go
@@ -128,16 +128,16 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
}
// GetVastUrlTracking creates a vast url tracking
-func GetVastUrlTracking(externalUrl string, bidid string, bidder string, accountId string, timestamp int64, integrationType string) string {
+func GetVastUrlTracking(externalUrl string, bidid string, bidder string, accountId string, timestamp int64, integration string) string {
eventReq := &analytics.EventRequest{
- Type: analytics.Imp,
- BidID: bidid,
- AccountID: accountId,
- Bidder: bidder,
- Timestamp: timestamp,
- Format: analytics.Blank,
- IntegrationType: integrationType,
+ Type: analytics.Imp,
+ BidID: bidid,
+ AccountID: accountId,
+ Bidder: bidder,
+ Timestamp: timestamp,
+ Format: analytics.Blank,
+ Integration: integration,
}
return EventRequestToUrl(externalUrl, eventReq)
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 96c69eb6afc..cda7ef3059a 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -1838,7 +1838,9 @@ func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper) er
if reqPrebid == nil {
reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: deps.cfg.AccountDefaults.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
- req.RebuildRequest()
+ } else if reqPrebid.Integration == "" {
+ reqPrebid.Integration = deps.cfg.AccountDefaults.DefaultIntegration
+ reqExt.SetPrebid(reqPrebid)
}
deps.cfg.IntegrationType = reqPrebid.Integration
return nil
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index eef3bc0e874..e08a6fd5030 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1709,6 +1709,7 @@ func TestSetIntegrationType(t *testing.T) {
nil,
nil,
hardcodedResponseIPValidator{response: true},
+ empty_fetcher.EmptyFetcher{},
}
testCases := []struct {
@@ -1731,6 +1732,13 @@ func TestSetIntegrationType(t *testing.T) {
},
expectedIntegrationType: "TestDefaultIntegrationType",
},
+ {
+ description: "Test 3",
+ givenRequestWrapper: &openrtb_ext.RequestWrapper{
+ BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": ""}}`)},
+ },
+ expectedIntegrationType: "TestDefaultIntegrationType",
+ },
}
for _, test := range testCases {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
index 76dc1c2bb5c..5e2ac8f737d 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
@@ -27,5 +27,5 @@
}
},
"expectedReturnCode": 400,
- "expectedErrorMessage": "Invalid request: request.ext is invalid: request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
+ "expectedErrorMessage": "Invalid request: request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
}
From 1e6272862af0d26cdc55b087360ebca79a8b1611 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Thu, 20 Jan 2022 09:42:34 -0800
Subject: [PATCH 03/10] Updated vtrack URL integration, altered tests,
refactoring
---
config/config.go | 3 --
endpoints/events/vtrack.go | 24 +++++++++-----
endpoints/openrtb2/auction.go | 31 ++++++++++++-------
endpoints/openrtb2/auction_test.go | 18 +++++++----
.../invalid-whole/cache-nothing.json | 4 +--
5 files changed, 50 insertions(+), 30 deletions(-)
diff --git a/config/config.go b/config/config.go
index 15276598441..1b415fdf798 100644
--- a/config/config.go
+++ b/config/config.go
@@ -89,8 +89,6 @@ type Configuration struct {
GenerateBidID bool `mapstructure:"generate_bid_id"`
// GenerateRequestID overrides the bidrequest.id in an AMP Request or an App Stored Request with a generated UUID if set to true. The default is false.
GenerateRequestID bool `mapstructure:"generate_request_id"`
- // Integration Type value lives in config so that it can be updated from the request, and then passed for the event URL
- IntegrationType string
}
const MIN_COOKIE_SIZE_BYTES = 500
@@ -1003,7 +1001,6 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("auto_gen_source_tid", true)
v.SetDefault("generate_bid_id", false)
v.SetDefault("generate_request_id", false)
- v.SetDefault("account_defaults.default_integration", "")
v.SetDefault("request_timeout_headers.request_time_in_queue", "")
v.SetDefault("request_timeout_headers.request_timeout_in_queue", "")
diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go
index ec9907025b1..0c20fe9fca1 100644
--- a/endpoints/events/vtrack.go
+++ b/endpoints/events/vtrack.go
@@ -21,9 +21,10 @@ import (
)
const (
- AccountParameter = "a"
- ImpressionCloseTag = ""
- ImpressionOpenTag = ""
+ AccountParameter = "a"
+ IntegrationParameter = "int"
+ ImpressionCloseTag = ""
+ ImpressionOpenTag = ""
)
type vtrackEndpoint struct {
@@ -69,6 +70,9 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
return
}
+ // get integration value from request parameter
+ integrationType := getIntegrationType(r)
+
// parse puts request from request body
req, err := ParseVTrackRequest(r, v.Cfg.MaxRequestSize+1)
@@ -96,7 +100,7 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
// insert impression tracking if account allows events and bidder allows VAST modification
if v.Cache != nil {
- cachingResponse, errs := v.handleVTrackRequest(ctx, req, account)
+ cachingResponse, errs := v.handleVTrackRequest(ctx, req, account, integrationType)
if len(errs) > 0 {
w.WriteHeader(http.StatusInternalServerError)
@@ -191,10 +195,10 @@ func ParseVTrackRequest(httpRequest *http.Request, maxRequestSize int64) (req *B
}
// handleVTrackRequest handles a VTrack request
-func (v *vtrackEndpoint) handleVTrackRequest(ctx context.Context, req *BidCacheRequest, account *config.Account) (*BidCacheResponse, []error) {
+func (v *vtrackEndpoint) handleVTrackRequest(ctx context.Context, req *BidCacheRequest, account *config.Account, integration string) (*BidCacheResponse, []error) {
biddersAllowingVastUpdate := getBiddersAllowingVastUpdate(req, &v.BidderInfos, v.Cfg.VTrack.AllowUnknownBidder)
// cache data
- r, errs := v.cachePutObjects(ctx, req, biddersAllowingVastUpdate, account.ID)
+ r, errs := v.cachePutObjects(ctx, req, biddersAllowingVastUpdate, account.ID, integration)
// handle pbs caching errors
if len(errs) != 0 {
@@ -217,7 +221,7 @@ func (v *vtrackEndpoint) handleVTrackRequest(ctx context.Context, req *BidCacheR
}
// cachePutObjects caches BidCacheRequest data
-func (v *vtrackEndpoint) cachePutObjects(ctx context.Context, req *BidCacheRequest, biddersAllowingVastUpdate map[string]struct{}, accountId string) ([]string, []error) {
+func (v *vtrackEndpoint) cachePutObjects(ctx context.Context, req *BidCacheRequest, biddersAllowingVastUpdate map[string]struct{}, accountId string, integration string) ([]string, []error) {
var cacheables []prebid_cache_client.Cacheable
for _, c := range req.Puts {
@@ -230,7 +234,7 @@ func (v *vtrackEndpoint) cachePutObjects(ctx context.Context, req *BidCacheReque
}
if _, ok := biddersAllowingVastUpdate[c.Bidder]; ok && nc.Data != nil {
- nc.Data = ModifyVastXmlJSON(v.Cfg.ExternalURL, nc.Data, c.BidID, c.Bidder, accountId, c.Timestamp, v.Cfg.IntegrationType)
+ nc.Data = ModifyVastXmlJSON(v.Cfg.ExternalURL, nc.Data, c.BidID, c.Bidder, accountId, c.Timestamp, integration)
}
cacheables = append(cacheables, *nc)
@@ -269,6 +273,10 @@ func getAccountId(httpRequest *http.Request) string {
return httpRequest.URL.Query().Get(AccountParameter)
}
+func getIntegrationType(httpRequest *http.Request) string {
+ return httpRequest.URL.Query().Get(IntegrationParameter)
+}
+
// ModifyVastXmlString rewrites and returns the string vastXML and a flag indicating if it was modified
func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, timestamp int64, integrationType string) (string, bool) {
ci := strings.Index(vast, ImpressionCloseTag)
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index cda7ef3059a..efc02b7f8f5 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -193,6 +193,14 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
return
}
+ // Set Integration Information
+ err := deps.setIntegrationType(req, account)
+ if err != nil {
+ errL = append(errL, err)
+ writeError(errL, w, &labels)
+ return
+ }
+
// rebuild/resync the request in the request wrapper.
if err := req.RebuildRequest(); err != nil {
errL = append(errL, err)
@@ -312,13 +320,6 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request) (req *openrtb_
lmt.ModifyForIOS(req.BidRequest)
- // Integration Type Handling
- err = deps.setIntegrationType(req)
- if err != nil {
- errs = []error{err}
- return
- }
-
errL := deps.validateRequest(req, false)
if len(errL) > 0 {
errs = append(errs, errL...)
@@ -1829,19 +1830,27 @@ func checkIfAppRequest(request []byte) (bool, error) {
return false, nil
}
-func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper) error {
+func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper, account *config.Account) error {
reqExt, err := req.GetRequestExt()
if err != nil {
return err
}
reqPrebid := reqExt.GetPrebid()
if reqPrebid == nil {
- reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: deps.cfg.AccountDefaults.DefaultIntegration}
+ reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: account.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
} else if reqPrebid.Integration == "" {
- reqPrebid.Integration = deps.cfg.AccountDefaults.DefaultIntegration
+ reqPrebid.Integration = account.DefaultIntegration
reqExt.SetPrebid(reqPrebid)
}
- deps.cfg.IntegrationType = reqPrebid.Integration
return nil
}
+
+func getIntegrationFromRequest(req *openrtb_ext.RequestWrapper) (string, error) {
+ reqExt, err := req.GetRequestExt()
+ if err != nil {
+ return "", err
+ }
+ reqPrebid := reqExt.GetPrebid()
+ return reqPrebid.Integration, nil
+}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index e08a6fd5030..173a8d4cd7d 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1699,7 +1699,7 @@ func TestSetIntegrationType(t *testing.T) {
&mockStoredReqFetcher{},
empty_fetcher.EmptyFetcher{},
empty_fetcher.EmptyFetcher{},
- &config.Configuration{MaxRequestSize: maxSize, AccountDefaults: config.Account{DefaultIntegration: "TestDefaultIntegrationType"}},
+ &config.Configuration{},
&metricsConfig.NilMetricsEngine{},
analyticsConf.NewPBSAnalytics(&config.Analytics{}),
map[string]string{},
@@ -1715,6 +1715,7 @@ func TestSetIntegrationType(t *testing.T) {
testCases := []struct {
description string
givenRequestWrapper *openrtb_ext.RequestWrapper
+ givenAccount *config.Account
expectedError error
expectedIntegrationType string
}{
@@ -1723,6 +1724,7 @@ func TestSetIntegrationType(t *testing.T) {
givenRequestWrapper: &openrtb_ext.RequestWrapper{
BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": "TestIntegrationType"}}`)},
},
+ givenAccount: &config.Account{DefaultIntegration: "TestDefaultIntegration"},
expectedIntegrationType: "TestIntegrationType",
},
{
@@ -1730,21 +1732,25 @@ func TestSetIntegrationType(t *testing.T) {
givenRequestWrapper: &openrtb_ext.RequestWrapper{
BidRequest: &openrtb2.BidRequest{Ext: []byte(``)},
},
- expectedIntegrationType: "TestDefaultIntegrationType",
+ givenAccount: &config.Account{DefaultIntegration: "TestDefaultIntegration"},
+ expectedIntegrationType: "TestDefaultIntegration",
},
{
- description: "Test 3",
+ description: "Request has blank integration in request, expect default integration value ",
givenRequestWrapper: &openrtb_ext.RequestWrapper{
BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": ""}}`)},
},
- expectedIntegrationType: "TestDefaultIntegrationType",
+ givenAccount: &config.Account{DefaultIntegration: "TestDefaultIntegration"},
+ expectedIntegrationType: "TestDefaultIntegration",
},
}
for _, test := range testCases {
- err := deps.setIntegrationType(test.givenRequestWrapper)
+ err := deps.setIntegrationType(test.givenRequestWrapper, test.givenAccount)
assert.Empty(t, err, test.description)
- assert.Equalf(t, test.expectedIntegrationType, deps.cfg.IntegrationType, "Integration type information isn't correct: %s\n", test.description)
+ integrationTypeFromReq, err2 := getIntegrationFromRequest(test.givenRequestWrapper)
+ assert.Empty(t, err2, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, integrationTypeFromReq, "Integration type information isn't correct: %s\n", test.description)
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
index 5e2ac8f737d..9bbc96609bf 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
@@ -27,5 +27,5 @@
}
},
"expectedReturnCode": 400,
- "expectedErrorMessage": "Invalid request: request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
-}
+ "expectedErrorMessage": "Invalid request: request.ext is invalid: request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
+}
\ No newline at end of file
From 5bbabae49eb3bfec26e7b4494581c51ecd341504 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Tue, 25 Jan 2022 14:25:30 -0800
Subject: [PATCH 04/10] Added integration type validation, minor refactoring
---
endpoints/openrtb2/auction.go | 34 +++++++++++++++++++++-------
endpoints/openrtb2/auction_test.go | 36 ++++++++++++++++++++++++++----
2 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index efc02b7f8f5..4e235a07a25 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -12,6 +12,7 @@ import (
"regexp"
"strconv"
"time"
+ "unicode"
"github.com/prebid/prebid-server/firstpartydata"
@@ -47,6 +48,7 @@ import (
const storedRequestTimeoutMillis = 50
const ampChannel = "amp"
const appChannel = "app"
+const integrationParamMaxLength = 64
var (
dntKey string = http.CanonicalHeaderKey("DNT")
@@ -1836,21 +1838,37 @@ func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper, ac
return err
}
reqPrebid := reqExt.GetPrebid()
- if reqPrebid == nil {
+ if reqPrebid == nil && account != nil {
+ err := validateIntegrationType(account.DefaultIntegration)
+ if err != nil {
+ return err
+ }
reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: account.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
- } else if reqPrebid.Integration == "" {
+ } else if reqPrebid.Integration == "" && account.DefaultIntegration != "" {
+ err := validateIntegrationType(account.DefaultIntegration)
+ if err != nil {
+ return err
+ }
reqPrebid.Integration = account.DefaultIntegration
reqExt.SetPrebid(reqPrebid)
+ } else {
+ err := validateIntegrationType(reqPrebid.Integration)
+ if err != nil {
+ return err
+ }
}
return nil
}
-func getIntegrationFromRequest(req *openrtb_ext.RequestWrapper) (string, error) {
- reqExt, err := req.GetRequestExt()
- if err != nil {
- return "", err
+func validateIntegrationType(integrationType string) error {
+ if len(integrationType) > integrationParamMaxLength {
+ return errors.New("integration type length is too long")
}
- reqPrebid := reqExt.GetPrebid()
- return reqPrebid.Integration, nil
+ for _, char := range integrationType {
+ if !(unicode.IsDigit(char) || unicode.IsLetter(char)) && char != '-' && char != '_' {
+ return errors.New("integration type can only contain numbers, letters and these characters '-', '_'")
+ }
+ }
+ return nil
}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index 173a8d4cd7d..8f8c0cf98b1 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1743,14 +1743,33 @@ func TestSetIntegrationType(t *testing.T) {
givenAccount: &config.Account{DefaultIntegration: "TestDefaultIntegration"},
expectedIntegrationType: "TestDefaultIntegration",
},
+ {
+ description: "Given integration type is too long, expect error to be thrown",
+ givenRequestWrapper: &openrtb_ext.RequestWrapper{
+ BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": "IntegrationTypeLongerThanMaxIntegrationTypeLongerThanMaxIntegration"}}`)},
+ },
+ expectedError: errors.New("integration type length is too long"),
+ },
+ {
+ description: "Default integration type contains invalid characters, expect error to be thrown",
+ givenRequestWrapper: &openrtb_ext.RequestWrapper{
+ BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": ""}}`)},
+ },
+ givenAccount: &config.Account{DefaultIntegration: "$$TestDefaultIntegration$$"},
+ expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
+ },
}
for _, test := range testCases {
err := deps.setIntegrationType(test.givenRequestWrapper, test.givenAccount)
- assert.Empty(t, err, test.description)
- integrationTypeFromReq, err2 := getIntegrationFromRequest(test.givenRequestWrapper)
- assert.Empty(t, err2, test.description)
- assert.Equalf(t, test.expectedIntegrationType, integrationTypeFromReq, "Integration type information isn't correct: %s\n", test.description)
+ if test.expectedError != nil {
+ assert.Equalf(t, test.expectedError, err, "Error doesn't match expected")
+ } else {
+ assert.Empty(t, err, test.description)
+ integrationTypeFromReq, err2 := getIntegrationFromRequest(test.givenRequestWrapper)
+ assert.Empty(t, err2, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, integrationTypeFromReq, "Integration type information isn't correct: %s\n", test.description)
+ }
}
}
@@ -4531,3 +4550,12 @@ func getObject(t *testing.T, filename, key string) json.RawMessage {
}
return obj
}
+
+func getIntegrationFromRequest(req *openrtb_ext.RequestWrapper) (string, error) {
+ reqExt, err := req.GetRequestExt()
+ if err != nil {
+ return "", err
+ }
+ reqPrebid := reqExt.GetPrebid()
+ return reqPrebid.Integration, nil
+}
From 75c980edc2844e40b9d7089c74076bd8525eb430 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Wed, 26 Jan 2022 14:38:33 -0800
Subject: [PATCH 05/10] Updated JSON exchange tests, updated event URL to apply
integration type
---
exchange/events.go | 11 ++++++-----
.../events-bid-account-off-request-on.json | 9 +++++----
.../events-bid-account-on-request-off.json | 12 +++++++-----
.../events-vast-account-off-request-on.json | 5 +++--
.../events-vast-account-on-request-off.json | 7 ++++---
5 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/exchange/events.go b/exchange/events.go
index 4c31f8ddbdb..263eff10963 100644
--- a/exchange/events.go
+++ b/exchange/events.go
@@ -112,10 +112,11 @@ func (ev *eventTracking) makeEventURL(evType analytics.EventType, pbsBid *pbsOrt
}
return events.EventRequestToUrl(ev.externalURL,
&analytics.EventRequest{
- Type: evType,
- BidID: bidId,
- Bidder: string(bidderName),
- AccountID: ev.accountID,
- Timestamp: ev.auctionTimestampMs,
+ Type: evType,
+ BidID: bidId,
+ Bidder: string(bidderName),
+ AccountID: ev.accountID,
+ Timestamp: ev.auctionTimestampMs,
+ Integration: ev.integrationType,
})
}
diff --git a/exchange/exchangetest/events-bid-account-off-request-on.json b/exchange/exchangetest/events-bid-account-off-request-on.json
index b88ec67c2bc..1dd2648e0d1 100644
--- a/exchange/exchangetest/events-bid-account-off-request-on.json
+++ b/exchange/exchangetest/events-bid-account-off-request-on.json
@@ -20,6 +20,7 @@
],
"ext": {
"prebid": {
+ "integration" : "testIntegrationType",
"events": {}
}
}
@@ -75,8 +76,8 @@
"prebid": {
"type": "banner",
"events": {
- "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&ts=1234567890",
- "win": "http://localhost/event?t=win&b=winning-bid&a=testaccount&bidder=appnexus&ts=1234567890"
+ "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890",
+ "win": "http://localhost/event?t=win&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890"
}
}
}
@@ -92,8 +93,8 @@
"prebid": {
"type": "banner",
"events": {
- "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&ts=1234567890",
- "win": "http://localhost/event?t=win&b=losing-bid&a=testaccount&bidder=appnexus&ts=1234567890"
+ "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890",
+ "win": "http://localhost/event?t=win&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890"
}
}
}
diff --git a/exchange/exchangetest/events-bid-account-on-request-off.json b/exchange/exchangetest/events-bid-account-on-request-off.json
index e440b0309bb..31e519b2796 100644
--- a/exchange/exchangetest/events-bid-account-on-request-off.json
+++ b/exchange/exchangetest/events-bid-account-on-request-off.json
@@ -19,7 +19,9 @@
}
],
"ext": {
- "prebid": {}
+ "prebid": {
+ "integration" : "testIntegrationType"
+ }
}
}
},
@@ -73,8 +75,8 @@
"prebid": {
"type": "banner",
"events": {
- "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&ts=1234567890",
- "win": "http://localhost/event?t=win&b=winning-bid&a=testaccount&bidder=appnexus&ts=1234567890"
+ "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890",
+ "win": "http://localhost/event?t=win&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890"
}
}
}
@@ -90,8 +92,8 @@
"prebid": {
"type": "banner",
"events": {
- "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&ts=1234567890",
- "win": "http://localhost/event?t=win&b=losing-bid&a=testaccount&bidder=appnexus&ts=1234567890"
+ "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890",
+ "win": "http://localhost/event?t=win&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890"
}
}
}
diff --git a/exchange/exchangetest/events-vast-account-off-request-on.json b/exchange/exchangetest/events-vast-account-off-request-on.json
index 13afb8409af..262b859a500 100644
--- a/exchange/exchangetest/events-vast-account-off-request-on.json
+++ b/exchange/exchangetest/events-vast-account-off-request-on.json
@@ -31,6 +31,7 @@
"includewinners": true,
"includebidderkeys": false
},
+ "integration" : "testIntegrationType",
"events": {}
}
}
@@ -121,7 +122,7 @@
"bid": [
{
"id": "winning-bid",
- "adm": "prebid.org wrapper",
+ "adm": "prebid.org wrapper",
"nurl": "http://domain.com/winning-bid",
"impid": "my-imp-id",
"price": 0.71,
@@ -145,7 +146,7 @@
},
{
"id": "losing-bid",
- "adm": "prebid.org wrapper",
+ "adm": "prebid.org wrapper",
"nurl": "http://domain.com/losing-bid",
"impid": "my-imp-id",
"price": 0.21,
diff --git a/exchange/exchangetest/events-vast-account-on-request-off.json b/exchange/exchangetest/events-vast-account-on-request-off.json
index 21f47356d5b..c5941e25a77 100644
--- a/exchange/exchangetest/events-vast-account-on-request-off.json
+++ b/exchange/exchangetest/events-vast-account-on-request-off.json
@@ -26,7 +26,8 @@
"targeting": {
"includewinners": true,
"includebidderkeys": false
- }
+ },
+ "integration" : "testIntegrationType"
}
}
}
@@ -115,7 +116,7 @@
"bid": [
{
"id": "winning-bid",
- "adm": "prebid.org wrapper",
+ "adm": "prebid.org wrapper",
"nurl": "http://domain.com/winning-bid",
"impid": "my-imp-id",
"price": 0.71,
@@ -138,7 +139,7 @@
},
{
"id": "losing-bid",
- "adm": "prebid.org wrapper",
+ "adm": "prebid.org wrapper",
"nurl": "http://domain.com/losing-bid",
"impid": "my-imp-id",
"price": 0.21,
From c12acb373a92b5cba9841e3586a661318547b298 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Mon, 7 Feb 2022 09:51:54 -0800
Subject: [PATCH 06/10] Added integration validation to event/vtrack URLs
---
endpoints/events/event.go | 29 +++++++++++++++++++++++++++++
endpoints/events/event_test.go | 17 +++++++++--------
endpoints/events/vtrack.go | 15 ++++++++++++---
endpoints/openrtb2/auction.go | 27 ---------------------------
endpoints/openrtb2/auction_test.go | 29 +++++------------------------
5 files changed, 55 insertions(+), 62 deletions(-)
diff --git a/endpoints/events/event.go b/endpoints/events/event.go
index d187d5fafd1..6cc535729f5 100644
--- a/endpoints/events/event.go
+++ b/endpoints/events/event.go
@@ -8,6 +8,7 @@ import (
"net/url"
"strconv"
"time"
+ "unicode"
"github.com/julienschmidt/httprouter"
accountService "github.com/prebid/prebid-server/account"
@@ -33,6 +34,8 @@ const (
IntegrationTypeParameter = "int"
)
+const integrationParamMaxLength = 64
+
type eventEndpoint struct {
Accounts stored_requests.AccountFetcher
Analytics analytics.PBSAnalyticsModule
@@ -163,6 +166,10 @@ func ParseEventRequest(r *http.Request) (*analytics.EventRequest, []error) {
errs = append(errs, err)
}
+ if err := readIntegrationType(event, r); err != nil {
+ errs = append(errs, err)
+ }
+
// Bidder
event.Bidder = r.URL.Query().Get(BidderParameter)
@@ -328,3 +335,25 @@ func checkRequiredParameter(httpRequest *http.Request, parameter string) (string
return t, nil
}
+
+func readIntegrationType(er *analytics.EventRequest, httpRequest *http.Request) error {
+ integrationType := httpRequest.URL.Query().Get(IntegrationParameter)
+ err := validateIntegrationType(integrationType)
+ if err != nil {
+ return err
+ }
+ er.Integration = integrationType
+ return nil
+}
+
+func validateIntegrationType(integrationType string) error {
+ if len(integrationType) > integrationParamMaxLength {
+ return errors.New("integration type length is too long")
+ }
+ for _, char := range integrationType {
+ if !(unicode.IsDigit(char) || unicode.IsLetter(char)) && char != '-' && char != '_' {
+ return errors.New("integration type can only contain numbers, letters and these characters '-', '_'")
+ }
+ }
+ return nil
+}
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index f8431ad5913..47e51ff3186 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -588,15 +588,16 @@ func TestShouldParseEventCorrectly(t *testing.T) {
expected *analytics.EventRequest
}{
"one": {
- req: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder", strings.NewReader("")),
+ req: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=intType", strings.NewReader("")),
expected: &analytics.EventRequest{
- Type: analytics.Win,
- BidID: "bidId",
- Timestamp: 1000,
- Bidder: "bidder",
- AccountID: "",
- Format: analytics.Blank,
- Analytics: analytics.Enabled,
+ Type: analytics.Win,
+ BidID: "bidId",
+ Timestamp: 1000,
+ Bidder: "bidder",
+ AccountID: "",
+ Format: analytics.Blank,
+ Analytics: analytics.Enabled,
+ Integration: "intType",
},
},
"two": {
diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go
index 0c20fe9fca1..4bead1453e8 100644
--- a/endpoints/events/vtrack.go
+++ b/endpoints/events/vtrack.go
@@ -71,7 +71,11 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
}
// get integration value from request parameter
- integrationType := getIntegrationType(r)
+ integrationType, err := getIntegrationType(r)
+ if err != nil {
+ w.Write([]byte(fmt.Sprintf("Invalid integration type: %s\n", err.Error())))
+ return
+ }
// parse puts request from request body
req, err := ParseVTrackRequest(r, v.Cfg.MaxRequestSize+1)
@@ -273,8 +277,13 @@ func getAccountId(httpRequest *http.Request) string {
return httpRequest.URL.Query().Get(AccountParameter)
}
-func getIntegrationType(httpRequest *http.Request) string {
- return httpRequest.URL.Query().Get(IntegrationParameter)
+func getIntegrationType(httpRequest *http.Request) (string, error) {
+ integrationType := httpRequest.URL.Query().Get(IntegrationParameter)
+ err := validateIntegrationType(integrationType)
+ if err != nil {
+ return "", err
+ }
+ return integrationType, nil
}
// ModifyVastXmlString rewrites and returns the string vastXML and a flag indicating if it was modified
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 4e235a07a25..d5f074512b0 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -12,7 +12,6 @@ import (
"regexp"
"strconv"
"time"
- "unicode"
"github.com/prebid/prebid-server/firstpartydata"
@@ -48,7 +47,6 @@ import (
const storedRequestTimeoutMillis = 50
const ampChannel = "amp"
const appChannel = "app"
-const integrationParamMaxLength = 64
var (
dntKey string = http.CanonicalHeaderKey("DNT")
@@ -1839,36 +1837,11 @@ func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper, ac
}
reqPrebid := reqExt.GetPrebid()
if reqPrebid == nil && account != nil {
- err := validateIntegrationType(account.DefaultIntegration)
- if err != nil {
- return err
- }
reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: account.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
} else if reqPrebid.Integration == "" && account.DefaultIntegration != "" {
- err := validateIntegrationType(account.DefaultIntegration)
- if err != nil {
- return err
- }
reqPrebid.Integration = account.DefaultIntegration
reqExt.SetPrebid(reqPrebid)
- } else {
- err := validateIntegrationType(reqPrebid.Integration)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func validateIntegrationType(integrationType string) error {
- if len(integrationType) > integrationParamMaxLength {
- return errors.New("integration type length is too long")
- }
- for _, char := range integrationType {
- if !(unicode.IsDigit(char) || unicode.IsLetter(char)) && char != '-' && char != '_' {
- return errors.New("integration type can only contain numbers, letters and these characters '-', '_'")
- }
}
return nil
}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index 8f8c0cf98b1..bef065c382a 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1716,7 +1716,6 @@ func TestSetIntegrationType(t *testing.T) {
description string
givenRequestWrapper *openrtb_ext.RequestWrapper
givenAccount *config.Account
- expectedError error
expectedIntegrationType string
}{
{
@@ -1743,33 +1742,15 @@ func TestSetIntegrationType(t *testing.T) {
givenAccount: &config.Account{DefaultIntegration: "TestDefaultIntegration"},
expectedIntegrationType: "TestDefaultIntegration",
},
- {
- description: "Given integration type is too long, expect error to be thrown",
- givenRequestWrapper: &openrtb_ext.RequestWrapper{
- BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": "IntegrationTypeLongerThanMaxIntegrationTypeLongerThanMaxIntegration"}}`)},
- },
- expectedError: errors.New("integration type length is too long"),
- },
- {
- description: "Default integration type contains invalid characters, expect error to be thrown",
- givenRequestWrapper: &openrtb_ext.RequestWrapper{
- BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"integration": ""}}`)},
- },
- givenAccount: &config.Account{DefaultIntegration: "$$TestDefaultIntegration$$"},
- expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
- },
}
for _, test := range testCases {
err := deps.setIntegrationType(test.givenRequestWrapper, test.givenAccount)
- if test.expectedError != nil {
- assert.Equalf(t, test.expectedError, err, "Error doesn't match expected")
- } else {
- assert.Empty(t, err, test.description)
- integrationTypeFromReq, err2 := getIntegrationFromRequest(test.givenRequestWrapper)
- assert.Empty(t, err2, test.description)
- assert.Equalf(t, test.expectedIntegrationType, integrationTypeFromReq, "Integration type information isn't correct: %s\n", test.description)
- }
+ assert.Empty(t, err, test.description)
+ integrationTypeFromReq, err2 := getIntegrationFromRequest(test.givenRequestWrapper)
+ assert.Empty(t, err2, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, integrationTypeFromReq, "Integration type information isn't correct: %s\n", test.description)
+
}
}
From f12d6f4558bec7bdeb5c89f30796024fbf47402a Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Mon, 7 Feb 2022 16:35:27 -0800
Subject: [PATCH 07/10] Added more tests for integration validation
---
endpoints/events/event_test.go | 68 ++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index 47e51ff3186..ddcae3c7aaf 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -4,6 +4,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
+ "errors"
"io/ioutil"
"net/http"
"net/http/httptest"
@@ -677,3 +678,70 @@ func TestEventRequestToUrl(t *testing.T) {
})
}
}
+
+func TestReadIntegrationType(t *testing.T) {
+ testCases := []struct {
+ description string
+ givenHttpRequest *http.Request
+ givenEventRequest *analytics.EventRequest
+ expectedIntegrationType string
+ expectedError error
+ }{
+ {
+ description: "Integration type in http request is valid, expect same integration time and no errors",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationType", strings.NewReader("")),
+ givenEventRequest: &analytics.EventRequest{
+ Type: analytics.Imp,
+ BidID: "bidid",
+ AccountID: "accountId",
+ Bidder: "bidder",
+ Timestamp: 1234567,
+ Format: analytics.Blank,
+ Analytics: analytics.Enabled,
+ Integration: "",
+ },
+ expectedIntegrationType: "TestIntegrationType",
+ expectedError: nil,
+ },
+ {
+ description: "Integration type in http request is too long, expect too long error",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationTypeTooLongTestIntegrationTypeTooLongTestIntegrationType", strings.NewReader("")),
+ givenEventRequest: &analytics.EventRequest{
+ Type: analytics.Imp,
+ BidID: "bidid",
+ AccountID: "accountId",
+ Bidder: "bidder",
+ Timestamp: 1234567,
+ Format: analytics.Blank,
+ Analytics: analytics.Enabled,
+ Integration: "",
+ },
+ expectedError: errors.New("integration type length is too long"),
+ },
+ {
+ description: "Integration type in http request contains invalid character, expect invalid character error",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=Te$tIntegrationType", strings.NewReader("")),
+ givenEventRequest: &analytics.EventRequest{
+ Type: analytics.Imp,
+ BidID: "bidid",
+ AccountID: "accountId",
+ Bidder: "bidder",
+ Timestamp: 1234567,
+ Format: analytics.Blank,
+ Analytics: analytics.Enabled,
+ Integration: "",
+ },
+ expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
+ },
+ }
+
+ for _, test := range testCases {
+ err := readIntegrationType(test.givenEventRequest, test.givenHttpRequest)
+ if err != nil {
+ assert.Equal(t, test.expectedError, err, test.description)
+ } else {
+ assert.Empty(t, err, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, test.givenEventRequest.Integration, test.description)
+ }
+ }
+}
From afa43b1042f38068b6415def3ab5980c96151df3 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Tue, 8 Feb 2022 12:32:09 -0800
Subject: [PATCH 08/10] Address minor feedback
---
endpoints/events/event.go | 2 +-
endpoints/events/event_test.go | 44 ++++++---------------------------
endpoints/events/vtrack_test.go | 38 ++++++++++++++++++++++++++++
endpoints/openrtb2/auction.go | 6 ++++-
4 files changed, 51 insertions(+), 39 deletions(-)
diff --git a/endpoints/events/event.go b/endpoints/events/event.go
index 6cc535729f5..fd47683ae49 100644
--- a/endpoints/events/event.go
+++ b/endpoints/events/event.go
@@ -351,7 +351,7 @@ func validateIntegrationType(integrationType string) error {
return errors.New("integration type length is too long")
}
for _, char := range integrationType {
- if !(unicode.IsDigit(char) || unicode.IsLetter(char)) && char != '-' && char != '_' {
+ if !unicode.IsDigit(char) && !unicode.IsLetter(char) && char != '-' && char != '_' {
return errors.New("integration type can only contain numbers, letters and these characters '-', '_'")
}
}
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index ddcae3c7aaf..e75c33a5f31 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -683,65 +683,35 @@ func TestReadIntegrationType(t *testing.T) {
testCases := []struct {
description string
givenHttpRequest *http.Request
- givenEventRequest *analytics.EventRequest
expectedIntegrationType string
expectedError error
}{
{
- description: "Integration type in http request is valid, expect same integration time and no errors",
- givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationType", strings.NewReader("")),
- givenEventRequest: &analytics.EventRequest{
- Type: analytics.Imp,
- BidID: "bidid",
- AccountID: "accountId",
- Bidder: "bidder",
- Timestamp: 1234567,
- Format: analytics.Blank,
- Analytics: analytics.Enabled,
- Integration: "",
- },
+ description: "Integration type in http request is valid, expect same integration time and no errors",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationType", strings.NewReader("")),
expectedIntegrationType: "TestIntegrationType",
expectedError: nil,
},
{
description: "Integration type in http request is too long, expect too long error",
givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationTypeTooLongTestIntegrationTypeTooLongTestIntegrationType", strings.NewReader("")),
- givenEventRequest: &analytics.EventRequest{
- Type: analytics.Imp,
- BidID: "bidid",
- AccountID: "accountId",
- Bidder: "bidder",
- Timestamp: 1234567,
- Format: analytics.Blank,
- Analytics: analytics.Enabled,
- Integration: "",
- },
- expectedError: errors.New("integration type length is too long"),
+ expectedError: errors.New("integration type length is too long"),
},
{
description: "Integration type in http request contains invalid character, expect invalid character error",
givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=Te$tIntegrationType", strings.NewReader("")),
- givenEventRequest: &analytics.EventRequest{
- Type: analytics.Imp,
- BidID: "bidid",
- AccountID: "accountId",
- Bidder: "bidder",
- Timestamp: 1234567,
- Format: analytics.Blank,
- Analytics: analytics.Enabled,
- Integration: "",
- },
- expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
+ expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
},
}
for _, test := range testCases {
- err := readIntegrationType(test.givenEventRequest, test.givenHttpRequest)
+ testEventRequest := &analytics.EventRequest{}
+ err := readIntegrationType(testEventRequest, test.givenHttpRequest)
if err != nil {
assert.Equal(t, test.expectedError, err, test.description)
} else {
assert.Empty(t, err, test.description)
- assert.Equalf(t, test.expectedIntegrationType, test.givenEventRequest.Integration, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, testEventRequest.Integration, test.description)
}
}
}
diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go
index 54c041bde43..1d792b6b12d 100644
--- a/endpoints/events/vtrack_test.go
+++ b/endpoints/events/vtrack_test.go
@@ -4,8 +4,10 @@ import (
"bytes"
"context"
"encoding/json"
+ "errors"
"fmt"
"io/ioutil"
+ "net/http"
"net/http/httptest"
"strings"
"testing"
@@ -690,3 +692,39 @@ func getVTrackRequestData(wi bool, wic bool) (db []byte, e error) {
return data.Bytes(), e
}
+
+func TestGetIntegrationType(t *testing.T) {
+ testCases := []struct {
+ description string
+ givenHttpRequest *http.Request
+ expectedIntegrationType string
+ expectedError error
+ }{
+ {
+ description: "Integration type in http request is valid, expect same integration time and no errors",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationType", strings.NewReader("")),
+ expectedIntegrationType: "TestIntegrationType",
+ expectedError: nil,
+ },
+ {
+ description: "Integration type in http request is too long, expect too long error",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=TestIntegrationTypeTooLongTestIntegrationTypeTooLongTestIntegrationType", strings.NewReader("")),
+ expectedError: errors.New("integration type length is too long"),
+ },
+ {
+ description: "Integration type in http request contains invalid character, expect invalid character error",
+ givenHttpRequest: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=Te$tIntegrationType", strings.NewReader("")),
+ expectedError: errors.New("integration type can only contain numbers, letters and these characters '-', '_'"),
+ },
+ }
+
+ for _, test := range testCases {
+ integrationType, err := getIntegrationType(test.givenHttpRequest)
+ if err != nil {
+ assert.Equal(t, test.expectedError, err, test.description)
+ } else {
+ assert.Empty(t, err, test.description)
+ assert.Equalf(t, test.expectedIntegrationType, integrationType, test.description)
+ }
+ }
+}
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 0d98fbd2ef9..c953d12d08a 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -1887,7 +1887,11 @@ func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper, ac
return err
}
reqPrebid := reqExt.GetPrebid()
- if reqPrebid == nil && account != nil {
+
+ if account == nil {
+ return nil
+ }
+ if reqPrebid == nil {
reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: account.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
} else if reqPrebid.Integration == "" && account.DefaultIntegration != "" {
From a609124495d9c3a099bcb4ff07523add2e11d288 Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Tue, 8 Feb 2022 13:49:39 -0800
Subject: [PATCH 09/10] Added test coverage for readIntegrationType error
---
endpoints/events/event_test.go | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index e75c33a5f31..6de3936da3f 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -394,6 +394,41 @@ func TestShouldNotPassEventToAnalyticsReporterWhenAccountNotFound(t *testing.T)
assert.Equal(t, "Account 'testacc' doesn't support events", string(d))
}
+func TestShouldReturnBadRequestWhenIntegrationValueIsInvalid(t *testing.T) {
+ // mock AccountsFetcher
+ mockAccountsFetcher := &mockAccountsFetcher{}
+
+ // mock PBS Analytics Module
+ mockAnalyticsModule := &eventsMockAnalyticsModule{
+ Fail: false,
+ }
+
+ // mock config
+ cfg := &config.Configuration{
+ AccountDefaults: config.Account{},
+ }
+
+ // prepare
+ reqData := ""
+
+ req := httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=bidder&int=Te$tIntegrationType", strings.NewReader(reqData))
+ recorder := httptest.NewRecorder()
+
+ e := NewEventEndpoint(cfg, mockAccountsFetcher, mockAnalyticsModule)
+
+ // execute
+ e(recorder, req, nil)
+
+ d, err := ioutil.ReadAll(recorder.Result().Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // validate
+ assert.Equal(t, 400, recorder.Result().StatusCode, "Expected 400 on request with invalid integration type parameter")
+ assert.Equal(t, "invalid request: integration type can only contain numbers, letters and these characters '-', '_'\n", string(d))
+}
+
func TestShouldNotPassEventToAnalyticsReporterWhenAccountEventNotEnabled(t *testing.T) {
// mock AccountsFetcher
From e7f1c644fd0afecbaf3fe3380769833b75b25e6b Mon Sep 17 00:00:00 2001
From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com>
Date: Wed, 9 Feb 2022 16:33:27 -0800
Subject: [PATCH 10/10] Minor feedback updates
---
endpoints/events/event_test.go | 2 +-
endpoints/events/vtrack.go | 1 +
endpoints/events/vtrack_test.go | 2 +-
endpoints/openrtb2/auction.go | 4 ++--
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go
index 6de3936da3f..09ad6d5747a 100644
--- a/endpoints/events/event_test.go
+++ b/endpoints/events/event_test.go
@@ -742,7 +742,7 @@ func TestReadIntegrationType(t *testing.T) {
for _, test := range testCases {
testEventRequest := &analytics.EventRequest{}
err := readIntegrationType(testEventRequest, test.givenHttpRequest)
- if err != nil {
+ if test.expectedError != nil {
assert.Equal(t, test.expectedError, err, test.description)
} else {
assert.Empty(t, err, test.description)
diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go
index 4bead1453e8..5e6a90249d1 100644
--- a/endpoints/events/vtrack.go
+++ b/endpoints/events/vtrack.go
@@ -73,6 +73,7 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro
// get integration value from request parameter
integrationType, err := getIntegrationType(r)
if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Invalid integration type: %s\n", err.Error())))
return
}
diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go
index 1d792b6b12d..d8905d7b443 100644
--- a/endpoints/events/vtrack_test.go
+++ b/endpoints/events/vtrack_test.go
@@ -720,7 +720,7 @@ func TestGetIntegrationType(t *testing.T) {
for _, test := range testCases {
integrationType, err := getIntegrationType(test.givenHttpRequest)
- if err != nil {
+ if test.expectedError != nil {
assert.Equal(t, test.expectedError, err, test.description)
} else {
assert.Empty(t, err, test.description)
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index c953d12d08a..33db0a94434 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -1888,13 +1888,13 @@ func (deps *endpointDeps) setIntegrationType(req *openrtb_ext.RequestWrapper, ac
}
reqPrebid := reqExt.GetPrebid()
- if account == nil {
+ if account == nil || account.DefaultIntegration == "" {
return nil
}
if reqPrebid == nil {
reqPrebid = &openrtb_ext.ExtRequestPrebid{Integration: account.DefaultIntegration}
reqExt.SetPrebid(reqPrebid)
- } else if reqPrebid.Integration == "" && account.DefaultIntegration != "" {
+ } else if reqPrebid.Integration == "" {
reqPrebid.Integration = account.DefaultIntegration
reqExt.SetPrebid(reqPrebid)
}