Skip to content

Commit

Permalink
Prebid core: bidder-specific control over storage access via `bidderS…
Browse files Browse the repository at this point in the history
…ettings.allowStorage`

#7280
  • Loading branch information
dgirardi committed Jan 31, 2022
1 parent f2b050d commit c40f340
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 3 deletions.
18 changes: 16 additions & 2 deletions src/storageManager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {hook} from './hook.js';
import { hasDeviceAccess, checkCookieSupport, logError } from './utils.js';
import {hasDeviceAccess, checkCookieSupport, logError, logInfo} from './utils.js';
import includes from 'prebidjs-polyfill/includes.js';
import {bidderSettings as defaultBidderSettings} from './bidderSettings.js';
import {config} from './config.js';

const moduleTypeWhiteList = ['core', 'prebid-module'];

Expand All @@ -22,13 +24,25 @@ export let storageCallbacks = [];
* - Module type: Some modules may need these functions but are not vendor. e.g prebid core files in src and modules like currency.
* @param {storageOptions} options
*/
export function newStorageManager({gvlid, moduleName, moduleType} = {}) {
export function newStorageManager({gvlid, moduleName, moduleType} = {}, {bidderSettings = defaultBidderSettings} = {}) {
function isBidderDisallowed() {
const bidder = config.getCurrentBidder();
if (bidder == null) {
return false;
}
const storageAllowed = bidderSettings.get(bidder, 'storageAllowed');
return storageAllowed == null ? false : !storageAllowed;
}
function isValid(cb) {
if (includes(moduleTypeWhiteList, moduleType)) {
let result = {
valid: true
}
return cb(result);
} else if (isBidderDisallowed()) {
logInfo(`bidderSettings denied access to device storage for bidder '${config.getCurrentBidder()}'`);
const result = {valid: false};
return cb(result);
} else {
let value;
let hookDetails = {
Expand Down
76 changes: 75 additions & 1 deletion test/spec/unit/core/storageManager_spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { resetData, getCoreStorageManager, storageCallbacks, getStorageManager } from 'src/storageManager.js';
import {
resetData,
getCoreStorageManager,
storageCallbacks,
getStorageManager,
newStorageManager
} from 'src/storageManager.js';
import { config } from 'src/config.js';
import * as utils from 'src/utils.js';
import {hook} from '../../../../src/hook.js';

describe('storage manager', function() {
before(() => {
hook.ready();
});

beforeEach(function() {
resetData();
});
Expand Down Expand Up @@ -95,4 +106,67 @@ describe('storage manager', function() {
expect(localStorage.getItem('unrelated')).to.be.eq('dummy');
});
});

describe('when bidderSettings.allowStorage is defined', () => {
let mgr;
const DENIED_BIDDER = 'denied-bidder';
const DENY_KEY = 'storageAllowed';

const COOKIE = 'test-cookie';
const LS_KEY = 'test-localstorage';

function mockBidderSettings() {
return {
get(bidder, key) {
if (bidder === DENIED_BIDDER && key === DENY_KEY) {
return false;
} else {
return undefined;
}
}
}
}

beforeEach(() => {
mgr = newStorageManager({}, {bidderSettings: mockBidderSettings()});
});

afterEach(() => {
mgr.setCookie(COOKIE, 'delete', new Date().toUTCString());
mgr.removeDataFromLocalStorage(LS_KEY);
})

Object.entries({
disallowed: [DENIED_BIDDER, false],
allowed: ['allowed-bidder', true]
}).forEach(([test, [bidderCode, shouldWork]]) => {
const testDesc = (desc) => `should ${shouldWork ? '' : 'not'} ${desc} for ${test} bidders`

it(testDesc('allow cookies'), () => {
config.runWithBidder(bidderCode, () => {
mgr.setCookie(COOKIE, 'value');
expect(mgr.getCookie(COOKIE)).to.equal(shouldWork ? 'value' : null);
});
});

it(testDesc('allow localStorage'), () => {
config.runWithBidder(bidderCode, () => {
mgr.setDataInLocalStorage(LS_KEY, 'value');
expect(mgr.getDataFromLocalStorage(LS_KEY)).to.equal(shouldWork ? 'value' : null);
})
});

it(testDesc('report localStorage as available'), () => {
config.runWithBidder(bidderCode, () => {
expect(mgr.hasLocalStorage()).to.equal(shouldWork);
});
});

it(testDesc('report cookies as available'), () => {
config.runWithBidder(bidderCode, () => {
expect(mgr.cookiesAreEnabled()).to.equal(shouldWork);
})
})
});
})
});

0 comments on commit c40f340

Please sign in to comment.