Skip to content

Commit

Permalink
feat(medic/cht-couch2pg#137) - Strip security information when insert…
Browse files Browse the repository at this point in the history
…ing user documents
  • Loading branch information
kennsippell authored Jun 23, 2023
2 parents c093b28 + c65602b commit 174bb19
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 10 deletions.
22 changes: 14 additions & 8 deletions lib/importer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ var sanitise = function(string) {
return string.replace(/(\\+u0000)|\u0000/g, ''); // eslint-disable-line
};

const removeSecurityDetails = function(doc) {
const isUserDoc = doc && doc.type === 'user' && doc._id.startsWith('org.couchdb.user:');
if (isUserDoc) {
delete doc.password_scheme;
delete doc.derived_key;
delete doc.salt;
}
};

var deleteDocuments = function(db, postgresTable, docIdsToDelete) {
if (docIdsToDelete && docIdsToDelete.length) {
var query = format(DELETE_STMT, postgresTable, docIdsToDelete);
Expand Down Expand Up @@ -95,16 +104,13 @@ var loadAndStoreDocs = function(db, couchdb, concurrentDocLimit, docsToDownload,
}).then(function(couchDbResult) {
log.debug('Inserting ' + couchDbResult.rows.length + ' results into postgresql');

var insertSql = format(
INSERT_DOC_STMT,
postgresTable,
couchDbResult.rows.map(function(row) {
return [row.doc];
})
);
const docsToInsert = couchDbResult.rows.map(function(row) {
removeSecurityDetails(row.doc);
return [row.doc];
});

let insertSql = format(INSERT_DOC_STMT, postgresTable, docsToInsert);
insertSql = sanitise(insertSql);

return db.query(insertSql);
}).then(function() {
return loadAndStoreDocs(db, couchdb, concurrentDocLimit, docsToDownload, postgresTable);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "couch2pg",
"version": "0.7.0",
"version": "0.7.1",
"bin": {
"couch2pg": "./cli.js"
},
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/importer.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,50 @@ describe('importer', function() {
allDocs.args[0][0].keys.should.deep.equal(['123']);
});
});

it('removes security information from user docs', function () {
const userDocId = 'org.couchdb.user:test_user';
sinon.stub(db, 'one').resolves(STORED_SEQ);
sinon.stub(couchdb, 'changes')
.onCall(0).resolves({
results: [
{ id: userDocId, seq: 1 },
],
last_seq: 2
})
.onCall(1).resolves({
results: [],
last_seq: 2
});
const query = sinon.stub(db, 'query').resolves();
const allDocs = sinon.stub(couchdb, 'allDocs');
allDocs.resolves({
rows: [{
id: userDocId,
doc: {
_id: userDocId,
_rev: '3-37b63ea82ca461bfa6b3d4cfda7dbf88',
name: 'test_user',
type: 'user',
roles: ['chw'],
facility_id: 'c0ca5e2b-508a-4ba7-b934-f6e4751223bf',
password_scheme: 'pbkdf2',
iterations: 10,
derived_key: '5ccbfab2b06a67450c3fbcda9fc0f4e27e5ba957',
salt: '713733ce185df96773d6bd4a860749ee'
}
}],
});

return importer(db, couchdb).importBatch().then(function() {
allDocs.args[0][0].keys.should.deep.equal([userDocId]);
query.args[1][0].should.include(`INSERT INTO couchdb (doc) VALUES ('{"_id":"${userDocId}"`);
query.args[1][0].should.include(`"roles":["chw"],`);
query.args[1][0].should.not.include('derived_key');
query.args[1][0].should.not.include('salt');
query.args[1][0].should.not.include('password_scheme');
});
})
});

describe('IO failure propagation:', function() {
Expand Down

0 comments on commit 174bb19

Please sign in to comment.