Skip to content

Commit 07baedb

Browse files
author
Stefan-Gabriel Muscalu
committed
Merge remote-tracking branch 'upstream/1.0' into fix/known_hosts-fingerprint-duplication-error/1.0
# Conflicts: # src/v1/internal/ch-node.js
2 parents b1aa869 + 4d19e69 commit 07baedb

File tree

4 files changed

+78
-68
lines changed

4 files changed

+78
-68
lines changed

neokit

Submodule neokit updated 1 file

src/v1/internal/ch-node.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,29 @@ function userHome() {
3636
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
3737
}
3838

39+
function mkFullPath(pathToCreate) {
40+
try {
41+
fs.mkdirSync( pathToCreate );
42+
} catch (e) {
43+
if(e.code === 'ENOENT') {
44+
// Create parent dir
45+
mkFullPath(path.dirname( pathToCreate ));
46+
// And now try again
47+
mkFullPath( pathToCreate );
48+
return;
49+
}
50+
if (e.code === 'EEXIST') {
51+
return;
52+
}
53+
throw e;
54+
}
55+
}
56+
3957
function loadFingerprint( serverId, knownHostsPath, cb ) {
40-
if( !fs.existsSync( knownHostsPath )) {
41-
cb(null);
42-
return;
58+
try {
59+
fs.accessSync( knownHostsPath );
60+
} catch(e) {
61+
return cb(null)
4362
}
4463
let found = false;
4564
require('readline').createInterface({
@@ -64,11 +83,13 @@ function storeFingerprint( serverId, knownHostsPath, fingerprint, cb ) {
6483
return cb(null);
6584
}
6685

67-
// we make the line as appended
68-
// ( 1 is more efficient to store than true because true is an oddball )
69-
_lockFingerprintFromAppending[serverId] = 1;
86+
// If file doesn't exist, create full path to it
87+
try {
88+
fs.accessSync(knownHostsPath);
89+
} catch (_) {
90+
mkFullPath(path.dirname(knownHostsPath));
91+
}
7092

71-
// we append to file
7293
fs.appendFile(knownHostsPath, serverId + " " + fingerprint + EOL, "utf8", (err) => {
7394
delete _lockFingerprintFromAppending[serverId];
7495
if (err) {

test/internal/tls.test.js

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
var NodeChannel = require('../../lib/v1/internal/ch-node.js');
2020
var neo4j = require("../../lib/v1");
2121
var fs = require("fs");
22+
var path = require('path');
2223
var hasFeature = require("../../lib/v1/internal/features");
2324

2425
describe('trust-signed-certificates', function() {
@@ -76,6 +77,44 @@ describe('trust-on-first-use', function() {
7677

7778
var driver;
7879

80+
it("should create known_hosts file including full path if it doesn't exist", function(done) {
81+
// Assuming we only run this test on NodeJS with TOFU support
82+
if( !hasFeature("trust_on_first_use") ) {
83+
done();
84+
return;
85+
}
86+
87+
// Given
88+
// Non existing directory
89+
var knownHostsDir = path.join("build", "hosts");
90+
var knownHostsPath = path.join(knownHostsDir, "known_hosts");
91+
try {
92+
fs.unlinkSync(knownHostsPath);
93+
} catch (_) { }
94+
try {
95+
fs.rmdirSync(knownHostsDir);
96+
} catch (_) { }
97+
98+
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
99+
encrypted: true,
100+
trust: "TRUST_ON_FIRST_USE",
101+
knownHosts: knownHostsPath
102+
});
103+
104+
// When
105+
driver.session().run( "RETURN 1").then( function() {
106+
// Then we get to here.
107+
// And then the known_hosts file should have been created
108+
expect( function() { fs.accessSync(knownHostsPath) }).not.toThrow()
109+
done();
110+
}).catch( function(){
111+
// Just here to gracefully exit test on failure so we don't get timeouts
112+
// when done() isn't called.
113+
expect( 'this' ).toBe( 'to never happen' );
114+
done();
115+
});
116+
});
117+
79118
it('should not throw an error if the host file contains two host duplicates', function(done) {
80119
'use strict';
81120
// Assuming we only run this test on NodeJS with TOFU support
@@ -141,60 +180,7 @@ describe('trust-on-first-use', function() {
141180
done();
142181
});
143182
});
144-
145-
it('should not duplicate fingerprint entries', function(done) {
146-
// Assuming we only run this test on NodeJS with TOFU support
147-
if( !hasFeature("trust_on_first_use") ) {
148-
done();
149-
return;
150-
}
151-
152-
// Given
153-
var knownHostsPath = "build/known_hosts";
154-
if( fs.existsSync(knownHostsPath) ) {
155-
fs.unlinkSync(knownHostsPath);
156-
}
157-
fs.writeFileSync(knownHostsPath, '');
158-
159-
driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
160-
encrypted: true,
161-
trust: "TRUST_ON_FIRST_USE",
162-
knownHosts: knownHostsPath
163-
});
164-
165-
// When
166-
driver.session();
167-
driver.session();
168-
169-
setTimeout(function() {
170-
var lines = {};
171-
fs.readFileSync(knownHostsPath, 'utf8')
172-
.split('\n')
173-
.filter(function(line) {
174-
return !! (line.trim());
175-
})
176-
.forEach(function(line) {
177-
if (!lines[line]) {
178-
lines[line] = 0;
179-
}
180-
lines[line]++;
181-
});
182-
183-
var duplicatedLines = Object
184-
.keys(lines)
185-
.map(function(line) {
186-
return lines[line];
187-
})
188-
.filter(function(count) {
189-
return count > 1;
190-
})
191-
.length;
192-
193-
expect( duplicatedLines ).toBe( 0 );
194-
done();
195-
}, 1000);
196-
});
197-
183+
198184
it('should should give helpful error if database cert does not match stored certificate', function(done) {
199185
// Assuming we only run this test on NodeJS with TOFU support
200186
if( !hasFeature("trust_on_first_use") ) {

test/v1/tck/steps/authsteps.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ module.exports = function () {
5656
this.Then(/^a `Protocol Error` is raised$/, function () {
5757
var message = this.err.fields[0].message
5858
var code = this.err.fields[0].code
59-
var expectedStartOfMessage = 'No operations allowed until you send an INIT message successfully.'
60-
var expectedCode = 'Neo.ClientError.Request.Invalid'
6159

62-
if (message.indexOf(expectedStartOfMessage) != 0) {
63-
throw new Error("Wrong error messsage. Expected: '" + expectedStartOfMessage + "'. Got: '" + message + "'");
64-
}
60+
// TODO uncomment this once we fix the init sync
61+
//var expectedStartOfMessage = 'No operations allowed until you send an INIT message successfully.'
62+
var expectedCode = 'Neo.ClientError';
63+
64+
// TODO uncomment this once we fix the init sync
65+
//if (message.indexOf(expectedStartOfMessage) != 0) {
66+
// throw new Error("Wrong error messsage. Expected: '" + expectedStartOfMessage + "'. Got: '" + message + "'");
67+
//}
6568

66-
if ( code != expectedCode) {
69+
if (code.indexOf(expectedCode) != 0) {
6770
throw new Error("Wrong error code. Expected: '" + expectedCode + "'. Got: '" + code + "'");
6871
}
6972
});

0 commit comments

Comments
 (0)