Skip to content

Commit

Permalink
Added TransmitPreciseGeo activity handling in modules (prebid#3348)
Browse files Browse the repository at this point in the history
  • Loading branch information
VeronikaSolovei9 authored Jan 16, 2024
1 parent 3789cf9 commit 27b2ff6
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 70 deletions.
1 change: 1 addition & 0 deletions endpoints/openrtb2/amp_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
activityControl = privacy.NewActivityControl(&account.Privacy)

hookExecutor.SetActivityControl(activityControl)
hookExecutor.SetAccount(account)

secGPC := r.Header.Get("Sec-GPC")

Expand Down
1 change: 1 addition & 0 deletions endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
activityControl = privacy.NewActivityControl(&account.Privacy)

hookExecutor.SetActivityControl(activityControl)
hookExecutor.SetAccount(account)

ctx := context.Background()

Expand Down
40 changes: 29 additions & 11 deletions hooks/hookexecution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package hookexecution
import (
"context"
"fmt"
"github.com/prebid/prebid-server/v2/config"
"github.com/prebid/prebid-server/v2/ortb"
"github.com/prebid/prebid-server/v2/util/iputil"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -68,7 +70,7 @@ func executeGroup[H any, P any](

for _, hook := range group.Hooks {
mCtx := executionCtx.getModuleContext(hook.Module)
newPayload := handleModuleActivities(hook.Code, executionCtx.activityControl, payload)
newPayload := handleModuleActivities(hook.Code, executionCtx.activityControl, payload, executionCtx.account)
wg.Add(1)
go func(hw hooks.HookWrapper[H], moduleCtx hookstage.ModuleInvocationContext) {
defer wg.Done()
Expand Down Expand Up @@ -315,28 +317,44 @@ func handleHookMutations[P any](
return payload
}

func handleModuleActivities[P any](hookCode string, activityControl privacy.ActivityControl, payload P) P {
func handleModuleActivities[P any](hookCode string, activityControl privacy.ActivityControl, payload P, account *config.Account) P {
payloadData, ok := any(&payload).(hookstage.RequestUpdater)
if !ok {
return payload
}

scopeGeneral := privacy.Component{Type: privacy.ComponentTypeGeneral, Name: hookCode}
transmitUserFPDActivityAllowed := activityControl.Allow(privacy.ActivityTransmitUserFPD, scopeGeneral, privacy.ActivityRequest{})
transmitPreciseGeoActivityAllowed := activityControl.Allow(privacy.ActivityTransmitPreciseGeo, scopeGeneral, privacy.ActivityRequest{})

if !transmitUserFPDActivityAllowed {
// changes need to be applied to new payload and leave original payload unchanged
bidderReq := payloadData.GetBidderRequestPayload()
if transmitUserFPDActivityAllowed && transmitPreciseGeoActivityAllowed {
return payload
}

bidderReqCopy := ortb.CloneBidderReq(bidderReq.BidRequest)
// changes need to be applied to new payload and leave original payload unchanged
bidderReq := payloadData.GetBidderRequestPayload()

bidderReqCopy := ortb.CloneBidderReq(bidderReq.BidRequest)

if !transmitUserFPDActivityAllowed {
privacy.ScrubUserFPD(bidderReqCopy)
}
if !transmitPreciseGeoActivityAllowed {
ipConf := privacy.IPConf{}
if account != nil {
ipConf = privacy.IPConf{IPV6: account.Privacy.IPv6Config, IPV4: account.Privacy.IPv4Config}
} else {
ipConf = privacy.IPConf{
IPV6: config.IPv6{AnonKeepBits: iputil.IPv6DefaultMaskingBitSize},
IPV4: config.IPv4{AnonKeepBits: iputil.IPv4DefaultMaskingBitSize}}
}

var newPayload = payload
var np = any(&newPayload).(hookstage.RequestUpdater)
np.SetBidderRequestPayload(bidderReqCopy)
return newPayload
privacy.ScrubGeoAndDeviceIP(bidderReqCopy, ipConf)
}

return payload
var newPayload = payload
var np = any(&newPayload).(hookstage.RequestUpdater)
np.SetBidderRequestPayload(bidderReqCopy)
return newPayload

}
91 changes: 87 additions & 4 deletions hooks/hookexecution/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import (
"testing"
)

const (
testIpv6 = "1111:2222:3333:4444:5555:6666:7777:8888"
testIPv6Scrubbed = "1111:2222::"
testIPv6ScrubbedDefault = "1111:2222:3333:4400::"
testIPv6ScrubBytes = 32
)

func TestHandleModuleActivitiesBidderRequestPayload(t *testing.T) {

testCases := []struct {
Expand Down Expand Up @@ -49,13 +56,43 @@ func TestHandleModuleActivitiesBidderRequestPayload(t *testing.T) {
}},
},
},
{
description: "payload should change when transmitPreciseGeo is blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.BidderRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", false),
expectedPayloadData: hookstage.BidderRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIPv6ScrubbedDefault},
},
}},
},
{
description: "payload should not change when transmitPreciseGeo is not blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.BidderRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", true),
expectedPayloadData: hookstage.BidderRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
},
}
for _, test := range testCases {
t.Run(test.description, func(t *testing.T) {
//check input payload didn't change
origInPayloadData := test.inPayloadData
activityControl := privacy.NewActivityControl(test.privacyConfig)
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData)
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData, nil)
assert.Equal(t, test.expectedPayloadData.Request.BidRequest, newPayload.Request.BidRequest)
assert.Equal(t, origInPayloadData, test.inPayloadData)
})
Expand Down Expand Up @@ -101,13 +138,45 @@ func TestHandleModuleActivitiesProcessedAuctionRequestPayload(t *testing.T) {
}},
},
},

{
description: "payload should change when transmitPreciseGeo is blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.ProcessedAuctionRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", false),
expectedPayloadData: hookstage.ProcessedAuctionRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIPv6Scrubbed},
}},
},
},
{
description: "payload should not change when transmitPreciseGeo is not blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.ProcessedAuctionRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", true),
expectedPayloadData: hookstage.ProcessedAuctionRequestPayload{
Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{
Device: &openrtb2.Device{IPv6: testIpv6},
}},
},
},
}
for _, test := range testCases {
t.Run(test.description, func(t *testing.T) {
//check input payload didn't change
origInPayloadData := test.inPayloadData
activityControl := privacy.NewActivityControl(test.privacyConfig)
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData)
account := &config.Account{Privacy: config.AccountPrivacy{IPv6Config: config.IPv6{testIPv6ScrubBytes}}}
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData, account)
assert.Equal(t, test.expectedPayloadData.Request.BidRequest, newPayload.Request.BidRequest)
assert.Equal(t, origInPayloadData, test.inPayloadData)
})
Expand All @@ -124,7 +193,7 @@ func TestHandleModuleActivitiesNoBidderRequestPayload(t *testing.T) {
expectedPayloadData hookstage.RawAuctionRequestPayload
}{
{
description: "payload should change when userFPD is blocked by activity",
description: "payload should not change when userFPD is blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.RawAuctionRequestPayload{},
privacyConfig: getTransmitUFPDActivityConfig("foo", false),
Expand All @@ -137,13 +206,27 @@ func TestHandleModuleActivitiesNoBidderRequestPayload(t *testing.T) {
privacyConfig: getTransmitUFPDActivityConfig("foo", true),
expectedPayloadData: hookstage.RawAuctionRequestPayload{},
},
{
description: "payload should not change when transmitPreciseGeo is blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.RawAuctionRequestPayload{},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", false),
expectedPayloadData: hookstage.RawAuctionRequestPayload{},
},
{
description: "payload should not change when transmitPreciseGeo is not blocked by activity",
hookCode: "foo",
inPayloadData: hookstage.RawAuctionRequestPayload{},
privacyConfig: getTransmitPreciseGeoActivityConfig("foo", true),
expectedPayloadData: hookstage.RawAuctionRequestPayload{},
},
}
for _, test := range testCases {
t.Run(test.description, func(t *testing.T) {
//check input payload didn't change
origInPayloadData := test.inPayloadData
activityControl := privacy.NewActivityControl(test.privacyConfig)
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData)
newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData, &config.Account{})
assert.Equal(t, test.expectedPayloadData, newPayload)
assert.Equal(t, origInPayloadData, test.inPayloadData)
})
Expand Down
Loading

0 comments on commit 27b2ff6

Please sign in to comment.