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 },
+ },
+ });
+};