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

Support case insensitive bidder name in ext.prebid.data.eidpermissions.bidders #3127

Closed
wants to merge 6 commits into from
28 changes: 18 additions & 10 deletions endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,12 @@ func validateBidders(bidders []string, knownBidders map[string]openrtb_ext.Bidde
return errors.New(`bidder wildcard "*" mixed with specific bidders`)
}
} else {
_, isCoreBidder := knownBidders[bidder]
bidderName := bidder
normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderName)
if ok {
bidderName = normalizedCoreBidder.String()
}
_, isCoreBidder := knownBidders[bidderName]
_, isAlias := knownAliases[bidder]
if !isCoreBidder && !isAlias {
return fmt.Errorf(`unrecognized bidder "%v"`, bidder)
Expand Down Expand Up @@ -1510,12 +1515,12 @@ func (deps *endpointDeps) validateImpExt(imp *openrtb_ext.ImpWrapper, aliases ma
errL := []error{}

for bidder, ext := range prebid.Bidder {
coreBidder := bidder
coreBidder, _ := openrtb_ext.NormalizeBidderName(bidder)
if tmp, isAlias := aliases[bidder]; isAlias {
coreBidder = tmp
coreBidder = openrtb_ext.BidderName(tmp)
}

if coreBidderNormalized, isValid := deps.bidderMap[coreBidder]; isValid {
if coreBidderNormalized, isValid := deps.bidderMap[coreBidder.String()]; isValid {
if err := deps.paramsValidator.Validate(coreBidderNormalized, ext); err != nil {
return []error{fmt.Errorf("request.imp[%d].ext.prebid.bidder.%s failed validation.\n%v", impIndex, bidder, err)}
}
Expand Down Expand Up @@ -1575,18 +1580,21 @@ func (deps *endpointDeps) parseBidExt(req *openrtb_ext.RequestWrapper) error {
}

func (deps *endpointDeps) validateAliases(aliases map[string]string) error {
for alias, coreBidder := range aliases {
if _, isCoreBidderDisabled := deps.disabledBidders[coreBidder]; isCoreBidderDisabled {
return fmt.Errorf("request.ext.prebid.aliases.%s refers to disabled bidder: %s", alias, coreBidder)
for alias, bidderName := range aliases {
normalisedBidderName, _ := openrtb_ext.NormalizeBidderName(bidderName)
coreBidderName := normalisedBidderName.String()
if _, isCoreBidderDisabled := deps.disabledBidders[coreBidderName]; isCoreBidderDisabled {
return fmt.Errorf("request.ext.prebid.aliases.%s refers to disabled bidder: %s", alias, bidderName)
}

if _, isCoreBidder := deps.bidderMap[coreBidder]; !isCoreBidder {
return fmt.Errorf("request.ext.prebid.aliases.%s refers to unknown bidder: %s", alias, coreBidder)
if _, isCoreBidder := deps.bidderMap[coreBidderName]; !isCoreBidder {
return fmt.Errorf("request.ext.prebid.aliases.%s refers to unknown bidder: %s", alias, bidderName)
}

if alias == coreBidder {
if alias == coreBidderName {
return fmt.Errorf("request.ext.prebid.aliases.%s defines a no-op alias. Choose a different alias, or remove this entry.", alias)
}
aliases[alias] = coreBidderName
}
return nil
}
Expand Down
78 changes: 68 additions & 10 deletions endpoints/openrtb2/auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2833,19 +2833,21 @@ func TestValidateImpExt(t *testing.T) {

for _, group := range testGroups {
for _, test := range group.testCases {
imp := &openrtb2.Imp{Ext: test.impExt}
impWrapper := &openrtb_ext.ImpWrapper{Imp: imp}
t.Run(test.description, func(t *testing.T) {
imp := &openrtb2.Imp{Ext: test.impExt}
impWrapper := &openrtb_ext.ImpWrapper{Imp: imp}

errs := deps.validateImpExt(impWrapper, nil, 0, false, nil)
errs := deps.validateImpExt(impWrapper, nil, 0, false, nil)

assert.NoError(t, impWrapper.RebuildImp(), test.description+":rebuild_imp")
assert.NoError(t, impWrapper.RebuildImp(), test.description+":rebuild_imp")

if len(test.expectedImpExt) > 0 {
assert.JSONEq(t, test.expectedImpExt, string(imp.Ext), "imp.ext JSON does not match expected. Test: %s. %s\n", group.description, test.description)
} else {
assert.Empty(t, imp.Ext, "imp.ext expected to be empty but was: %s. Test: %s. %s\n", string(imp.Ext), group.description, test.description)
}
assert.Equal(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description)
if len(test.expectedImpExt) > 0 {
assert.JSONEq(t, test.expectedImpExt, string(imp.Ext), "imp.ext JSON does not match expected. Test: %s. %s\n", group.description, test.description)
} else {
assert.Empty(t, imp.Ext, "imp.ext expected to be empty but was: %s. Test: %s. %s\n", string(imp.Ext), group.description, test.description)
}
assert.Equal(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description)
})
}
}
}
Expand Down Expand Up @@ -5771,3 +5773,59 @@ func TestSetSeatNonBidRaw(t *testing.T) {
})
}
}

func TestValidateAliases(t *testing.T) {
deps := &endpointDeps{
disabledBidders: map[string]string{"rubicon": "rubicon"},
bidderMap: map[string]openrtb_ext.BidderName{"appnexus": openrtb_ext.BidderName("appnexus")},
}

testCases := []struct {
description string
aliases map[string]string
expectedAliases map[string]string
expectedError error
}{
{
description: "valid case",
aliases: map[string]string{"test": "appnexus"},
expectedAliases: map[string]string{"test": "appnexus"},
expectedError: nil,
},
{
description: "valid case - case insensitive",
aliases: map[string]string{"test": "Appnexus"},
expectedAliases: map[string]string{"test": "appnexus"},
expectedError: nil,
},
{
description: "disabled bidder",
aliases: map[string]string{"test": "rubicon"},
expectedAliases: nil,
expectedError: errors.New("request.ext.prebid.aliases.test refers to disabled bidder: rubicon"),
},
{
description: "coreBidderName not found",
aliases: map[string]string{"test": "anyBidder"},
expectedAliases: nil,
expectedError: errors.New("request.ext.prebid.aliases.test refers to unknown bidder: anyBidder"),
},
{
description: "alias name is coreBidder name",
aliases: map[string]string{"appnexus": "appnexus"},
expectedAliases: nil,
expectedError: errors.New("request.ext.prebid.aliases.appnexus defines a no-op alias. Choose a different alias, or remove this entry."),
},
}

for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
err := deps.validateAliases(testCase.aliases)
if err != nil {
assert.Equal(t, testCase.expectedError, err)
} else {
assert.ObjectsAreEqualValues(testCase.expectedAliases, map[string]string{"test": "appnexus"})
}
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"description": "This demonstrates all extension in case insensitive.",
"config": {
"mockBidders": [
{
"bidderName": "appnexus",
"currency": "USD",
"price": 1.00
},
{
"bidderName": "rubicon",
"currency": "USD",
"price": 1.00
}
]
},
"mockBidRequest": {
"id": "some-request-id",
"site": {
"page": "prebid.org"
},
"user": {
"ext": {
"consent": "gdpr-consent-string",
"prebid": {
"buyeruids": {
"appnexus": "override-appnexus-id-in-cookie"
}
}
}
},
"regs": {
"ext": {
"gdpr": 1,
"us_privacy": "1NYN"
}
},
"imp": [
{
"id": "some-impression-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
},
{
"w": 300,
"h": 600
}
]
},
"ext": {
"appnexus": {
"placementId": 12883451
},
"districtm": {
"placementId": 105
},
"rubicon": {
"accountId": 1001,
"siteId": 113932,
"zoneId": 535510
}
}
}
],
"tmax": 500,
"ext": {
"prebid": {
"aliases": {
"districtm": "Appnexus"
},
"bidadjustmentfactors": {
"appnexus": 1.01,
"districtm": 0.98,
"rubicon": 0.99
},
"cache": {
"bids": {}
},
"channel": {
"name": "video",
"version": "1.0"
},
"targeting": {
"includewinners": false,
"pricegranularity": {
"precision": 2,
"ranges": [
{
"max": 20,
"increment": 0.10
}
]
}
}
}
}
},
"expectedBidResponse": {
"id": "some-request-id",
"seatbid": [
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 1.01
}
],
"seat": "appnexus"
},
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 0.98
}
],
"seat": "districtm"
},
{
"bid": [
{
"id": "rubicon-bid",
"impid": "some-impression-id",
"price": 0.99
}
],
"seat": "rubicon"
}
],
"bidid": "test bid id",
"cur": "USD",
"nbr": 0
},
"expectedReturnCode": 200
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
"description": "This demonstrates all of the OpenRTB extensions supported by Prebid Server. Very few requests will need all of these at once.",
"config": {
"mockBidders": [
{"bidderName": "appnexus", "currency": "USD", "price": 1.00},
{"bidderName": "rubicon", "currency": "USD", "price": 1.00}
{
"bidderName": "appnexus",
"currency": "USD",
"price": 1.00
},
{
"bidderName": "rubicon",
"currency": "USD",
"price": 1.00
}
]
},
"mockBidRequest": {
Expand Down Expand Up @@ -91,42 +99,42 @@
}
},
"expectedBidResponse": {
"id":"some-request-id",
"seatbid": [
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 1.01
}
],
"seat": "appnexus"
},
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 0.98
}
],
"seat": "districtm"
},
{
"bid": [
{
"id": "rubicon-bid",
"impid": "some-impression-id",
"price": 0.99
}
],
"seat": "rubicon"
}
],
"bidid":"test bid id",
"cur":"USD",
"nbr":0
"id": "some-request-id",
"seatbid": [
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 1.01
}
],
"seat": "appnexus"
},
{
"bid": [
{
"id": "appnexus-bid",
"impid": "some-impression-id",
"price": 0.98
}
],
"seat": "districtm"
},
{
"bid": [
{
"id": "rubicon-bid",
"impid": "some-impression-id",
"price": 0.99
}
],
"seat": "rubicon"
}
],
"bidid": "test bid id",
"cur": "USD",
"nbr": 0
},
"expectedReturnCode": 200
}
}
Loading