Skip to content

Commit

Permalink
Fixes #193, allow full range of auth, without needing to ask for a pa…
Browse files Browse the repository at this point in the history
…ssword
  • Loading branch information
jrburke committed May 28, 2014
1 parent c394bac commit 47a2650
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 94 deletions.
10 changes: 9 additions & 1 deletion lib/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ function github(args, opts) {

//Try to get a token from the user, and retry.
retryWithAuth().then(d.resolve, d.fail);
} else if (response.statusCode === 401) {
githubAuth.fetch({
forceAuthRefresh: true
}).then(function (info) {
options.token = info.token;
github(args, options).then(d.resolve, d.fail);
});
} else if (response.statusCode === 301 ||
response.statusCode === 302) {
//Redirect, try the new location
Expand All @@ -136,7 +143,8 @@ function github(args, opts) {
}

if (options.token) {
req.setHeader('Authorization', 'token ' + options.token);
var basicAuth = new Buffer(options.token + ':x-oauth-basic').toString('base64');
req.setHeader('Authorization', 'Basic ' + basicAuth);
}

req.setHeader('User-Agent', config.userAgent);
Expand Down
115 changes: 22 additions & 93 deletions lib/github/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = (auth = {
name;

//If already have a token, wrap it up.
if (localConfig[configKey]) {
if (localConfig[configKey] && !options.forceAuthRefresh) {
d.resolve(localConfig[configKey]);
return d.promise;
}
Expand All @@ -49,98 +49,27 @@ module.exports = (auth = {
}
}

log('Log in to GitHub to complete action ' +
'(your password is not saved. It is sent over ' +
'SSL to GitHub and converted to an OAuth token)');
v.prompt('GitHub user name:')
.then(function (promptName) {
name = promptName;
return v.promptHidden('GitHub password:');
}).then(function (pw) {
log('\nContacting GitHub...');
var basicAuth = new Buffer(name + ':' + pw)
.toString('base64'),
requestBody = JSON.stringify({
scopes: authConfig.scopes,
note: authConfig.note,
note_url: authConfig.noteUrl
}),
urlParts = url.parse(authConfig.domain + authConfig.authPath),
req;

urlParts.method = 'POST';

req = https.request(urlParts, function (res) {
var body = '',
hasError;

if (res.statusCode === 401) {
v.prompt('Incorrect GitHub user name or password. Retry [y]?')
.then(function (answer) {
answer = answer && answer.toLowerCase();
if (!answer || answer.indexOf('y') === 0) {
d.resolve(auth.fetch(options));
} else {
d.resolve();
}
})
.fail(d);
return;
} else if (res.statusCode !== 201) {
log('GitHub responded with error status: ' +
res.statusCode);
d.resolve();
return;
}

res.setEncoding('utf8');

res.on('data', function (chunk) {
body += chunk;
});

res.on('error', function (err) {
hasError = true;
log('GitHub responded with error: ' + err.toString());
d.resolve();
});

res.on('end', function () {
var config = voloConfig.getLocal();
if (!hasError) {
body = JSON.parse(body);

config[configKey] = {
user: name,
token: body.token,
scopes: authConfig.scopes
};

v.prompt('Save OAuth token for later use [y]?')
.then(function (save) {
save = save && save.toLowerCase();
if (!save || save === 'y' || save === 'yes') {
var saveLocation = voloConfig.saveLocal();
if (saveLocation) {
log('Token saved in ' + saveLocation);
}
}
return config[configKey];
})
.then(d.resolve, d.reject);
}
});

});

req.setHeader('User-Agent', ghConfig.userAgent);
req.setHeader('Authorization', 'Basic ' + basicAuth);
req.setHeader('Content-Type',
'application/json; charset=UTF-8');
req.setHeader('Content-Length', requestBody.length);
req.end(requestBody);

}).fail(d);
log('GitHub access token required to complete action. In a web browesr, go to:');
log('');
log('https://github.com/settings/applications');
log('');
log('and generate a new "Personal access token" for volo. Only "repo" and "public_repo" ' +
'permissions are needed. Paste the generated token below.');

v.prompt('GitHub Personal Access Token:')
.then(function (token) {
var config = voloConfig.getLocal();
config[configKey] = {
token: token
};

var saveLocation = voloConfig.saveLocal();
if (saveLocation) {
log('Token saved in ' + saveLocation);
}

return config[configKey];
}).then(d.resolve, d.reject);

return d.promise;
}
Expand Down

0 comments on commit 47a2650

Please sign in to comment.