diff --git a/README.md b/README.md index 69cd5a37..a70a73a0 100644 --- a/README.md +++ b/README.md @@ -570,6 +570,7 @@ The API is structured into sub modules. You may require sub modules directly, e. const sfcc_code = require('sfcc-ci').code; const sfcc_instance = require('sfcc-ci').instance; const sfcc_job = require('sfcc-ci').job; + const sfcc_user = require('sfcc-ci').user; const sfcc_webdav = require('sfcc-ci').webdav; ``` @@ -584,8 +585,18 @@ The following APIs are available (assuming `sfcc` refers to `require('sfcc-ci')` sfcc.instance.upload(instance, file, token, options, callback); sfcc.instance.import(instance, file_name, token, callback); sfcc.job.run(instance, job_id, job_params, token, callback); - sfcc.job.status(instance, job_id, job_execution_id, token, callback); - sfcc.webdav.upload(instance, path, file, token, options, callback); + sfcc.user.create(org, user, mail, firstName, lastName, token).then(result => ...).catch(err => ...); + sfcc.user.list(org, role, login, count, sortBy, token).then(result => ...).catch(err => ...); + sfcc.user.update(login, changes, token).then(result => ...).catch(err => ...); + sfcc.user.grant(login, role, scope, token).then(result => ...).catch(err => ...); + sfcc.user.revoke(login, role, scope, token).then(result => ...).catch(err => ...); + sfcc.user.delete(login, purge, token).then(result => ...).catch(err => ...); + sfcc.user.createLocal(instance, login, user, token).then(result => ...).catch(err => ...); + sfcc.user.searchLocal(instance, login, query, role, sortBy, count, start, token).then(result => ...).catch(err => ...); + sfcc.user.updateLocal(instance, login, changes, token).then(result => ...).catch(err => ...); + sfcc.user.grantLocal(instance, login, role, token).then(result => ...).catch(err => ...); + sfcc.user.revokeLocal(instance, login, role, token).then(result => ...).catch(err => ...); + sfcc.user.deleteLocal(instance, login, token).then(result => ...).catch(err => ...); ``` ### Authentication ### @@ -785,6 +796,195 @@ callback | (Function) | Callback function executed as a result. The err *** +### User ### + +APIs available in `require('sfcc').user`: + +`create(org, user, mail, firstName, lastName, token)` + +Creates a new user into Account Manager + +Param | Type | Description +------------- | ------------| -------------------------------- +org | (String) | The org ID where to create the user +user | (Object) | The user object with all the required data in it +mail | (String) | The email of the user +firstName | (String) | The firstname of the user +lastName | (String) | The lastname of the user +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the newly created user object. + +*** + +`list(org, role, login, count, sortBy, token)` + +Lists all users eligible to manage from the Account Manager, based on the given filters (if any provided) + +Param | Type | Description +------------- | ------------| -------------------------------- +org | (String) | The org ID or null, if all users should be retrieved +role | (String) | The role or null, if all users should be retrieved +login | (String) | The login or null, if all users should be retrieved +count | (Number) | The max count of list items +sortBy | (String) | (Optional) field to sort the list of users by +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the results array. + +*** + +`update(login, changes, token)` + +Update a user into Account Manager + +Param | Type | Description +------------- | ------------| -------------------------------- +login | (String) | The login of the user to update +changes | (Object) | The changes to the user details +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the updated user. + +*** + +`grant(login, role, scope, token)` + +Grant a role to a user into Account Manager + +Param | Type | Description +------------- | ------------| -------------------------------- +login | (String) | The login (email) of the user +role | (String) | The role to grant +scope | (String) | The scope of the role to revoke +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the changed user. + +*** + +`revoke(login, role, scope, token)` + +Revoke a role to a user from Account Manager + +Param | Type | Description +------------- | ------------| -------------------------------- +login | (String) | The login (email) of the user +role | (String) | The role to grant +scope | (String) | The scope of the role to revoke +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the changed user. + +*** + +`delete(login, purge, token)` + +Delete a user from Account Manager + +Param | Type | Description +------------- | ------------| -------------------------------- +login | (String) | The user to delete +purge | (Boolean) | Whether to purge the user completely +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is a boolean value that confirms if the user has been deleted or not. + +*** + +`createLocal(instance, login, user, token)` + +Creates a new local user on an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to create the user on +login | (String) | The user to delete +user | (Object) | The user details +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the created user. + +*** + +`searchLocal(instance, login, query, role, sortBy, count, start, token)` + +Search for local users on an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to create the user on +login | (String) | The login or null, if all users should be retrieved +query | (String) | The query to search users for +role | (String) | The role to search users for +sortBy | (String) | (Optional) field to sort users by +count | (Number) | (Optional) number of items per page +start | (Number) | (Optional) zero-based index of the first search hit to include +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the results of the search. + +*** + +`updateLocal(instance, login, changes, token)` + +Update a local user on an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to update the user on +login | (String) | The login of the local user to update +changes | (Object) | The changes to the user details +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the updated user. + +*** + +`grantLocal(instance, login, role, token)` + +Grant a role to a local user on an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to apply the role on the user on +login | (String) | The login of the local user to grant +role | (String) | The role to grant +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the changed user. + +*** + +`revokeLocal(instance, login, role, token)` + +Revoke a role from a local user on an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to apply the role on the user on +login | (String) | The login of the local user to revoke +role | (String) | The role to revoke +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is the changed user. + +*** + +`deleteLocal(instance, login, token)` + +Delete a local user from an instance + +Param | Type | Description +------------- | ------------| -------------------------------- +instance | (String) | The instance to delete the user on +login | (String) | The login of the local user to delete +token | (String) | The Oauth token to use use for authentication + +**Returns:** (Promise) The [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with its `resolve` or `reject` methods called respectively with the `result` or the `error`. The `result` variable here is a boolean value that confirms if the user has been deleted or not. + +*** + ### WebDAV ### APIs available in `require('sfcc').webdav`: diff --git a/index.js b/index.js index c8a49bbf..0d7aa3e0 100755 --- a/index.js +++ b/index.js @@ -10,4 +10,5 @@ exports.cartridge = require('./lib/cartridge').api; exports.code = require('./lib/code').api; exports.instance = require('./lib/instance').api; exports.job = require('./lib/job').api; +exports.user = require('./lib/user').api; exports.webdav = require('./lib/webdav').api; \ No newline at end of file diff --git a/lib/org.js b/lib/org.js index f0eced80..6d26d96b 100644 --- a/lib/org.js +++ b/lib/org.js @@ -63,12 +63,13 @@ function getOptions(path, token, method) { * Retrieves detals of an org * * @param {String} org the name of the org + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the org are available as arguments to the callback function */ -function getOrg(org, callback) { +function getOrg(org, token, callback) { // build the request options - var options = getOptions(API_BASE + '/organizations/search/findByName?startsWith=' + org + '&ignoreCase=false', - auth.getToken(), 'GET'); + var options = getOptions(API_BASE + '/organizations/search/findByName?startsWith=' + encodeURIComponent(org) + '&ignoreCase=false', + token || auth.getToken(), 'GET'); // do the request request(options, function (err, res, body) { @@ -160,7 +161,7 @@ module.exports.cli = { list : function(orgId, asJson, sortBy) { // get details of a single org if org was passed if ( typeof(orgId) !== 'undefined' && orgId !== null ) { - getOrg(orgId, function(err, org) { + getOrg(orgId, undefined, function(err, org) { if (err) { console.error(err.message); return; diff --git a/lib/user.js b/lib/user.js index 7c45a0af..abb5e207 100644 --- a/lib/user.js +++ b/lib/user.js @@ -14,8 +14,8 @@ var libOrg = require('./org'); const API_BASE = '/dw/rest/v1'; const USER_LIST_PAGE_SIZE = 25; -const USER_ALLOWED_READ_PROPERTIES = [ 'id', 'userState', 'roles', 'roleTenantFilter', 'primaryOrganization', 'mail', - 'firstName', 'lastName', 'displayName', 'organizations' ]; +const USER_ALLOWED_READ_PROPERTIES = [ 'id', 'userState', 'roles', 'roleTenantFilter', 'preferredLocale', + 'preferredlocale', 'primaryOrganization', 'mail', 'firstName', 'lastName', 'displayName', 'organizations' ]; const ROLE_NAMES_MAP = { 'bm-admin' : 'ECOM_ADMIN', 'bm-user' : 'ECOM_USER' }; const ROLE_NAMES_MAP_REVERSE = { 'ECOM_ADMIN' : 'bm-admin', 'ECOM_USER' : 'bm-user' }; @@ -104,11 +104,12 @@ function getOptions(path, token, method) { * Retrieves details of a user. * * @param {String} login the login of the user + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the user are available as arguments to the callback function */ -function getUser(login, callback) { +function getUser(login, token, callback) { // build the request options - var options = getOptions(API_BASE + '/users/search/findByLogin/?login=' + login, auth.getToken(), 'GET'); + var options = getOptions(API_BASE + '/users/search/findByLogin/?login=' + login, token || auth.getToken(), 'GET'); // do the request request(options, function (err, res, body) { @@ -201,9 +202,10 @@ function toInternalUser(user) { * @param {String} org the org to return users from * @param {String} role the role to narrow users to * @param {Number} count the max count of items in the list + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error, the result and the list of users of the current page are available as arguments to the callback function */ -function getUsers(org, role, count, callback) { +function getUsers(org, role, count, token, callback) { // the page size var size = USER_LIST_PAGE_SIZE if ( count ) { @@ -222,7 +224,7 @@ function getUsers(org, role, count, callback) { } // build the request options - var options = getOptions(API_BASE + endpoint, auth.getToken(), 'GET'); + var options = getOptions(API_BASE + endpoint, token || auth.getToken(), 'GET'); // do the request request(options, function (err, res, body) { @@ -246,11 +248,12 @@ function getUsers(org, role, count, callback) { * * @param {String} orgID the org id to create the user in * @param {Object} user the user details + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the created user are available as arguments to the callback function */ -function createUser(orgID, user, callback) { +function createUser(orgID, user, token, callback) { // build the request options - var options = getOptions(API_BASE + '/users', auth.getToken(), 'POST'); + var options = getOptions(API_BASE + '/users', token || auth.getToken(), 'POST'); // update with default roles if (typeof(user['roles']) === 'undefined') { @@ -296,11 +299,12 @@ function createUser(orgID, user, callback) { * * @param {Object} user the user to update * @param {Object} changes the changes to make to the user + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the updated user are available as arguments to the callback function */ -function updateUser(user, changes, callback) { +function updateUser(user, changes, token, callback) { // build the request options - var options = getOptions(API_BASE + '/users/' + user['id'], auth.getToken(), 'PUT'); + var options = getOptions(API_BASE + '/users/' + user['id'], token || auth.getToken(), 'PUT'); // merge changes with user var updatedUser = Object.assign(user, changes); @@ -345,13 +349,14 @@ function updateUser(user, changes, callback) { * * @param {Object} user the user to delete * @param {Boolean} purge flag, whether to purge the user completely, false by default + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the user are available as arguments to the callback function */ -function deleteUser(user, purge, callback) { +function deleteUser(user, purge, token, callback) { // for purging we fire a full DELETE request if (purge) { // build the request options - var options = getOptions(API_BASE + '/users/' + user['id'], auth.getToken(), 'DELETE'); + var options = getOptions(API_BASE + '/users/' + user['id'], token || auth.getToken(), 'DELETE'); // do the request request(options, function (err, res, body) { @@ -425,9 +430,10 @@ function deleteUser(user, purge, callback) { * @param {String} instance the instance to create the user in * @param {String} login the login of the user * @param {Object} user the user details + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the created user are available as arguments to the callback function */ -function createLocalUser(instance, login, user, callback) { +function createLocalUser(instance, login, user, token, callback) { // error, in case password has been provided // the user has to set his password via link in activation email sent by the instance if ( user['password'] ) { @@ -439,7 +445,7 @@ function createLocalUser(instance, login, user, callback) { var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/users/' + login; // build the request options - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'PUT'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'PUT'); // merge the passed user object with some hard coded properties var mergedUser = Object.assign(user, { @@ -471,14 +477,15 @@ function createLocalUser(instance, login, user, callback) { * Retrieves details of a local user. * * @param {String} login the login of the local user + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the user are available as arguments to the callback function */ -function getLocalUser(instance, login, callback) { +function getLocalUser(instance, login, token, callback) { // build the request options var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/users/' + login; // build the request options - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'GET'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'GET'); // do the request request(options, function (err, res, body) { @@ -509,14 +516,15 @@ function getLocalUser(instance, login, callback) { * @param {String} instance the instance to update the user on * @param {Object} user the local user to update * @param {Object} changes the changes to apply to the user + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the updated user are available as arguments */ -function updateLocalUser(instance, user, changes, callback) { +function updateLocalUser(instance, user, changes, token, callback) { // build the request options var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/users/' + user['login']; // build the request options - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'PATCH'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'PATCH'); // add resource_state required for deletion options['headers'] = { @@ -550,12 +558,13 @@ function updateLocalUser(instance, user, changes, callback) { * @param {String} instance instance to grant the user the role on * @param {String} login the login of the user * @param {String} role the role to grant + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the changed user are available as arguments to the callback function */ -function grantLocalRole(instance, login, role, callback) { +function grantLocalRole(instance, login, role, token, callback) { // build the request options var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/roles/' + role + '/users/' + login; - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'PUT'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'PUT'); // do the request request(options, function (err, res, body) { @@ -581,12 +590,13 @@ function grantLocalRole(instance, login, role, callback) { * @param {String} instance instance to revoke the user the role from * @param {String} login the login of the user * @param {String} role the role to revoke + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the changed user are available as arguments to the callback function */ -function revokeLocalRole(instance, login, role, callback) { +function revokeLocalRole(instance, login, role, token, callback) { // build the request options var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/roles/' + role + '/users/' + login; - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'DELETE'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'DELETE'); // do the request request(options, function (err, res, body) { @@ -612,14 +622,15 @@ function revokeLocalRole(instance, login, role, callback) { * @param {String} instance the instance to create the user in * @param {String} login the login of the user * @param {String} state resource state before deletion + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error is available as argument to the callback function */ -function deleteLocalUser(instance, login, state, callback) { +function deleteLocalUser(instance, login, state, token, callback) { // build the request options var endpoint = '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/users/' + login; // build the request options - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'DELETE'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'DELETE'); // add resource_state required for deletion if ( state ) { @@ -655,9 +666,10 @@ function deleteLocalUser(instance, login, state, callback) { * @param {String} sortBy the field to sort users by * @param {String} count optional number of items per page * @param {String} start zero-based index of the first search hit to include + * @param {String} token oauth token * @param {Boolean} callback the callback to execute, the error, the result and the list of users of the current page are available as arguments to the callback function */ -function searchLocalUsers(instance, query, role, sortBy, count, start, callback) { +function searchLocalUsers(instance, query, role, sortBy, count, start, token, callback) { // the page size var size = USER_LIST_PAGE_SIZE if ( count ) { @@ -677,7 +689,7 @@ function searchLocalUsers(instance, query, role, sortBy, count, start, callback) } // build the request options - var options = ocapi.getOptions(instance, endpoint, auth.getToken(), 'POST'); + var options = ocapi.getOptions(instance, endpoint, token || auth.getToken(), 'POST'); // default query, match all var q = { @@ -708,7 +720,7 @@ function searchLocalUsers(instance, query, role, sortBy, count, start, callback) if ( !query && !role && !sortBy && count > 200 ) { // modify the request options var options = ocapi.getOptions(instance, '/s/-/dw/data/' + ocapi.getOcapiVersion() + '/users?count=' + - size + '&select=(**)', auth.getToken(), 'GET'); + size + '&select=(**)', token || auth.getToken(), 'GET'); } // do the request @@ -734,11 +746,12 @@ function searchLocalUsers(instance, query, role, sortBy, count, start, callback) * @param {Object} user the user to grant the role for * @param {String} role the role to grant * @param {String} scope the optional scope of the role + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the changed user are available as arguments to the callback function */ -function grantRole(user, role, scope, callback) { +function grantRole(user, role, scope, token, callback) { // build the request options - var options = getOptions(API_BASE + '/users/' + user['id'], auth.getToken(), 'PUT'); + var options = getOptions(API_BASE + '/users/' + user['id'], token || auth.getToken(), 'PUT'); console.debug("Existing user: %s", JSON.stringify(user)); @@ -807,11 +820,12 @@ function grantRole(user, role, scope, callback) { * @param {Object} user the user to revoke the role from * @param {String} role the role to revoke * @param {String} scope the optional scope of the role to reduce + * @param {String} token oauth token * @param {Function} callback the callback to execute, the error and the changed user are available as arguments to the callback function */ -function revokeRole(user, role, scope, callback) { +function revokeRole(user, role, scope, token, callback) { // build the request options - var options = getOptions(API_BASE + '/users/' + user['id'], auth.getToken(), 'PUT'); + var options = getOptions(API_BASE + '/users/' + user['id'], token || auth.getToken(), 'PUT'); console.debug("Existing user: %s", JSON.stringify(user)); @@ -906,8 +920,10 @@ module.exports.cli = { * @param {String} firstName the first name * @param {String} lastName the last name * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - create : function(org, user, mail, firstName, lastName, asJson) { + create : function(org, user, mail, firstName, lastName, asJson, token, callback) { // respect user, login, firstName and lastName (if passed) if (typeof(user) === 'undefined' || user === null) { user = {}; @@ -922,8 +938,13 @@ module.exports.cli = { user['lastName'] = lastName; } - libOrg.getOrg(org, function(err, foundOrg) { + libOrg.getOrg(org, token, function(err, foundOrg) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -931,8 +952,13 @@ module.exports.cli = { } return; } - createUser(foundOrg['id'], user, function(err, newUser) { + createUser(foundOrg['id'], user, token, function(err, newUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -941,6 +967,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, newUser); + return; + } + // the result var result = { message : util.format('New user %s in org %s created.', newUser.mail, org), @@ -965,12 +996,19 @@ module.exports.cli = { * @param {Number} count the max count of list items * @param {Boolean} asJson optional flag to force output in json, false by default * @param {String} sortBy optional field to sort the list of users by + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - list : function(org, role, login, count, asJson, sortBy) { + list : function(org, role, login, count, asJson, sortBy, token, callback) { // get details of a single user if login was passed if ( typeof(login) !== 'undefined' && login !== null ) { - getUser(login, function(err, user) { + getUser(login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -978,6 +1016,12 @@ module.exports.cli = { } return; } + + if (typeof callback !== 'undefined') { + callback(undefined, [user]); + return; + } + if (asJson) { console.json(user); return; @@ -991,6 +1035,11 @@ module.exports.cli = { // define the callback var getUsersCallback = function(err, result, list) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1003,6 +1052,11 @@ module.exports.cli = { list = require('./json').sort(list, sortBy); } + if (typeof callback !== 'undefined') { + callback(undefined, list); + return; + } + if (asJson) { // if sorted, then only provide the list of the current page if (sortBy) { @@ -1029,8 +1083,13 @@ module.exports.cli = { // in case org was passed, resolve org uuid if ( org ) { - libOrg.getOrg(org, function(err, foundOrg) { + libOrg.getOrg(org, token, function(err, foundOrg) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1038,12 +1097,12 @@ module.exports.cli = { } return; } - getUsers(foundOrg['id'], role, count, getUsersCallback); + getUsers(foundOrg['id'], role, count, token, getUsersCallback); }); return; } // no org was passed - getUsers(null, role, count, getUsersCallback); + getUsers(null, role, count, token, getUsersCallback); }, /** @@ -1052,10 +1111,17 @@ module.exports.cli = { * @param {String} login login of the user to update * @param {Object} changes changes to the user details * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - update : function(login, changes, asJson) { - getUser(login, function(err, user) { + update : function(login, changes, asJson, token, callback) { + getUser(login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1063,8 +1129,13 @@ module.exports.cli = { } return; } - updateUser(user, changes, function(err, updatedUser) { + updateUser(user, changes, token, function(err, updatedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1073,6 +1144,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, updatedUser); + return; + } + // the result var result = { message : util.format('User %s has been updated.', login), @@ -1095,8 +1171,10 @@ module.exports.cli = { * @param {String} role the role to grant * @param {String} scope the scope of the role to grant * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - grant : function(login, role, scope, asJson) { + grant : function(login, role, scope, asJson, token, callback) { if (typeof(login) === 'undefined' || login === null) { console.error("Missing login. Please pass a login using -l,--login"); return; @@ -1105,8 +1183,13 @@ module.exports.cli = { console.error("Missing role. Please pass a role using -r,--role"); return; } - getUser(login, function(err, user) { + getUser(login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1114,8 +1197,13 @@ module.exports.cli = { } return; } - grantRole(user, role, scope, function(err, changedUser) { + grantRole(user, role, scope, token, function(err, changedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1124,6 +1212,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, changedUser); + return; + } + // the result var result = { message : util.format('User %s granted role %s.', login, role), @@ -1150,8 +1243,10 @@ module.exports.cli = { * @param {String} role the role to revoke * @param {String} scope the scope of the role to revoke * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - revoke : function(login, role, scope, asJson) { + revoke : function(login, role, scope, asJson, token, callback) { if (typeof(login) === 'undefined' || login === null) { console.error("Missing login. Please pass a login using -l,--login"); return; @@ -1160,8 +1255,13 @@ module.exports.cli = { console.error("Missing role. Please pass a role using -r,--role"); return; } - getUser(login, function(err, user) { + getUser(login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1169,8 +1269,13 @@ module.exports.cli = { } return; } - revokeRole(user, role, scope, function(err, changedUser) { + revokeRole(user, role, scope, token, function(err, changedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1179,6 +1284,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, changedUser); + return; + } + // the result var result = { message : util.format('User %s revoked role %s.', login, role), @@ -1204,10 +1314,17 @@ module.exports.cli = { * @param {Object} login the user to delete * @param {Boolean} purge whether to purge the user completely * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - delete : function(login, purge, asJson) { - getUser(login, function(err, user) { + delete : function(login, purge, asJson, token, callback) { + getUser(login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1215,8 +1332,13 @@ module.exports.cli = { } return; } - deleteUser(user, purge, function(err) { + deleteUser(user, purge, token, function(err) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1225,6 +1347,12 @@ module.exports.cli = { return; } + + if (typeof callback !== 'undefined') { + callback(undefined, true); + return; + } + // the result var result = { message : util.format('User %s %s.', login, ( purge ? 'purged' : 'deleted' )), @@ -1247,8 +1375,10 @@ module.exports.cli = { * @param {String} login the login of the user * @param {Object} user the user details * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - createLocal : function(instance, login, user, asJson) { + createLocal : function(instance, login, user, asJson, token, callback) { if (typeof(user) === 'undefined' || user === null) { console.error("Missing user details. Please pass details using -u,--user"); return; @@ -1257,8 +1387,13 @@ module.exports.cli = { console.error("Missing login. Please pass a login using -l,--login"); return; } - createLocalUser(instance, login, user, function(err, newUser) { + createLocalUser(instance, login, user, token, function(err, newUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1267,6 +1402,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, newUser); + return; + } + // the result var result = { message : util.format('New user %s in instance %s created.', newUser.login, instance), @@ -1292,12 +1432,19 @@ module.exports.cli = { * @param {String} count optional number of items per page * @param {String} start optional zero-based index of the first search hit to include * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - searchLocal : function(instance, login, query, role, sortBy, count, start, asJson) { + searchLocal : function(instance, login, query, role, sortBy, count, start, asJson, token, callback) { // get details of a single user if login was passed if ( typeof(login) !== 'undefined' && login !== null ) { - getLocalUser(instance, login, function(err, user) { + getLocalUser(instance, login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1305,6 +1452,12 @@ module.exports.cli = { } return; } + + if (typeof callback !== 'undefined') { + callback(undefined, [user]); + return; + } + if (asJson) { console.json(user); return; @@ -1315,8 +1468,13 @@ module.exports.cli = { return; } // get all users - searchLocalUsers(instance, query, role, sortBy, count, start, function(err, result, list) { + searchLocalUsers(instance, query, role, sortBy, count, start, token, function(err, result, list) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1325,6 +1483,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, list); + return; + } + if (asJson) { // silently make list of users contained in property data available via property hits if (typeof(result['hits']) == 'undefined' && typeof(result['data']) != 'undefined' ) { @@ -1357,8 +1520,10 @@ module.exports.cli = { * @param {String} login login of the local user to update * @param {Object} changes changes to the user details * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - updateLocal : function(instance, login, changes, asJson) { + updateLocal : function(instance, login, changes, asJson, token, callback) { if (typeof(instance) === 'undefined' || instance === null) { console.error('Missing instance. Please pass an instance using -i,--instance'); return; @@ -1367,8 +1532,13 @@ module.exports.cli = { console.error('Missing login. Please pass a login using -l,--login'); return; } - getLocalUser(instance, login, function(err, user) { + getLocalUser(instance, login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1376,8 +1546,13 @@ module.exports.cli = { } return; } - updateLocalUser(instance, user, changes, function(err, updatedUser) { + updateLocalUser(instance, user, changes, token, function(err, updatedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1386,6 +1561,12 @@ module.exports.cli = { return; } + + if (typeof callback !== 'undefined') { + callback(undefined, updatedUser); + return; + } + // the result var result = { message : util.format('User %s has been updated on %s.', login, instance), @@ -1408,8 +1589,10 @@ module.exports.cli = { * @param {String} login the login of the user * @param {String} role the role to grant * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - grantLocal : function(instance, login, role, asJson) { + grantLocal : function(instance, login, role, asJson, token, callback) { if (typeof(instance) === 'undefined' || instance === null) { console.error('Missing instance. Please pass an instance using -i,--instance'); return; @@ -1422,8 +1605,13 @@ module.exports.cli = { console.error('Missing role. Please pass a role using -r,--role'); return; } - getLocalUser(instance, login, function(err, user) { + getLocalUser(instance, login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1431,8 +1619,13 @@ module.exports.cli = { } return; } - grantLocalRole(instance, login, role, function(err, changedUser) { + grantLocalRole(instance, login, role, token, function(err, changedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1441,6 +1634,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, changedUser); + return; + } + // the result var result = { message : util.format('Granted role %s to user %s on %s', role, login, instance), @@ -1463,8 +1661,10 @@ module.exports.cli = { * @param {String} login the login of the user * @param {String} role the role to revoke * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - revokeLocal : function(instance, login, role, asJson) { + revokeLocal : function(instance, login, role, asJson, token, callback) { if (typeof(instance) === 'undefined' || instance === null) { console.error('Missing instance. Please pass an instance using -i,--instance'); return; @@ -1477,8 +1677,13 @@ module.exports.cli = { console.error('Missing role. Please pass a role using -r,--role'); return; } - getLocalUser(instance, login, function(err, user) { + getLocalUser(instance, login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1486,8 +1691,13 @@ module.exports.cli = { } return; } - revokeLocalRole(instance, login, role, function(err, changedUser) { + revokeLocalRole(instance, login, role, token, function(err, changedUser) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1496,6 +1706,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, changedUser); + return; + } + // the result var result = { message : util.format('Revoked role %s from user %s on %s.', role, login, instance), @@ -1517,10 +1732,17 @@ module.exports.cli = { * @param {String} instance instance to delete the user from * @param {Object} login the user to delete * @param {Boolean} asJson optional flag to force output in json, false by default + * @param {String} token oauth token + * @param {Function} callback callback function to call when called through the Javascript API */ - deleteLocal : function(instance, login, asJson) { - getLocalUser(instance, login, function(err, user) { + deleteLocal : function(instance, login, asJson, token, callback) { + getLocalUser(instance, login, token, function(err, user) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1528,8 +1750,13 @@ module.exports.cli = { } return; } - deleteLocalUser(instance, login, user['_resource_state'], function(err) { + deleteLocalUser(instance, login, user['_resource_state'], token, function(err) { if (err) { + if (typeof callback !== 'undefined') { + callback(err, undefined); + return; + } + if (asJson) { console.json({error: err.message}); } else { @@ -1538,6 +1765,11 @@ module.exports.cli = { return; } + if (typeof callback !== 'undefined') { + callback(undefined, true); + return; + } + // the result var result = { message : util.format('User %s deleted from %s.', login, instance), @@ -1552,4 +1784,229 @@ module.exports.cli = { }); }); } +}; + +module.exports.api = { + /** + * Creates a new user. + * + * @param {String} org the org to create the user in + * @param {Object} user the user details + * @param {String} mail the login (email) of the new user (must be unique) + * @param {String} firstName the first name + * @param {String} lastName the last name + * @param {String} token oauth token + */ + create: (org, user, mail, firstName, lastName, token) => new Promise((resolve, reject) => { + module.exports.cli.create(org, user, mail, firstName, lastName, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Lists all users eligible to manage + * + * @param {String} org the org or null, if all users should be retrieved + * @param {String} role the role or null, if all users should be retrieved + * @param {String} login the login or null, if all users should be retrieved + * @param {Number} count the max count of list items + * @param {String} sortBy optional field to sort the list of users by + * @param {String} token oauth token + */ + list: (org, role, login, count, sortBy, token) => new Promise((resolve, reject) => { + module.exports.cli.list(org, role, login, count, false, sortBy, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Update a user. + * + * @param {String} login login of the user to update + * @param {Object} changes changes to the user details + * @param {String} token oauth token + */ + update: (login, changes, token) => new Promise((resolve, reject) => { + module.exports.cli.update(login, changes, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Grant a role to a user + * + * @param {String} login the login (email) of the user + * @param {String} role the role to grant + * @param {String} scope the scope of the role to grant + * @param {String} token oauth token + */ + grant: (login, role, scope, token) => new Promise((resolve, reject) => { + module.exports.cli.grant(login, role, scope, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Revoke a role from a user + * + * @param {String} login the login (email) of the user + * @param {String} role the role to revoke + * @param {String} scope the scope of the role to revoke + * @param {String} token oauth token + */ + revoke: (login, role, scope, token) => new Promise((resolve, reject) => { + module.exports.cli.revoke(login, role, scope, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Delete a user. + * + * @param {Object} login the user to delete + * @param {Boolean} purge whether to purge the user completely + * @param {String} token oauth token + */ + delete: (login, purge, token) => new Promise((resolve, reject) => { + module.exports.cli.delete(login, purge, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Creates a new local user on an instance. + * + * @param {String} instance the instance to create the user on + * @param {String} login the login of the user + * @param {Object} user the user details + * @param {String} token oauth token + */ + createLocal: (instance, login, user, token) => new Promise((resolve, reject) => { + module.exports.cli.createLocal(instance, login, user, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Search for local users on an instance + * + * @param {String} instance the instance to search users on + * @param {String} login the login or null, if all users should be retrieved + * @param {String} query the query to search users for + * @param {String} role the role to search users for + * @param {String} sortBy optional field to sort users by + * @param {String} count optional number of items per page + * @param {String} start optional zero-based index of the first search hit to include + * @param {String} token oauth token + */ + searchLocal: (instance, login, query, role, sortBy, count, start, token) => new Promise((resolve, reject) => { + module.exports.cli.searchLocal(instance, login, query, role, sortBy, count, start, false, token, + (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Update a local user. + * + * @param {String} instance instance to grant the user the role on + * @param {String} login login of the local user to update + * @param {Object} changes changes to the user details + * @param {String} token oauth token + */ + updateLocal: (instance, login, changes, token) => new Promise((resolve, reject) => { + module.exports.cli.updateLocal(instance, login, changes, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Grant a role to a local user + * + * @param {String} instance instance to grant the user the role on + * @param {String} login the login of the user + * @param {String} role the role to grant + * @param {String} token oauth token + */ + grantLocal: (instance, login, role, token) => new Promise((resolve, reject) => { + module.exports.cli.grantLocal(instance, login, role, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Revoke a role from a local user + * + * @param {String} instance instance to revoke the user the role from + * @param {String} login the login of the user + * @param {String} role the role to revoke + * @param {String} token oauth token + */ + revokeLocal: (instance, login, role, token) => new Promise((resolve, reject) => { + module.exports.cli.revokeLocal(instance, login, role, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }), + /** + * Delete a local user. + * + * @param {String} instance instance to delete the user from + * @param {Object} login the user to delete + * @param {String} token oauth token + */ + deleteLocal: (instance, login, token) => new Promise((resolve, reject) => { + module.exports.cli.deleteLocal(instance, login, false, token, (err, result) => { + if (err) { + reject(err); + return; + } + + resolve(result); + }); + }) }; \ No newline at end of file diff --git a/test/unit/org.js b/test/unit/org.js index 2ad525f9..526a8336 100644 --- a/test/unit/org.js +++ b/test/unit/org.js @@ -36,7 +36,7 @@ describe('Tests for lib/org.js', function() { it('makes a get request', function() { - org.getOrg('myorg', function(){}); + org.getOrg('myorg', undefined, function(){}); const getArgs = requestStub.getCall(0).args[0]; expect(getArgs.uri).to.equal('https://am.host/dw/rest/v1/organizations/search/findByName' + @@ -55,7 +55,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('The operation could not be performed properly. '); done(); }); @@ -72,7 +72,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('Authentication invalid. Please (re-)authenticate by running ' + '´sfcc-ci auth:login´ or ´sfcc-ci client:auth´'); done(); @@ -90,7 +90,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('Getting org failed: Permission error'); done(); }); @@ -107,7 +107,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('Getting org failed: 500'); done(); }); @@ -124,7 +124,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('Unknown org myorg'); expect(found).to.be.undefined; done(); @@ -142,7 +142,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err.message).to.equal('Org myorg is ambiguous'); expect(found).to.be.undefined; done(); @@ -160,7 +160,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found) { + org.getOrg('myorg', undefined, function(err, found) { expect(err).to.be.undefined; expect(found).to.eql({ id: 1, name: 'myorg' }); done(); @@ -178,7 +178,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found){ + org.getOrg('myorg', undefined, function(err, found){ expect(err).to.be.undefined; expect(found).to.eql({ id: 1, name: 'myorg' }); done(); @@ -196,7 +196,7 @@ describe('Tests for lib/org.js', function() { } }); - org.getOrg('myorg', function(err, found){ + org.getOrg('myorg', undefined, function(err, found){ expect(err).to.be.undefined; expect(found).to.eql({ id: 1, name: 'myorg' }); done();