Skip to content

Commit

Permalink
Merge branch 'prebid:master' into theadx
Browse files Browse the repository at this point in the history
  • Loading branch information
mustafakemal16 committed Feb 15, 2024
2 parents dde7749 + 902d262 commit 7811aaf
Show file tree
Hide file tree
Showing 12 changed files with 761 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/helpers/pull-request-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ class userHelper {
repo: this.repo,
username: this.owner,
})
return data.permission === adminPermission || data.permission === writePermission
console.log(JSON.stringify(data))
return data.permission === writePermission || data.permission === adminPermission
}
}

Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ jobs:
return hasPermission
outputs:
hasWritePermission: ${{ steps.check.outputs.result }}

debug-step:
name: Debug step
runs-on: ubuntu-latest
steps:
- name: Debug
run: echo ${{ needs.check-permission.outputs.hasWritePermission }}

build-master:
name: Build master
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
# Resolves to empty string for push events and falls back to HEAD.
ref: ${{ github.event.pull_request.head.sha }}
Expand All @@ -29,6 +29,6 @@ jobs:
severity: 'CRITICAL,HIGH'

- name: Upload Results To GitHub Security Tab
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
2 changes: 1 addition & 1 deletion adapters/bidder.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Bidder interface {
type TimeoutBidder interface {
Bidder

// MakeTimeoutNotice functions much the same as MakeRequests, except it is fed the bidder request that timed out,
// MakeTimeoutNotification functions much the same as MakeRequests, except it is fed the bidder request that timed out,
// and expects that only one notification "request" will be generated. A use case for multiple timeout notifications
// has not been anticipated.
//
Expand Down
56 changes: 49 additions & 7 deletions adapters/yieldlab/types.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,60 @@
package yieldlab

import (
"github.com/prebid/prebid-server/v2/openrtb_ext"
"strconv"
"time"
)

type bidResponse struct {
ID uint64 `json:"id"`
Price uint `json:"price"`
Advertiser string `json:"advertiser"`
Adsize string `json:"adsize"`
Pid uint64 `json:"pid"`
Did uint64 `json:"did"`
Pvid string `json:"pvid"`
ID uint64 `json:"id"`
Price uint `json:"price"`
Advertiser string `json:"advertiser"`
Adsize string `json:"adsize"`
Pid uint64 `json:"pid"`
Did uint64 `json:"did"`
Pvid string `json:"pvid"`
DSA *dsaResponse `json:"dsa,omitempty"`
}

// dsaResponse defines Digital Service Act (DSA) parameters from Yieldlab yieldprobe response.
type dsaResponse struct {
Behalf string `json:"behalf,omitempty"`
Paid string `json:"paid,omitempty"`
Adrender *int `json:"adrender,omitempty"`
Transparency []dsaTransparency `json:"transparency,omitempty"`
}

// openRTBExtRegsWithDSA defines the contract for bidrequest.regs.ext with the missing DSA property.
//
// The openrtb_ext.ExtRegs needs to be extended on yieldlab adapter level until DSA has been implemented
// by the prebid server team (https://github.com/prebid/prebid-server/issues/3424).
type openRTBExtRegsWithDSA struct {
openrtb_ext.ExtRegs
DSA *dsaRequest `json:"dsa,omitempty"`
}

// responseExtWithDSA defines seatbid.bid.ext with the DSA object.
type responseExtWithDSA struct {
DSA dsaResponse `json:"dsa"`
}

// dsaRequest defines Digital Service Act (DSA) parameter
// as specified by the OpenRTB 2.X DSA Transparency community extension.
//
// Should rather come from openrtb_ext package but will be defined here until DSA has been
// implemented by the prebid server team (https://github.com/prebid/prebid-server/issues/3424).
type dsaRequest struct {
Required *int `json:"dsarequired"`
PubRender *int `json:"pubrender"`
DataToPub *int `json:"datatopub"`
Transparency []dsaTransparency `json:"transparency"`
}

// dsaTransparency Digital Service Act (DSA) transparency object
type dsaTransparency struct {
Domain string `json:"domain,omitempty"`
Params []int `json:"dsaparams,omitempty"`
}

type cacheBuster func() string
Expand Down
107 changes: 105 additions & 2 deletions adapters/yieldlab/yieldlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,94 @@ func (a *YieldlabAdapter) makeEndpointURL(req *openrtb2.BidRequest, params *open
}
}

dsa, err := getDSA(req)
if err != nil {
return "", err
}
if dsa != nil {
if dsa.Required != nil {
q.Set("dsarequired", strconv.Itoa(*dsa.Required))
}
if dsa.PubRender != nil {
q.Set("dsapubrender", strconv.Itoa(*dsa.PubRender))
}
if dsa.DataToPub != nil {
q.Set("dsadatatopub", strconv.Itoa(*dsa.DataToPub))
}
if len(dsa.Transparency) != 0 {
transparencyParam := makeDSATransparencyURLParam(dsa.Transparency)
if len(transparencyParam) != 0 {
q.Set("dsatransparency", transparencyParam)
}
}
}

uri.RawQuery = q.Encode()

return uri.String(), nil
}

// getDSA extracts the Digital Service Act (DSA) properties from the request.
func getDSA(req *openrtb2.BidRequest) (*dsaRequest, error) {
if req.Regs == nil || req.Regs.Ext == nil {
return nil, nil
}

var extRegs openRTBExtRegsWithDSA
err := json.Unmarshal(req.Regs.Ext, &extRegs)
if err != nil {
return nil, fmt.Errorf("failed to parse Regs.Ext object from Yieldlab response: %v", err)
}

return extRegs.DSA, nil
}

// makeDSATransparencyURLParam creates the transparency url parameter
// as specified by the OpenRTB 2.X DSA Transparency community extension.
//
// Example result: platform1domain.com~1~~SSP2domain.com~1_2
func makeDSATransparencyURLParam(transparencyObjects []dsaTransparency) string {
valueSeparator, itemSeparator, objectSeparator := "_", "~", "~~"

var b strings.Builder

concatParams := func(params []int) {
b.WriteString(strconv.Itoa(params[0]))
for _, param := range params[1:] {
b.WriteString(valueSeparator)
b.WriteString(strconv.Itoa(param))
}
}

concatTransparency := func(object dsaTransparency) {
if len(object.Domain) == 0 {
return
}

b.WriteString(object.Domain)
if len(object.Params) != 0 {
b.WriteString(itemSeparator)
concatParams(object.Params)
}
}

concatTransparencies := func(objects []dsaTransparency) {
if len(objects) == 0 {
return
}

concatTransparency(objects[0])
for _, obj := range objects[1:] {
b.WriteString(objectSeparator)
concatTransparency(obj)
}
}

concatTransparencies(transparencyObjects)

return b.String()
}

func (a *YieldlabAdapter) makeFormats(req *openrtb2.BidRequest) (bool, string) {
var formats []string
const sizesSeparator, adslotSizesSeparator = "|", ","
Expand Down Expand Up @@ -253,6 +336,7 @@ func (a *YieldlabAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa
}
}

var bidErrors []error
for _, bid := range bids {
width, height, err := splitSize(bid.Adsize)
if err != nil {
Expand All @@ -269,7 +353,13 @@ func (a *YieldlabAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa
if imp, exists := adslotToImpMap[strconv.FormatUint(bid.ID, 10)]; !exists {
continue
} else {
var bidType openrtb_ext.BidType
extJson, err := makeResponseExt(bid)
if err != nil {
bidErrors = append(bidErrors, err)
// skip as bids with missing ext.dsa will be discarded anyway
continue
}

responseBid := &openrtb2.Bid{
ID: strconv.FormatUint(bid.ID, 10),
Price: float64(bid.Price) / 100,
Expand All @@ -278,8 +368,10 @@ func (a *YieldlabAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa
DealID: strconv.FormatUint(bid.Pid, 10),
W: int64(width),
H: int64(height),
Ext: extJson,
}

var bidType openrtb_ext.BidType
if imp.Video != nil {
bidType = openrtb_ext.BidTypeVideo
responseBid.NURL = a.makeAdSourceURL(internalRequest, req, bid)
Expand All @@ -299,7 +391,18 @@ func (a *YieldlabAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa
}
}

return bidderResponse, nil
return bidderResponse, bidErrors
}

func makeResponseExt(bid *bidResponse) (json.RawMessage, error) {
if bid.DSA != nil {
extJson, err := json.Marshal(responseExtWithDSA{*bid.DSA})
if err != nil {
return nil, fmt.Errorf("failed to make JSON for seatbid.bid.ext for adslotID %v. This is most likely a programming issue", bid.ID)
}
return extJson, nil
}
return nil, nil
}

func (a *YieldlabAdapter) findBidReq(adslotID uint64, params []*openrtb_ext.ExtImpYieldlab) *openrtb_ext.ExtImpYieldlab {
Expand Down
92 changes: 92 additions & 0 deletions adapters/yieldlab/yieldlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,98 @@ func Test_makeSupplyChain(t *testing.T) {
}
}

func Test_makeDSATransparencyUrlParam(t *testing.T) {
tests := []struct {
name string
transparencies []dsaTransparency
expected string
}{
{
name: "No transparency objects",
transparencies: []dsaTransparency{},
expected: "",
},
{
name: "Nil transparency",
transparencies: nil,
expected: "",
},
{
name: "Params without a domain",
transparencies: []dsaTransparency{
{
Params: []int{1, 2},
},
},
expected: "",
},
{
name: "Params without a params",
transparencies: []dsaTransparency{
{
Domain: "domain.com",
},
},
expected: "domain.com",
},
{
name: "One object; No Params",
transparencies: []dsaTransparency{
{
Domain: "domain.com",
Params: []int{},
},
},
expected: "domain.com",
},
{
name: "One object; One Param",
transparencies: []dsaTransparency{
{
Domain: "domain.com",
Params: []int{1},
},
},
expected: "domain.com~1",
},
{
name: "Three domain objects",
transparencies: []dsaTransparency{
{
Domain: "domain1.com",
Params: []int{1, 2},
},
{
Domain: "domain2.com",
Params: []int{3, 4},
},
{
Domain: "domain3.com",
Params: []int{5, 6},
},
},
expected: "domain1.com~1_2~~domain2.com~3_4~~domain3.com~5_6",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual := makeDSATransparencyURLParam(test.transparencies)
assert.Equal(t, test.expected, actual)
})
}
}

func Test_getDSA_invalidRequestExt(t *testing.T) {
req := &openrtb2.BidRequest{
Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"DSA":"wrongValueType"}`)},
}

dsa, err := getDSA(req)

assert.NotNil(t, err)
assert.Nil(t, dsa)
}

func TestYieldlabAdapter_makeEndpointURL_invalidEndpoint(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderYieldlab, config.Adapter{
Endpoint: "test$:/something§"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
Expand Down
Loading

0 comments on commit 7811aaf

Please sign in to comment.