Skip to content

Commit 6c36615

Browse files
committed
Set network_userid to empty UUID in anonymous mode to prevent collector_payload_format_violation (close #126)
1 parent a9f4a8f commit 6c36615

File tree

2 files changed

+93
-32
lines changed

2 files changed

+93
-32
lines changed

core/src/main/scala/com.snowplowanalytics.snowplow.collectors.scalastream/CollectorService.scala

+13-4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class CollectorService(
8282
override val doNotTrackCookie = config.doNotTrackHttpCookie
8383
override val enableDefaultRedirect = config.enableDefaultRedirect
8484

85+
private val spAnonymousNuid = "00000000-0000-0000-0000-000000000000"
86+
8587
/**
8688
* Determines the path to be used in the response,
8789
* based on whether a mapping can be found in the config for the original request path.
@@ -112,7 +114,7 @@ class CollectorService(
112114
case Right(params) =>
113115
val redirect = path.startsWith("/r/")
114116

115-
val nuidOpt = networkUserId(request, cookie)
117+
val nuidOpt = networkUserId(request, cookie, spAnonymous)
116118
val bouncing = params.contains(config.cookieBounce.name)
117119
// we bounce if it's enabled and we couldn't retrieve the nuid and we're not already bouncing
118120
val bounce = config.cookieBounce.enabled && nuidOpt.isEmpty && !bouncing &&
@@ -243,7 +245,7 @@ class CollectorService(
243245
userAgent.foreach(e.userAgent = _)
244246
refererUri.foreach(e.refererUri = _)
245247
e.hostname = hostname
246-
e.networkUserId = spAnonymous.fold(networkUserId)(_ => "")
248+
e.networkUserId = networkUserId
247249
e.headers = (headers(request, spAnonymous) ++ contentType).asJava
248250
contentType.foreach(e.contentType = _)
249251
e
@@ -457,8 +459,15 @@ class CollectorService(
457459
* @param requestCookie cookie associated to the Http request
458460
* @return a network user id
459461
*/
460-
def networkUserId(request: HttpRequest, requestCookie: Option[HttpCookie]): Option[String] =
461-
request.uri.query().get("nuid").orElse(requestCookie.map(_.value))
462+
def networkUserId(
463+
request: HttpRequest,
464+
requestCookie: Option[HttpCookie],
465+
spAnonymous: Option[String]
466+
): Option[String] =
467+
spAnonymous match {
468+
case Some(_) => Some(spAnonymousNuid)
469+
case None => request.uri.query().get("nuid").orElse(requestCookie.map(_.value))
470+
}
462471

463472
/**
464473
* Creates an Access-Control-Allow-Origin header which specifically allows the domain which made

core/src/test/scala/com.snowplowanalytics.snowplow.collectors.scalastream/CollectorServiceSpec.scala

+80-28
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class CollectorServiceSpec extends Specification {
129129
None,
130130
Some("b"),
131131
"p",
132-
Some(HttpCookie("sp","cookie-nuid")),
132+
Some(HttpCookie("sp", "cookie-nuid")),
133133
None,
134134
None,
135135
"h",
@@ -143,14 +143,14 @@ class CollectorServiceSpec extends Specification {
143143
l must have size 1
144144
val newEvent = new CollectorPayload("iglu-schema", "ip", System.currentTimeMillis, "UTF-8", "collector")
145145
deserializer.deserialize(newEvent, l.head)
146-
newEvent.networkUserId shouldEqual ""
146+
newEvent.networkUserId shouldEqual "00000000-0000-0000-0000-000000000000"
147147
}
148148
"network_userid from cookie should persist if SP-Anonymous is not present" in {
149149
val (_, l) = service.cookie(
150150
None,
151151
Some("b"),
152152
"p",
153-
Some(HttpCookie("sp","cookie-nuid")),
153+
Some(HttpCookie("sp", "cookie-nuid")),
154154
None,
155155
None,
156156
"h",
@@ -340,9 +340,10 @@ class CollectorServiceSpec extends Specification {
340340
e.contentType shouldEqual ct.get
341341
}
342342
"fill the correct values if SP-Anonymous is present" in {
343-
val l = `Location`("l")
344-
val ct = Some("image/gif")
345-
val r = HttpRequest().withHeaders(l :: hs)
343+
val l = `Location`("l")
344+
val ct = Some("image/gif")
345+
val r = HttpRequest().withHeaders(l :: hs)
346+
val nuid = service.networkUserId(r, None, Some("*")).get
346347
val e =
347348
service.buildEvent(
348349
Some("q"),
@@ -353,7 +354,7 @@ class CollectorServiceSpec extends Specification {
353354
"h",
354355
"unknown",
355356
r,
356-
"nuid",
357+
nuid,
357358
ct,
358359
Some("*")
359360
)
@@ -367,16 +368,29 @@ class CollectorServiceSpec extends Specification {
367368
e.userAgent shouldEqual "ua"
368369
e.refererUri shouldEqual "ref"
369370
e.hostname shouldEqual "h"
370-
e.networkUserId shouldEqual ""
371+
e.networkUserId shouldEqual "00000000-0000-0000-0000-000000000000"
371372
e.headers shouldEqual (List(l) ++ ct).map(_.toString).asJava
372373
e.contentType shouldEqual ct.get
373374
}
374375
"have a null queryString if it's None" in {
375-
val l = `Location`("l")
376-
val ct = Some("image/gif")
377-
val r = HttpRequest().withHeaders(l :: hs)
376+
val l = `Location`("l")
377+
val ct = Some("image/gif")
378+
val r = HttpRequest().withHeaders(l :: hs)
379+
val nuid = service.networkUserId(r, None, Some("*")).get
378380
val e =
379-
service.buildEvent(None, Some("b"), "p", Some("ua"), Some("ref"), "h", "unknown", r, "nuid", ct, Some("*"))
381+
service.buildEvent(
382+
None,
383+
Some("b"),
384+
"p",
385+
Some("ua"),
386+
Some("ref"),
387+
"h",
388+
"unknown",
389+
r,
390+
nuid,
391+
ct,
392+
Some("*")
393+
)
380394
e.schema shouldEqual "iglu:com.snowplowanalytics.snowplow/CollectorPayload/thrift/1-0-0"
381395
e.ipAddress shouldEqual "unknown"
382396
e.encoding shouldEqual "UTF-8"
@@ -387,17 +401,30 @@ class CollectorServiceSpec extends Specification {
387401
e.userAgent shouldEqual "ua"
388402
e.refererUri shouldEqual "ref"
389403
e.hostname shouldEqual "h"
390-
e.networkUserId shouldEqual ""
404+
e.networkUserId shouldEqual "00000000-0000-0000-0000-000000000000"
391405
e.headers shouldEqual (List(l) ++ ct).map(_.toString).asJava
392406
e.contentType shouldEqual ct.get
393407
}
394408
"have an empty nuid if SP-Anonymous is present" in {
395-
val l = `Location`("l")
396-
val ct = Some("image/gif")
397-
val r = HttpRequest().withHeaders(l :: hs)
409+
val l = `Location`("l")
410+
val ct = Some("image/gif")
411+
val r = HttpRequest().withHeaders(l :: hs)
412+
val nuid = service.networkUserId(r, None, Some("*")).get
398413
val e =
399-
service.buildEvent(None, Some("b"), "p", Some("ua"), Some("ref"), "h", "unknown", r, "nuid", ct, Some("*"))
400-
e.networkUserId shouldEqual ""
414+
service.buildEvent(
415+
None,
416+
Some("b"),
417+
"p",
418+
Some("ua"),
419+
Some("ref"),
420+
"h",
421+
"unknown",
422+
r,
423+
nuid,
424+
ct,
425+
Some("*")
426+
)
427+
e.networkUserId shouldEqual "00000000-0000-0000-0000-000000000000"
401428
}
402429
"have a nuid if SP-Anonymous is not present" in {
403430
val l = `Location`("l")
@@ -671,17 +698,42 @@ class CollectorServiceSpec extends Specification {
671698
}
672699

673700
"netwokUserId" in {
674-
"give back the nuid query param if present" in {
675-
service.networkUserId(
676-
HttpRequest().withUri(Uri().withRawQueryString("nuid=12")),
677-
Some(HttpCookie("nuid", "13"))
678-
) shouldEqual Some("12")
679-
}
680-
"give back the request cookie if there no nuid query param" in {
681-
service.networkUserId(HttpRequest(), Some(HttpCookie("nuid", "13"))) shouldEqual Some("13")
701+
"with SP-Anonymous header not present" in {
702+
"give back the nuid query param if present" in {
703+
service.networkUserId(
704+
HttpRequest().withUri(Uri().withRawQueryString("nuid=12")),
705+
Some(HttpCookie("nuid", "13")),
706+
None
707+
) shouldEqual Some("12")
708+
}
709+
"give back the request cookie if there no nuid query param" in {
710+
service.networkUserId(HttpRequest(), Some(HttpCookie("nuid", "13")), None) shouldEqual Some("13")
711+
}
712+
"give back none otherwise" in {
713+
service.networkUserId(HttpRequest(), None, None) shouldEqual None
714+
}
682715
}
683-
"give back none otherwise" in {
684-
service.networkUserId(HttpRequest(), None) shouldEqual None
716+
717+
"with SP-Anonymous header present" in {
718+
"give back the dummy nuid" in {
719+
"if query param is present" in {
720+
service.networkUserId(
721+
HttpRequest().withUri(Uri().withRawQueryString("nuid=12")),
722+
Some(HttpCookie("nuid", "13")),
723+
Some("*")
724+
) shouldEqual Some("00000000-0000-0000-0000-000000000000")
725+
}
726+
"if the request cookie can be used in place of a missing nuid query param" in {
727+
service.networkUserId(HttpRequest(), Some(HttpCookie("nuid", "13")), Some("*")) shouldEqual Some(
728+
"00000000-0000-0000-0000-000000000000"
729+
)
730+
}
731+
"in any other case" in {
732+
service.networkUserId(HttpRequest(), None, Some("*")) shouldEqual Some(
733+
"00000000-0000-0000-0000-000000000000"
734+
)
735+
}
736+
}
685737
}
686738
}
687739

0 commit comments

Comments
 (0)