Skip to content

Commit

Permalink
add virginia mspa and testing, fix typos. (LiveRamp#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
kylehalverson authored Jun 2, 2023
1 parent 0613edf commit 891f6be
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 5 deletions.
6 changes: 4 additions & 2 deletions gpp_parsed_consent.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ func MapGppSectionToParser(s string) ([]GppSectionParser, error) {
var gppSection GppSectionParser
switch sid := gppHeader.Sections[i-1]; sid {
case 7:
gppSection = NewMspaNationl(segments[i])
gppSection = NewMspaNational(segments[i])
case 9:
gppSection = NewMspaVA(segments[i])
default:
// Skip if no matching struct, as Section ID is not supported yet.
// Any newly supported Section IDs should be added as cases here.
Expand Down Expand Up @@ -134,7 +136,7 @@ func ParseGppConsent(s string) (map[int]GppParsedConsent, error) {
var consentErr error
consent, consentErr = gpp.ParseConsent()
if consentErr != nil {
// If an error, quietly do not add teh consent value to map.
// If an error, quietly do not add the consent value to map.
} else {
gppConsents[gpp.GetSectionId()] = consent
}
Expand Down
89 changes: 89 additions & 0 deletions gpp_parsed_consent_fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,95 @@ var gppParsedConsentFixtures = map[string]map[int]*iabconsent.MspaParsedConsent{
Gpc: true,
},
},
// Valid GPP w/ US Virgina MSPA, Subsection of GPC False.
"DBABRg~BVoYYYA": {9: {
Version: 1,
SharingNotice: iabconsent.NoticeProvided,
SaleOptOutNotice: iabconsent.NoticeProvided,
TargetedAdvertisingOptOutNotice: iabconsent.NoticeProvided,
SaleOptOut: iabconsent.NotOptedOut,
TargetedAdvertisingOptOut: iabconsent.NotOptedOut,
SensitiveDataProcessing: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.NoConsent,
2: iabconsent.Consent,
3: iabconsent.ConsentNotApplicable,
4: iabconsent.NoConsent,
5: iabconsent.Consent,
6: iabconsent.ConsentNotApplicable,
7: iabconsent.NoConsent,
},
KnownChildSensitiveDataConsents: map[int]iabconsent.MspaConsent{
0: iabconsent.Consent,
},
MspaCoveredTransaction: iabconsent.MspaNotApplicable,
MspaOptOutOptionMode: iabconsent.MspaNotApplicable,
MspaServiceProviderMode: iabconsent.MspaNotApplicable,
Gpc: false,
},
},
// Valid GPP w/ US US National and Virgina MSPA, Subsection of GPC False.
"DBACLMA~BVVqAAEABAA~BVoYYYA": {7: {
Version: 1,
SharingNotice: iabconsent.NoticeProvided,
SaleOptOutNotice: iabconsent.NoticeProvided,
SharingOptOutNotice: iabconsent.NoticeProvided,
TargetedAdvertisingOptOutNotice: iabconsent.NoticeProvided,
SensitiveDataProcessingOptOutNotice: iabconsent.NoticeProvided,
SensitiveDataLimitUseNotice: iabconsent.NoticeProvided,
SaleOptOut: iabconsent.NotOptedOut,
SharingOptOut: iabconsent.NotOptedOut,
TargetedAdvertisingOptOut: iabconsent.NotOptedOut,
SensitiveDataProcessing: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.ConsentNotApplicable,
2: iabconsent.ConsentNotApplicable,
3: iabconsent.ConsentNotApplicable,
4: iabconsent.ConsentNotApplicable,
5: iabconsent.ConsentNotApplicable,
6: iabconsent.ConsentNotApplicable,
7: iabconsent.NoConsent,
8: iabconsent.ConsentNotApplicable,
9: iabconsent.ConsentNotApplicable,
10: iabconsent.ConsentNotApplicable,
11: iabconsent.ConsentNotApplicable,
},
KnownChildSensitiveDataConsents: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.ConsentNotApplicable,
},
PersonalDataConsents: iabconsent.NoConsent,
MspaCoveredTransaction: iabconsent.MspaNotApplicable,
MspaOptOutOptionMode: iabconsent.MspaNotApplicable,
MspaServiceProviderMode: iabconsent.MspaNotApplicable,
Gpc: false,
},
9: {
Version: 1,
SharingNotice: iabconsent.NoticeProvided,
SaleOptOutNotice: iabconsent.NoticeProvided,
TargetedAdvertisingOptOutNotice: iabconsent.NoticeProvided,
SaleOptOut: iabconsent.NotOptedOut,
TargetedAdvertisingOptOut: iabconsent.NotOptedOut,
SensitiveDataProcessing: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.NoConsent,
2: iabconsent.Consent,
3: iabconsent.ConsentNotApplicable,
4: iabconsent.NoConsent,
5: iabconsent.Consent,
6: iabconsent.ConsentNotApplicable,
7: iabconsent.NoConsent,
},
KnownChildSensitiveDataConsents: map[int]iabconsent.MspaConsent{
0: iabconsent.Consent,
},
MspaCoveredTransaction: iabconsent.MspaNotApplicable,
MspaOptOutOptionMode: iabconsent.MspaNotApplicable,
MspaServiceProviderMode: iabconsent.MspaNotApplicable,
Gpc: false,
},
},
// Valid GPP string w/ sections for EU TCF V2 and US Privacy
// Since both are not supported, Consent fixture should be blank.
"DBACNY~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN": {},
Expand Down
55 changes: 55 additions & 0 deletions mspa_parsed_consent_fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,58 @@ var usNationalConsentFixtures = map[string]*iabconsent.MspaParsedConsent{
Gpc: false,
},
}

var usVAConsentFixtures = map[string]*iabconsent.MspaParsedConsent{
// With subsection of GPC True.
"BVoYYYA.YA": {
Version: 1,
SharingNotice: iabconsent.NoticeProvided,
SaleOptOutNotice: iabconsent.NoticeProvided,
TargetedAdvertisingOptOutNotice: iabconsent.NoticeProvided,
SaleOptOut: iabconsent.NotOptedOut,
TargetedAdvertisingOptOut: iabconsent.NotOptedOut,
SensitiveDataProcessing: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.NoConsent,
2: iabconsent.Consent,
3: iabconsent.ConsentNotApplicable,
4: iabconsent.NoConsent,
5: iabconsent.Consent,
6: iabconsent.ConsentNotApplicable,
7: iabconsent.NoConsent,
},
KnownChildSensitiveDataConsents: map[int]iabconsent.MspaConsent{
0: iabconsent.Consent,
},
MspaCoveredTransaction: iabconsent.MspaNotApplicable,
MspaOptOutOptionMode: iabconsent.MspaNotApplicable,
MspaServiceProviderMode: iabconsent.MspaNotApplicable,
Gpc: true,
},
// Without subsection.
"BVoYYYA": {
Version: 1,
SharingNotice: iabconsent.NoticeProvided,
SaleOptOutNotice: iabconsent.NoticeProvided,
TargetedAdvertisingOptOutNotice: iabconsent.NoticeProvided,
SaleOptOut: iabconsent.NotOptedOut,
TargetedAdvertisingOptOut: iabconsent.NotOptedOut,
SensitiveDataProcessing: map[int]iabconsent.MspaConsent{
0: iabconsent.ConsentNotApplicable,
1: iabconsent.NoConsent,
2: iabconsent.Consent,
3: iabconsent.ConsentNotApplicable,
4: iabconsent.NoConsent,
5: iabconsent.Consent,
6: iabconsent.ConsentNotApplicable,
7: iabconsent.NoConsent,
},
KnownChildSensitiveDataConsents: map[int]iabconsent.MspaConsent{
0: iabconsent.Consent,
},
MspaCoveredTransaction: iabconsent.MspaNotApplicable,
MspaOptOutOptionMode: iabconsent.MspaNotApplicable,
MspaServiceProviderMode: iabconsent.MspaNotApplicable,
Gpc: false,
},
}
44 changes: 42 additions & 2 deletions mspa_parsed_consent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (s *MspaSuite) TestParseUsNational(c *check.C) {
for k, v := range usNationalConsentFixtures {
c.Log(k)

var gppSection = iabconsent.NewMspaNationl(k)
var gppSection = iabconsent.NewMspaNational(k)
var p, err = gppSection.ParseConsent()

c.Check(err, check.IsNil)
Expand Down Expand Up @@ -136,7 +136,47 @@ func (s *MspaSuite) TestParseUsNationalError(c *check.C) {
for _, t := range tcs {
c.Log(t.desc)

var gppSection = iabconsent.NewMspaNationl(t.usNatString)
var gppSection = iabconsent.NewMspaNational(t.usNatString)
var p, err = gppSection.ParseConsent()

c.Check(p, check.IsNil)
c.Check(err, check.ErrorMatches, t.expected.Error())
}
}

func (s *MspaSuite) TestParseUsVA(c *check.C) {
for k, v := range usVAConsentFixtures {
c.Log(k)

var gppSection = iabconsent.NewMspaVA(k)
var p, err = gppSection.ParseConsent()

c.Check(err, check.IsNil)
c.Check(p, check.DeepEquals, v)
}
}

func (s *MspaSuite) TestParseUsVAError(c *check.C) {
var tcs = []struct {
desc string
usVAString string
expected error
}{
{
desc: "Wrong Version.",
usVAString: "DVoYYYA",
expected: errors.New("non-v1 string passed."),
},
{
desc: "Bad Decoding.",
usVAString: "$%&*(",
expected: errors.New("parse usva consent string: illegal base64 data at input byte 0"),
},
}
for _, t := range tcs {
c.Log(t.desc)

var gppSection = iabconsent.NewMspaVA(t.usVAString)
var p, err = gppSection.ParseConsent()

c.Check(p, check.IsNil)
Expand Down
54 changes: 53 additions & 1 deletion mspa_sections.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ type MspaUsNational struct {
GppSection
}

func NewMspaNationl(section string) *MspaUsNational {
type MspaUsVA struct {
GppSection
}

func NewMspaNational(section string) *MspaUsNational {
return &MspaUsNational{GppSection{sectionId: 7, sectionValue: section}}
}

func NewMspaVA(section string) *MspaUsVA {
return &MspaUsVA{GppSection{sectionId: 9, sectionValue: section}}
}

func (m *MspaUsNational) ParseConsent() (GppParsedConsent, error) {
var segments = strings.Split(m.sectionValue, ".")

Expand Down Expand Up @@ -61,3 +69,47 @@ func (m *MspaUsNational) ParseConsent() (GppParsedConsent, error) {

return p, r.Err
}

func (m *MspaUsVA) ParseConsent() (GppParsedConsent, error) {
var segments = strings.Split(m.sectionValue, ".")

var b, err = base64.RawURLEncoding.DecodeString(segments[0])
if err != nil {
return nil, errors.Wrap(err, "parse usva consent string")
}

var r = NewConsentReader(b)

// This block of code directly describes the format of the payload.
// The spec for the consent string can be found here:
// https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/tree/main/Sections/US-States/VA
var p = &MspaParsedConsent{}
p.Version, _ = r.ReadInt(6)

if p.Version != 1 {
return nil, errors.New("non-v1 string passed.")
}

p.SharingNotice, _ = r.ReadMspaNotice()
p.SaleOptOutNotice, _ = r.ReadMspaNotice()
p.TargetedAdvertisingOptOutNotice, _ = r.ReadMspaNotice()
p.SaleOptOut, _ = r.ReadMspaOptOut()
p.TargetedAdvertisingOptOut, _ = r.ReadMspaOptOut()
// This has a shorter length than UsNational.
p.SensitiveDataProcessing, _ = r.ReadMspaBitfieldConsent(8)
// While an array in UsNational, we can just use an array of 1 for a single value.
p.KnownChildSensitiveDataConsents, _ = r.ReadMspaBitfieldConsent(1)
// 0 is not a valid value according to the docs for MspaCoveredTransaction. Instead of erroring,
// return the value of the string, and let downstream processing handle if the value is 0.
p.MspaCoveredTransaction, _ = r.ReadMspaNaYesNo()
p.MspaOptOutOptionMode, _ = r.ReadMspaNaYesNo()
p.MspaServiceProviderMode, _ = r.ReadMspaNaYesNo()

if len(segments) > 1 {
var gppSubsectionConsent *GppSubSection
gppSubsectionConsent, _ = ParseGppSubSections(segments[1:])
p.Gpc = gppSubsectionConsent.Gpc
}

return p, r.Err
}

0 comments on commit 891f6be

Please sign in to comment.