From c82b7f91bdfdf8722377e2275424aa13e69c4076 Mon Sep 17 00:00:00 2001 From: Tyrone Tse Date: Wed, 27 Mar 2024 12:33:21 -0500 Subject: [PATCH 1/2] security.js updated function checkUserAccess for users that are members of the imsUserGroup, that if a page has the property reporting-access then access to the page is only granted if the user is member of te group defined by the property imsReportingGroup in the file admin-config.xlsx site-config.js : Updated the function getQuickLinkConfig to show the quick link to users who are members of the new column Group in shared-quicklinks tab of file site-config.xlsx --- scripts/security.js | 29 ++++++++++++++++++++++++++--- scripts/site-config.js | 17 ++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/scripts/security.js b/scripts/security.js index 659a7c98..27f66ea1 100644 --- a/scripts/security.js +++ b/scripts/security.js @@ -96,6 +96,9 @@ export function isPublicPage() { return document.querySelector('head meta[name="public-access"]')?.getAttribute('content').toLowerCase() === 'true'; } +export function isReportingAccessPage() { + return document.querySelector('head meta[name="reporting-access"]')?.getAttribute('content').toLowerCase() === 'true'; +} export async function checkUserAccess() { if (isUnifiedShellRuntimeAvailable()) return !!user.get('imsProfile'); await getBearerToken(); @@ -104,8 +107,17 @@ export async function checkUserAccess() { const imsLibSecurityModule = await import('./security-imslib.js'); if (isPublicPage()) { return true; - } - return await imsLibSecurityModule.isUserInSecurityGroup(imsUserGroup, await getBearerToken()); + } + + const isIMSUser = await imsLibSecurityModule.isUserInSecurityGroup(imsUserGroup, await getBearerToken()); + //Check if IMS Users have access to Reporting Page + if (isReportingAccessPage() && isIMSUser) { + const adminConfig = await getAdminConfig(); + //The name of the group is in property imsReportingGroup in admin-config.xslx + return await checkGroupAccess('imsReportingGroup'); + } else { + return isIMSUser; + } } } @@ -113,4 +125,15 @@ export async function checkAddAssetsAccess() { const adminConfig = await getAdminConfig(); const securityGroupMemberships = await getSecurityGroupMemberships(await getBearerToken()); return securityGroupMemberships.some((grp) => grp.groupName === adminConfig.imsAuthorGroup); -} \ No newline at end of file +} + +/** + * Checks Group Access for the group that is stored in the admin-config.xslx for + * for the property name in parameter adminConfigGroupPropertyName + * @returns {boolean} for access to the group + */ +export async function checkGroupAccess(adminConfigGroupPropertyName) { + const adminConfig = await getAdminConfig(); + const securityGroupMemberships = await getSecurityGroupMemberships(await getBearerToken()); + return securityGroupMemberships.some((grp) => grp.groupName === adminConfig[adminConfigGroupPropertyName]); +} diff --git a/scripts/site-config.js b/scripts/site-config.js index c906db24..438baec0 100644 --- a/scripts/site-config.js +++ b/scripts/site-config.js @@ -1,5 +1,6 @@ import { fetchCached } from './fetch-util.js'; import { toCamelCase } from './lib-franklin.js'; +import { checkGroupAccess } from './security.js'; const QA_BASE_PATH = 'qa'; const DRAFTS_BASE_PATH = 'drafts'; @@ -285,14 +286,24 @@ async function mapUserSettingsForId(configId, result) { export async function getQuickLinkConfig() { const result = []; const response = await getConfig('site-config.json'); - response.quicklinks?.data.forEach((row) => { - if (row.Title && row.Page) { + + for (const row of response.quicklinks?.data || []) { + if (row.Title && row.Page && row.Group == '') { result.push({ title: row.Title, page: row.Page, }); + } else if (row.Title && row.Page && row.Group) { + if (await checkGroupAccess(row.Group)) + { + result.push({ + title: row.Title, + page: row.Page, + }); + } } - }); + } + return result; } From 59d7905380e4bff697cec072cc0e635fe4072708 Mon Sep 17 00:00:00 2001 From: Tyrone Tse Date: Thu, 28 Mar 2024 14:55:45 -0500 Subject: [PATCH 2/2] securiity.js : Deleted function isReportingAccessPage() as it is not needed any more. Updated function checkUserAccess() : Update code for non public pages, check if the current page path is in the pages returned by the function getQuickLinks. If it does not exist in quick links, then the user does not have access to the page. The functionQuickLinks already has logic to check if a page is only accessible by users of a page group. Renamed function checkGroupAccess(adminConfigGroupPropertyName) to checkPageGroupAccess(adminConfigGroupPropertyName) --- scripts/security.js | 26 ++++++++++++-------------- scripts/site-config.js | 5 ++--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/scripts/security.js b/scripts/security.js index 27f66ea1..af8ebbc5 100644 --- a/scripts/security.js +++ b/scripts/security.js @@ -1,6 +1,6 @@ import { fetchCached } from './fetch-util.js'; import { isUnifiedShellRuntimeAvailable, shell, user } from '../contenthub/unified-shell.js'; -import { getAdminConfig } from './site-config.js'; +import { getAdminConfig, getBrandingConfig, isContentHub, getQuickLinkConfig, getBaseConfigPath } from './site-config.js'; import { getSecurityGroupMemberships } from './security-imslib.js'; /** @@ -96,9 +96,6 @@ export function isPublicPage() { return document.querySelector('head meta[name="public-access"]')?.getAttribute('content').toLowerCase() === 'true'; } -export function isReportingAccessPage() { - return document.querySelector('head meta[name="reporting-access"]')?.getAttribute('content').toLowerCase() === 'true'; -} export async function checkUserAccess() { if (isUnifiedShellRuntimeAvailable()) return !!user.get('imsProfile'); await getBearerToken(); @@ -109,15 +106,16 @@ export async function checkUserAccess() { return true; } - const isIMSUser = await imsLibSecurityModule.isUserInSecurityGroup(imsUserGroup, await getBearerToken()); - //Check if IMS Users have access to Reporting Page - if (isReportingAccessPage() && isIMSUser) { - const adminConfig = await getAdminConfig(); - //The name of the group is in property imsReportingGroup in admin-config.xslx - return await checkGroupAccess('imsReportingGroup'); - } else { - return isIMSUser; - } + const isIMSUser = await imsLibSecurityModule.isUserInSecurityGroup(imsUserGroup, await getBearerToken()); + if (isIMSUser) { + //Check if current page is present in the array of pages returned by function getQuickLinkConfig() + const presentInQuickLinks = (await getQuickLinkConfig()).some((grp) => grp.page === (window.location.pathname.replace(getBaseConfigPath((window.location.pathname)),''))); + return presentInQuickLinks; + } + else + { //Not IMSUser + return isIMSUser; + } } } @@ -132,7 +130,7 @@ export async function checkAddAssetsAccess() { * for the property name in parameter adminConfigGroupPropertyName * @returns {boolean} for access to the group */ -export async function checkGroupAccess(adminConfigGroupPropertyName) { +export async function checkPageGroupAccess(adminConfigGroupPropertyName) { const adminConfig = await getAdminConfig(); const securityGroupMemberships = await getSecurityGroupMemberships(await getBearerToken()); return securityGroupMemberships.some((grp) => grp.groupName === adminConfig[adminConfigGroupPropertyName]); diff --git a/scripts/site-config.js b/scripts/site-config.js index 438baec0..c0bc0603 100644 --- a/scripts/site-config.js +++ b/scripts/site-config.js @@ -1,6 +1,6 @@ import { fetchCached } from './fetch-util.js'; import { toCamelCase } from './lib-franklin.js'; -import { checkGroupAccess } from './security.js'; +import { checkPageGroupAccess } from './security.js'; const QA_BASE_PATH = 'qa'; const DRAFTS_BASE_PATH = 'drafts'; @@ -294,7 +294,7 @@ export async function getQuickLinkConfig() { page: row.Page, }); } else if (row.Title && row.Page && row.Group) { - if (await checkGroupAccess(row.Group)) + if (await checkPageGroupAccess(row.Group)) { result.push({ title: row.Title, @@ -303,7 +303,6 @@ export async function getQuickLinkConfig() { } } } - return result; }