You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by fl...@apache.org on 2018/08/30 14:31:06 UTC
[22/50] tinkerpop git commit: Implementation of Sasl authentication.
Implementation of Sasl authentication.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/2a8b4b4f
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/2a8b4b4f
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/2a8b4b4f
Branch: refs/heads/TINKERPOP-1774
Commit: 2a8b4b4ff5cf55b82fe2af8f8390724c6688467f
Parents: 675c077
Author: Matthew Allen <ma...@runbox.com>
Authored: Fri Jul 6 20:49:54 2018 +0100
Committer: Matthew Allen <ma...@runbox.com>
Committed: Thu Aug 23 06:33:51 2018 +0100
----------------------------------------------------------------------
.../lib/driver/authenticator.js | 14 ++++++
.../lib/driver/driver-remote-connection.js | 44 ++++++++-----------
.../lib/driver/sasl-authenticator.js | 45 ++++++++++++++++++++
.../javascript/gremlin-javascript/lib/utils.js | 23 +++++++++-
4 files changed, 99 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2a8b4b4f/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/authenticator.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/authenticator.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/authenticator.js
new file mode 100644
index 0000000..053aecd
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/authenticator.js
@@ -0,0 +1,14 @@
+'use strict';
+
+/** @abstract */
+class Authenticator {
+ constructor(credentials) {
+ this._credentials = credentials;
+ }
+
+ evaluateChallenge(ws, header) {
+ throw new Error("evaluateChallenge should be implemented");
+ }
+}
+
+module.exports = Authenticator;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2a8b4b4f/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index 0f7cedb..153c278 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -22,7 +22,6 @@
*/
'use strict';
-const crypto = require('crypto');
const WebSocket = require('ws');
const util = require('util');
const RemoteConnection = require('./remote-connection').RemoteConnection;
@@ -31,7 +30,8 @@ const serializer = require('../structure/io/graph-serializer');
const responseStatusCode = {
success: 200,
noContent: 204,
- partialContent: 206
+ partialContent: 206,
+ authenticationChallenge: 407,
};
const defaultMimeType = 'application/vnd.gremlin-v2.0+json';
@@ -48,6 +48,7 @@ class DriverRemoteConnection extends RemoteConnection {
* @param {Boolean} [options.rejectUnauthorized] Determines whether to verify or not the server certificate.
* @param {String} [options.traversalSource] The traversal source. Defaults to: 'g'.
* @param {GraphSONWriter} [options.writer] The writer to use.
+ * @param {Authenticator} [options.authenticator] The authentication handler to use.
* @constructor
*/
constructor(url, options) {
@@ -76,7 +77,13 @@ class DriverRemoteConnection extends RemoteConnection {
const mimeType = options.mimeType || defaultMimeType;
this._header = String.fromCharCode(mimeType.length) + mimeType;
this.isOpen = false;
+ this.connectionError = false;
+ this.connectionErrorMessage = '';
this.traversalSource = options.traversalSource || 'g';
+
+ if (options.authenticator) {
+ this._authenticator = options.authenticator;
+ }
}
/**
@@ -102,7 +109,7 @@ class DriverRemoteConnection extends RemoteConnection {
/** @override */
submit(bytecode) {
return this.open().then(() => new Promise((resolve, reject) => {
- const requestId = getUuid();
+ const requestId = utils.getUuid();
this._responseHandlers[requestId] = {
callback: (err, result) => err ? reject(err) : resolve(result),
result: null
@@ -112,12 +119,12 @@ class DriverRemoteConnection extends RemoteConnection {
}));
}
- _getRequest(id, bytecode) {
+ _getRequest(id, bytecode, op, args) {
return ({
'requestId': { '@type': 'g:UUID', '@value': id },
- 'op': 'bytecode',
+ 'op': op || 'bytecode',
'processor': 'traversal',
- 'args': {
+ 'args': args || {
'gremlin': this._writer.adaptObject(bytecode),
'aliases': { 'g': this.traversalSource }
}
@@ -151,7 +158,11 @@ class DriverRemoteConnection extends RemoteConnection {
return;
}
- if (response.status.code >= 400) {
+ if (response.status.code === responseStatusCode.authenticationChallenge && this._authenticator) {
+ this._authenticator.evaluateChallenge(this._ws, this._header);
+ return;
+ }
+ else if (response.status.code >= 400) {
// callback in error
return handler.callback(
new Error(util.format('Server error: %s (%d)', response.status.message, response.status.code)));
@@ -203,25 +214,6 @@ class DriverRemoteConnection extends RemoteConnection {
}
}
-function getUuid() {
- const buffer = crypto.randomBytes(16);
- //clear the version
- buffer[6] &= 0x0f;
- //set the version 4
- buffer[6] |= 0x40;
- //clear the variant
- buffer[8] &= 0x3f;
- //set the IETF variant
- buffer[8] |= 0x80;
- const hex = buffer.toString('hex');
- return (
- hex.substr(0, 8) + '-' +
- hex.substr(8, 4) + '-' +
- hex.substr(12, 4) + '-' +
- hex.substr(16, 4) + '-' +
- hex.substr(20, 12));
-}
-
const bufferFromString = (Int8Array.from !== Buffer.from && Buffer.from) || function newBuffer(text) {
return new Buffer(text, 'utf8');
};
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2a8b4b4f/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/sasl-authenticator.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/sasl-authenticator.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/sasl-authenticator.js
new file mode 100644
index 0000000..1f08b7d
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/sasl-authenticator.js
@@ -0,0 +1,45 @@
+'use strict';
+
+const Authenticator = require('./authenticator');
+const utils = require('../utils');
+
+class SaslAuthenticator extends Authenticator {
+ /**
+ * Creates a new instance of SaslAuthenticator.
+ * @param {Object} [credentials] The authentication credential options.
+ * @param {String} [credentials.username] The user for the authentication response.
+ * @param {String} [credentials.password] The plaintext password for authentication response.
+ * @constructor
+ */
+ constructor(credentials) {
+ super(credentials);
+ }
+
+ evaluateChallenge(ws, header) {
+ const message = bufferFromString(header + JSON.stringify({
+ 'requestId': { '@type': 'g:UUID', '@value': utils.getUuid() },
+ 'op': 'authentication',
+ 'processor': 'traversal',
+ 'args': {
+ 'sasl': this.saslArgument()
+ }
+ }));
+
+ return ws.send(message);
+ }
+
+ saslArgument() {
+ if (this._credentials.username === null || this._credentials.username.length === 0
+ || this._credentials.password === null || this._credentials.password.length === 0 ) {
+ return '';
+ }
+ return new Buffer(`\0${this._credentials.username}\0${this._credentials.password}`).toString('base64');
+ }
+}
+
+
+const bufferFromString = (Int8Array.from !== Buffer.from && Buffer.from) || function newBuffer(text) {
+ return new Buffer(text, 'utf8');
+};
+
+module.exports = SaslAuthenticator;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2a8b4b4f/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
index e3a001c..7abc5fe 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
@@ -23,6 +23,8 @@
*/
'use strict';
+const crypto = require('crypto');
+
exports.toLong = function toLong(value) {
return new Long(value);
};
@@ -32,4 +34,23 @@ const Long = exports.Long = function Long(value) {
throw new TypeError('Ty')
}
this.value = value.toString();
-};
\ No newline at end of file
+};
+
+exports.getUuid = function getUuid() {
+ const buffer = crypto.randomBytes(16);
+ //clear the version
+ buffer[6] &= 0x0f;
+ //set the version 4
+ buffer[6] |= 0x40;
+ //clear the variant
+ buffer[8] &= 0x3f;
+ //set the IETF variant
+ buffer[8] |= 0x80;
+ const hex = buffer.toString('hex');
+ return (
+ hex.substr(0, 8) + '-' +
+ hex.substr(8, 4) + '-' +
+ hex.substr(12, 4) + '-' +
+ hex.substr(16, 4) + '-' +
+ hex.substr(20, 12));
+}
\ No newline at end of file