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

Uoe 4350 same site #11

Merged
merged 5 commits into from
Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions adapters/adform/adform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -198,7 +198,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest {
pbsCookie := usersync.ParsePBSCookieFromRequest(prebidHttpRequest, &config.HostCookie{})
pbsCookie.TrySync("adform", adformTestData.buyerUID)
fakeWriter := httptest.NewRecorder()
pbsCookie.SetCookieOnResponse(fakeWriter, "", time.Minute)
pbsCookie.SetCookieOnResponse(fakeWriter, prebidHttpRequest, "", time.Minute)
prebidHttpRequest.Header.Add("Cookie", fakeWriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/appnexus/appnexus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -363,7 +363,7 @@ func TestAppNexusBasicResponse(t *testing.T) {
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("adnxs", andata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/audienceNetwork/facebook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

type tagInfo struct {
Expand Down Expand Up @@ -209,7 +209,7 @@ func GenerateBidRequestForTestData(fbdata bidInfo, url string) (*pbs.PBSRequest,
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("audienceNetwork", fbdata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/lifestreet/lifestreet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

type lsTagInfo struct {
Expand Down Expand Up @@ -227,7 +227,7 @@ func TestLifestreetBasicResponse(t *testing.T) {

pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/pubmatic/pubmatic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"testing"
"time"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/cache/dummycache"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -656,7 +656,7 @@ func TestPubmaticSampleRequest(t *testing.T) {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("pubmatic", "12345")
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/pulsepoint/pulsepoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"testing"
"time"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/cache/dummycache"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"
)

/**
Expand Down Expand Up @@ -226,7 +226,7 @@ func SampleRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("pulsepoint", "pulsepointUser123")
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))
// parse the http request
cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/rubicon/rubicon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (

"strings"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/mxmCherry/openrtb"
)

type rubiAppendTrackerUrlTestScenario struct {
Expand Down Expand Up @@ -945,7 +945,7 @@ func CreatePrebidRequest(server *httptest.Server, t *testing.T) (an *RubiconAdap
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("rubicon", rubidata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/sovrn/sovrn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"net/http/httptest"
"testing"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"

"context"
"net/http"
Expand Down Expand Up @@ -188,7 +188,7 @@ func SampleSovrnRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("sovrn", testSovrnUserId)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))
// parse the http request
cacheClient, _ := dummycache.New()
Expand Down
14 changes: 11 additions & 3 deletions endpoints/cookie_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ func (deps *cookieSyncDeps) Endpoint(w http.ResponseWriter, r *http.Request, _ h
parsedReq.Bidders = append(parsedReq.Bidders, string(bidder))
}
}
isBrowserApplicable := usersync.IsBrowserApplicableForSameSite(r)
needSyncupForSameSite := false
if isBrowserApplicable {
_, err1 := r.Cookie(usersync.SameSiteCookieName)
if err1 == http.ErrNoCookie {
needSyncupForSameSite = true
}
}

parsedReq.filterExistingSyncs(deps.syncers, userSyncCookie)
parsedReq.filterExistingSyncs(deps.syncers, userSyncCookie, needSyncupForSameSite)
adapterSyncs := make(map[openrtb_ext.BidderName]bool)
for _, b := range parsedReq.Bidders {
// assume all bidders will be GDPR blocked
Expand Down Expand Up @@ -193,15 +201,15 @@ type cookieSyncRequest struct {
Limit int `json:"limit"`
}

func (req *cookieSyncRequest) filterExistingSyncs(valid map[openrtb_ext.BidderName]usersync.Usersyncer, cookie *usersync.PBSCookie) {
func (req *cookieSyncRequest) filterExistingSyncs(valid map[openrtb_ext.BidderName]usersync.Usersyncer, cookie *usersync.PBSCookie, needSyncupForSameSite bool) {
for i := 0; i < len(req.Bidders); i++ {
thisBidder := req.Bidders[i]
//added hack to support to old wrapper versions having indexExchange as partner
//TODO: Remove when a stable version is released
if thisBidder == "indexExchange" {
thisBidder = "ix"
}
if syncer, isValid := valid[openrtb_ext.BidderName(thisBidder)]; !isValid || cookie.HasLiveSync(syncer.FamilyName()) {
if syncer, isValid := valid[openrtb_ext.BidderName(thisBidder)]; !isValid || (cookie.HasLiveSync(syncer.FamilyName()) && !needSyncupForSameSite) {
req.Bidders = append(req.Bidders[:i], req.Bidders[i+1:]...)
i--
}
Expand Down
4 changes: 2 additions & 2 deletions endpoints/setuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"net/http"
"time"

"github.com/julienschmidt/httprouter"
"github.com/PubMatic-OpenWrap/prebid-server/analytics"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/gdpr"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/PubMatic-OpenWrap/prebid-server/pbsmetrics"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/julienschmidt/httprouter"
)

func NewSetUIDEndpoint(cfg config.HostCookie, perms gdpr.Permissions, pbsanalytics analytics.PBSAnalyticsModule, metrics pbsmetrics.MetricsEngine) httprouter.Handle {
Expand Down Expand Up @@ -76,7 +76,7 @@ func NewSetUIDEndpoint(cfg config.HostCookie, perms gdpr.Permissions, pbsanalyti
so.Success = true
}

pc.SetCookieOnResponse(w, cfg.Domain, cookieTTL)
pc.SetCookieOnResponse(w, r, cfg.Domain, cookieTTL)
})
}

Expand Down
6 changes: 3 additions & 3 deletions pbs/usersync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import (
"strings"
"time"

"github.com/golang/glog"
"github.com/julienschmidt/httprouter"
"github.com/PubMatic-OpenWrap/prebid-server/analytics"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/pbsmetrics"
"github.com/PubMatic-OpenWrap/prebid-server/ssl"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/golang/glog"
"github.com/julienschmidt/httprouter"
)

// Recaptcha code from https://github.com/haisum/recaptcha/blob/master/recaptcha.go
Expand Down Expand Up @@ -95,7 +95,7 @@ func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httpr
pc := usersync.ParsePBSCookieFromRequest(r, deps.HostCookieConfig)
pc.SetPreference(optout == "")

pc.SetCookieOnResponse(w, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration())
pc.SetCookieOnResponse(w, r, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration())
if optout == "" {
http.Redirect(w, r, deps.HostCookieConfig.OptInURL, 301)
} else {
Expand Down
67 changes: 62 additions & 5 deletions usersync/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,27 @@ import (
"encoding/json"
"errors"
"net/http"
"strconv"
"strings"
"time"

"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
)

// DEFAULT_TTL is the default amount of time which a cookie is considered valid.
const DEFAULT_TTL = 14 * 24 * time.Hour
const UID_COOKIE_NAME = "uids"
const (
// DEFAULT_TTL is the default amount of time which a cookie is considered valid.
DEFAULT_TTL = 14 * 24 * time.Hour
UID_COOKIE_NAME = "uids"
chromeStr = "Chrome/"
chromeiOSStr = "CriOS/"
chromeMinVer = 67
chromeStrLen = len(chromeStr)
chromeiOSStrLen = len(chromeiOSStr)
SameSiteCookieName = "SSCookie"
SameSiteCookieValue = "1"
SameSiteAttribute = "; SameSite=None"
)

// customBidderTTLs stores rules about how long a particular UID sync is valid for each bidder.
// If a bidder does a cookie sync *without* listing a rule here, then the DEFAULT_TTL will be used.
Expand Down Expand Up @@ -160,12 +172,57 @@ func (cookie *PBSCookie) GetId(bidderName openrtb_ext.BidderName) (id string, ex
}

// SetCookieOnResponse is a shortcut for "ToHTTPCookie(); cookie.setDomain(domain); setCookie(w, cookie)"
func (cookie *PBSCookie) SetCookieOnResponse(w http.ResponseWriter, domain string, ttl time.Duration) {
func (cookie *PBSCookie) SetCookieOnResponse(w http.ResponseWriter, r *http.Request, domain string, ttl time.Duration) {
httpCookie := cookie.ToHTTPCookie(ttl)
if domain != "" {
httpCookie.Domain = domain
}
http.SetCookie(w, httpCookie)
cookieStr := httpCookie.String()
var sameSiteCookie *http.Cookie
if IsBrowserApplicableForSameSite(r) {
cookieStr += SameSiteAttribute
sameSiteCookie = &http.Cookie{
Name: SameSiteCookieName,
Value: SameSiteCookieValue,
Expires: time.Now().Add(ttl),
Path: "/",
}
sameSiteCookieStr := sameSiteCookie.String()
sameSiteCookieStr += SameSiteAttribute
w.Header().Add("Set-Cookie", sameSiteCookieStr)
}
if cookieStr != "" {
w.Header().Add("Set-Cookie", cookieStr)
}
}

// IsBrowserApplicableForSameSite function checks if browser is Chrome and browser version is greater than the minimum version for adding the SameSite attribute
func IsBrowserApplicableForSameSite(req *http.Request) bool {
result := false
ua := req.UserAgent()

index := strings.Index(ua, chromeStr)
criOSIndex := strings.Index(ua, chromeiOSStr)
if index != -1 {
result = checkChromeBrowserVersion(ua, index, chromeStrLen)
} else if criOSIndex != -1 {
result = checkChromeBrowserVersion(ua, criOSIndex, chromeiOSStrLen)
}
return result
}

func checkChromeBrowserVersion(ua string, index int, chromeStrLength int) bool {
result := false
vIndex := index + chromeStrLength
dotIndex := strings.Index(ua[vIndex:], ".")
if dotIndex == -1 {
dotIndex = len(ua[vIndex:])
}
version, _ := strconv.Atoi(ua[vIndex : vIndex+dotIndex])
if version >= chromeMinVer {
result = true
}
return result
}

// Unsync removes the user's ID for the given family from this cookie.
Expand Down
30 changes: 29 additions & 1 deletion usersync/cookie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -353,11 +354,38 @@ func newSampleCookie() *PBSCookie {

func writeThenRead(cookie *PBSCookie) *PBSCookie {
w := httptest.NewRecorder()
cookie.SetCookieOnResponse(w, "mock-domain", 90*24*time.Hour)
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")

header := http.Header{}
header.Add("Cookie", writtenCookie)
request := http.Request{Header: header}
return ParsePBSCookieFromRequest(&request, &config.HostCookie{})
}

func TestSetCookieOnResponseForSameSiteNone(t *testing.T) {
cookie := newSampleCookie()
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")
t.Log("Set-Cookie is: ", writtenCookie)
if !strings.Contains(writtenCookie, "SSCookie=1") {
t.Error("Set-Cookie should contain SSCookie=1")
}
}

func TestSetCookieOnResponseForOlderChromeVersion(t *testing.T) {
cookie := newSampleCookie()
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3770.142 Safari/537.36")
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")
t.Log("Set-Cookie is: ", writtenCookie)
if strings.Contains(writtenCookie, "SameSite=none") {
t.Error("Set-Cookie should not contain SameSite=none")
}
}