-
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.
Merge pull request snyk#1071 from snyk/feat/reachable-vulns-support-f…
…or-maven feat: support maven reachable vulnerabilities for `snyk test`
- Loading branch information
Showing
19 changed files
with
453 additions
and
25 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
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
11 changes: 11 additions & 0 deletions
11
src/lib/errors/feature-not-supported-by-package-manager-error.ts
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,11 @@ | ||
import { CustomError } from './custom-error'; | ||
import { SupportedPackageManagers } from '../package-managers'; | ||
|
||
export class FeatureNotSupportedByPackageManagerError extends CustomError { | ||
constructor(feature: string, packageManager: SupportedPackageManagers) { | ||
super(`Unsupported package manager ${packageManager} for ${feature}.`); | ||
this.code = 422; | ||
|
||
this.userMessage = `'${feature}' is not supported for package manager '${packageManager}'.`; | ||
} | ||
} |
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
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,59 @@ | ||
import * as graphlib from 'graphlib'; | ||
import { CallGraph } from '@snyk/cli-interface/legacy/common'; | ||
|
||
import { | ||
REACHABLE_VULNS_SUPPORTED_PACKAGE_MANAGERS, | ||
SupportedPackageManagers, | ||
} from './package-managers'; | ||
import { isFeatureFlagSupportedForOrg } from './feature-flags'; | ||
import { | ||
AuthFailedError, | ||
FeatureNotSupportedByPackageManagerError, | ||
UnsupportedFeatureFlagError, | ||
} from './errors'; | ||
|
||
const featureFlag = 'reachableVulns'; | ||
|
||
export function serializeCallGraphWithMetrics( | ||
callGraph: CallGraph, | ||
): { | ||
callGraph: any; | ||
nodeCount: number; | ||
edgeCount: number; | ||
} { | ||
return { | ||
callGraph: graphlib.json.write(callGraph), | ||
nodeCount: callGraph.nodeCount(), | ||
edgeCount: callGraph.edgeCount(), | ||
}; | ||
} | ||
|
||
export async function validatePayload( | ||
packageManager: SupportedPackageManagers, | ||
org: any, | ||
): Promise<boolean> { | ||
if (!REACHABLE_VULNS_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) { | ||
throw new FeatureNotSupportedByPackageManagerError( | ||
'Reachable vulns', | ||
packageManager, | ||
); | ||
} | ||
const reachableVulnsSupportedRes = await isFeatureFlagSupportedForOrg( | ||
featureFlag, | ||
org, | ||
); | ||
|
||
if (reachableVulnsSupportedRes.code === 401) { | ||
throw AuthFailedError( | ||
reachableVulnsSupportedRes.error, | ||
reachableVulnsSupportedRes.code, | ||
); | ||
} | ||
if (reachableVulnsSupportedRes.userMessage) { | ||
throw new UnsupportedFeatureFlagError( | ||
featureFlag, | ||
reachableVulnsSupportedRes.userMessage, | ||
); | ||
} | ||
return true; | ||
} |
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,12 @@ | ||
import { Options, TestOptions } from '../types'; | ||
import * as config from '../config'; | ||
import { SupportedPackageManagers } from '../package-managers'; | ||
import * as reachableVulns from '../reachable-vulns'; | ||
|
||
export async function validateOptions(options: Options & TestOptions) { | ||
if (options.reachableVulns) { | ||
const pkgManager = options.packageManager as SupportedPackageManagers; | ||
const org = options.org || config.org; | ||
await reachableVulns.validatePayload(pkgManager, org); | ||
} | ||
} |
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,94 @@ | ||
import * as tap from 'tap'; | ||
import * as cli from '../../src/cli/commands'; | ||
import { fakeServer } from './fake-server'; | ||
|
||
const { test, only } = tap; | ||
(tap as any).runOnly = false; // <- for debug. set to true, and replace a test to only(..) | ||
|
||
const port = (process.env.PORT = process.env.SNYK_PORT = '12345'); | ||
process.env.SNYK_API = 'http://localhost:' + port + '/api/v1'; | ||
process.env.SNYK_HOST = 'http://localhost:' + port; | ||
process.env.LOG_LEVEL = '0'; | ||
const apiKey = '123456789'; | ||
let oldkey; | ||
let oldendpoint; | ||
const server = fakeServer(process.env.SNYK_API, apiKey); | ||
const before = tap.runOnly ? only : test; | ||
const after = tap.runOnly ? only : test; | ||
|
||
// @later: remove this config stuff. | ||
// Was copied straight from ../src/cli-server.js | ||
before('setup', async (t) => { | ||
t.plan(3); | ||
let key = await cli.config('get', 'api'); | ||
oldkey = key; | ||
t.pass('existing user config captured'); | ||
|
||
key = await cli.config('get', 'endpoint'); | ||
oldendpoint = key; | ||
t.pass('existing user endpoint captured'); | ||
|
||
await new Promise((resolve) => { | ||
server.listen(port, resolve); | ||
}); | ||
t.pass('started demo server'); | ||
t.end(); | ||
}); | ||
|
||
// @later: remove this config stuff. | ||
// Was copied straight from ../src/cli-server.js | ||
before('prime config', async (t) => { | ||
await cli.config('set', 'api=' + apiKey); | ||
t.pass('api token set'); | ||
await cli.config('unset', 'endpoint'); | ||
t.pass('endpoint removed'); | ||
t.end(); | ||
}); | ||
|
||
test('test vulnerable project with --reachable-vulns not supported package manager', async (t) => { | ||
try { | ||
await cli.test('gradle', { | ||
reachableVulns: true, | ||
}); | ||
t.fail('expected test to throw exception'); | ||
} catch (err) { | ||
t.equal(err.code, 422, 'should throw exception'); | ||
t.equal( | ||
err.userMessage, | ||
`'Reachable vulns' is not supported for package manager 'npm'.`, | ||
'correct user message', | ||
); | ||
} | ||
}); | ||
|
||
// @later: try and remove this config stuff | ||
// Was copied straight from ../src/cli-server.js | ||
after('teardown', async (t) => { | ||
t.plan(4); | ||
|
||
delete process.env.SNYK_API; | ||
delete process.env.SNYK_HOST; | ||
delete process.env.SNYK_PORT; | ||
t.notOk(process.env.SNYK_PORT, 'fake env values cleared'); | ||
|
||
await new Promise((resolve) => { | ||
server.close(resolve); | ||
}); | ||
t.pass('server shutdown'); | ||
let key = 'set'; | ||
let value = 'api=' + oldkey; | ||
if (!oldkey) { | ||
key = 'unset'; | ||
value = 'api'; | ||
} | ||
await cli.config(key, value); | ||
t.pass('user config restored'); | ||
if (oldendpoint) { | ||
await cli.config('endpoint', oldendpoint); | ||
t.pass('user endpoint restored'); | ||
t.end(); | ||
} else { | ||
t.pass('no endpoint'); | ||
t.end(); | ||
} | ||
}); |
Oops, something went wrong.