Skip to content

Commit 7edbd13

Browse files
committed
Adding Enum for Purposes
1 parent 80428e0 commit 7edbd13

File tree

7 files changed

+176
-22
lines changed

7 files changed

+176
-22
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.iab.gdpr;
2+
3+
/**
4+
*
5+
* Enumeration of currently defined purposes by IAB
6+
*
7+
* @see <a href="https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework">https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework</a>
8+
*
9+
*/
10+
public enum Purpose {
11+
12+
STORAGE_AND_ACCESS(1), // The storage of information, or access to information that is already stored, on user device such as accessing advertising identifiers
13+
// and/or other device identifiers, and/or using cookies or similar technologies.
14+
15+
PERSONALIZATION(2), // The collection and processing of information about user of a site to subsequently personalize advertising for them in other contexts,
16+
// i.e. on other sites or apps, over time. Typically, the content of the site or app is used to make inferences about user interests, which inform future selections.
17+
18+
AD_SELECTION(3), // The collection of information and combination with previously collected information, to select and deliver advertisements and to measure the delivery
19+
// and effectiveness of such advertisements. This includes using previously collected information about user interests to select ads, processing data about
20+
// what advertisements were shown, how often they were shown, when and where they were shown, and whether they took any action related to the advertisement,
21+
// including for example clicking an ad or making a purchase.
22+
23+
CONTENT_DELIVERY(4), // The collection of information, and combination with previously collected information, to select and deliver content and to measure the delivery and
24+
// effectiveness of such content. This includes using previously collected information about user interests to select content, processing data about
25+
// what content was shown, how often or how long it was shown, when and where it was shown, and whether they took any action related to the content,
26+
// including for example clicking on content.
27+
28+
MEASUREMENT(5), // The collection of information about user use of content, and combination with previously collected information, used to measure, understand,
29+
// and report on user usage of content.
30+
31+
UNDEFINED(-1), // Purpose ID that is currently not defined
32+
;
33+
34+
private final int id;
35+
36+
Purpose(int id) {
37+
this.id = id;
38+
}
39+
40+
public int getId() {
41+
return id;
42+
}
43+
44+
/**
45+
* Map numeric purpose ID to Enum
46+
* @param purposeId purpose ID
47+
* @return Enum value of purpose
48+
*/
49+
public static Purpose valueOf(int purposeId) {
50+
switch(purposeId) {
51+
case 1: return STORAGE_AND_ACCESS;
52+
case 2: return PERSONALIZATION;
53+
case 3: return AD_SELECTION;
54+
case 4: return CONTENT_DELIVERY;
55+
case 5: return MEASUREMENT;
56+
default: return UNDEFINED;
57+
}
58+
}
59+
}

src/main/java/com/iab/gdpr/consent/VendorConsent.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.iab.gdpr.consent;
22

3+
import com.iab.gdpr.Purpose;
4+
35
import java.time.Instant;
46
import java.util.Set;
57

@@ -63,7 +65,13 @@ public interface VendorConsent {
6365
*
6466
* @return the set of purpose id's which are permitted according to this consent string
6567
*/
66-
Set<Integer> getAllowedPurposes();
68+
Set<Integer> getAllowedPurposeIds();
69+
70+
/**
71+
*
72+
* @return the set of allowed purposes which are permitted according to this consent string
73+
*/
74+
Set<Purpose> getAllowedPurposes();
6775

6876
/**
6977
*
@@ -84,6 +92,13 @@ public interface VendorConsent {
8492
*/
8593
boolean isPurposeAllowed(int purposeId);
8694

95+
/**
96+
* Check whether specified purpose is allowed
97+
* @param purpose purpose to check
98+
* @return true if purpose is allowed in this consent, false otherwise
99+
*/
100+
boolean isPurposeAllowed(Purpose purpose);
101+
87102
/**
88103
* Check whether vendor with specified ID is allowd
89104
* @param vendorId vendor ID

src/main/java/com/iab/gdpr/consent/implementation/v1/ByteBufferBackedVendorConsent.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33

44
import com.iab.gdpr.Bits;
5+
import com.iab.gdpr.Purpose;
56
import com.iab.gdpr.consent.VendorConsent;
67
import com.iab.gdpr.exception.VendorConsentParseException;
78

89
import java.time.Instant;
910
import java.util.Arrays;
1011
import java.util.HashSet;
1112
import java.util.Set;
13+
import java.util.stream.Collectors;
1214

1315
import static com.iab.gdpr.GdprConstants.*;
1416

@@ -71,7 +73,7 @@ public int getVendorListVersion() {
7173
}
7274

7375
@Override
74-
public Set<Integer> getAllowedPurposes() {
76+
public Set<Integer> getAllowedPurposeIds() {
7577
final Set<Integer> allowedPurposes = new HashSet<>();
7678
for (int i = PURPOSES_OFFSET; i < PURPOSES_OFFSET + PURPOSES_SIZE; i++) {
7779
if (bits.getBit(i)) {
@@ -81,6 +83,11 @@ public Set<Integer> getAllowedPurposes() {
8183
return allowedPurposes;
8284
}
8385

86+
@Override
87+
public Set<Purpose> getAllowedPurposes() {
88+
return getAllowedPurposeIds().stream().map(Purpose::valueOf).collect(Collectors.toSet());
89+
}
90+
8491
@Override
8592
public int getAllowedPurposesBits() {
8693
return bits.getInt(PURPOSES_OFFSET, PURPOSES_SIZE);
@@ -94,7 +101,12 @@ public int getMaxVendorId() {
94101
@Override
95102
public boolean isPurposeAllowed(int purposeId) {
96103
if (purposeId < 1) return false;
97-
return getAllowedPurposes().contains(purposeId);
104+
return getAllowedPurposeIds().contains(purposeId);
105+
}
106+
107+
@Override
108+
public boolean isPurposeAllowed(Purpose purpose) {
109+
return isPurposeAllowed(purpose.getId());
98110
}
99111

100112
@Override
@@ -189,7 +201,7 @@ public String toString() {
189201
",ConsentScreen=" + getConsentScreen() +
190202
",ConsentLanguage=" + getConsentLanguage() +
191203
",VendorListVersion=" + getVendorListVersion() +
192-
",PurposesAllowed=" + getAllowedPurposes() +
204+
",PurposesAllowed=" + getAllowedPurposeIds() +
193205
",MaxVendorId=" + getMaxVendorId() +
194206
",EncodingType=" + encodingType() +
195207
"}";

src/main/java/com/iab/gdpr/consent/implementation/v1/VendorConsentBuilder.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import com.iab.gdpr.Bits;
44
import com.iab.gdpr.GdprConstants;
5+
import com.iab.gdpr.Purpose;
56
import com.iab.gdpr.consent.range.RangeEntry;
67
import com.iab.gdpr.consent.VendorConsent;
78

89
import java.time.Instant;
910
import java.util.*;
11+
import java.util.stream.Collectors;
1012

1113
import static com.iab.gdpr.GdprConstants.*;
1214

@@ -102,17 +104,30 @@ public VendorConsentBuilder withVendorListVersion(int vendorListVersion) {
102104
}
103105

104106
/**
105-
* With allowed puposes
107+
* With allowed purpose IDs
108+
* @param allowedPurposeIds set of allowed purposes
109+
* @return builder
110+
*/
111+
public VendorConsentBuilder withAllowedPurposeIds(Set<Integer> allowedPurposeIds) {
112+
// Validate
113+
Objects.requireNonNull(allowedPurposeIds, "Argument allowedPurposeIds is null");
114+
final boolean invalidPurposeIdFound = allowedPurposeIds.stream().anyMatch(purposeId -> purposeId < 0 || purposeId > PURPOSES_SIZE);
115+
if (invalidPurposeIdFound) throw new IllegalArgumentException("Invalid purpose ID found");
116+
117+
this.allowedPurposes = allowedPurposeIds;
118+
return this;
119+
}
120+
121+
/**
122+
* With allowed purposes
106123
* @param allowedPurposes set of allowed purposes
107124
* @return builder
108125
*/
109-
public VendorConsentBuilder withAllowedPurposes(Set<Integer> allowedPurposes) {
126+
public VendorConsentBuilder withAllowedPurposes(Set<Purpose> allowedPurposes) {
110127
// Validate
111128
Objects.requireNonNull(allowedPurposes, "Argument allowedPurposes is null");
112-
final boolean invalidPurposeIdFound = allowedPurposes.stream().anyMatch(purposeId -> purposeId < 0 || purposeId > PURPOSES_SIZE);
113-
if (invalidPurposeIdFound) throw new IllegalArgumentException("Invalid purpose ID found");
114129

115-
this.allowedPurposes = allowedPurposes;
130+
this.allowedPurposes = allowedPurposes.stream().map(Purpose::getId).collect(Collectors.toSet());
116131
return this;
117132
}
118133

src/main/java/com/iab/gdpr/util/ConsentStringParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* Draft_for_Public_Comment_Transparency%20%26%20Consent%20Framework%20-%20cookie%20and%20vendor%20list%20format%
4444
* 20specification%20v1.0a.pdf
4545
*/
46+
@Deprecated
4647
public class ConsentStringParser {
4748
private Bits bits;
4849

src/test/java/com/iab/gdpr/consent/implementation/v1/ByteBufferBackedVendorConsentTest.java

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.iab.gdpr.consent.implementation.v1;
22

3+
import com.iab.gdpr.Purpose;
34
import com.iab.gdpr.consent.VendorConsent;
45
import com.iab.gdpr.consent.VendorConsentDecoder;
56
import com.iab.gdpr.exception.VendorConsentParseException;
@@ -9,9 +10,11 @@
910
import java.time.Instant;
1011
import java.time.LocalDateTime;
1112
import java.time.ZoneOffset;
13+
import java.time.format.DateTimeFormatter;
1214
import java.util.Arrays;
1315
import java.util.HashSet;
1416

17+
import static com.iab.gdpr.Purpose.*;
1518
import static org.hamcrest.Matchers.is;
1619
import static org.junit.Assert.*;
1720

@@ -166,13 +169,19 @@ public void testgetAllowedPurposes() {
166169
ByteBufferBackedVendorConsent vendorConsent = new ByteBufferBackedVendorConsent(Utils.fromBinaryString(binaryString));
167170

168171
// Then: correct allowed versions are returned
169-
assertThat(vendorConsent.getAllowedPurposes(),is(new HashSet<>(Arrays.asList(1,2,3,4,5,15,24))));
172+
assertThat(vendorConsent.getAllowedPurposeIds(),is(new HashSet<>(Arrays.asList(1,2,3,4,5,15,24))));
173+
assertThat(vendorConsent.getAllowedPurposes(),is(new HashSet<>(Arrays.asList(STORAGE_AND_ACCESS,PERSONALIZATION,AD_SELECTION,CONTENT_DELIVERY,MEASUREMENT,UNDEFINED))));
170174
assertThat(vendorConsent.getAllowedPurposesBits(),is(16253441));
171175
assertTrue(vendorConsent.isPurposeAllowed(1));
176+
assertTrue(vendorConsent.isPurposeAllowed(STORAGE_AND_ACCESS));
172177
assertTrue(vendorConsent.isPurposeAllowed(2));
178+
assertTrue(vendorConsent.isPurposeAllowed(PERSONALIZATION));
173179
assertTrue(vendorConsent.isPurposeAllowed(3));
180+
assertTrue(vendorConsent.isPurposeAllowed(AD_SELECTION));
174181
assertTrue(vendorConsent.isPurposeAllowed(4));
182+
assertTrue(vendorConsent.isPurposeAllowed(CONTENT_DELIVERY));
175183
assertTrue(vendorConsent.isPurposeAllowed(5));
184+
assertTrue(vendorConsent.isPurposeAllowed(MEASUREMENT));
176185
assertTrue(vendorConsent.isPurposeAllowed(15));
177186
assertTrue(vendorConsent.isPurposeAllowed(24));
178187
}
@@ -403,7 +412,7 @@ public void testRealString2() {
403412
assertThat(vendorConsent.getConsentLanguage(), is("FR"));
404413
assertThat(vendorConsent.getConsentRecordCreated(), is(Instant.ofEpochMilli(14924661858L * 100)));
405414
assertThat(vendorConsent.getConsentRecordLastUpdated(), is(Instant.ofEpochMilli(15240021858L * 100)));
406-
assertThat(vendorConsent.getAllowedPurposes().size(), is(5));
415+
assertThat(vendorConsent.getAllowedPurposeIds().size(), is(5));
407416
assertThat(vendorConsent.getAllowedPurposesBits(), is(6291482));
408417

409418
assertTrue(vendorConsent.isPurposeAllowed(2));
@@ -431,7 +440,7 @@ public void testRealString3() {
431440
assertThat(vendorConsent.getConsentLanguage(), is("EN"));
432441
assertThat(vendorConsent.getConsentRecordCreated(), is(Instant.ofEpochMilli(14924661858L * 100)));
433442
assertThat(vendorConsent.getConsentRecordLastUpdated(), is(Instant.ofEpochMilli(15240021858L * 100)));
434-
assertThat(vendorConsent.getAllowedPurposes().size(), is(8));
443+
assertThat(vendorConsent.getAllowedPurposeIds().size(), is(8));
435444
assertThat(vendorConsent.getAllowedPurposesBits(), is(2000001));
436445

437446
assertTrue(vendorConsent.isPurposeAllowed(4));
@@ -463,7 +472,7 @@ public void testRealString4() {
463472
assertThat(vendorConsent.getConsentLanguage(), is("FR"));
464473
assertThat(vendorConsent.getConsentRecordCreated(), is(Instant.ofEpochMilli(15270622944L * 100)));
465474
assertThat(vendorConsent.getConsentRecordLastUpdated(), is(Instant.ofEpochMilli(15271660607L * 100)));
466-
assertThat(vendorConsent.getAllowedPurposes().size(), is(5));
475+
assertThat(vendorConsent.getAllowedPurposeIds().size(), is(5));
467476

468477
assertTrue(vendorConsent.isPurposeAllowed(1));
469478
assertTrue(vendorConsent.isPurposeAllowed(2));
@@ -498,4 +507,45 @@ public void testRealString5() {
498507
assertTrue(vendorConsent.isVendorAllowed(27));
499508
}
500509

510+
@Test
511+
public void testRealString6() {
512+
// Given: known vendor consent string
513+
final String consentString = "BOOj_adOOj_adABABADEAb-AAAA-iATAAUAA2ADAAMgAgABIAC0AGQANAAcAA-ACKAEwAKIAaABFACQAHIAP0B9A";
514+
515+
// When: vendor vendorConsent is constructed
516+
final VendorConsent vendorConsent = VendorConsentDecoder.fromBase64String(consentString);
517+
518+
// Then: values match expectation
519+
assertThat(vendorConsent.getVersion(),is(1));
520+
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
521+
assertThat(vendorConsent.getConsentRecordCreated(),is(LocalDateTime.parse("2018-05-30 08:48:54.100",formatter).toInstant(ZoneOffset.UTC)));
522+
assertThat(vendorConsent.getConsentRecordLastUpdated(),is(LocalDateTime.parse("2018-05-30 08:48:54.100",formatter).toInstant(ZoneOffset.UTC)));
523+
assertThat(vendorConsent.getCmpId(),is(1));
524+
assertThat(vendorConsent.getCmpVersion(),is(1));
525+
assertThat(vendorConsent.getConsentScreen(),is(0));
526+
assertThat(vendorConsent.getConsentLanguage(),is("DE"));
527+
assertThat(vendorConsent.getAllowedPurposeIds(),is(new HashSet<>(Arrays.asList(1,2,3,4,5))));
528+
assertThat(vendorConsent.getMaxVendorId(),is(1000));
529+
assertTrue(vendorConsent.isVendorAllowed(10));
530+
assertTrue(vendorConsent.isVendorAllowed(13));
531+
assertTrue(vendorConsent.isVendorAllowed(24));
532+
assertTrue(vendorConsent.isVendorAllowed(25));
533+
assertTrue(vendorConsent.isVendorAllowed(32));
534+
assertTrue(vendorConsent.isVendorAllowed(36));
535+
assertTrue(vendorConsent.isVendorAllowed(45));
536+
assertTrue(vendorConsent.isVendorAllowed(50));
537+
assertTrue(vendorConsent.isVendorAllowed(52));
538+
assertTrue(vendorConsent.isVendorAllowed(56));
539+
assertTrue(vendorConsent.isVendorAllowed(62));
540+
assertTrue(vendorConsent.isVendorAllowed(69));
541+
assertTrue(vendorConsent.isVendorAllowed(76));
542+
assertTrue(vendorConsent.isVendorAllowed(81));
543+
assertTrue(vendorConsent.isVendorAllowed(104));
544+
assertTrue(vendorConsent.isVendorAllowed(138));
545+
assertTrue(vendorConsent.isVendorAllowed(144));
546+
assertTrue(vendorConsent.isVendorAllowed(228));
547+
assertTrue(vendorConsent.isVendorAllowed(253));
548+
assertTrue(vendorConsent.isVendorAllowed(1000));
549+
}
550+
501551
}

src/test/java/com/iab/gdpr/consent/implementation/v1/VendorConsentBuilderTest.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.iab.gdpr.consent.implementation.v1;
22

3+
import com.iab.gdpr.Purpose;
34
import com.iab.gdpr.consent.range.RangeEntry;
45
import com.iab.gdpr.consent.range.SingleRangeEntry;
56
import com.iab.gdpr.consent.range.StartEndRangeEntry;
@@ -15,6 +16,7 @@
1516
import java.util.List;
1617
import java.util.Set;
1718

19+
import static com.iab.gdpr.Purpose.*;
1820
import static org.hamcrest.Matchers.is;
1921
import static org.junit.Assert.assertFalse;
2022
import static org.junit.Assert.assertThat;
@@ -35,7 +37,7 @@ public void testInvalidPurpose() {
3537
final Set<Integer> allowedPurposes = new HashSet<>(Arrays.asList(1, 2, 3, 99));
3638

3739
// When: passing set to the builder
38-
new VendorConsentBuilder().withAllowedPurposes(allowedPurposes);
40+
new VendorConsentBuilder().withAllowedPurposeIds(allowedPurposes);
3941

4042
// Then: exception is thrown
4143
}
@@ -131,7 +133,7 @@ public void testValidBidFieldEncoding() {
131133
.withConsentScreenID(consentScreenID)
132134
.withConsentLanguage(consentLanguage)
133135
.withVendorListVersion(vendorListVersion)
134-
.withAllowedPurposes(allowedPurposes)
136+
.withAllowedPurposeIds(allowedPurposes)
135137
.withMaxVendorId(maxVendorId)
136138
.withVendorEncodingType(vendorEncodingType)
137139
.withBitField(allowedVendors)
@@ -146,7 +148,7 @@ public void testValidBidFieldEncoding() {
146148
assertThat(vendorConsent.getCmpVersion(),is(cmpVersion));
147149
assertThat(vendorConsent.getConsentScreen(),is(consentScreenID));
148150
assertThat(vendorConsent.getVendorListVersion(),is(vendorListVersion));
149-
assertThat(vendorConsent.getAllowedPurposes(),is(allowedPurposes));
151+
assertThat(vendorConsent.getAllowedPurposeIds(),is(allowedPurposes));
150152
assertThat(vendorConsent.getMaxVendorId(),is(maxVendorId));
151153

152154
assertTrue(vendorConsent.isPurposeAllowed(1));
@@ -169,7 +171,7 @@ public void testValidBidFieldEncoding() {
169171
@Test
170172
public void testValidRangedEncoding() {
171173
// Given: set of consent string parameters
172-
final Set<Integer> allowedPurposes = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
174+
final Set<Purpose> allowedPurposes = new HashSet<>(Arrays.asList(STORAGE_AND_ACCESS, PERSONALIZATION, AD_SELECTION, CONTENT_DELIVERY, MEASUREMENT));
173175
final int cmpId = 10;
174176
final int cmpVersion = 3;
175177
final int consentScreenID = 4;
@@ -211,11 +213,11 @@ public void testValidRangedEncoding() {
211213
assertThat(vendorConsent.getAllowedPurposes(),is(allowedPurposes));
212214
assertThat(vendorConsent.getMaxVendorId(),is(maxVendorId));
213215

214-
assertTrue(vendorConsent.isPurposeAllowed(1));
215-
assertTrue(vendorConsent.isPurposeAllowed(2));
216-
assertTrue(vendorConsent.isPurposeAllowed(3));
217-
assertTrue(vendorConsent.isPurposeAllowed(4));
218-
assertTrue(vendorConsent.isPurposeAllowed(5));
216+
assertTrue(vendorConsent.isPurposeAllowed(STORAGE_AND_ACCESS));
217+
assertTrue(vendorConsent.isPurposeAllowed(PERSONALIZATION));
218+
assertTrue(vendorConsent.isPurposeAllowed(AD_SELECTION));
219+
assertTrue(vendorConsent.isPurposeAllowed(CONTENT_DELIVERY));
220+
assertTrue(vendorConsent.isPurposeAllowed(MEASUREMENT));
219221

220222
assertTrue(vendorConsent.isVendorAllowed(10));
221223
assertTrue(vendorConsent.isVendorAllowed(150));

0 commit comments

Comments
 (0)