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

     1  package openrtb_ext
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/xeipuuv/gojsonschema"
    13  )
    14  
    15  // BidderName refers to a core bidder id or an alias id.
    16  type BidderName string
    17  
    18  var aliasBidderToParent map[BidderName]BidderName = map[BidderName]BidderName{}
    19  
    20  var coreBidderNames []BidderName = []BidderName{
    21  	Bidder33Across,
    22  	BidderAax,
    23  	BidderAceex,
    24  	BidderAcuityAds,
    25  	BidderAdelement,
    26  	BidderAdf,
    27  	BidderAdgeneration,
    28  	BidderAdhese,
    29  	BidderAdkernel,
    30  	BidderAdkernelAdn,
    31  	BidderAdman,
    32  	BidderAdmixer,
    33  	BidderAdnuntius,
    34  	BidderAdOcean,
    35  	BidderAdoppler,
    36  	BidderAdot,
    37  	BidderAdpone,
    38  	BidderAdprime,
    39  	BidderAdquery,
    40  	BidderAdrino,
    41  	BidderAdsinteractive,
    42  	BidderAdtarget,
    43  	BidderAdtrgtme,
    44  	BidderAdtelligent,
    45  	BidderAdvangelists,
    46  	BidderAdView,
    47  	BidderAdxcg,
    48  	BidderAdyoulike,
    49  	BidderAidem,
    50  	BidderAJA,
    51  	BidderAlgorix,
    52  	BidderAlkimi,
    53  	BidderAMX,
    54  	BidderApacdex,
    55  	BidderAppnexus,
    56  	BidderAppush,
    57  	BidderAso,
    58  	BidderAudienceNetwork,
    59  	BidderAutomatad,
    60  	BidderAvocet,
    61  	BidderAxis,
    62  	BidderAxonix,
    63  	BidderBeachfront,
    64  	BidderBeintoo,
    65  	BidderBematterfull,
    66  	BidderBetween,
    67  	BidderBeyondMedia,
    68  	BidderBidmachine,
    69  	BidderBidmyadz,
    70  	BidderBidsCube,
    71  	BidderBidstack,
    72  	BidderBizzclick,
    73  	BidderBliink,
    74  	BidderBlue,
    75  	BidderBluesea,
    76  	BidderBmtm,
    77  	BidderBoldwin,
    78  	BidderBrave,
    79  	BidderBWX,
    80  	BidderCadentApertureMX,
    81  	BidderCcx,
    82  	BidderCoinzilla,
    83  	BidderColossus,
    84  	BidderCompass,
    85  	BidderConnectAd,
    86  	BidderConsumable,
    87  	BidderConversant,
    88  	BidderCpmstar,
    89  	BidderCriteo,
    90  	BidderCWire,
    91  	BidderDatablocks,
    92  	BidderDecenterAds,
    93  	BidderDeepintent,
    94  	BidderDefinemedia,
    95  	BidderDianomi,
    96  	BidderEdge226,
    97  	BidderDmx,
    98  	BidderDXKulture,
    99  	BidderEmtv,
   100  	BidderEmxDigital,
   101  	BidderEPlanning,
   102  	BidderEpom,
   103  	BidderEVolution,
   104  	BidderFlipp,
   105  	BidderFreewheelSSP,
   106  	BidderFRVRAdNetwork,
   107  	BidderGamma,
   108  	BidderGamoshi,
   109  	BidderGlobalsun,
   110  	BidderGothamads,
   111  	BidderGrid,
   112  	BidderGumGum,
   113  	BidderHuaweiAds,
   114  	BidderImds,
   115  	BidderImpactify,
   116  	BidderImprovedigital,
   117  	BidderInfyTV,
   118  	BidderInMobi,
   119  	BidderInteractiveoffers,
   120  	BidderInvibes,
   121  	BidderIQX,
   122  	BidderIQZone,
   123  	BidderIx,
   124  	BidderJixie,
   125  	BidderKargo,
   126  	BidderKayzen,
   127  	BidderKidoz,
   128  	BidderKiviads,
   129  	BidderLmKiviads,
   130  	BidderKrushmedia,
   131  	BidderLemmadigital,
   132  	BidderLiftoff,
   133  	BidderLimelightDigital,
   134  	BidderLockerDome,
   135  	BidderLogan,
   136  	BidderLogicad,
   137  	BidderLoyal,
   138  	BidderLunaMedia,
   139  	BidderMabidder,
   140  	BidderMadvertise,
   141  	BidderMarsmedia,
   142  	BidderMediafuse,
   143  	BidderMedianet,
   144  	BidderMgid,
   145  	BidderMgidX,
   146  	BidderMinuteMedia,
   147  	BidderMobfoxpb,
   148  	BidderMobileFuse,
   149  	BidderMotorik,
   150  	BidderNextMillennium,
   151  	BidderNoBid,
   152  	BidderOms,
   153  	BidderOneTag,
   154  	BidderOpenWeb,
   155  	BidderOpenx,
   156  	BidderOperaads,
   157  	BidderOrbidder,
   158  	BidderOutbrain,
   159  	BidderOwnAdx,
   160  	BidderPangle,
   161  	BidderPGAMSsp,
   162  	BidderPlaydigo,
   163  	BidderPubmatic,
   164  	BidderPubnative,
   165  	BidderPulsepoint,
   166  	BidderPWBid,
   167  	BidderReadpeak,
   168  	BidderRelevantDigital,
   169  	BidderRevcontent,
   170  	BidderRichaudience,
   171  	BidderRise,
   172  	BidderRoulax,
   173  	BidderRTBHouse,
   174  	BidderRubicon,
   175  	BidderSeedingAlliance,
   176  	BidderSaLunaMedia,
   177  	BidderScreencore,
   178  	BidderSharethrough,
   179  	BidderSilverMob,
   180  	BidderSilverPush,
   181  	BidderSmaato,
   182  	BidderSmartAdserver,
   183  	BidderSmartHub,
   184  	BidderSmartRTB,
   185  	BidderSmartx,
   186  	BidderSmartyAds,
   187  	BidderSmileWanted,
   188  	BidderSmrtconnect,
   189  	BidderSonobi,
   190  	BidderSovrn,
   191  	BidderSovrnXsp,
   192  	BidderSspBC,
   193  	BidderStroeerCore,
   194  	BidderTaboola,
   195  	BidderTappx,
   196  	BidderTeads,
   197  	BidderTelaria,
   198  	BidderTheadx,
   199  	BidderTpmn,
   200  	BidderTrafficGate,
   201  	BidderTriplelift,
   202  	BidderTripleliftNative,
   203  	BidderTrustedstack,
   204  	BidderUcfunnel,
   205  	BidderUndertone,
   206  	BidderUnicorn,
   207  	BidderUnruly,
   208  	BidderVideoByte,
   209  	BidderVideoHeroes,
   210  	BidderVidoomy,
   211  	BidderVisibleMeasures,
   212  	BidderVisx,
   213  	BidderVox,
   214  	BidderVrtcal,
   215  	BidderXeworks,
   216  	BidderYahooAds,
   217  	BidderYandex,
   218  	BidderYeahmobi,
   219  	BidderYieldlab,
   220  	BidderYieldmo,
   221  	BidderYieldone,
   222  	BidderZeroClickFraud,
   223  	BidderZetaGlobalSsp,
   224  	BidderZmaticoo,
   225  }
   226  
   227  func GetAliasBidderToParent() map[BidderName]BidderName {
   228  	return aliasBidderToParent
   229  }
   230  
   231  func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) error {
   232  	if IsBidderNameReserved(aliasBidderName) {
   233  		return fmt.Errorf("alias %s is a reserved bidder name and cannot be used", aliasBidderName)
   234  	}
   235  	aliasBidder := BidderName(aliasBidderName)
   236  	coreBidderNames = append(coreBidderNames, aliasBidder)
   237  	aliasBidderToParent[aliasBidder] = parentBidderName
   238  	bidderNameLookup[strings.ToLower(aliasBidderName)] = aliasBidder
   239  	return nil
   240  }
   241  
   242  func (name *BidderName) String() string {
   243  	if name == nil {
   244  		return ""
   245  	}
   246  	return string(*name)
   247  }
   248  
   249  // Names of reserved bidders. These names may not be used by a core bidder or alias.
   250  const (
   251  	BidderReservedAll     BidderName = "all"     // Reserved for the /info/bidders/all endpoint.
   252  	BidderReservedContext BidderName = "context" // Reserved for first party data.
   253  	BidderReservedData    BidderName = "data"    // Reserved for first party data.
   254  	BidderReservedGeneral BidderName = "general" // Reserved for non-bidder specific messages when using a map keyed on the bidder name.
   255  	BidderReservedGPID    BidderName = "gpid"    // Reserved for Global Placement ID (GPID).
   256  	BidderReservedPrebid  BidderName = "prebid"  // Reserved for Prebid Server configuration.
   257  	BidderReservedSKAdN   BidderName = "skadn"   // Reserved for Apple's SKAdNetwork OpenRTB extension.
   258  	BidderReservedTID     BidderName = "tid"     // Reserved for Per-Impression Transactions IDs for Multi-Impression Bid Requests.
   259  	BidderReservedAE      BidderName = "ae"      // Reserved for FLEDGE Auction Environment
   260  )
   261  
   262  // IsBidderNameReserved returns true if the specified name is a case insensitive match for a reserved bidder name.
   263  func IsBidderNameReserved(name string) bool {
   264  	if strings.EqualFold(name, string(BidderReservedAll)) {
   265  		return true
   266  	}
   267  
   268  	if strings.EqualFold(name, string(BidderReservedContext)) {
   269  		return true
   270  	}
   271  
   272  	if strings.EqualFold(name, string(BidderReservedData)) {
   273  		return true
   274  	}
   275  
   276  	if strings.EqualFold(name, string(BidderReservedGeneral)) {
   277  		return true
   278  	}
   279  
   280  	if strings.EqualFold(name, string(BidderReservedGPID)) {
   281  		return true
   282  	}
   283  
   284  	if strings.EqualFold(name, string(BidderReservedSKAdN)) {
   285  		return true
   286  	}
   287  
   288  	if strings.EqualFold(name, string(BidderReservedPrebid)) {
   289  		return true
   290  	}
   291  
   292  	if strings.EqualFold(name, string(BidderReservedTID)) {
   293  		return true
   294  	}
   295  
   296  	if strings.EqualFold(name, string(BidderReservedAE)) {
   297  		return true
   298  	}
   299  
   300  	return false
   301  }
   302  
   303  // Names of core bidders. These names *must* match the bidder code in Prebid.js if an adapter also exists in that
   304  // project. You may *not* use the name 'general' as that is reserved for general error messages nor 'context' as
   305  // that is reserved for first party data.
   306  //
   307  // Please keep this list alphabetized to minimize merge conflicts.
   308  const (
   309  	Bidder33Across          BidderName = "33across"
   310  	BidderAax               BidderName = "aax"
   311  	BidderAceex             BidderName = "aceex"
   312  	BidderAcuityAds         BidderName = "acuityads"
   313  	BidderAdelement         BidderName = "adelement"
   314  	BidderAdf               BidderName = "adf"
   315  	BidderAdgeneration      BidderName = "adgeneration"
   316  	BidderAdhese            BidderName = "adhese"
   317  	BidderAdkernel          BidderName = "adkernel"
   318  	BidderAdkernelAdn       BidderName = "adkernelAdn"
   319  	BidderAdman             BidderName = "adman"
   320  	BidderAdmixer           BidderName = "admixer"
   321  	BidderAdnuntius         BidderName = "adnuntius"
   322  	BidderAdOcean           BidderName = "adocean"
   323  	BidderAdoppler          BidderName = "adoppler"
   324  	BidderAdot              BidderName = "adot"
   325  	BidderAdpone            BidderName = "adpone"
   326  	BidderAdprime           BidderName = "adprime"
   327  	BidderAdquery           BidderName = "adquery"
   328  	BidderAdrino            BidderName = "adrino"
   329  	BidderAdsinteractive    BidderName = "adsinteractive"
   330  	BidderAdtarget          BidderName = "adtarget"
   331  	BidderAdtrgtme          BidderName = "adtrgtme"
   332  	BidderAdtelligent       BidderName = "adtelligent"
   333  	BidderAdvangelists      BidderName = "advangelists"
   334  	BidderAdView            BidderName = "adview"
   335  	BidderAdxcg             BidderName = "adxcg"
   336  	BidderAdyoulike         BidderName = "adyoulike"
   337  	BidderAidem             BidderName = "aidem"
   338  	BidderAJA               BidderName = "aja"
   339  	BidderAlgorix           BidderName = "algorix"
   340  	BidderAlkimi            BidderName = "alkimi"
   341  	BidderAMX               BidderName = "amx"
   342  	BidderApacdex           BidderName = "apacdex"
   343  	BidderAppnexus          BidderName = "appnexus"
   344  	BidderAppush            BidderName = "appush"
   345  	BidderAso               BidderName = "aso"
   346  	BidderAudienceNetwork   BidderName = "audienceNetwork"
   347  	BidderAutomatad         BidderName = "automatad"
   348  	BidderAvocet            BidderName = "avocet"
   349  	BidderAxis              BidderName = "axis"
   350  	BidderAxonix            BidderName = "axonix"
   351  	BidderBeachfront        BidderName = "beachfront"
   352  	BidderBeintoo           BidderName = "beintoo"
   353  	BidderBematterfull      BidderName = "bematterfull"
   354  	BidderBetween           BidderName = "between"
   355  	BidderBeyondMedia       BidderName = "beyondmedia"
   356  	BidderBidmachine        BidderName = "bidmachine"
   357  	BidderBidmyadz          BidderName = "bidmyadz"
   358  	BidderBidsCube          BidderName = "bidscube"
   359  	BidderBidstack          BidderName = "bidstack"
   360  	BidderBizzclick         BidderName = "bizzclick"
   361  	BidderBliink            BidderName = "bliink"
   362  	BidderBlue              BidderName = "blue"
   363  	BidderBluesea           BidderName = "bluesea"
   364  	BidderBmtm              BidderName = "bmtm"
   365  	BidderBoldwin           BidderName = "boldwin"
   366  	BidderBrave             BidderName = "brave"
   367  	BidderBWX               BidderName = "bwx"
   368  	BidderCadentApertureMX  BidderName = "cadent_aperture_mx"
   369  	BidderCcx               BidderName = "ccx"
   370  	BidderCoinzilla         BidderName = "coinzilla"
   371  	BidderColossus          BidderName = "colossus"
   372  	BidderCompass           BidderName = "compass"
   373  	BidderConnectAd         BidderName = "connectad"
   374  	BidderConsumable        BidderName = "consumable"
   375  	BidderConversant        BidderName = "conversant"
   376  	BidderCpmstar           BidderName = "cpmstar"
   377  	BidderCriteo            BidderName = "criteo"
   378  	BidderCWire             BidderName = "cwire"
   379  	BidderDatablocks        BidderName = "datablocks"
   380  	BidderDecenterAds       BidderName = "decenterads"
   381  	BidderDeepintent        BidderName = "deepintent"
   382  	BidderDefinemedia       BidderName = "definemedia"
   383  	BidderDianomi           BidderName = "dianomi"
   384  	BidderEdge226           BidderName = "edge226"
   385  	BidderDmx               BidderName = "dmx"
   386  	BidderDXKulture         BidderName = "dxkulture"
   387  	BidderEmtv              BidderName = "emtv"
   388  	BidderEmxDigital        BidderName = "emx_digital"
   389  	BidderEPlanning         BidderName = "eplanning"
   390  	BidderEpom              BidderName = "epom"
   391  	BidderEVolution         BidderName = "e_volution"
   392  	BidderFlipp             BidderName = "flipp"
   393  	BidderFreewheelSSP      BidderName = "freewheelssp"
   394  	BidderFRVRAdNetwork     BidderName = "frvradn"
   395  	BidderGamma             BidderName = "gamma"
   396  	BidderGamoshi           BidderName = "gamoshi"
   397  	BidderGlobalsun         BidderName = "globalsun"
   398  	BidderGothamads         BidderName = "gothamads"
   399  	BidderGrid              BidderName = "grid"
   400  	BidderGumGum            BidderName = "gumgum"
   401  	BidderHuaweiAds         BidderName = "huaweiads"
   402  	BidderImds              BidderName = "imds"
   403  	BidderImpactify         BidderName = "impactify"
   404  	BidderImprovedigital    BidderName = "improvedigital"
   405  	BidderInfyTV            BidderName = "infytv"
   406  	BidderInMobi            BidderName = "inmobi"
   407  	BidderInteractiveoffers BidderName = "interactiveoffers"
   408  	BidderInvibes           BidderName = "invibes"
   409  	BidderIQX               BidderName = "iqx"
   410  	BidderIQZone            BidderName = "iqzone"
   411  	BidderIx                BidderName = "ix"
   412  	BidderJixie             BidderName = "jixie"
   413  	BidderKargo             BidderName = "kargo"
   414  	BidderKayzen            BidderName = "kayzen"
   415  	BidderKidoz             BidderName = "kidoz"
   416  	BidderKiviads           BidderName = "kiviads"
   417  	BidderLmKiviads         BidderName = "lm_kiviads"
   418  	BidderKrushmedia        BidderName = "krushmedia"
   419  	BidderLemmadigital      BidderName = "lemmadigital"
   420  	BidderLiftoff           BidderName = "liftoff"
   421  	BidderLimelightDigital  BidderName = "limelightDigital"
   422  	BidderLockerDome        BidderName = "lockerdome"
   423  	BidderLogan             BidderName = "logan"
   424  	BidderLogicad           BidderName = "logicad"
   425  	BidderLoyal             BidderName = "loyal"
   426  	BidderLunaMedia         BidderName = "lunamedia"
   427  	BidderMabidder          BidderName = "mabidder"
   428  	BidderMadvertise        BidderName = "madvertise"
   429  	BidderMarsmedia         BidderName = "marsmedia"
   430  	BidderMediafuse         BidderName = "mediafuse"
   431  	BidderMedianet          BidderName = "medianet"
   432  	BidderMgid              BidderName = "mgid"
   433  	BidderMgidX             BidderName = "mgidX"
   434  	BidderMinuteMedia       BidderName = "minutemedia"
   435  	BidderMobfoxpb          BidderName = "mobfoxpb"
   436  	BidderMobileFuse        BidderName = "mobilefuse"
   437  	BidderMotorik           BidderName = "motorik"
   438  	BidderNextMillennium    BidderName = "nextmillennium"
   439  	BidderNoBid             BidderName = "nobid"
   440  	BidderOms               BidderName = "oms"
   441  	BidderOneTag            BidderName = "onetag"
   442  	BidderOpenWeb           BidderName = "openweb"
   443  	BidderOpenx             BidderName = "openx"
   444  	BidderOperaads          BidderName = "operaads"
   445  	BidderOrbidder          BidderName = "orbidder"
   446  	BidderOutbrain          BidderName = "outbrain"
   447  	BidderOwnAdx            BidderName = "ownadx"
   448  	BidderPangle            BidderName = "pangle"
   449  	BidderPGAMSsp           BidderName = "pgamssp"
   450  	BidderPlaydigo          BidderName = "playdigo"
   451  	BidderPubmatic          BidderName = "pubmatic"
   452  	BidderPubnative         BidderName = "pubnative"
   453  	BidderPulsepoint        BidderName = "pulsepoint"
   454  	BidderPWBid             BidderName = "pwbid"
   455  	BidderReadpeak          BidderName = "readpeak"
   456  	BidderRelevantDigital   BidderName = "relevantdigital"
   457  	BidderRevcontent        BidderName = "revcontent"
   458  	BidderRichaudience      BidderName = "richaudience"
   459  	BidderRise              BidderName = "rise"
   460  	BidderRoulax            BidderName = "roulax"
   461  	BidderRTBHouse          BidderName = "rtbhouse"
   462  	BidderRubicon           BidderName = "rubicon"
   463  	BidderSeedingAlliance   BidderName = "seedingAlliance"
   464  	BidderSaLunaMedia       BidderName = "sa_lunamedia"
   465  	BidderScreencore        BidderName = "screencore"
   466  	BidderSharethrough      BidderName = "sharethrough"
   467  	BidderSilverMob         BidderName = "silvermob"
   468  	BidderSilverPush        BidderName = "silverpush"
   469  	BidderSmaato            BidderName = "smaato"
   470  	BidderSmartAdserver     BidderName = "smartadserver"
   471  	BidderSmartHub          BidderName = "smarthub"
   472  	BidderSmartRTB          BidderName = "smartrtb"
   473  	BidderSmartx            BidderName = "smartx"
   474  	BidderSmartyAds         BidderName = "smartyads"
   475  	BidderSmileWanted       BidderName = "smilewanted"
   476  	BidderSmrtconnect       BidderName = "smrtconnect"
   477  	BidderSonobi            BidderName = "sonobi"
   478  	BidderSovrn             BidderName = "sovrn"
   479  	BidderSovrnXsp          BidderName = "sovrnXsp"
   480  	BidderSspBC             BidderName = "sspBC"
   481  	BidderStroeerCore       BidderName = "stroeerCore"
   482  	BidderTaboola           BidderName = "taboola"
   483  	BidderTappx             BidderName = "tappx"
   484  	BidderTeads             BidderName = "teads"
   485  	BidderTelaria           BidderName = "telaria"
   486  	BidderTheadx            BidderName = "theadx"
   487  	BidderTpmn              BidderName = "tpmn"
   488  	BidderTrafficGate       BidderName = "trafficgate"
   489  	BidderTriplelift        BidderName = "triplelift"
   490  	BidderTripleliftNative  BidderName = "triplelift_native"
   491  	BidderTrustedstack      BidderName = "trustedstack"
   492  	BidderUcfunnel          BidderName = "ucfunnel"
   493  	BidderUndertone         BidderName = "undertone"
   494  	BidderUnicorn           BidderName = "unicorn"
   495  	BidderUnruly            BidderName = "unruly"
   496  	BidderVideoByte         BidderName = "videobyte"
   497  	BidderVideoHeroes       BidderName = "videoheroes"
   498  	BidderVidoomy           BidderName = "vidoomy"
   499  	BidderVisibleMeasures   BidderName = "visiblemeasures"
   500  	BidderVisx              BidderName = "visx"
   501  	BidderVox               BidderName = "vox"
   502  	BidderVrtcal            BidderName = "vrtcal"
   503  	BidderXeworks           BidderName = "xeworks"
   504  	BidderYahooAds          BidderName = "yahooAds"
   505  	BidderYandex            BidderName = "yandex"
   506  	BidderYeahmobi          BidderName = "yeahmobi"
   507  	BidderYieldlab          BidderName = "yieldlab"
   508  	BidderYieldmo           BidderName = "yieldmo"
   509  	BidderYieldone          BidderName = "yieldone"
   510  	BidderZeroClickFraud    BidderName = "zeroclickfraud"
   511  	BidderZetaGlobalSsp     BidderName = "zeta_global_ssp"
   512  	BidderZmaticoo          BidderName = "zmaticoo"
   513  )
   514  
   515  // CoreBidderNames returns a slice of all core bidders.
   516  func CoreBidderNames() []BidderName {
   517  	return coreBidderNames
   518  }
   519  
   520  // BuildBidderMap builds a map of string to BidderName, to remain compatbile with the
   521  // prebioud BidderMap variable.
   522  func BuildBidderMap() map[string]BidderName {
   523  	lookup := make(map[string]BidderName)
   524  	for _, name := range CoreBidderNames() {
   525  		lookup[string(name)] = name
   526  	}
   527  	return lookup
   528  }
   529  
   530  // BuildBidderStringSlice builds a slioce of strings for each BidderName.
   531  func BuildBidderStringSlice() []string {
   532  	coreBidders := CoreBidderNames()
   533  	slice := make([]string, len(coreBidders))
   534  	for i, name := range CoreBidderNames() {
   535  		slice[i] = string(name)
   536  	}
   537  	return slice
   538  }
   539  
   540  func BuildBidderNameHashSet() map[string]struct{} {
   541  	hashSet := make(map[string]struct{})
   542  	for _, name := range CoreBidderNames() {
   543  		hashSet[string(name)] = struct{}{}
   544  	}
   545  	return hashSet
   546  }
   547  
   548  // bidderNameLookup is a map of the lower case version of the bidder name to the precise BidderName value.
   549  var bidderNameLookup = func() map[string]BidderName {
   550  	lookup := make(map[string]BidderName)
   551  	for _, name := range CoreBidderNames() {
   552  		bidderNameLower := strings.ToLower(string(name))
   553  		lookup[bidderNameLower] = name
   554  	}
   555  	return lookup
   556  }()
   557  
   558  func NormalizeBidderName(name string) (BidderName, bool) {
   559  	nameLower := strings.ToLower(name)
   560  	bidderName, exists := bidderNameLookup[nameLower]
   561  	return bidderName, exists
   562  }
   563  
   564  // NormalizeBidderNameOrUnchanged returns the normalized name of known bidders, otherwise returns
   565  // the name exactly as provided.
   566  func NormalizeBidderNameOrUnchanged(name string) BidderName {
   567  	if normalized, exists := NormalizeBidderName(name); exists {
   568  		return normalized
   569  	}
   570  	return BidderName(name)
   571  }
   572  
   573  // The BidderParamValidator is used to enforce bidrequest.imp[i].ext.prebid.bidder.{anyBidder} values.
   574  //
   575  // This is treated differently from the other types because we rely on JSON-schemas to validate bidder params.
   576  type BidderParamValidator interface {
   577  	Validate(name BidderName, ext json.RawMessage) error
   578  	// Schema returns the JSON schema used to perform validation.
   579  	Schema(name BidderName) string
   580  }
   581  
   582  type bidderParamsFileSystem interface {
   583  	readDir(name string) ([]os.DirEntry, error)
   584  	readFile(name string) ([]byte, error)
   585  	newReferenceLoader(source string) gojsonschema.JSONLoader
   586  	newSchema(l gojsonschema.JSONLoader) (*gojsonschema.Schema, error)
   587  	abs(path string) (string, error)
   588  }
   589  
   590  type standardBidderParamsFileSystem struct{}
   591  
   592  func (standardBidderParamsFileSystem) readDir(name string) ([]os.DirEntry, error) {
   593  	return os.ReadDir(name)
   594  }
   595  
   596  func (standardBidderParamsFileSystem) readFile(name string) ([]byte, error) {
   597  	return os.ReadFile(name)
   598  }
   599  
   600  func (standardBidderParamsFileSystem) newReferenceLoader(source string) gojsonschema.JSONLoader {
   601  	return gojsonschema.NewReferenceLoader(source)
   602  }
   603  
   604  func (standardBidderParamsFileSystem) newSchema(l gojsonschema.JSONLoader) (*gojsonschema.Schema, error) {
   605  	return gojsonschema.NewSchema(l)
   606  }
   607  
   608  func (standardBidderParamsFileSystem) abs(path string) (string, error) {
   609  	return filepath.Abs(path)
   610  }
   611  
   612  var paramsValidator bidderParamsFileSystem = standardBidderParamsFileSystem{}
   613  
   614  // NewBidderParamsValidator makes a BidderParamValidator, assuming all the necessary files exist in the filesystem.
   615  // This will error if, for example, a Bidder gets added but no JSON schema is written for them.
   616  func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, error) {
   617  	fileInfos, err := paramsValidator.readDir(schemaDirectory)
   618  	if err != nil {
   619  		return nil, fmt.Errorf("Failed to read JSON schemas from directory %s. %v", schemaDirectory, err)
   620  	}
   621  
   622  	bidderMap := BuildBidderMap()
   623  
   624  	schemaContents := make(map[BidderName]string, 50)
   625  	schemas := make(map[BidderName]*gojsonschema.Schema, 50)
   626  	for _, fileInfo := range fileInfos {
   627  		bidderName := strings.TrimSuffix(fileInfo.Name(), ".json")
   628  		if _, ok := bidderMap[bidderName]; !ok {
   629  			return nil, fmt.Errorf("File %s/%s does not match a valid BidderName.", schemaDirectory, fileInfo.Name())
   630  		}
   631  
   632  		toOpen, err := paramsValidator.abs(filepath.Join(schemaDirectory, fileInfo.Name()))
   633  		if err != nil {
   634  			return nil, fmt.Errorf("Failed to get an absolute representation of the path: %s, %v", toOpen, err)
   635  		}
   636  		schemaLoader := paramsValidator.newReferenceLoader("file:///" + filepath.ToSlash(toOpen))
   637  		loadedSchema, err := paramsValidator.newSchema(schemaLoader)
   638  		if err != nil {
   639  			return nil, fmt.Errorf("Failed to load json schema at %s: %v", toOpen, err)
   640  		}
   641  
   642  		fileBytes, err := paramsValidator.readFile(fmt.Sprintf("%s/%s", schemaDirectory, fileInfo.Name()))
   643  		if err != nil {
   644  			return nil, fmt.Errorf("Failed to read file %s/%s: %v", schemaDirectory, fileInfo.Name(), err)
   645  		}
   646  
   647  		schemas[BidderName(bidderName)] = loadedSchema
   648  		schemaContents[BidderName(bidderName)] = string(fileBytes)
   649  	}
   650  
   651  	// set alias bidder params schema to its parent
   652  	for alias, parent := range aliasBidderToParent {
   653  		parentSchema := schemas[parent]
   654  		schemas[alias] = parentSchema
   655  
   656  		parentSchemaContents := schemaContents[parent]
   657  		schemaContents[alias] = parentSchemaContents
   658  	}
   659  
   660  	return &bidderParamValidator{
   661  		schemaContents: schemaContents,
   662  		parsedSchemas:  schemas,
   663  	}, nil
   664  }
   665  
   666  type bidderParamValidator struct {
   667  	schemaContents map[BidderName]string
   668  	parsedSchemas  map[BidderName]*gojsonschema.Schema
   669  }
   670  
   671  func (validator *bidderParamValidator) Validate(name BidderName, ext json.RawMessage) error {
   672  	result, err := validator.parsedSchemas[name].Validate(gojsonschema.NewBytesLoader(ext))
   673  	if err != nil {
   674  		return err
   675  	}
   676  	if !result.Valid() {
   677  		errBuilder := bytes.NewBuffer(make([]byte, 0, 300))
   678  		for _, err := range result.Errors() {
   679  			errBuilder.WriteString(err.String())
   680  		}
   681  		return errors.New(errBuilder.String())
   682  	}
   683  	return nil
   684  }
   685  
   686  func (validator *bidderParamValidator) Schema(name BidderName) string {
   687  	return validator.schemaContents[name]
   688  }