Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Snyk/snyk
Browse files Browse the repository at this point in the history
  • Loading branch information
oakfang committed Jul 7, 2016
2 parents 2aa8fea + c559172 commit 56ef30b
Show file tree
Hide file tree
Showing 31 changed files with 2,037 additions and 124 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "stage-3"]
}
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/test
config.*.json
!config.default.json
tmp
19 changes: 8 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ cache:
- node_modules
notifications:
email: false
services:
- mongodb
- redis-server
addons:
postgresql: "9.4"
node_js:
- '5'
- '4'
- '0.10'
matrix:
include:
- node_js: "5"
- node_js: "4"
- node_js: "0.10"
env: BABEL=true
script: "[[ $BABEL == true ]] && npm run test:babel || npm test"
before_install:
- npm i -g npm@^2.0.0
before_script:
- npm prune
- psql -c 'create database test;' -U postgres
- psql -U postgres -c "create extension hstore" test
after_success:
- npm run travis-coverage
- python scripts/travis_after_all.py
- export $(cat .to_export_back)
- npm run semantic-release
Expand Down
10 changes: 8 additions & 2 deletions cli/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ function args(processargv) {
if (alias[arg] !== undefined) {
acc[alias[arg]] = true;
} else if (arg.indexOf('-') === 0) {
acc[arg.slice(1)] = true;
arg = arg.slice(1);
if (arg.indexOf('=') === -1) {
acc[arg] = true;
} else {
var parts = arg.split('=');
acc[parts.shift()] = parts.join('=');
}
} else {
acc[arg] = true;
}
Expand Down Expand Up @@ -105,4 +111,4 @@ function args(processargv) {
command: command,
options: argv,
};
}
}
15 changes: 12 additions & 3 deletions cli/commands/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ function resetAttempts() {
attemptsLeft = 30;
}

function githubAuth() {
function githubAuth(via) {
var token = uuid.v4(); // generate a random key
var redirects = {
wizard: '/authenticated',
};

var url = authUrl + '/login?token=' + token;

// validate that via comes from our code, and not from user & CLI
// currently only support `wizard` but we'll add more over time.
if (redirects[via]) {
url += '&redirectUri=' + new Buffer(redirects[via]).toString('base64');
}

var msg =
'\nNow redirecting you to our github auth page, go ahead and log in,\n' +
'and once the auth is complete, return to this prompt and you\'ll\n' +
Expand Down Expand Up @@ -131,14 +140,14 @@ function verifyAPI(api) {
});
}

function auth(api) {
function auth(api, via) {
var promise;
resetAttempts();
if (api) {
// user is manually setting the API token on the CLI - let's trust them
promise = verifyAPI(api);
} else {
promise = githubAuth();
promise = githubAuth(via);
}

return promise.then(function (data) {
Expand Down
2 changes: 1 addition & 1 deletion cli/commands/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ function help(item) {
.catch(function () {
return '"' + item + '" help can\'t be found';
});
}
}
6 changes: 5 additions & 1 deletion cli/commands/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ function monitor(path, options) {
.then(snyk.monitor.bind(null, path, { method: 'cli' }))
.then(function (res) {
var endpoint = url.parse(config.API);
endpoint.pathname = '/monitor/' + res.id;
var leader = '';
if (res.org) {
leader = '/org/' + res.org;
}
endpoint.pathname = leader + '/monitor/' + res.id;
return 'Captured a snapshot of this project\'s dependencies.\n' +
'Explore this snapshot at ' + url.format(endpoint) + '\n' +
'Notifications about newly disclosed vulnerabilities\n' +
Expand Down
41 changes: 26 additions & 15 deletions cli/commands/protect/prompts.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var protect = require('../../../lib/protect');
var moduleToObject = require('snyk-module');
var undefsafe = require('undefsafe');
var config = require('../../../lib/config');
var snyk = require('../../../lib/');
var snykPolicy = require('snyk-policy');

// via http://stackoverflow.com/a/4760279/22617
function sort(prop) {
Expand Down Expand Up @@ -220,7 +220,14 @@ function getPatchPrompts(vulns, policy) {
main: true,
id: acc[last].id + '-' + i,
count: 1,
upgrades: [acc[last].from],
upgrades: [{
// all this information is used when the user selects group patch
// specifically: in ./tasks.js~42
from: acc[last].from,
filename: acc[last].__filename,
patches: acc[last].patches,
version: acc[last].version,
},],
patch: true,
};

Expand All @@ -237,10 +244,6 @@ function getPatchPrompts(vulns, policy) {
offset++;
}

// if (acc[last].grouped.affected.full.indexOf(curr.version) === -1) {
// acc[last].grouped.affected.full += ' / ' + curr.version;
// }

acc[last].grouped.count++;

curr.grouped = {
Expand All @@ -249,12 +252,17 @@ function getPatchPrompts(vulns, policy) {
};

// add the from path to our group upgrades if we don't have it already
var have = !!acc[last].grouped.upgrades.filter(function (from) {
return from.join(' ') === curr.from.join(' ');
var have = !!acc[last].grouped.upgrades.filter(function (upgrade) {
return upgrade.from.join(' ') === curr.from.join(' ');
}).length;

if (!have) {
acc[last].grouped.upgrades.push(curr.from);
acc[last].grouped.upgrades.push({
from: curr.from,
filename: curr.__filename,
patches: curr.patches,
version: curr.version,
});
} else {
if (!acc[last].grouped.includes) {
acc[last].grouped.includes = [];
Expand Down Expand Up @@ -282,7 +290,7 @@ function getPatchPrompts(vulns, policy) {
});

// console.log(res.map(_ => _.grouped));
var prompts = generatePrompt(res, policy);
var prompts = generatePrompt(res, policy, 'p');


return prompts;
Expand Down Expand Up @@ -310,7 +318,7 @@ function getIgnorePrompts(vulns, policy) {
return true;
});

var prompts = generatePrompt(res, policy);
var prompts = generatePrompt(res, policy, 'i');

return prompts;

Expand Down Expand Up @@ -394,7 +402,7 @@ function getUpdatePrompts(vulns, policy) {
return !!curr.upgradePath[1];
});

var prompts = generatePrompt(res, policy);
var prompts = generatePrompt(res, policy, 'u');

return prompts;
}
Expand Down Expand Up @@ -425,7 +433,10 @@ function canBeUpgraded(vuln) {
});
}

function generatePrompt(vulns, policy) {
function generatePrompt(vulns, policy, prefix) {
if (!prefix) {
prefix = '';
}
if (!vulns) {
vulns = []; // being defensive, but maybe we should throw an error?
}
Expand Down Expand Up @@ -464,7 +475,7 @@ function generatePrompt(vulns, policy) {
var prompts = vulns.map(function (vuln, i) {
var id = vuln.id || ('node-' + vuln.name + '@' + vuln.below);

id += '-' + i;
id += '-' + prefix + i;

// make complete copies of the actions, otherwise we'll mutate the object
var ignore = _.cloneDeep(ignoreAction);
Expand Down Expand Up @@ -744,7 +755,7 @@ function generatePrompt(vulns, policy) {
prompts = prompts.reduce(function (acc, curr) {
acc.push(curr);
// console.log(curr.choices[0].value.vuln);
var rule = snyk.policy.getByVuln(policy, curr.choices[0].value.vuln);
var rule = snykPolicy.getByVuln(policy, curr.choices[0].value.vuln);
var defaultAnswer = 'None given';
if (rule && rule.type === 'ignore') {
defaultAnswer = rule.reason;
Expand Down
7 changes: 5 additions & 2 deletions cli/commands/protect/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ function answersToTasks(answers) {

var additional = vuln.grouped.upgrades.slice(1);

additional.forEach(function (from) {
additional.forEach(function (upgrade) {
var copy = _.cloneDeep(vuln);
copy.from = from;
copy.from = upgrade.from;
copy.__filename = upgrade.filename;
copy.patches = upgrade.patches;
copy.version = upgrade.version;
tasks[task].push(copy);
});
}
Expand Down
40 changes: 31 additions & 9 deletions cli/commands/protect/wizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ function wizard(options) {
// with an empty object
if (error.code === 'ENOENT') {
options.newPolicy = true;
return {};
return snyk.policy.create();
}

throw error;
}).then(function (policy) {
return auth.isAuthed().then(function (authed) {
analytics.add('inline-auth', !authed);
if (!authed) {
return auth();
return auth(null, 'wizard');
}
}).then(function () {
var intro = __dirname + '/../../../help/wizard-intro.txt';
Expand Down Expand Up @@ -212,7 +212,7 @@ function processAnswers(answers, policy, options) {
throw e;
}

return snyk.policy.save(policy, cwd, spinner).then(function () {
return policy.save(cwd, spinner).then(function () {
// don't do this during testing
if (isCI || process.env.TAP) {
return Promise.resolve();
Expand Down Expand Up @@ -318,22 +318,40 @@ function processAnswers(answers, policy, options) {
if (answers['misc-add-test'] || answers['misc-add-protect']) {
debug('updating %s', packageFile);

var installPromise;
var lbl = 'Updating package.json...';

if (undefsafe(pkg, 'dependencies.snyk') ||
undefsafe(pkg, 'peerDependencies.snyk') ||
undefsafe(pkg, 'optionalDependencies.snyk')) {
installPromise = Promise.resolve(); // do nothing
// nothing to do as the user already has Snyk
// TODO decide whether we should update the version being used
// and how do we reconcile if the global install is older
// than the local version?
} else {
installPromise = npm.bind(null, 'install', 'snyk', live, cwd);
if (answers['misc-add-protect']) {
if (!pkg.dependencies) {
pkg.dependencies = {};
}
pkg.dependencies.snyk = snykVersion;
lbl = 'Adding Snyk to production dependencies (used by snyk protect)';

// but also check if we should remove it from devDependencies
if (undefsafe(pkg, 'devDependencies.snyk')) {
delete pkg.devDependencies.snyk;
}
} else if (!undefsafe(pkg, 'devDependencies.snyk')) {
if (!pkg.devDependencies) {
pkg.devDependencies = {};
}
lbl = 'Adding Snyk to devDependencies (used by npm test)';
pkg.devDependencies.snyk = snykVersion;
}
}

// finally, add snyk as a dependency because they'll need it
// during the protect process
var lbl = 'Updating package.json...';
return spinner(lbl)
.then(fs.writeFile(packageFile, JSON.stringify(pkg, '', 2)))
.then(installPromise)
.then(spinner.clear(lbl));
}
})
Expand Down Expand Up @@ -366,7 +384,11 @@ function processAnswers(answers, policy, options) {
})
.then(function (monitorRes) {
var endpoint = url.parse(config.API);
endpoint.pathname = '/monitor/' + monitorRes.id;
var leader = '';
if (monitorRes.org) {
leader = '/org/' + monitorRes.org;
}
endpoint.pathname = leader + '/monitor/' + monitorRes.id;

return (options.newPolicy ?
// if it's a newly created file
Expand Down
12 changes: 9 additions & 3 deletions cli/commands/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function test(path, options) {
}
summary += ' for known vulnerabilities';

if (res.ok) {
if (res.ok && res.vulnerabilities.length === 0) {
summary = chalk.green('✓ ' + summary + ', no vulnerable paths found.');

if (!isCI) {
Expand Down Expand Up @@ -122,7 +122,7 @@ function test(path, options) {

var sep = '\n\n';

var error = new Error(res.vulnerabilities.map(function (vuln) {
var body = res.vulnerabilities.map(function (vuln) {
var res = '';
var name = vuln.name + '@' + vuln.version;
var severity = vuln.severity[0].toUpperCase() + vuln.severity.slice(1);
Expand Down Expand Up @@ -184,7 +184,13 @@ function test(path, options) {
' dependency.');
}
return res;
}).join(sep) + sep + summary);
}).join(sep) + sep + summary;

if (res.ok) {
return body;
}

var error = new Error(body);

error.code = 'VULNS';
throw error;
Expand Down
3 changes: 2 additions & 1 deletion help/config.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
config:

Configuration:

$ snyk config [command] [key[=value]]

Expand Down
3 changes: 3 additions & 0 deletions help/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Commands:
Options:

--dev .............. include devDependencies (defaults to production only).
--org=<org-name> ... associate a snapshot (or wizard snapshot) with a specific
organisation. For more help run `snyk --help=orgs`.
--ignore-policy .... ignores and resets the state of your policy file.
--trust-policies ... applies and uses ignore rules from your dependencies's
Snyk policies, otherwise ignore policies are only
Expand All @@ -35,6 +37,7 @@ Examples:

$ snyk test
$ snyk test ionic@1.6.5
$ snyk monitor --org=my-team

Pro tip: use `snyk test` in your test scripts, if a vulnerability is
found, the process will exit with a non-zero exit code.
Expand Down

0 comments on commit 56ef30b

Please sign in to comment.