Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cookie sync endpoint to be case insensitive #3103

Merged
merged 6 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion endpoints/cookie_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) {
assert.IsType(t, &cookieSyncEndpoint{}, endpoint)

assert.Equal(t, expected.config, result.config)
assert.Equal(t, expected.chooser, result.chooser)
assert.ObjectsAreEqualValues(expected.chooser, result.chooser)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own understanding, why was this changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we mocked normalizedBidderNamesLookup field in standardChooser - apparently, go changes the address of the struct by copying the values to a new struct. Hence, the address are different however the values are same and that is what the assert statement is doing.

assert.Equal(t, expected.metrics, result.metrics)
assert.Equal(t, expected.pbsAnalytics, result.pbsAnalytics)
assert.Equal(t, expected.accountsFetcher, result.accountsFetcher)
Expand Down
5 changes: 3 additions & 2 deletions openrtb_ext/bidders.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) err
aliasBidder := BidderName(aliasBidderName)
coreBidderNames = append(coreBidderNames, aliasBidder)
aliasBidderToParent[aliasBidder] = parentBidderName
bidderNameLookup[strings.ToLower(aliasBidderName)] = aliasBidder
return nil
}

Expand Down Expand Up @@ -560,11 +561,11 @@ var bidderNameLookup = func() map[string]BidderName {
lookup[bidderNameLower] = name
}
return lookup
}
}()

func NormalizeBidderName(name string) (BidderName, bool) {
nameLower := strings.ToLower(name)
bidderName, exists := bidderNameLookup()[nameLower]
bidderName, exists := bidderNameLookup[nameLower]
return bidderName, exists
}

Expand Down
6 changes: 5 additions & 1 deletion usersync/bidderfilter.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package usersync

import (
"strings"
)

// BidderFilter determines if a bidder has permission to perform a user sync activity.
type BidderFilter interface {
// Allowed returns true if the filter determines the bidder has permission and false if either
Expand Down Expand Up @@ -40,7 +44,7 @@ func (f SpecificBidderFilter) Allowed(bidder string) bool {
func NewSpecificBidderFilter(bidders []string, mode BidderFilterMode) BidderFilter {
biddersLookup := make(map[string]struct{}, len(bidders))
for _, bidder := range bidders {
biddersLookup[bidder] = struct{}{}
biddersLookup[strings.ToLower(bidder)] = struct{}{}
}

return SpecificBidderFilter{biddersLookup: biddersLookup, mode: mode}
Expand Down
7 changes: 7 additions & 0 deletions usersync/bidderfilter_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package usersync

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -69,6 +70,12 @@ func TestSpecificBidderFilter(t *testing.T) {
mode: BidderFilterMode(-1),
expected: false,
},
{
description: "Case Insensitive Include - One",
bidders: []string{strings.ToUpper(bidder)},
mode: BidderFilterModeInclude,
expected: true,
},
}

for _, test := range testCases {
Expand Down
32 changes: 22 additions & 10 deletions usersync/chooser.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package usersync

import (
"github.com/prebid/prebid-server/openrtb_ext"
"strings"
)

// Chooser determines which syncers are eligible for a given request.
type Chooser interface {
// Choose considers bidders to sync, filters the bidders, and returns the result of the
Expand All @@ -15,9 +20,10 @@ func NewChooser(bidderSyncerLookup map[string]Syncer) Chooser {
}

return standardChooser{
bidderSyncerLookup: bidderSyncerLookup,
biddersAvailable: bidders,
bidderChooser: standardBidderChooser{shuffler: randomShuffler{}},
bidderSyncerLookup: bidderSyncerLookup,
biddersAvailable: bidders,
bidderChooser: standardBidderChooser{shuffler: randomShuffler{}},
normalizeValidBidderName: openrtb_ext.NormalizeBidderName,
}
}

Expand Down Expand Up @@ -100,9 +106,10 @@ type Privacy interface {

// standardChooser implements the user syncer algorithm per official Prebid specification.
type standardChooser struct {
bidderSyncerLookup map[string]Syncer
biddersAvailable []string
bidderChooser bidderChooser
bidderSyncerLookup map[string]Syncer
biddersAvailable []string
bidderChooser bidderChooser
normalizeValidBidderName func(name string) (openrtb_ext.BidderName, bool)
}

// Choose randomly selects user syncers which are permitted by the user's privacy settings and
Expand Down Expand Up @@ -136,7 +143,12 @@ func (c standardChooser) Choose(request Request, cookie *Cookie) Result {
}

func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{}, syncTypeFilter SyncTypeFilter, privacy Privacy, cookie *Cookie) (Syncer, BidderEvaluation) {
syncer, exists := c.bidderSyncerLookup[bidder]
bidderNormalized, exists := c.normalizeValidBidderName(bidder)
if !exists {
return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder}
}

syncer, exists := c.bidderSyncerLookup[bidderNormalized.String()]
if !exists {
return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder}
}
Expand All @@ -147,7 +159,7 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{}
}
syncersSeen[syncer.Key()] = struct{}{}

if !syncer.SupportsType(syncTypeFilter.ForBidder(bidder)) {
if !syncer.SupportsType(syncTypeFilter.ForBidder(strings.ToLower(bidder))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this line also use bidderNormalized.String()? And we don't have include the strings package into this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot use normalised bidder name here and the reason is there is biddersLookup map that is created in NewSpecificBidderFilter function with key of the map being lower cased. . This map is used when we call syncTypeFilter.ForBidder function. Hope this clarifies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, but when I subbed in bidderNomarlized.String() for strings.ToLower(bidder), all of the tests still passed. This is more of a nitpick if anything, so I'm happy to approve if you want to stick with the current code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexBVolcy It is because test cases are setup that way. If you setup a test case where you use suntContent as bidder name, you will be able to fail your test. In fact I have updated one of the test to reflect this - c124abb

return nil, BidderEvaluation{Status: StatusTypeNotSupported, Bidder: bidder, SyncerKey: syncer.Key()}
}

Expand All @@ -160,11 +172,11 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{}
return nil, BidderEvaluation{Status: StatusBlockedByPrivacy, Bidder: bidder, SyncerKey: syncer.Key()}
}

if !privacy.GDPRAllowsBidderSync(bidder) {
if !privacy.GDPRAllowsBidderSync(bidderNormalized.String()) {
return nil, BidderEvaluation{Status: StatusBlockedByGDPR, Bidder: bidder, SyncerKey: syncer.Key()}
}

if !privacy.CCPAAllowsBidderSync(bidder) {
if !privacy.CCPAAllowsBidderSync(bidderNormalized.String()) {
return nil, BidderEvaluation{Status: StatusBlockedByCCPA, Bidder: bidder, SyncerKey: syncer.Key()}
}

Expand Down
Loading
Loading