From e502c10be7e54ab4d244c7e058090715b6a6f78a Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Thu, 25 Apr 2024 22:44:47 -0400 Subject: [PATCH 1/5] Refactor Bid Splitter Privacy Functions --- endpoints/cookie_sync_test.go | 8 +- endpoints/openrtb2/test_utils.go | 4 +- endpoints/setuid_test.go | 4 +- exchange/utils.go | 159 ++++++++++++++++--------------- exchange/utils_test.go | 6 +- gdpr/gdpr.go | 4 +- gdpr/impl.go | 33 ++++--- gdpr/impl_test.go | 21 ++-- 8 files changed, 120 insertions(+), 119 deletions(-) diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 35d7dd4baf5..e1417d50d7b 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -2212,9 +2212,9 @@ func (m *MockGDPRPerms) BidderSyncAllowed(ctx context.Context, bidder openrtb_ex return args.Bool(0), args.Error(1) } -func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { args := m.Called(ctx, bidderCoreName, bidder) - return args.Get(0).(gdpr.AuctionPermissions), args.Error(1) + return args.Get(0).(gdpr.AuctionPermissions) } type FakeAccountsFetcher struct { @@ -2244,10 +2244,10 @@ func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: true, - }, nil + } } func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index 6fedb73cd47..e4b21239bdb 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -1400,10 +1400,10 @@ func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: true, - }, nil + } } type mockPlanBuilder struct { diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index d576b8a0093..87208a09114 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -1701,12 +1701,12 @@ func (g *fakePermsSetUID) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return false, nil } -func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: g.personalInfoAllowed, PassGeo: g.personalInfoAllowed, PassID: g.personalInfoAllowed, - }, nil + } } type fakeSyncer struct { diff --git a/exchange/utils.go b/exchange/utils.go index d5e94316a62..749f6a82253 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -69,8 +69,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, return } - allowedBidderRequests = make([]BidderRequest, 0) - bidderImpWithBidResp := stored_responses.InitStoredBidResponses(req.BidRequest, auctionReq.StoredBidResponses) impsByBidder, err := splitImps(req.BidRequest.Imp) @@ -149,102 +147,110 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, gdprPerms = rs.gdprPermsBuilder(auctionReq.TCF2Config, gdprRequestInfo) } - // bidder level privacy policies + allowedBidderRequests = make([]BidderRequest, 0, len(allBidderRequests)) + for _, bidderRequest := range allBidderRequests { - // fetchBids activity - scopedName := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} - fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !fetchBidsActivityAllowed { - // skip the call to a bidder if fetchBids activity is not allowed - // do not add this bidder to allowedBidderRequests + auctionPermissions := gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName) + + // privacy blocking + if rs.isBidderBlockedByPrivacy(req, auctionReq.Activities, auctionPermissions, bidderRequest.BidderCoreName, bidderRequest.BidderName) { continue } - var auctionPermissions gdpr.AuctionPermissions - var gdprErr error + // fpd + applyFPD(auctionReq.FirstPartyData, bidderRequest) - if gdprEnforced { - auctionPermissions, gdprErr = gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName) - if !auctionPermissions.AllowBidRequest { - // auction request is not permitted by GDPR - // do not add this bidder to allowedBidderRequests - rs.me.RecordAdapterGDPRRequestBlocked(bidderRequest.BidderCoreName) - continue - } + // privacy scrubbing + if err := rs.applyPrivacy(&bidderRequest, auctionReq, auctionPermissions, ccpaEnforcer, lmt, coppa); err != nil { + errs = append(errs, err) + continue } - ipConf := privacy.IPConf{IPV6: auctionReq.Account.Privacy.IPv6Config, IPV4: auctionReq.Account.Privacy.IPv4Config} + // GPP downgrade: always downgrade unless we can confirm GPP is supported + if shouldSetLegacyPrivacy(rs.bidderInfo, string(bidderRequest.BidderCoreName)) { + setLegacyGDPRFromGPP(bidderRequest.BidRequest, gpp) + setLegacyUSPFromGPP(bidderRequest.BidRequest, gpp) + } - // FPD should be applied before policies, otherwise it overrides policies and activities restricted data - applyFPD(auctionReq.FirstPartyData, bidderRequest) + allowedBidderRequests = append(allowedBidderRequests, bidderRequest) + } - reqWrapper := &openrtb_ext.RequestWrapper{ - BidRequest: ortb.CloneBidRequestPartial(bidderRequest.BidRequest), - } + return +} + +func (rs *requestSplitter) isBidderBlockedByPrivacy(r *openrtb_ext.RequestWrapper, activities privacy.ActivityControl, auctionPermissions gdpr.AuctionPermissions, coreBidder, bidderName openrtb_ext.BidderName) bool { + // activities control + scope := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName.String()} + fetchBidsActivityAllowed := activities.Allow(privacy.ActivityFetchBids, scope, privacy.NewRequestFromBidRequest(*r)) + if !fetchBidsActivityAllowed { + return true + } + + // gdpr + if !auctionPermissions.AllowBidRequest { + rs.me.RecordAdapterGDPRRequestBlocked(coreBidder) + return true + } - passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName, privacy.NewRequestFromBidRequest(*req)) - buyerUIDSet := reqWrapper.User != nil && reqWrapper.User.BuyerUID != "" - buyerUIDRemoved := false - if !passIDActivityAllowed { - privacy.ScrubUserFPD(reqWrapper) + return false +} + +func (rs *requestSplitter) applyPrivacy(bidderRequest *BidderRequest, auctionReq AuctionRequest, auctionPermissions gdpr.AuctionPermissions, ccpaEnforcer privacy.PolicyEnforcer, lmt bool, coppa bool) error { + scope := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} + ipConf := privacy.IPConf{IPV6: auctionReq.Account.Privacy.IPv6Config, IPV4: auctionReq.Account.Privacy.IPv4Config} + + reqWrapper := &openrtb_ext.RequestWrapper{ + BidRequest: ortb.CloneBidRequestPartial(bidderRequest.BidRequest), + } + + passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + buyerUIDSet := reqWrapper.User != nil && reqWrapper.User.BuyerUID != "" + buyerUIDRemoved := false + if !passIDActivityAllowed { + privacy.ScrubUserFPD(reqWrapper) + buyerUIDRemoved = true + } else { + if !auctionPermissions.PassID { + privacy.ScrubGdprID(reqWrapper) buyerUIDRemoved = true - } else { - // run existing policies (GDPR, CCPA, COPPA, LMT) - // potentially block passing IDs based on GDPR - if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassID) { - privacy.ScrubGdprID(reqWrapper) - buyerUIDRemoved = true - } - // potentially block passing IDs based on CCPA - if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) - buyerUIDRemoved = true - } - } - if buyerUIDSet && buyerUIDRemoved { - rs.me.RecordAdapterBuyerUIDScrubbed(bidderRequest.BidderCoreName) } - passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !passGeoActivityAllowed { - privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) - } else { - // run existing policies (GDPR, CCPA, COPPA, LMT) - // potentially block passing geo based on GDPR - if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassGeo) { - privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) - } - // potentially block passing geo based on CCPA - if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) - } + if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) + buyerUIDRemoved = true } + } + if buyerUIDSet && buyerUIDRemoved { + rs.me.RecordAdapterBuyerUIDScrubbed(bidderRequest.BidderCoreName) + } - if lmt || coppa { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", coppa) + passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + if !passGeoActivityAllowed { + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) + } else { + if !auctionPermissions.PassGeo { + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } - - passTIDAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !passTIDAllowed { - privacy.ScrubTID(reqWrapper) + if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) } + } - err := reqWrapper.RebuildRequest() - if err != nil { - errs = append(errs, err) - } - bidderRequest.BidRequest = reqWrapper.BidRequest + if lmt || coppa { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", coppa) + } - allowedBidderRequests = append(allowedBidderRequests, bidderRequest) + passTIDAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + if !passTIDAllowed { + privacy.ScrubTID(reqWrapper) + } - // GPP downgrade: always downgrade unless we can confirm GPP is supported - if shouldSetLegacyPrivacy(rs.bidderInfo, string(bidderRequest.BidderCoreName)) { - setLegacyGDPRFromGPP(bidderRequest.BidRequest, gpp) - setLegacyUSPFromGPP(bidderRequest.BidRequest, gpp) - } + if err := reqWrapper.RebuildRequest(); err != nil { + return err } - return + bidderRequest.BidRequest = reqWrapper.BidRequest + return nil } func shouldSetLegacyPrivacy(bidderInfo config.BidderInfos, bidder string) bool { @@ -457,7 +463,6 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request } func buildRequestExtAlternateBidderCodes(bidder string, accABC *openrtb_ext.ExtAlternateBidderCodes, reqABC *openrtb_ext.ExtAlternateBidderCodes) *openrtb_ext.ExtAlternateBidderCodes { - if altBidderCodes := copyExtAlternateBidderCodes(bidder, reqABC); altBidderCodes != nil { return altBidderCodes } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index eeef2e3a2d2..7c161f77c0e 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -45,7 +45,7 @@ func (p *permissionsMock) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (gdpr.AuctionPermissions, error) { +func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { permissions := gdpr.AuctionPermissions{ PassGeo: p.passGeo, PassID: p.passID, @@ -53,7 +53,7 @@ func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCo if p.allowAllBidders { permissions.AllowBidRequest = true - return permissions, p.activitiesError + return permissions // might need a tweak } for _, allowedBidder := range p.allowedBidders { @@ -62,7 +62,7 @@ func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCo } } - return permissions, p.activitiesError + return permissions } type fakePermissionsBuilder struct { diff --git a/gdpr/gdpr.go b/gdpr/gdpr.go index 1b4f6cb4680..4f7df2f3ab7 100644 --- a/gdpr/gdpr.go +++ b/gdpr/gdpr.go @@ -20,8 +20,8 @@ type Permissions interface { // Determines whether or not to send PI information to a bidder, or mask it out. // - // If the consent string was nonsensical, the returned error will be an ErrorMalformedConsent. - AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) + // If the consent string was nonsensical, the no permissions are granted. + AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions } type PermissionsBuilder func(TCF2ConfigReader, RequestInfo) Permissions diff --git a/gdpr/impl.go b/gdpr/impl.go index 614c06d9a6a..e5f4f0b4c2e 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -56,33 +56,36 @@ func (p *permissionsImpl) BidderSyncAllowed(ctx context.Context, bidder openrtb_ } // AuctionActivitiesAllowed determines whether auction activities are permitted for a given bidder -func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) { +func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions { if _, ok := p.nonStandardPublishers[p.publisherID]; ok { - return AllowAll, nil + return AllowAll } + if p.gdprSignal != SignalYes { - return AllowAll, nil + return AllowAll } + if p.consent == "" { - return p.defaultPermissions(), nil + return p.defaultPermissions() } + pc, err := parseConsent(p.consent) if err != nil { - return p.defaultPermissions(), err + return DenyAll } + vendorID, _ := p.resolveVendorID(bidderCoreName, bidder) vendor, err := p.getVendor(ctx, vendorID, *pc) if err != nil { - return p.defaultPermissions(), err + return p.defaultPermissions() } - vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} - - permissions = AuctionPermissions{} - permissions.AllowBidRequest = p.allowBidRequest(bidderCoreName, pc.consentMeta, vendorInfo) - permissions.PassGeo = p.allowGeo(bidderCoreName, pc.consentMeta, vendor) - permissions.PassID = p.allowID(bidderCoreName, pc.consentMeta, vendorInfo) - return permissions, nil + vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} + return AuctionPermissions{ + AllowBidRequest: p.allowBidRequest(bidderCoreName, pc.consentMeta, vendorInfo), + PassGeo: p.allowGeo(bidderCoreName, pc.consentMeta, vendor), + PassID: p.allowID(bidderCoreName, pc.consentMeta, vendorInfo), + } } // defaultPermissions returns a permissions object that denies passing user IDs while @@ -222,6 +225,6 @@ func (a AlwaysAllow) HostCookiesAllowed(ctx context.Context) (bool, error) { func (a AlwaysAllow) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) { return true, nil } -func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) { - return AllowAll, nil +func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions { + return AllowAll } diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go index 64fa4434d4d..2a5826ad4cb 100644 --- a/gdpr/impl_test.go +++ b/gdpr/impl_test.go @@ -335,9 +335,8 @@ func TestAllowActivities(t *testing.T) { perms.gdprSignal = tt.gdpr perms.publisherID = tt.publisherID - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName) + permissions := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName) - assert.Nil(t, err, tt.description) assert.Equal(t, tt.passID, permissions.PassID, tt.description) } } @@ -437,8 +436,7 @@ func TestAllowActivitiesBidderWithoutGVLID(t *testing.T) { purposeEnforcerBuilder: NewPurposeEnforcerBuilder(&tcf2AggConfig), } - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderWithoutGVLID, bidderWithoutGVLID) - assert.NoError(t, err) + permissions := perms.AuctionActivitiesAllowed(context.Background(), bidderWithoutGVLID, bidderWithoutGVLID) assert.Equal(t, tt.allowBidRequest, permissions.AllowBidRequest) assert.Equal(t, tt.passID, permissions.PassID) }) @@ -658,8 +656,7 @@ func TestAllowActivitiesGeoAndID(t *testing.T) { perms.consent = td.consent perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) @@ -695,8 +692,7 @@ func TestAllowActivitiesWhitelist(t *testing.T) { } // Assert that an item that otherwise would not be allowed PI access, gets approved because it is found in the GDPR.NonStandardPublishers array - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed") + permissions := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus) assert.EqualValuesf(t, true, permissions.PassGeo, "PassGeo failure") assert.EqualValuesf(t, true, permissions.PassID, "PassID failure") } @@ -767,8 +763,7 @@ func TestAllowActivitiesPubRestrict(t *testing.T) { perms.aliasGVLIDs = td.aliasGVLIDs perms.consent = td.consent - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) } @@ -1101,8 +1096,7 @@ func TestAllowActivitiesBidRequests(t *testing.T) { perms.cfg = &tcf2AggConfig perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) @@ -1196,8 +1190,7 @@ func TestAllowActivitiesVendorException(t *testing.T) { perms.cfg = &tcf2AggConfig perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) From 826df54145b038b83287d8099d7c985a5e582392 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 29 May 2024 18:50:39 -0400 Subject: [PATCH 2/5] Remove Comment --- exchange/utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 7c161f77c0e..2a515117bdf 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -53,7 +53,7 @@ func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCo if p.allowAllBidders { permissions.AllowBidRequest = true - return permissions // might need a tweak + return permissions } for _, allowedBidder := range p.allowedBidders { From b5642efb2b4a43c1fec0a5d7e7c4bfa659105234 Mon Sep 17 00:00:00 2001 From: bsardo <1168933+bsardo@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:54:15 -0400 Subject: [PATCH 3/5] Change DenyAll back to default permissions --- gdpr/impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdpr/impl.go b/gdpr/impl.go index e5f4f0b4c2e..27c10cf8fd5 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -71,7 +71,7 @@ func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCo pc, err := parseConsent(p.consent) if err != nil { - return DenyAll + return p.defaultPermissions() } vendorID, _ := p.resolveVendorID(bidderCoreName, bidder) From 54f21293f98050d8cb2232818280c441646f0460 Mon Sep 17 00:00:00 2001 From: bsardo <1168933+bsardo@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:55:13 -0400 Subject: [PATCH 4/5] Always allow when gdpr is not enforced --- exchange/utils.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exchange/utils.go b/exchange/utils.go index 749f6a82253..61a50004b8e 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -145,6 +145,8 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, PublisherID: auctionReq.LegacyLabels.PubID, } gdprPerms = rs.gdprPermsBuilder(auctionReq.TCF2Config, gdprRequestInfo) + } else { + gdprPerms = gdpr.AlwaysAllow{} } allowedBidderRequests = make([]BidderRequest, 0, len(allBidderRequests)) @@ -187,6 +189,7 @@ func (rs *requestSplitter) isBidderBlockedByPrivacy(r *openrtb_ext.RequestWrappe } // gdpr + // if gdprEnforced && !auctionPermissions.AllowBidRequest { if !auctionPermissions.AllowBidRequest { rs.me.RecordAdapterGDPRRequestBlocked(coreBidder) return true @@ -210,6 +213,7 @@ func (rs *requestSplitter) applyPrivacy(bidderRequest *BidderRequest, auctionReq privacy.ScrubUserFPD(reqWrapper) buyerUIDRemoved = true } else { + // if gdprEnforced && !auctionPermissions.PassID { if !auctionPermissions.PassID { privacy.ScrubGdprID(reqWrapper) buyerUIDRemoved = true @@ -228,6 +232,7 @@ func (rs *requestSplitter) applyPrivacy(bidderRequest *BidderRequest, auctionReq if !passGeoActivityAllowed { privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } else { + // if gdprEnforced && !auctionPermissions.PassGeo { if !auctionPermissions.PassGeo { privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } From a65b59c02e0754e41710e1734673898f9e70d567 Mon Sep 17 00:00:00 2001 From: bsardo <1168933+bsardo@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:31:25 -0400 Subject: [PATCH 5/5] Remove unnecessary else and commented out gdprEnforced conditionals --- exchange/utils.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/exchange/utils.go b/exchange/utils.go index 61a50004b8e..749f6a82253 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -145,8 +145,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, PublisherID: auctionReq.LegacyLabels.PubID, } gdprPerms = rs.gdprPermsBuilder(auctionReq.TCF2Config, gdprRequestInfo) - } else { - gdprPerms = gdpr.AlwaysAllow{} } allowedBidderRequests = make([]BidderRequest, 0, len(allBidderRequests)) @@ -189,7 +187,6 @@ func (rs *requestSplitter) isBidderBlockedByPrivacy(r *openrtb_ext.RequestWrappe } // gdpr - // if gdprEnforced && !auctionPermissions.AllowBidRequest { if !auctionPermissions.AllowBidRequest { rs.me.RecordAdapterGDPRRequestBlocked(coreBidder) return true @@ -213,7 +210,6 @@ func (rs *requestSplitter) applyPrivacy(bidderRequest *BidderRequest, auctionReq privacy.ScrubUserFPD(reqWrapper) buyerUIDRemoved = true } else { - // if gdprEnforced && !auctionPermissions.PassID { if !auctionPermissions.PassID { privacy.ScrubGdprID(reqWrapper) buyerUIDRemoved = true @@ -232,7 +228,6 @@ func (rs *requestSplitter) applyPrivacy(bidderRequest *BidderRequest, auctionReq if !passGeoActivityAllowed { privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } else { - // if gdprEnforced && !auctionPermissions.PassGeo { if !auctionPermissions.PassGeo { privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) }