=pod
=encoding utf8
=for html
=for html
=for html
=for html
=for html
=head1 NAME
GDPR::IAB::TCFv2 - Transparency & Consent String version 2 parser
=head1 VERSION
Version 0.06
=head1 SYNOPSIS
The purpose of this package is to parse Transparency & Consent String (TC String) as defined by IAB version 2.
use strict;
use warnings;
use GDPR::IAB::TCFv2;
use GDPR::IAB::TCFv2::Constants::Purpose qw<:all>;
use GDPR::IAB::TCFv2::Constants::SpecialFeature qw<:all>;
my $consent = GDPR::IAB::TCFv2->Parse(
'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA.argAC0gAAAAAAAAAAAA'
);
use feature qw;
say $consent->version; # 2
say $consent->created; # epoch 1228644257 or 07/12/2008
say $consent->last_updated; # epoch 1326215413 or 10/01/2012
say $consent->cmp_id; # 21 - Traffective GmbH
say $consent->cmp_version; # 7
say $consent->consent_screen; # 2
say $consent->consent_language; # "EN"
say $consent->vendor_list_version; # 23
use List::MoreUtils qw;
say "find consent for purpose ids 1, 3, 9 and 10" if all {
$consent->is_purpose_consent_allowed($_)
} ( # constants exported by GDPR::IAB::TCFv2::Constants::Purpose
InfoStorageAccess, # 1
PersonalizationProfile, # 3
MarketResearch, # 9
DevelopImprove, # 10
);
say "find consent for vendor id 284 (Weborama)" if $consent->vendor_consent(284);
# Geolocation exported by GDPR::IAB::TCFv2::Constants::SpecialFeature
say "user is opt in for special feature 'Geolocation (id 1)'"
if $consent->is_special_feature_opt_in(Geolocation);
=head1 ACRONYMS
L: General Data Protection Regulation
L: Interactive Advertising Bureau
L: The Transparency & Consent Framework
=head1 CONSTRUCTOR
=head2 Parse
The Parse method will decode and validate a base64 encoded version of the tcf v2 string.
Will return a C immutable object that allow easy access to different properties.
Will die if can't decode the string.
use GDPR::IAB::TCFv2;
my $consent = GDPR::IAB::TCFv2->Parse(
'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA.argAC0gAAAAAAAAAAAA'
);
=head1 METHODS
=head2 version
Version number of the encoding format. The value is 2 for this format.
=head2 created
Epoch time format when TC String was created in numeric format. You can easily parse with L if needed.
On scalar context it returns epoch in seconds. On list context it returns epoch in seconds and nanoseconds.
use GDPR::IAB::TCFv2;
use Test::More tests => 3;
my $consent = GDPR::IAB::TCFv2->Parse(
'CLcVDxRMWfGmWAVAHCENAXCkAKDAADnAABRgA5mdfCKZuYJez-NQm0TBMYA4oCAAGQYIAAAAAAEAIAEgAA.argAC0gAAAAAAAAAAAA'
);
is $consent->created, 1228644257,
'should return the creation epoch 07/12/2008';
my ( $seconds, $nanoseconds ) = $consent->created;
is $seconds, 1228644257,
'should return the creation epoch 07/12/2008 on list context';
is $nanoseconds, 700000000,
'should return the 700000000 nanoseconds of epoch on list context';
=head2 last_updated
Epoch time format when TC String was last updated in numeric format. You can easily parse with L if needed.
On scalar context it returns epoch in seconds. On list context it returns epoch in seconds and nanoseconds, like the C
=head2 cmp_id
Consent Management Platform ID that last updated the TC String. Is a unique ID will be assigned to each Consent Management Platform.
=head2 cmp_version
Consent Management Platform version of the CMP that last updated this TC String.
Each change to a CMP should increment their internally assigned version number as a record of which version the user gave consent and transparency was established.
=head2 consent_screen
CMP Screen number at which consent was given for a user with the CMP that last updated this TC String.
The number is a CMP internal designation and is CmpVersion specific. The number is used for identifying on which screen a user gave consent as a record.
=head2 consent_language
Two-letter L language code in which the CMP UI was presented.
=head2 vendor_list_version
Number corresponds to L vendorListVersion.
Version of the GVL used to create this TC String.
=head2 policy_version
Version of policy used within L.
From the corresponding field in the GVL that was used for obtaining consent.
=head2 is_service_specific
This field must always have the value of 1. When a Vendor encounters a TC String with C then it is considered invalid.
=head2 use_non_standard_stacks
If true, CMP used non-IAB standard texts during consent gathering.
Setting this to 1 signals to Vendors that a private CMP has modified standard Stack descriptions and/or their translations and/or that a CMP has modified or supplemented standard Illustrations and/or their translations as allowed by the policy..
=head2 is_special_feature_opt_in
If true means Opt in.
The TCF L designates certain Features as "special" which means a CMP must afford the user a means to opt in to their use. These "Special Features" are published and numerically identified in the L from normal Features.
See also: L.
=head2 is_purpose_consent_allowed
If true means Consent.
The user's consent value for each Purpose established on the legal basis of consent.
my $ok = $instance->is_purpose_consent_allowed(1);
See also: L.
=head2 is_purpose_legitimate_interest_allowed
The user's consent value for each Purpose established on the legal basis of legitimate interest.
my $ok = $instance->is_purpose_legitimate_interest_allowed(1);
See also: L.
=head2 purpose_one_treatment
CMPs can use the PublisherCC field to indicate the legal jurisdiction the publisher is under to help vendors determine whether the vendor needs consent for Purpose 1.
Returns true if Purpose 1 was NOT disclosed at all.
Returns false if Purpose 1 was disclosed commonly as consent as expected by the L.
=head2 publisher_country_code
Two-letter L language code of the country that determines legislation of reference.
Commonly, this corresponds to the country in which the publisher's business entity is established.
=head2 max_vendor_id_consent
The maximum Vendor ID that is represented in the following bit field or range encoding.
Because this section can be a variable length, this indicates the last ID of the section so that a decoder will know when it has reached the end.
=head2 vendor_consent
If true, vendor has consent.
The consent value for each Vendor ID.
my $ok = $instance->vendor_consent(284); # if true, consent ok for Weborama (vendor id 284).
=head2 max_vendor_id_legitimate_interest
The maximum Vendor ID that is represented in the following bit field or range encoding.
Because this section can be a variable length, this indicates the last ID of the section so that a decoder will know when it has reached the end.
=head2 vendor_legitimate_interest
If true, legitimate interest established.
The legitimate interest value for each Vendor ID
my $ok = $instance->vendor_legitimate_interest(284); # if true, legitimate interest established for Weborama (vendor id 284).
=head1 FUNCTIONS
=head2 looksLikeIsConsentVersion2
Will check if a given tc string starts with a literal C.
=head1 SEE ALSO
The original documentation of the L.
=head1 AUTHOR
Tiago Peczenyj L
=head1 BUGS
Please report any bugs or feature requests to L.
=head1 LICENSE AND COPYRIGHT
Copyright 2023 Tiago Peczenyj
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See L for more information.
=head1 DISCLAIMER
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=cut