diff --git a/package.json b/package.json index 1abfd21..5efb727 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,8 @@ "qscloud-app": "src/qscloud/qscloud-app-nr.js", "qscloud-license": "src/qscloud/qscloud-license-nr.js", "qscloud-reload": "src/qscloud/qscloud-reload-nr.js", - "qscloud-reload-status": "src/qscloud/qscloud-reload-status-nr.js" + "qscloud-reload-status": "src/qscloud/qscloud-reload-status-nr.js", + "qscloud-user": "src/qscloud/qscloud-user-nr.js" } } } diff --git a/src/lib/cloud/user.js b/src/lib/cloud/user.js new file mode 100644 index 0000000..92522b4 --- /dev/null +++ b/src/lib/cloud/user.js @@ -0,0 +1,32 @@ +/* eslint-disable no-await-in-loop */ + +// Function to get all users and their associated metadata +// Parameters: +// node: node object +// qlik: authentication object +// +// Return +// Success: An array of user objects +// Failure: false +async function getUsers(node, qlik) { + let allItems = []; + try { + const items = await qlik.users.getUsers({ limit: 100 }); + + // eslint-disable-next-line no-restricted-syntax + for await (const item of items.pagination) { + allItems.push(item); + } + } catch (error) { + node.log(`Error getting users: ${error}`); + allItems = false; + } + + // Return the spaces' metadata + return allItems; +} + +// Make the function available to other files +module.exports = { + getUsers, +}; diff --git a/src/qscloud/qscloud-user-nr.html b/src/qscloud/qscloud-user-nr.html new file mode 100644 index 0000000..da87051 --- /dev/null +++ b/src/qscloud/qscloud-user-nr.html @@ -0,0 +1,71 @@ + + + + + diff --git a/src/qscloud/qscloud-user-nr.js b/src/qscloud/qscloud-user-nr.js new file mode 100644 index 0000000..91325d5 --- /dev/null +++ b/src/qscloud/qscloud-user-nr.js @@ -0,0 +1,83 @@ +/* eslint-disable no-await-in-loop */ +const { authenticate } = require('../lib/cloud/auth'); +const { getUsers } = require('../lib/cloud/user'); + +// eslint-disable-next-line func-names +module.exports = function (RED) { + function QlikSenseCloudUser(config) { + RED.nodes.createNode(this, config); + const node = this; + + // Get data from node configuration + node.tenant = RED.nodes.getNode(config.tenant); + node.op = config.op || 'r'; + + node.on('input', async (msg, send, done) => { + try { + const outMsg = { + payload: {}, + }; + + // Get auth object + const { auth, qlik } = await authenticate(node, done); + + if (!auth) { + // Error when authenticating + node.status({ fill: 'red', shape: 'ring', text: 'error authenticating' }); + done('Error authenticating'); + return false; + } + + // Which operation to perform? + if (node.op === 'c') { + // Create users + } else if (node.op === 'r') { + // Read users + node.log('Getting users from Qlik Sense Cloud...'); + node.status({ fill: 'yellow', shape: 'dot', text: 'getting users' }); + + // Add app arrays to out message + outMsg.payload.user = []; + + // Get user information from Qlik Sense Cloud + const users = await getUsers(node, qlik); + + // Add users to out message + users.forEach((user) => { + outMsg.payload.user.push(user); + }); + + // Log success + node.log(`Found ${outMsg.payload.user.length} matching users on Qlik Sense Cloud.`); + node.status({ fill: 'green', shape: 'dot', text: 'users retrieved' }); + } else if (node.op === 'u') { + // Update users + } else if (node.op === 'd') { + // Delete users + } else { + // Invalid operation. Log error and return + node.status({ fill: 'red', shape: 'ring', text: 'invalid operation' }); + node.log(`Invalid operation: ${node.op}`); + done(`Invalid operation: ${node.op}`); + return false; + } + + // Send message to output 1 + send(outMsg); + + done(); + } catch (err) { + node.error(err); + done(err); + } + + return true; + }); + } + + RED.nodes.registerType('qscloud-user', QlikSenseCloudUser, { + defaults: { + tenant: { value: '', type: 'qscloud-tenant', required: true }, + }, + }); +};