UNPKG

oidc-lib

Version:

A library for creating OIDC Service Providers

334 lines (276 loc) 10.6 kB
module.exports = { initialize: initialize, createOrUpdateDocument: createOrUpdateDocument, getDocument: getDocument, deleteDocument: deleteDocument, queryCollection: queryCollection }; var pk = null; const HttpStatusCodes = { NOTFOUND: 404 }; async function initialize(pkInput, contentModuleName, provider){ try{ pk = pkInput; var dbInfo = { provider: provider, contentModuleName: contentModuleName }; validateModuleConfig(contentModuleName); pk.util.log_debug("Initializing FileDb in content module " + contentModuleName); dbInfo.contentModuleName = contentModuleName; dbInfo.databaseName = getDbModuleConfigProperty(contentModuleName, 'databaseName'); dbInfo.databasePath = './oidc_lib_data/filedb_data/' + dbInfo.databaseName; dbInfo.collections = {}; var collections = getDbModuleConfigProperty(contentModuleName, 'collections'); for (var collectionName in collections){ var collectionInfo = { definition: { "id": collectionName }, path: dbInfo.databasePath + '/' + collectionName }; dbInfo.collections[collectionName] = collectionInfo; } pk.dbs[contentModuleName] = dbInfo; getDatabase(dbInfo); for (var key in dbInfo.collections){ getCollection(dbInfo, key); } return dbInfo; } catch(err){ } }; function getDatabase (dbInfo) { var db_path_segs = dbInfo.databasePath.split('/'); var root = db_path_segs[0]; for (var count=1; count < db_path_segs.length; count++){ root += '/' + db_path_segs[count]; if (!pk.fs.existsSync(root)){ pk.fs.mkdirSync(root); } } return; }; function getCollection(dbInfo, collectionName) { var collectionInfo = dbInfo.collections[collectionName]; if (!pk.fs.existsSync(collectionInfo.path)){ pk.fs.mkdirSync(collectionInfo.path); } } function getDocument(dbInfo, collectionName, id) { return new Promise((resolve, reject) => { let documentPath = createIdPath(dbInfo, collectionName, id); if (!documentPath){ reject('configuration error creating IdPath in getDocument'); } var document; pk.fs.readFile(documentPath, "utf8", (err, data) => { if (err){ if (err.code === 'ENOENT'){ reject(err); } else{ pk.util.log_detail('unexpected error checking existance of record in file_db', err); reject('unexpected error id createOrUpdateDocument'); } return; } document = db_parse(data); resolve (db_export(document)); }); }); }; function createDocument(dbInfo, collectionName, document){ return new Promise((resolve, reject) => { let documentPath = createIdPath(dbInfo, collectionName, document.id); if (!documentPath){ reject('configuration error creating IdPath in createDocument'); } if (pk.fs.exists(documentPath)){ reject('Document already exists'); } else { var storedDoc = db_import(document); pk.fs.writeFileSync(documentPath, db_stringify(storedDoc)); resolve(document); } }); }; function createOrUpdateDocument(dbInfo, collectionName, document, options){ return new Promise((resolve, reject) => { if (!document.id){ reject("undefined document id needed for file_db") } let documentPath = createIdPath(dbInfo, collectionName, document.id); if (!documentPath){ reject('configuration error creating IdPath in updateOrCreateDocument'); } pk.fs.stat(documentPath, (err, stats) => { if (err && err.code !== 'ENOENT'){ pk.util.log_detail('unexpected error checking existance of record in file_db', err); reject('unexpected error id createOrUpdateDocument'); } if (stats){ var previousdocument = db_export(db_parse(pk.fs.readFileSync(documentPath, "utf8"))); if (options && options.updateLogic !== undefined){ pk.util.log_debug('Document existed - update logic being applied'); options.updateLogic(previousdocument, document); } } var storedDoc = db_import(document); pk.fs.writeFile(documentPath, db_stringify(storedDoc), (err) => { if (err){ var message = 'Error writing file-based db record to collection ' + collection; pk.util.log_detail(message, err); reject(message); return; } resolve(document); }); }); }); } function queryCollection(dbInfo, collectionName, queryDictionaryOrString, indexName) { if (typeof queryDictionaryOrString !== 'object'){ if (queryDictionaryOrString === undefined){ queryDictionaryOrString = {}; } else { throw 'file_db queryCollection currently does not support string queries'; } } var queryResponse = []; var collectionInfo = dbInfo.collections[collectionName]; var collection = readCollection(collectionInfo.path); return new Promise((resolve, reject) => { for (var id in collection){ var entry = db_export(collection[id]); var matchFound = true; for (var attribute in queryDictionaryOrString){ if (entry[attribute] !== queryDictionaryOrString[attribute]){ matchFound = false; break; } } if (matchFound){ queryResponse.push(entry); } } resolve(queryResponse); }); } function readCollection(collectionPath) { var collection = {}; var fnames = pk.fs.readdirSync(collectionPath); for (var i=0; i < fnames.length; i++){ var id = fnames[i]; var content = pk.fs.readFileSync(collectionPath + '/' + id, 'utf8'); collection[id] = db_parse(content); } return collection; } function deleteDocument(dbInfo, collectionName, id) { let documentPath = createIdPath(dbInfo, collectionName, id); if (!documentPath){ pk.util.log_error('configuration error creating IdPath in deleteDocument'); return; } pk.fs.unlink(documentPath, function (err) { if (!err){ pk.util.log_detail('filedb deleteDocument succeeded'); } }); }; function cleanup(pkInput, contentModuleName) { pk = pkInput; validateModuleConfig(contentModuleName); var endpoint = getDbModuleConfigProperty(contentModuleName, 'endpoint'); var primaryKey = getDbModuleConfigProperty(contentModuleName, 'primaryKey'); var client = new documentDbDocumentClient(endpoint, { "masterKey": primaryKey }); var databaseName = getDbModuleConfigProperty(contentModuleName, 'databaseName'); var databaseDefinition = { id: databaseName }; var databaseUrl = `dbs/${databaseDefinition.id}`; pk.util.log_debug(`Cleaning up by deleting database ${databaseDefinition.id}`); return new Promise((resolve, reject) => { client.deleteDatabase(databaseUrl, (err) => { if (err) reject(err) else resolve(null); }); }); } function validateModuleConfig(contentModuleName){ if (contentModuleName !== 'sts'){ if (pk.util.config.content_modules[contentModuleName].db === undefined){ throw "The " + contentModuleName + " content module does not define a db property in claimer_config"; } } } function getDbModuleConfigProperty(contentModuleName, propertyName, throwOnUndefined) { if (throwOnUndefined === undefined || throwOnUndefined === true){ var dbInstance = pk.util.config.sts.db; if (contentModuleName !== 'sts'){ dbInstance = pk.util.config.content_modules[contentModuleName].db; } if (dbInstance[propertyName] === undefined){ throw "Configuration property " + propertyName + " is not defined in content module " + contentModuleName; } } return dbInstance[propertyName]; } function isDbDisabled(pkInput, contentModuleName){ pk = pkInput; var isDisabled = getDbModuleConfigProperty('disabled', false, contentModuleName); if (isDisabled === undefined){ isDisabled = false; } return isDisabled; } function isset(param){ if (typeof param !== 'object'){ if (param === undefined || param === null || param.length === 0) return false; } return true; } function createIdPath(dbInfo, collectionName, id){ var collectionInfo = dbInfo.collections[collectionName]; if (!collectionInfo){ pk.util.log_error('FileDB attempt to access undefined collection: ' + collectionName); return; } return collectionInfo.path + '/' + encodeId(id); } function encodeId(id){ return encodeURIComponent(id); } function db_parse(data){ return JSON.parse(data); } function db_stringify(obj){ return JSON.stringify(obj); } function db_export(document){ var external = {}; for (var attr in document) { if (document.hasOwnProperty(attr)){ var val = document[attr]; if (attr === 'id'){ val = decodeURIComponent(val); } external[attr] = val; } } return external; } function db_import(external){ var document = {}; for (var attr in external) { if (external.hasOwnProperty(attr)){ var val = external[attr]; if (attr === 'id'){ val = encodeURIComponent(val); } document[attr] = val; } } return document; }