Skip to content

Commit

Permalink
GDPR enforcement: enforce consent when data is not available, but GDP…
Browse files Browse the repository at this point in the history
…R module is enabled
  • Loading branch information
dgirardi committed Jul 8, 2022
1 parent 071f344 commit 6f72a71
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 8 deletions.
23 changes: 17 additions & 6 deletions modules/gdprEnforcement.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ function getGvlidForAnalyticsAdapter(code) {
return adapterManager.getAnalyticsAdapter(code) && (adapterManager.getAnalyticsAdapter(code).gvlid || null);
}

export function shouldEnforce(consentData, purpose, name) {
if (consentData == null && gdprDataHandler.enabled) {
// there is no consent data, but the GDPR module has been installed and configured
// NOTE: this check is not foolproof, as `gdprDataHandler.enabled` is false when Prebid first loads (before `setConfig({consentManagement})`)
// so it's possible for a module to pass this check if they get here before that
logWarn(`Attempting operation that requires purpose ${purpose} consent while consent data is not available${name ? ` (module: ${name})` : ''}. Assuming no consent was given.`)
return true;
}
return consentData && consentData.gdprApplies;
}

/**
* This function takes in a rule and consentData and validates against the consentData provided. Depending on what it returns,
* the caller may decide to suppress a TCF-sensitive activity.
Expand Down Expand Up @@ -183,7 +194,7 @@ export function deviceAccessHook(fn, isVendorless, gvlid, moduleName, result, {v
fn.call(this, isVendorless, gvlid, moduleName, result);
} else {
const consentData = gdprDataHandler.getConsentData();
if (consentData && consentData.gdprApplies) {
if (shouldEnforce(consentData, 1, moduleName)) {
const curBidder = config.getCurrentBidder();
// Bidders have a copy of storage object with bidder code binded. Aliases will also pass the same bidder code when invoking storage functions and hence if alias tries to access device we will try to grab the gvl id for alias instead of original bidder
if (curBidder && (curBidder != moduleName) && adapterManager.aliasRegistry[curBidder] === moduleName) {
Expand Down Expand Up @@ -216,8 +227,8 @@ export function deviceAccessHook(fn, isVendorless, gvlid, moduleName, result, {v
*/
export function userSyncHook(fn, ...args) {
const consentData = gdprDataHandler.getConsentData();
if (consentData && consentData.gdprApplies) {
const curBidder = config.getCurrentBidder();
const curBidder = config.getCurrentBidder();
if (shouldEnforce(consentData, 1, curBidder)) {
const gvlid = getGvlid(curBidder);
let isAllowed = validateRules(purpose1Rule, consentData, curBidder, gvlid);
if (isAllowed) {
Expand All @@ -238,7 +249,7 @@ export function userSyncHook(fn, ...args) {
* @param {Object} consentData GDPR consent data
*/
export function userIdHook(fn, submodules, consentData) {
if (consentData && consentData.gdprApplies) {
if (shouldEnforce(consentData, 1, 'User ID')) {
let userIdModules = submodules.map((submodule) => {
const gvlid = getGvlid(submodule.submodule);
const moduleName = submodule.submodule.name;
Expand All @@ -265,7 +276,7 @@ export function userIdHook(fn, submodules, consentData) {
*/
export function makeBidRequestsHook(fn, adUnits, ...args) {
const consentData = gdprDataHandler.getConsentData();
if (consentData && consentData.gdprApplies) {
if (shouldEnforce(consentData, 2)) {
adUnits.forEach(adUnit => {
adUnit.bids = adUnit.bids.filter(bid => {
const currBidder = bid.bidder;
Expand Down Expand Up @@ -293,7 +304,7 @@ export function makeBidRequestsHook(fn, adUnits, ...args) {
*/
export function enableAnalyticsHook(fn, config) {
const consentData = gdprDataHandler.getConsentData();
if (consentData && consentData.gdprApplies) {
if (shouldEnforce(consentData, 7, 'Analytics')) {
if (!isArray(config)) {
config = [config]
}
Expand Down
5 changes: 5 additions & 0 deletions test/helpers/consentData.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {gdprDataHandler} from 'src/adapterManager.js';

export function mockGdprConsent(sandbox, getConsentData = () => null) {
sandbox.stub(gdprDataHandler, 'enabled').get(() => true)
sandbox.stub(gdprDataHandler, 'promise').get(() => Promise.resolve(getConsentData()));
sandbox.stub(gdprDataHandler, 'getConsentData').callsFake(getConsentData)
}

beforeEach(() => {
gdprDataHandler.reset();
})
7 changes: 5 additions & 2 deletions test/spec/modules/adnuntiusBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ describe('adnuntiusBidAdapter', function () {
const GVLID = 855;
const usi = utils.generateUUID()
const meta = [{ key: 'usi', value: usi }]
const storage = getStorageManager({gvlid: GVLID, moduleName: 'adnuntius'})
storage.setDataInLocalStorage('adn.metaData', JSON.stringify(meta))

before(() => {
const storage = getStorageManager({gvlid: GVLID, moduleName: 'adnuntius'})
storage.setDataInLocalStorage('adn.metaData', JSON.stringify(meta))
});

beforeEach(function () {
$$PREBID_GLOBAL$$.bidderSettings = {
Expand Down
1 change: 1 addition & 0 deletions test/test_deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ window.process = {
}
};

require('test/helpers/consentData.js');
require('test/helpers/prebidGlobal.js');
require('test/mocks/adloaderStub.js');
require('test/mocks/xhr.js');
Expand Down

0 comments on commit 6f72a71

Please sign in to comment.