diff options
author | Kat Marchán <kzm@sykosomatic.org> | 2017-01-06 05:06:26 +0300 |
---|---|---|
committer | C J Silverio <ceejceej@gmail.com> | 2017-02-10 02:37:51 +0300 |
commit | 95f51570337413497ed72d3e66ecf5ee2c165698 (patch) | |
tree | a1cdc0fbc2638072640ff008d0dd5618665f85ee /lib/auth | |
parent | 36541eccdfabbacceab87107a5ccef1d376c72a4 (diff) |
adduser: add oauth and saml support
PR-URL: https://github.com/npm/npm/pull/13389
Credit: @zkat
Reviewed-By: @iarna
Diffstat (limited to 'lib/auth')
-rw-r--r-- | lib/auth/oauth.js | 7 | ||||
-rw-r--r-- | lib/auth/saml.js | 7 | ||||
-rw-r--r-- | lib/auth/sso.js | 59 |
3 files changed, 73 insertions, 0 deletions
diff --git a/lib/auth/oauth.js b/lib/auth/oauth.js new file mode 100644 index 000000000..1cb3ffec6 --- /dev/null +++ b/lib/auth/oauth.js @@ -0,0 +1,7 @@ +var ssoAuth = require('./sso') +var npm = require('../npm') + +module.exports.login = function login () { + npm.config.set('sso-type', 'oauth') + ssoAuth.login.apply(this, arguments) +} diff --git a/lib/auth/saml.js b/lib/auth/saml.js new file mode 100644 index 000000000..ae92ea5bb --- /dev/null +++ b/lib/auth/saml.js @@ -0,0 +1,7 @@ +var ssoAuth = require('./sso') +var npm = require('../npm') + +module.exports.login = function login () { + npm.config.set('sso-type', 'saml') + ssoAuth.login.apply(this, arguments) +} diff --git a/lib/auth/sso.js b/lib/auth/sso.js new file mode 100644 index 000000000..faffe2fa5 --- /dev/null +++ b/lib/auth/sso.js @@ -0,0 +1,59 @@ +var log = require('npmlog') +var npm = require('../npm.js') +var output = require('../utils/output') +var opener = require('opener') + +module.exports.login = function login (creds, registry, scope, cb) { + var ssoType = npm.config.get('sso-type') + if (!ssoType) { return cb(new Error('Missing option: sso-type')) } + + var params = { + // We're reusing the legacy login endpoint, so we need some dummy + // stuff here to pass validation. They're never used. + auth: { + username: 'npm_' + ssoType + '_auth_dummy_user', + password: 'placeholder', + email: 'support@npmjs.com', + authType: ssoType + } + } + npm.registry.adduser(registry, params, function (er, doc) { + if (er) return cb(er) + if (!doc || !doc.token) return cb(new Error('no SSO token returned')) + if (!doc.sso) return cb(new Error('no SSO URL returned by services')) + + output('If your browser doesn\'t open, visit ' + + doc.sso + + ' to complete authentication') + opener(doc.sso, { command: npm.config.get('browser') }, function () { + pollForSession(registry, doc.token, function (err, username) { + if (err) return cb(err) + + log.info('adduser', 'Authorized user %s', username) + var scopeMessage = scope ? ' to scope ' + scope : '' + output('Logged in as %s%s on %s.', username, scopeMessage, registry) + + cb(null, { token: doc.token }) + }) + }) + }) +} + +function pollForSession (registry, token, cb) { + log.info('adduser', 'Polling for validated SSO session') + npm.registry.whoami(registry, { + auth: { + token: token + } + }, function (er, username) { + if (er && er.statusCode !== 401) { + cb(er) + } else if (!username) { + setTimeout(function () { + pollForSession(registry, token, cb) + }, npm.config.get('sso-poll-frequency')) + } else { + cb(null, username) + } + }) +} |