Skip to content

Commit

Permalink
add new method
Browse files Browse the repository at this point in the history
  • Loading branch information
peczenyj committed Dec 17, 2023
1 parent 41eed4a commit ada4a4b
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 13 deletions.
11 changes: 11 additions & 0 deletions README.pod
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,13 @@ It true, there is a publisher restriction of certain type, for a given purpose i
# with restriction type 0 'Purpose Flatly Not Allowed by Publisher'
my $ok = $instance->check_publisher_restriction(1, 0, 284);

or

my $ok = $instance->check_publisher_restriction(
purpose_id => 1,
restriction_type => 0,
vendor_id => 284);

Version 2.0 of the Framework introduced the ability for publishers to signal restrictions on how vendors may process personal data. Restrictions can be of two types:

=over
Expand Down Expand Up @@ -357,6 +364,10 @@ For the avoidance of doubt:

In case a vendor has declared flexibility for a purpose and there is no legal basis restriction signal it must always apply the default legal basis under which the purpose was registered aside from being registered as flexible. That means if a vendor declared a purpose as legitimate interest and also declared that purpose as flexible it may not apply a "consent" signal without a legal basis restriction signal to require consent.

=head2 publisher_restrictions

Similar to L</check_publisher_restriction> but return an hashref of purpose => restriction type for a given vendor (if any).

=head2 publisher_tc

If the consent string has a C<Publisher TC> section, we will decode this section as an instance of L<GDPR::IAB::TCFv2::PublisherTC>.
Expand Down
10 changes: 10 additions & 0 deletions lib/GDPR/IAB/TCFv2.pm
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ sub check_publisher_restriction {
->check_restriction( $purpose_id, $restriction_type, $vendor_id );
}

sub publisher_restrictions {
my ( $self, $vendor_id ) = @_;

return $self->{publisher}->restrictions($vendor_id);
}

sub publisher_tc {
my $self = shift;

Expand Down Expand Up @@ -1010,6 +1016,10 @@ For the avoidance of doubt:
In case a vendor has declared flexibility for a purpose and there is no legal basis restriction signal it must always apply the default legal basis under which the purpose was registered aside from being registered as flexible. That means if a vendor declared a purpose as legitimate interest and also declared that purpose as flexible it may not apply a "consent" signal without a legal basis restriction signal to require consent.
=head2 publisher_restrictions
Similar to L</check_publisher_restriction> but return an hashref of purpose => restriction type for a given vendor (if any).
=head2 publisher_tc
If the consent string has a C<Publisher TC> section, we will decode this section as an instance of L<GDPR::IAB::TCFv2::PublisherTC>.
Expand Down
29 changes: 22 additions & 7 deletions lib/GDPR/IAB/TCFv2/Publisher.pm
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,16 @@ sub Parse {
}

sub check_restriction {
my ( $self, $purpose_id, $restrict_type, $vendor ) = @_;
my ( $self, $purpose_id, $restriction_type, $vendor_id ) = @_;

return $self->{restrictions}
->check_restriction( $purpose_id, $restrict_type, $vendor );
->check_restriction( $purpose_id, $restriction_type, $vendor_id );
}

sub restrictions {
my ( $self, $vendor_id ) = @_;

return $self->{restrictions}->restrictions($vendor_id);
}

sub publisher_tc {
Expand Down Expand Up @@ -95,7 +101,7 @@ Combines the creation of L<GDPR::IAB::TCFv2::PublisherRestrictions> and L<GDPR::
options => { json => ... },
);
say "there is publisher restriction on purpose id 1, type 0 on vendor 284"
say "there is publisher restriction on purpose id 1, type 0 on vendor_id 284"
if $publisher->check_restriction(1, 0, 284);
=head1 CONSTRUCTOR
Expand Down Expand Up @@ -126,12 +132,21 @@ Key C<options> is the L<GDPR::IAB::TCFv2> options (includes the C<json> field to
=head2 check_restriction
Return true for a given combination of purpose id, restriction type and vendor
Return true for a given combination of purpose id, restriction type and vendor_id
my $purpose_id = 1;
my $restriction_type = 0;
my $vendor = 284;
$ok = $range->check_restriction($purpose_id, $restriction_type, $vendor);
my $vendor_id = 284;
$ok = $range->check_restriction($purpose_id, $restriction_type, $vendor_id);
=head2 restrictions
Return a map of purpose id => restriction type for a given vendor id
Example, by parsing the consent C<COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA> we can generate this.
my $restrictions = $range->restrictions(32);
# returns { 7 => 1 }
=head2 publisher_tc
Expand All @@ -155,7 +170,7 @@ Returns a hashref with the following format:
# 0 - Not Allowed
# 1 - Require Consent
# 2 - Require Legitimate Interest
'[vendor id]' => 1,
'[vendor_id id]' => 1,
},
}
}
Expand Down
33 changes: 31 additions & 2 deletions lib/GDPR/IAB/TCFv2/PublisherRestrictions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ sub Parse {
return $self;
}

sub restrictions {
my ( $self, $vendor_id ) = @_;

my %restrictions;

foreach my $purpose_id ( keys %{ $self->{restrictions} } ) {
foreach my $restriction_type (
keys %{ $self->{restrictions}->{$purpose_id} } )
{
if ( $self->{restrictions}->{$purpose_id}->{$restriction_type}
->contains($vendor_id) )
{
$restrictions{$purpose_id} = $restriction_type;
}
}
}

return \%restrictions;
}

sub check_restriction {
my $self = shift;

Expand Down Expand Up @@ -155,8 +175,17 @@ Return true for a given combination of purpose id, restriction type and vendor
my $purpose_id = 1;
my $restriction_type = 0;
my $vendor = 284;
my $ok = $range->check_restriction($purpose_id, $restriction_type, $vendor);
my $vendor_id = 284;
my $ok = $range->check_restriction($purpose_id, $restriction_type, $vendor_id);
=head2 restrictions
Return a map of purpose id => restriction type for a given vendor id
Example, by parsing the consent C<COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA> we can generate this.
my $restrictions = $range->restrictions(32);
# returns { 7 => 1 }
=head2 TO_JSON
Expand Down
4 changes: 2 additions & 2 deletions t/00-load.t
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ subtest "check interfaces" => sub {
@role_decoder_methods, qw<all>;

can_ok 'GDPR::IAB::TCFv2::PublisherRestrictions', @role_base_methods,
qw<check_restriction>;
qw<check_restriction restrictions>;
can_ok 'GDPR::IAB::TCFv2::Publisher', @role_base_methods,
qw<check_restriction>;
qw<check_restriction restrictions>;
can_ok 'GDPR::IAB::TCFv2::PublisherTC', @role_base_methods,
qw<num_custom_purposes
is_purpose_consent_allowed
Expand Down
39 changes: 37 additions & 2 deletions t/01-parse.t
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,16 @@ subtest "bitfield" => sub {
ok !$consent->check_publisher_restriction( 1, 0, 284 ),
"should have no publisher restriction to vendor 284 regarding purpose id 1 of type 0 'Purpose Flatly Not Allowed by Publisher' when called with positional parameters";

ok !$consent->check_publisher_restriction( purpose_id => 1,
restriction_type => 0, vendor_id => 284 ),
ok !$consent->check_publisher_restriction(
purpose_id => 1,
restriction_type => 0, vendor_id => 284
),
"should have no publisher restriction to vendor 284 regarding purpose id 1 of type 0 'Purpose Flatly Not Allowed by Publisher' when called with named parameters";

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

my $publisher_tc = $consent->publisher_tc;

ok !defined($publisher_tc), "should not return publisher_tc";
Expand Down Expand Up @@ -442,6 +448,10 @@ subtest "range" => sub {
ok !$consent->check_publisher_restriction( 1, 0, 284 ),
"should have no publisher restriction to vendor 284 regarding purpose id 1 of type 0 'Purpose Flatly Not Allowed by Publisher'";

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

my $publisher_tc = $consent->publisher_tc;

ok !defined($publisher_tc), "should not return publisher_tc";
Expand Down Expand Up @@ -503,6 +513,10 @@ subtest "range" => sub {
ok !$consent->check_publisher_restriction( 1, 0, 284 ),
"should have no publisher restriction to vendor 284 regarding purpose id 1 of type 0 'Purpose Flatly Not Allowed by Publisher'";

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

done_testing;
};
done_testing;
Expand Down Expand Up @@ -533,6 +547,14 @@ subtest "check publisher restriction" => sub {
ok !$consent->check_publisher_restriction( 5, 1, 32 ),
"must have publisher restriction to vendor 32 regarding purpose id 5 of type 1 'Require Consent'";

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

$restrictions = $consent->publisher_restrictions(32);
is_deeply $restrictions, { 7 => 1 },
"should return the restriction purpose id => restriction type map";

done_testing;
};

Expand Down Expand Up @@ -573,6 +595,15 @@ subtest "check publisher restriction" => sub {
ok $consent->check_publisher_restriction( 2, 1, 32 );
ok !$consent->check_publisher_restriction( 2, 1, 42 );

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

$restrictions = $consent->publisher_restrictions(32);
is_deeply $restrictions, { 1 => 0, 2 => 0, 7 => 0, 10 => 0 },
"should return the restriction purpose id => restriction type map";


done_testing;
};

Expand All @@ -592,6 +623,10 @@ subtest "check publisher restriction" => sub {
ok !$consent->check_publisher_restriction( 1, 0, 284 ),
"should have no publisher restriction to vendor 284 regarding purpose id 1 of type 0 'Purpose Flatly Not Allowed by Publisher'";

my $restrictions = $consent->publisher_restrictions(284);
is_deeply $restrictions, {},
"should return the restriction purpose id => restriction type map";

done_testing;
};

Expand Down

0 comments on commit ada4a4b

Please sign in to comment.