forked from Netflix-Skunkworks/stethoscope-app
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support cross-platform applications validation (Netflix-Skunkworks#172)
* Fix failing Accessible component test Previous failures were being swallowed by ReactDOM.render. Consideration should be given to the suggestion to add an Error Boundary to this component test: https://reactjs.org/docs/error-boundaries.html * Add "platform" to ApplicationRequirement Improve type comment hints * Pull-up os filtering to Security.applications * Implement linux app kmd source * Improve tests for security applications resolvers * Implement LinuxSecurity.applications resolver * Coerce Debian package versions into semver This is a bit of a Procrustean bed... Debian package version strings are all over the place, and long-predate notions of "semantic versioning". Still, we should make a best-effort to match on the leading version numbers of available packages, and document this caveat for the user. * Clarify platform filtering behavior
- Loading branch information
1 parent
60d03b5
commit 473180d
Showing
21 changed files
with
612 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import kmd from './kmd' | ||
import semver from './patchedSemver' | ||
|
||
// Filter applications array (specified in validation policy), return only those | ||
// elements appropriate for the running OS platform/version | ||
export default async function applicationPlatformFilter(applications = [], context, platform, version) { | ||
const osPlatform = platform || process.platform | ||
const osVersion = version || (await kmd('os', context)).system.version | ||
|
||
return applications.filter((app) => { | ||
if (!app.platform || app.platform.all) { | ||
return true | ||
} | ||
const platformStringRequirement = app.platform[osPlatform] | ||
return platformStringRequirement && semver.satisfies(osVersion, platformStringRequirement) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import applicationPlatformFilter from './applicationPlatformFilter' | ||
|
||
// validation policy fixture for application checks | ||
const apps = [ | ||
{ | ||
name: "CommonApp", | ||
description: "App found on all platforms", | ||
}, | ||
{ | ||
name: "CommonAppWithExplicitAll", | ||
description: "App found on all platforms", | ||
platform: { | ||
all: true | ||
} | ||
}, | ||
{ | ||
name: "PoorlyFilteredApp", | ||
description: "Doesn't apply to any platforms", | ||
platform: { | ||
all: false | ||
} | ||
}, | ||
{ | ||
name: "Terminal", | ||
description: "Terminal.app, present with all MacOS versions", | ||
platform: { | ||
darwin: ">=10.0.0" | ||
} | ||
}, | ||
{ | ||
name: "TV", | ||
description: "TV.app, introduced with MacOS Catalina", | ||
platform: { | ||
darwin: ">=10.15.0" | ||
}, | ||
paths: { | ||
darwin: "/System/Applications" | ||
} | ||
}, | ||
{ | ||
name: "bash", | ||
description: "Bourne Again Shell", | ||
platform: { | ||
linux: ">=12.04.0" | ||
} | ||
}, | ||
{ | ||
name: "Notepad.exe", | ||
description: "Default Win32 Editor", | ||
platform: { | ||
win32: ">=10.0.0" | ||
} | ||
} | ||
] | ||
|
||
describe('applicationPlatformFilter', () => { | ||
it('should return three apps for MacOS Sierra', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'darwin', '10.12.1') | ||
expect(filteredApps.length).toEqual(3) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
expect(filteredApps[2].name).toEqual('Terminal') | ||
}) | ||
|
||
it('should return four apps for MacOS Catalina', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'darwin', '10.15') | ||
expect(filteredApps.length).toEqual(4) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
expect(filteredApps[2].name).toEqual('Terminal') | ||
expect(filteredApps[3].name).toEqual('TV') | ||
}) | ||
|
||
it('should return three apps for Ubuntu Xenial ', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'linux', '16.04') | ||
expect(filteredApps.length).toEqual(3) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
expect(filteredApps[2].name).toEqual('bash') | ||
}) | ||
|
||
it('should return two apps for Ubuntu Hardy ', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'linux', '8.04') | ||
expect(filteredApps.length).toEqual(2) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
}) | ||
|
||
it('should return three apps for Windows 10', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'win32', '10.0') | ||
expect(filteredApps.length).toEqual(3) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
expect(filteredApps[2].name).toEqual('Notepad.exe') | ||
}) | ||
|
||
it('should return two apps for Windows 7', async () => { | ||
const filteredApps = await applicationPlatformFilter(apps, {}, 'win32', '6.1') | ||
expect(filteredApps.length).toEqual(2) | ||
expect(filteredApps[0].name).toEqual('CommonApp') | ||
expect(filteredApps[1].name).toEqual('CommonAppWithExplicitAll') | ||
}) | ||
|
||
it('should not return PoorlyFilteredApp', async () => { | ||
const macApps = await applicationPlatformFilter(apps, {}, 'darwin', '10.12') | ||
const linApps = await applicationPlatformFilter(apps, {}, 'linux', '8.04') | ||
const winApps = await applicationPlatformFilter(apps, {}, 'win32', '6.1') | ||
expect(macApps.some(app => app.name == 'PoorlyFilteredApp')).toEqual(false) | ||
expect(linApps.some(app => app.name == 'PoorlyFilteredApp')).toEqual(false) | ||
expect(winApps.some(app => app.name == 'PoorlyFilteredApp')).toEqual(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default function sanitizeDebianVersionString(version) { | ||
return version | ||
.replace(/^\d+:/, '') // trim leading epoch numbers | ||
.replace(/[^\d.].*$/, '') // trim trailing debian-revision strings | ||
.replace(/(\d+\.\d+\.\d+).*/, '$1') // trim remaining upstream-version to a semver | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import sanitizeDebianVersionString from './sanitizeDebianVersionString' | ||
|
||
describe('sanitizeDebianVersionString', () => { | ||
|
||
it('should not change semver-compatible versions', () => { | ||
const sanitized = sanitizeDebianVersionString('1.2.3') | ||
expect(sanitized).toEqual('1.2.3') | ||
}) | ||
|
||
it('should remove leading epochs', () => { | ||
const sanitized = sanitizeDebianVersionString('2:1.0.0') | ||
expect(sanitized).toEqual('1.0.0') | ||
}) | ||
|
||
it('should remove trailing debian revisions', () => { | ||
expect(sanitizeDebianVersionString('1:13.3.0-2build1~18.04.1')).toEqual('13.3.0') | ||
expect(sanitizeDebianVersionString('2:8.39-9')).toEqual('8.39') | ||
expect(sanitizeDebianVersionString('2:8.39-9')).toEqual('8.39') | ||
expect(sanitizeDebianVersionString('3.28.0.2-1ubuntu1.18.04.1')).toEqual('3.28.0') // NOTE: lossy match | ||
expect(sanitizeDebianVersionString('1.1.24+nmu5ubuntu1')).toEqual('1.1.24') | ||
expect(sanitizeDebianVersionString('1:1.2.11.dfsg-0ubuntu2')).toEqual('1.2.11') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.