Improve authentication handling (#908)

This commit is contained in:
Tomas Della Vedova
2019-07-18 10:33:11 +02:00
committed by GitHub
parent 24e674469e
commit 0ebbd71e9a
12 changed files with 602 additions and 142 deletions

View File

@ -20,6 +20,7 @@
'use strict'
const { EventEmitter } = require('events')
const { URL } = require('url')
const debug = require('debug')('elasticsearch')
const Transport = require('./lib/Transport')
const Connection = require('./lib/Connection')
@ -43,7 +44,12 @@ class Client extends EventEmitter {
// the url is a string divided by two '$', the first is the cloud url
// the second the elasticsearch instance, the third the kibana instance
const cloudUrls = Buffer.from(id.split(':')[1], 'base64').toString().split('$')
opts.node = `https://${username}:${password}@${cloudUrls[1]}.${cloudUrls[0]}`
// TODO: remove username and password here in 8
if (username && password) {
opts.auth = Object.assign({}, opts.auth, { username, password })
}
opts.node = `https://${cloudUrls[1]}.${cloudUrls[0]}`
// Cloud has better performances with compression enabled
// see https://github.com/elastic/elasticsearch-py/pull/704.
@ -61,6 +67,11 @@ class Client extends EventEmitter {
throw new ConfigurationError('Missing node(s) option')
}
const checkAuth = getAuth(opts.node || opts.nodes)
if (checkAuth && checkAuth.username && checkAuth.password) {
opts.auth = Object.assign({}, opts.auth, { username: checkAuth.username, password: checkAuth.password })
}
const options = Object.assign({}, {
Connection,
ConnectionPool,
@ -82,7 +93,8 @@ class Client extends EventEmitter {
nodeFilter: null,
nodeSelector: 'round-robin',
generateRequestId: null,
name: 'elasticsearch-js'
name: 'elasticsearch-js',
auth: null
}, opts)
this[kInitialOptions] = options
@ -96,6 +108,7 @@ class Client extends EventEmitter {
ssl: options.ssl,
agent: options.agent,
Connection: options.Connection,
auth: options.auth,
emit: this.emit.bind(this),
sniffEnabled: options.sniffInterval !== false ||
options.sniffOnStart !== false ||
@ -209,6 +222,41 @@ class Client extends EventEmitter {
}
}
function getAuth (node) {
if (Array.isArray(node)) {
for (const url of node) {
const auth = getUsernameAndPassword(url)
if (auth.username !== '' && auth.password !== '') {
return auth
}
}
return null
}
const auth = getUsernameAndPassword(node)
if (auth.username !== '' && auth.password !== '') {
return auth
}
return null
function getUsernameAndPassword (node) {
if (typeof node === 'string') {
const { username, password } = new URL(node)
return {
username: decodeURIComponent(username),
password: decodeURIComponent(password)
}
} else if (node.url instanceof URL) {
return {
username: decodeURIComponent(node.url.username),
password: decodeURIComponent(node.url.password)
}
}
}
}
const events = {
RESPONSE: 'response',
REQUEST: 'request',