github.com/prebid/prebid-server/v2@v2.18.0/openrtb_ext/alternatebiddercodes.go (about)

     1  package openrtb_ext
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  // ExtAlternateBidderCodes defines list of alternate bidder codes allowed by adatpers. This overrides host level configs.
     9  type ExtAlternateBidderCodes struct {
    10  	Enabled bool                                      `mapstructure:"enabled" json:"enabled"`
    11  	Bidders map[string]ExtAdapterAlternateBidderCodes `mapstructure:"bidders" json:"bidders"`
    12  }
    13  
    14  type ExtAdapterAlternateBidderCodes struct {
    15  	Enabled            bool     `mapstructure:"enabled" json:"enabled"`
    16  	AllowedBidderCodes []string `mapstructure:"allowedbiddercodes" json:"allowedbiddercodes"`
    17  }
    18  
    19  func (bidderCodes *ExtAlternateBidderCodes) IsValidBidderCode(bidder, alternateBidder string) (bool, error) {
    20  	if alternateBidder == "" || strings.EqualFold(bidder, alternateBidder) {
    21  		return true, nil
    22  	}
    23  
    24  	if !bidderCodes.Enabled {
    25  		return false, alternateBidderDisabledError(bidder, alternateBidder)
    26  	}
    27  
    28  	if bidderCodes.Bidders == nil {
    29  		return false, alternateBidderNotDefinedError(bidder, alternateBidder)
    30  	}
    31  
    32  	adapterCfg, found := bidderCodes.IsBidderInAlternateBidderCodes(bidder)
    33  	if !found {
    34  		return false, alternateBidderNotDefinedError(bidder, alternateBidder)
    35  	}
    36  
    37  	if !adapterCfg.Enabled {
    38  		// config has bidder entry but is not enabled, report it
    39  		return false, alternateBidderDisabledError(bidder, alternateBidder)
    40  	}
    41  
    42  	if adapterCfg.AllowedBidderCodes == nil || (len(adapterCfg.AllowedBidderCodes) == 1 && adapterCfg.AllowedBidderCodes[0] == "*") {
    43  		return true, nil
    44  	}
    45  
    46  	for _, code := range adapterCfg.AllowedBidderCodes {
    47  		if alternateBidder == code {
    48  			return true, nil
    49  		}
    50  	}
    51  
    52  	return false, fmt.Errorf("invalid biddercode %q sent by adapter %q", alternateBidder, bidder)
    53  }
    54  
    55  func alternateBidderDisabledError(bidder, alternateBidder string) error {
    56  	return fmt.Errorf("alternateBidderCodes disabled for %q, rejecting bids for %q", bidder, alternateBidder)
    57  }
    58  
    59  func alternateBidderNotDefinedError(bidder, alternateBidder string) error {
    60  	return fmt.Errorf("alternateBidderCodes not defined for adapter %q, rejecting bids for %q", bidder, alternateBidder)
    61  }
    62  
    63  // IsBidderInAlternateBidderCodes tries to find bidder in the altBidderCodes.Bidders map in a case sensitive
    64  // manner first. If no match is found it'll try it in a case insensitive way in linear time
    65  func (bidderCodes *ExtAlternateBidderCodes) IsBidderInAlternateBidderCodes(bidder string) (ExtAdapterAlternateBidderCodes, bool) {
    66  	if len(bidder) > 0 && bidderCodes != nil && len(bidderCodes.Bidders) > 0 {
    67  		// try constant time exact match
    68  		if adapterCfg, found := bidderCodes.Bidders[bidder]; found {
    69  			return adapterCfg, true
    70  		}
    71  
    72  		// check if we can find with a case insensitive comparison
    73  		for bidderName, adapterCfg := range bidderCodes.Bidders {
    74  			if strings.EqualFold(bidder, bidderName) {
    75  				return adapterCfg, true
    76  			}
    77  		}
    78  	}
    79  
    80  	return ExtAdapterAlternateBidderCodes{}, false
    81  }