Skip to content

Commit 85b3f3e

Browse files
committed
Dropped sync mode, made it really async-ish and simpler
1 parent 637fc76 commit 85b3f3e

File tree

5 files changed

+96
-234
lines changed

5 files changed

+96
-234
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,19 @@ var conn_info = {
1515
'user' : 'the_user_name' ,
1616
};
1717

18-
// --- sync ----
19-
conn_info.password = pgPass(conn_info);
20-
// connect to postgresql server
2118

2219
// ---- async ----
2320
pgPass(conn_info, function(pass){
24-
conn_info.password = pass;
21+
conn_info.password = pass;
2522
// connect to postgresql server
2623
});
2724
```
2825

2926
## Description
3027

31-
This module tries to read the `~/.pgpass ` file (or the equivalent for windows systems). If the environment variable `PGPASSFILE` is set, this file is used instead. If everything goes right, the password from said file is returned (in syn mode) or given to the callback (async mode); if the password cannot be read `null` is returned or passed to the callback.
28+
This module tries to read the `~/.pgpass` file (or the equivalent for windows systems). If the environment variable `PGPASSFILE` is set, this file is used instead. If everything goes right, the password from said file is to the callback; if the password cannot be read `undefined` is passed to the callback.
3229

33-
Cases where `null` is returned:
30+
Cases where `undefined` is returned:
3431

3532
- the environment variable `PGPASSWORD` is set
3633
- the file cannot be read (wrong permissions, no such file, ...)

lib/helper.js

Lines changed: 37 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function isRegFile(mode) {
2121

2222
var fieldNames = [ 'host', 'port', 'database', 'user', 'password' ];
2323
var nrOfFields = fieldNames.length;
24+
var passKey = fieldNames[ fieldNames.length -1 ];
2425

2526

2627
function warn() {
@@ -87,47 +88,54 @@ module.exports.usePgPass = function(stats, fname) {
8788
return true;
8889
};
8990

90-
module.exports.read = function(input, cb) {
91-
var isStream = (input instanceof Stream && input.readable === true);
92-
var isBuffer = Buffer.isBuffer(input);
93-
var results = [];
9491

95-
var func = isStream ? handleStream : (
96-
isBuffer ? handleBuffer : handleString
97-
);
92+
var matcher = module.exports.match = function(connInfo, entry) {
93+
return fieldNames.slice(0, -1).reduce(function(prev, field, idx){
94+
if (idx == 1) {
95+
// the port
96+
if ( Number( connInfo[field] || defaultPort ) === Number( entry[field] ) ) {
97+
return prev && true;
98+
}
99+
}
100+
return prev && (
101+
entry[field] === '*' ||
102+
entry[field] === connInfo[field]
103+
);
104+
}, true);
105+
};
98106

99-
return func(input);
100107

101-
function addLine(line) {
108+
module.exports.getPassword = function(connInfo, stream, cb) {
109+
var pass;
110+
var lineStream = stream.pipe(new Split());
111+
112+
function onLine(line) {
102113
var entry = parseLine(line);
103-
if (entry && isValidEntry(entry)) {
104-
results.push(entry);
114+
if (entry && isValidEntry(entry) && matcher(connInfo, entry)) {
115+
pass = entry[passKey];
116+
lineStream.end(); // -> calles onEnd(), but pass is set now
105117
}
106118
}
107119

108-
function handleString(str) {
109-
str.split(/\n\r?/).forEach(addLine);
110-
if (typeof cb === 'function') {
111-
cb(null, results);
112-
}
113-
return results;
114-
}
120+
var onEnd = function() {
121+
cb(pass);
122+
};
115123

116-
function handleBuffer(buf) {
117-
return handleString(buf.toString());
118-
}
124+
var onErr = function(err) {
125+
warn('WARNING: error on reading file: %s', err);
126+
cb(undefined);
127+
};
119128

120-
function handleStream(stream) {
121-
stream.pipe(new Split())
122-
.on('data', addLine)
123-
.on('end', cb.bind(null, null, results))
124-
.on('error', cb.bind(null, null, results)) // ignore errors
125-
;
129+
stream.on('error', onErr);
130+
lineStream
131+
.on('data', onLine)
132+
.on('end', onEnd)
133+
.on('error', onErr)
134+
;
126135

127-
return null;
128-
}
129136
};
130137

138+
131139
var parseLine = module.exports.parseLine = function(line) {
132140
if (line.length < 11 || line.match(/^\s+#/)) {
133141
return null;
@@ -220,40 +228,3 @@ var isValidEntry = module.exports.isValidEntry = function(entry){
220228
return true;
221229
};
222230

223-
224-
module.exports.getPassword = function(input, creds, add){
225-
input = input || {};
226-
creds = creds || [];
227-
228-
var matches = function(cred){
229-
return fieldNames.slice(0, -1).reduce(function(prev, field, idx){
230-
if (idx == 1) {
231-
// the port
232-
if ( Number( input[field] || defaultPort ) === Number( cred[field] ) ) {
233-
return prev && true;
234-
}
235-
}
236-
return prev && (
237-
cred[field] === '*' ||
238-
cred[field] === input[field]
239-
);
240-
}, true);
241-
};
242-
243-
for (var credIdx = 0 ; credIdx < creds.length ; credIdx += 1) {
244-
var cred = creds[credIdx];
245-
246-
if (matches(cred)) {
247-
var name = fieldNames[ nrOfFields - 1 ];
248-
var pass = cred[ name ];
249-
250-
if (add) {
251-
input[ name ] = pass;
252-
}
253-
254-
return pass;
255-
}
256-
}
257-
258-
return undefined;
259-
};

lib/index.js

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,19 @@ var path = require('path')
55
, helper = require( path.join(__dirname, 'helper.js') )
66
;
77

8-
function getPassword(file, conn, cb){
8+
9+
module.exports.warnTo = helper.warnTo;
10+
11+
module.exports = function(connInfo, cb) {
12+
var file = helper.getFileName();
13+
914
fs.stat(file, function(err, stat){
1015
if (err || !helper.usePgPass(stat, file)) {
1116
return cb(undefined);
1217
}
1318

1419
var st = fs.createReadStream(file);
1520

16-
return helper.read(st, function(err, results){
17-
return cb(helper.getPassword(conn, results));
18-
});
21+
helper.getPassword(connInfo, st, cb);
1922
});
20-
}
21-
22-
function getPasswordSync(file, conn){
23-
var stat;
24-
try {
25-
stat = fs.statSync(file);
26-
} catch (x) {
27-
return undefined;
28-
}
29-
30-
if (!helper.usePgPass(stat, file)) {
31-
return undefined;
32-
}
33-
34-
var content = fs.readFileSync(file);
35-
var results = helper.read(content);
36-
37-
return helper.getPassword(conn, results);
38-
}
39-
40-
41-
module.exports.warnTo = helper.warnTo;
42-
43-
module.exports = function(conn, cb) {
44-
var file = helper.getFileName();
45-
46-
if ('function' === typeof cb) {
47-
return getPassword(file, conn, cb);
48-
} else {
49-
return getPasswordSync(file, conn);
50-
}
51-
};
23+
};

test/helper.js

Lines changed: 30 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -225,120 +225,60 @@ describe('#isValidEntry()', function(){
225225
});
226226

227227

228-
describe('#read()', function(){
229-
var fileContent = [
230-
'somehost:112233:somedb:someuser:somepass' ,
231-
'otherhost:4:otherdb:other\\:user:' ,
232-
'thirdhost:5:thirddb:thirduser:thirdpass'
233-
].join('\n');
234-
235-
it('should handle a string', function(){
236-
var resReturn, resCb;
237-
238-
resReturn = helper.read(fileContent, function(err, res){
239-
resCb = res;
240-
});
241-
242-
assert.notEqual( resReturn, [] );
243-
assert.deepEqual( resReturn, resCb );
244-
});
245-
246-
it('should handle a buffer', function(){
247-
var resReturn, resCb;
248-
var buf = new Buffer(fileContent);
249-
250-
resReturn = helper.read(buf, function(err, res){
251-
resCb = res;
252-
});
253-
254-
assert.notEqual( resReturn, [] );
255-
assert.deepEqual( resReturn, resCb );
256-
});
257-
258-
it('should handle a stream', function(done){
259-
var resReturn, resCb;
260-
var stream = new Stream().queue(fileContent).end();
261-
262-
resReturn = helper.read(stream, function(err, res){
263-
assert.equal(err, null);
264-
assert.notEqual(res, null);
265-
assert.notEqual(res, []);
266-
done();
267-
});
268-
269-
assert.equal( resReturn, null );
270-
});
271-
272-
});
273228

274229

275230
describe('#getPassword()', function(){
276-
var creds = [
277-
{
278-
'host' : 'host1' ,
279-
'port' : '100' ,
280-
'database' : 'database1' ,
281-
'user' : 'user1' ,
282-
'password' : 'thepassword1'
283-
} , {
284-
'host' : '*' ,
285-
'port' : '*' ,
286-
'database' : 'database2' ,
287-
'user' : '*' ,
288-
'password' : 'thepassword2'
289-
}
290-
];
231+
var creds =
232+
'host1:100:database1:user1:thepassword1' + '\n' +
233+
'*:*:database2:*:thepassword2' + '\n'
234+
;
235+
291236
var conn1 = {
292237
'host' : 'host1' ,
293238
'port' : 100 ,
294239
'database' : 'database1' ,
295240
'user' : 'user1'
296241
};
297-
var conn2 = {
298-
'host' : 'host2' ,
299-
'database' : 'database2' ,
300-
'user' : 'user2'
301-
};
302242
var conn3 = {
303243
'host' : 'host3' ,
304244
'database' : 'database3' ,
305245
'user' : 'user3'
306246
};
307247

308-
it('should return a password', function(){
309-
var ret;
310248

311-
ret = helper.getPassword(conn1, creds);
312-
assert.equal(ret, creds[0].password);
249+
it('should not get password for non-matching conn_info', function(done){
250+
var st = new Stream();
313251

314-
ret = helper.getPassword(conn2, creds);
315-
assert.equal(ret, creds[1].password);
316-
});
252+
helper.getPassword(conn3, st, function(pass){
253+
assert.deepEqual(pass, undefined);
254+
done();
255+
});
317256

318-
it('should not return and not fill in a password', function(){
319-
var ret;
257+
st.write(creds);
258+
st.end();
259+
});
320260

321-
ret = helper.getPassword(conn3, undefined, true);
322-
assert(!ret);
323-
assert(!conn3.password);
261+
it('should get password for matching conn_info', function(done){
262+
var st = new Stream();
324263

325-
ret = helper.getPassword(conn1, undefined, true);
326-
assert(!ret);
327-
assert(!conn1.password);
264+
helper.getPassword(conn1, st, function(pass){
265+
assert.notDeepEqual(pass, undefined);
266+
done();
267+
});
328268

329-
ret = helper.getPassword({}, creds, true);
330-
assert(!ret);
269+
st.write(creds);
270+
st.end();
331271
});
332272

333-
it('should return and fill in a password', function(){
334-
var ret;
273+
it('should ignore no password on any error', function(done){
274+
var st = new Stream();
335275

336-
ret = helper.getPassword(conn1, creds, true);
337-
assert.equal(ret, creds[0].password);
338-
assert.equal(conn1.password, creds[0].password);
276+
helper.getPassword({}, st, function(pass){
277+
assert.deepEqual(pass, undefined);
278+
done();
279+
});
339280

340-
ret = helper.getPassword(conn2, creds, true);
341-
assert.equal(ret, creds[1].password);
342-
assert.equal(conn2.password, creds[1].password);
281+
st.emit('error', new Error('just some error'));
282+
st.end();
343283
});
344284
});

0 commit comments

Comments
 (0)