Skip to content

Commit

Permalink
Guard and cache fetchPermission chrome API.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hyperkid123 committed Sep 17, 2020
1 parent c9bc777 commit a8446ab
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 42 deletions.
43 changes: 24 additions & 19 deletions src/js/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { visibilityFunctions } from './consts';
import Cookies from 'js-cookie';
import logger from './jwt/logger';
import sourceOfTruth from './nav/sourceOfTruth';
import { fetchPermissions } from './rbac/fetchPermissions';
import { createFetchPermissionsWatcher } from './rbac/fetchPermissions';
import { getUrl } from './utils';
import flatMap from 'lodash/flatMap';
import { headerLoader } from './App/Header';
Expand Down Expand Up @@ -47,14 +47,17 @@ const PUBLIC_EVENTS = {
})
};

/**
* Global chrome cache
*/
let chromeCache;

export function chromeInit(libjwt) {
const { store, middlewareListener, actions } = spinUpStore();

// public API actions
const { identifyApp, appNavClick, clearActive, appAction, appObjectId, chromeNavUpdate } = actions;

let chromeCache;

// Init JWT first.
const jwtResolver = libjwt.initPromise
.then(async () => {
Expand Down Expand Up @@ -128,34 +131,36 @@ export function chromeInit(libjwt) {
}

export function bootstrap(libjwt, initFunc) {
const getUser = () => {
// here we need to init the qe plugin
// the "contract" is we will do this before anyone
// calls/finishes getUser
// this only does something if the correct localstorage
// vars are set

qe.init();

return libjwt.initPromise
.then(libjwt.jwt.getUserInfo)
.catch(() => {
libjwt.jwt.logoutAllTabs();
});
};
const fetchPermissions = createFetchPermissionsWatcher(chromeCache);
return {
chrome: {
auth: {
getOfflineToken: () => libjwt.getOfflineToken(),
doOffline: () => libjwt.jwt.doOffline(consts.noAuthParam, consts.offlineToken),
getToken: () => libjwt.jwt.getUserInfo().then(() => libjwt.jwt.getEncodedToken()),
getUser: () => {
// here we need to init the qe plugin
// the "contract" is we will do this before anyone
// calls/finishes getUser
// this only does something if the correct localstorage
// vars are set

qe.init();

return libjwt.initPromise
.then(libjwt.jwt.getUserInfo)
.catch(() => {
libjwt.jwt.logoutAllTabs();
});
},
getUser,
qe: qe,
logout: (bounce) => libjwt.jwt.logoutAllTabs(bounce),
login: () => libjwt.jwt.login()
},
isProd: window.location.host === 'cloud.redhat.com',
isBeta: () => (window.location.pathname.split('/')[1] === 'beta' ? true : false),
getUserPermissions: (app = '') => fetchPermissions(libjwt.jwt.getEncodedToken(), app),
getUserPermissions: (app = '') => getUser().then(() => fetchPermissions(libjwt.jwt.getEncodedToken(), app)),
isPenTest: () => Cookies.get('x-rh-insights-pentest') ? true : false,
getBundle: () => getUrl('bundle'),
getApp: () => getUrl('app'),
Expand Down
4 changes: 4 additions & 0 deletions src/js/jwt/__mocks__/jwt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* eslint-disable camelcase */
export const decodeToken = (x) => ({
session_state: x
});
28 changes: 23 additions & 5 deletions src/js/rbac/fetchPermissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import logger from '../jwt/logger';

const log = logger('fetchPermissions.js');

const perPage = 25;
const perPage = 100;

export const fetchPermissions = (userToken, app = '') => {
if (insights.chrome.getBundle() === 'openshift') {
return Promise.resolve([]);
}
const fetchPermissions = (userToken, app = '') => {
const rbacApi = createRbacAPI(userToken);
return rbacApi.getPrincipalAccess(app, undefined, perPage).then(({ data, meta }) => {
if (meta.count > perPage) {
Expand All @@ -23,3 +20,24 @@ export const fetchPermissions = (userToken, app = '') => {
}})
.catch(error => log(error));
};

export const createFetchPermissionsWatcher = (cache) => {
let currentCall = undefined;
return async (userToken, app = '') => {
if (insights.chrome.getBundle() === 'openshift') {
return Promise.resolve([]);
}
const permissions = await cache.getItem('permissions');
if (permissions) {
return permissions;
}
if (typeof currentCall === 'undefined') {
currentCall = fetchPermissions(userToken, app).then((data) => {
currentCall = undefined;
cache.setItem('permissions', data);
return data;
});
}
return currentCall;
};
};
46 changes: 28 additions & 18 deletions src/js/rbac/fetchPermissions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,35 @@ jest.mock('./rbac', () => () => {
});
});

import { fetchPermissions } from './fetchPermissions';
import './rbac';
import { createFetchPermissionsWatcher } from './fetchPermissions';

it('should send all the paginated data as array', async () => {
const data = fetchPermissions('uSeRtOkEn');
expect.assertions(1);
return data.then(permissions => expect(permissions).toEqual(mockedRbac.data));
});
jest.mock('../jwt/jwt');

it('should send the data as array', async () => {
const data = fetchPermissions('uSeRtOkEn');
expect.assertions(1);
return data.then(permissions => expect(permissions).toEqual(mockedRbac.data));
});
describe('fetchPermissions', () => {
let fetchPermissions;
beforeEach(() => {
const cache = { getItem: () => undefined, setItem: () => undefined };
fetchPermissions = createFetchPermissionsWatcher(cache);
});

it('should send all the paginated data as array', async () => {
const data = fetchPermissions('uSeRtOkEn');
expect.assertions(1);
return data.then(permissions => expect(permissions).toEqual(mockedRbac.data));
});

it('should not call any rbac', async () => {
const previousGetBundle = global.insights.chrome.getBundle;
global.window.insights.chrome.getBundle = () => 'openshift';
const data = await fetchPermissions('uSeRtOkEn');
expect(data).not.toEqual(mockedRbac.data);
global.window.insights.chrome.getBundle = previousGetBundle;
it('should send the data as array', async () => {
const data = fetchPermissions('uSeRtOkEn');
expect.assertions(1);
return data.then(permissions => expect(permissions).toEqual(mockedRbac.data));
});

it('should not call any rbac', async () => {
const previousGetBundle = global.insights.chrome.getBundle;
global.window.insights.chrome.getBundle = () => 'openshift';
const data = await fetchPermissions('uSeRtOkEn');
expect(data).not.toEqual(mockedRbac.data);
global.window.insights.chrome.getBundle = previousGetBundle;
});
});

0 comments on commit a8446ab

Please sign in to comment.