Skip to content

Commit

Permalink
feat(fedramp): only add domains if commercial (#3634)
Browse files Browse the repository at this point in the history
Co-authored-by: rstachof <[email protected]>
  • Loading branch information
robstax and rstachof authored Jun 25, 2024
1 parent 4bb70fa commit 521de20
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 51 deletions.
9 changes: 7 additions & 2 deletions packages/@webex/plugin-meetings/src/meetings/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint no-shadow: ["error", { "allow": ["eventType"] }] */

import {union} from 'lodash';
import '@webex/internal-plugin-mercury';
import '@webex/internal-plugin-conversation';
import '@webex/internal-plugin-metrics';
Expand Down Expand Up @@ -1001,7 +1001,10 @@ export default class Meetings extends WebexPlugin {
fetchUserPreferredWebexSite() {
return this.request.getMeetingPreferences().then((res) => {
if (res) {
this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
this.preferredWebexSite = preferredWebexSite;
// @ts-ignore
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
}

// fall back to getting the preferred site from the user information
Expand All @@ -1014,6 +1017,8 @@ export default class Meetings extends WebexPlugin {
user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
if (preferredWebexSite) {
this.preferredWebexSite = preferredWebexSite;
// @ts-ignore
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
} else {
throw new Error('site not found');
}
Expand Down
53 changes: 38 additions & 15 deletions packages/@webex/plugin-meetings/test/unit/spec/meetings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
import Meeting, {CallStateForMetrics} from '@webex/plugin-meetings/src/meeting';
import {Services} from '@webex/webex-core';
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
import Meetings from '@webex/plugin-meetings/src/meetings';
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
Expand Down Expand Up @@ -75,6 +76,8 @@ describe('plugin-meetings', () => {
let test1;
let test2;
let locusInfo;
let services;
let catalog;

describe('meetings index', () => {
beforeEach(() => {
Expand All @@ -93,9 +96,13 @@ describe('plugin-meetings', () => {
device: Device,
mercury: Mercury,
meetings: Meetings,
services: Services,
},
});

services = webex.internal.services;
catalog = services._getCatalog();

Object.assign(webex, {
logging: logger,
});
Expand Down Expand Up @@ -161,6 +168,7 @@ describe('plugin-meetings', () => {
],
})
),
_getCatalog: sinon.stub().returns(catalog),
fetchClientRegionInfo: sinon.stub().returns(Promise.resolve()),
},
metrics: {
Expand Down Expand Up @@ -1917,41 +1925,42 @@ describe('plugin-meetings', () => {
let loggerProxySpy;

it('should call request.getMeetingPreferences to get the preferred webex site ', async () => {
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), []);
assert.isDefined(webex.meetings.preferredWebexSite);
await webex.meetings.fetchUserPreferredWebexSite();

assert.equal(webex.meetings.preferredWebexSite, 'go.webex.com');
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), [
'go.webex.com',
]);
});

const setup = ({user} = {}) => {
loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), []);

Object.assign(webex.internal, {
services: {
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
},
user: {
get: sinon.stub().returns(Promise.resolve(user)),
},
});

Object.assign(webex.internal.services, {
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
});
};

it('should not fail if UserPreferred info is not fetched ', async () => {
setup();

Object.assign(webex.internal, {
services: {
getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
},
});

await webex.meetings.fetchUserPreferredWebexSite().then(() => {
assert.equal(webex.meetings.preferredWebexSite, '');
});
assert.calledOnceWithExactly(
loggerProxySpy,
'Failed to fetch preferred site from user - no site will be set'
);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), ['']);
});

it('should fall back to fetching the site from the user', async () => {
Expand All @@ -1968,6 +1977,10 @@ describe('plugin-meetings', () => {
await webex.meetings.fetchUserPreferredWebexSite();

assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), [
'',
'site.webex.com',
]);
assert.notCalled(loggerProxySpy);
});

Expand All @@ -1989,6 +2002,7 @@ describe('plugin-meetings', () => {
loggerProxySpy,
'Failed to fetch preferred site from user - no site will be set'
);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), ['']);
});
}
);
Expand All @@ -2005,6 +2019,7 @@ describe('plugin-meetings', () => {
loggerProxySpy,
'Failed to fetch preferred site from user - no site will be set'
);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), ['']);
});

it('should fall back to fetching the site from the user', async () => {
Expand All @@ -2022,6 +2037,10 @@ describe('plugin-meetings', () => {

assert.equal(webex.meetings.preferredWebexSite, 'site.webex.com');
assert.notCalled(loggerProxySpy);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), [
'',
'site.webex.com',
]);
});

forEach(
Expand All @@ -2042,6 +2061,7 @@ describe('plugin-meetings', () => {
loggerProxySpy,
'Failed to fetch preferred site from user - no site will be set'
);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), ['']);
});
}
);
Expand All @@ -2058,6 +2078,7 @@ describe('plugin-meetings', () => {
loggerProxySpy,
'Failed to fetch preferred site from user - no site will be set'
);
assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), ['']);
});
});
});
Expand Down Expand Up @@ -2344,12 +2365,14 @@ describe('plugin-meetings', () => {
sessionType: 'MAIN',
};
newLocus.self.state = 'JOINED';
newLocus.self.devices = [{
intent: {
reason: 'ON_HOLD_LOBBY',
type: 'WAIT',
}
}];
newLocus.self.devices = [
{
intent: {
reason: 'ON_HOLD_LOBBY',
type: 'WAIT',
},
},
];
LoggerProxy.logger.log = sinon.stub();
const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
assert.equal(result, true);
Expand Down
11 changes: 1 addition & 10 deletions packages/@webex/webex-core/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,7 @@ export default {
*
* @type {Array<string>}
*/
allowedDomains: [
'wbx2.com',
'ciscospark.com',
'webex.com',
'webexapis.com',
'broadcloudpbx.com',
'broadcloud.eu',
'broadcloud.com.au',
'broadcloudpbx.net',
],
allowedDomains: [],
},
device: {
preDiscoveryServices: {
Expand Down
14 changes: 13 additions & 1 deletion packages/@webex/webex-core/src/lib/services/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,16 @@ const SERVICE_CATALOGS_ENUM_TYPES = {
NUMBER: 'SERVICE_CATALOGS_ENUM_TYPES_NUMBER',
};

export {SERVICE_CATALOGS_ENUM_TYPES, NAMESPACE, SERVICE_CATALOGS};
// The default allowed domains that SDK can make requests to outside of service catalog
const COMMERCIAL_ALLOWED_DOMAINS = [
'wbx2.com',
'ciscospark.com',
'webex.com',
'webexapis.com',
'broadcloudpbx.com',
'broadcloud.eu',
'broadcloud.com.au',
'broadcloudpbx.net',
];

export {SERVICE_CATALOGS_ENUM_TYPES, NAMESPACE, SERVICE_CATALOGS, COMMERCIAL_ALLOWED_DOMAINS};
10 changes: 10 additions & 0 deletions packages/@webex/webex-core/src/lib/services/service-catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Url from 'url';

import AmpState from 'ampersand-state';

import {union} from 'lodash';
import ServiceUrl from './service-url';

/* eslint-disable no-underscore-dangle */
Expand Down Expand Up @@ -361,6 +362,15 @@ const ServiceCatalog = AmpState.extend({
this.allowedDomains = [...allowedDomains];
},

/**
*
* @param {Array<string>} newAllowedDomains - new allowed domains to add to existing set of allowed domains
* @returns {void}
*/
addAllowedDomains(newAllowedDomains) {
this.allowedDomains = union(this.allowedDomains, newAllowedDomains);
},

/**
* Update the current list of `ServiceUrl`s against a provided
* service hostmap.
Expand Down
7 changes: 7 additions & 0 deletions packages/@webex/webex-core/src/lib/services/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import Url from 'url';

import sha256 from 'crypto-js/sha256';

import {union} from 'lodash';
import WebexPlugin from '../webex-plugin';

import METRICS from './metrics';
import ServiceCatalog from './service-catalog';
import ServiceRegistry from './service-registry';
import ServiceState from './service-state';
import fedRampServices from './service-fed-ramp';
import {COMMERCIAL_ALLOWED_DOMAINS} from './constants';

const trailingSlashes = /(?:^\/)|(?:\/$)/;

Expand Down Expand Up @@ -941,6 +943,11 @@ const Services = WebexPlugin.extend({
catalog.updateServiceUrls('override', formattedOverrideServices);
}

// if not fedramp, append on the commercialAllowedDomains
if (!fedramp) {
services.allowedDomains = union(services.allowedDomains, COMMERCIAL_ALLOWED_DOMAINS);
}

// Check for allowed host domains.
if (services.allowedDomains) {
// Store the allowed domains as a property of the catalog.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import WebexCore, {
ServiceRegistry,
ServiceState,
ServiceUrl,
serviceConstants,
} from '@webex/webex-core';
import testUsers from '@webex/test-helper-test-users';
import uuid from 'uuid';
Expand Down Expand Up @@ -363,7 +364,9 @@ describe('webex-core', () => {

services.initConfig();

assert.deepEqual(allowedDomains, services._getCatalog().allowedDomains);
const expectedResult = [...allowedDomains, ...serviceConstants.COMMERCIAL_ALLOWED_DOMAINS];

assert.deepEqual(expectedResult, services._getCatalog().allowedDomains);
});
});

Expand Down
23 changes: 16 additions & 7 deletions packages/@webex/webex-core/test/unit/spec/interceptors/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import sinon from 'sinon';
import {browserOnly, nodeOnly} from '@webex/test-helper-mocha';
import Logger from '@webex/plugin-logger';
import MockWebex from '@webex/test-helper-mock-webex';
import {AuthInterceptor, config, Credentials, WebexHttpError, Token} from '@webex/webex-core';
import {
AuthInterceptor,
config,
Credentials,
WebexHttpError,
Token,
serviceConstants,
} from '@webex/webex-core';
import {cloneDeep, merge} from 'lodash';
import Metrics from '@webex/internal-plugin-metrics';

Expand Down Expand Up @@ -122,7 +129,7 @@ describe('webex-core', () => {
hasService: (service) => Object.keys(services).includes(service),
hasAllowedDomains: () => true,
isAllowedDomainUrl: (uri) =>
!!config.services.allowedDomains.find((host) => uri.includes(host)),
!!serviceConstants.COMMERCIAL_ALLOWED_DOMAINS.find((host) => uri.includes(host)),
getServiceFromUrl: (uri) => {
let targetKey;

Expand Down Expand Up @@ -249,7 +256,7 @@ describe('webex-core', () => {
hasService: (service) => Object.keys(services).includes(service),
hasAllowedDomains: () => true,
isAllowedDomainUrl: (uri) =>
!!config.services.allowedDomains.find((host) => uri.includes(host)),
!!serviceConstants.COMMERCIAL_ALLOWED_DOMAINS.find((host) => uri.includes(host)),
validateDomains: true,
};

Expand Down Expand Up @@ -323,7 +330,7 @@ describe('webex-core', () => {
it('resolves to true with an allowed domain uri', () =>
interceptor
.requiresCredentials({
uri: `https://${config.services.allowedDomains[0]}/resource`,
uri: `https://${serviceConstants.COMMERCIAL_ALLOWED_DOMAINS[0]}/resource`,
})
.then((response) => assert.isTrue(response)));

Expand All @@ -339,7 +346,7 @@ describe('webex-core', () => {
const {isAllowedDomainUrl} = webex.internal.services;

const result = isAllowedDomainUrl(
`https://${config.services.allowedDomains[0]}/resource`
`https://${serviceConstants.COMMERCIAL_ALLOWED_DOMAINS[0]}/resource`
);

assert.equal(result, true);
Expand All @@ -350,7 +357,7 @@ describe('webex-core', () => {

return interceptor
.requiresCredentials({
uri: `https://${config.services.allowedDomains[0]}/resource`,
uri: `https://${serviceConstants.COMMERCIAL_ALLOWED_DOMAINS[0]}/resource`,
})
.then((res) => {
assert.equal(res, true);
Expand All @@ -361,7 +368,9 @@ describe('webex-core', () => {
webex.internal.services.waitForService = sinon.stub();
const {waitForService} = webex.internal.services;

waitForService.resolves(`https://${config.services.allowedDomains[0]}/resource`);
waitForService.resolves(
`https://${serviceConstants.COMMERCIAL_ALLOWED_DOMAINS[0]}/resource`
);

return interceptor
.requiresCredentials({
Expand Down
Loading

0 comments on commit 521de20

Please sign in to comment.