Skip to content

Commit

Permalink
Merge pull request #127 from tobiaslohr/sandbox-inject-settings
Browse files Browse the repository at this point in the history
Sandbox inject settings
  • Loading branch information
tobiaslohr committed Apr 6, 2020
2 parents 338940a + 449c5a8 commit dcd2ca7
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 4 deletions.
11 changes: 10 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ program
.command('sandbox:create')
.option('-r, --realm <realm>','Realm to create the sandbox for')
.option('-t, --ttl <hours>','Number of hours the sandbox will live')
.option('--ocapi-settings <json>','Additional OCAPI settings applied to the sandbox')
.option('--webdav-settings <json>','Additional WebDAV permissions applied to the sandbox')
.option('-j, --json','Formats the output in json')
.option('-s, --sync', 'Operates in synchronous mode and waits until the operation has been finished.')
.option('-d, --default', 'Sets the created sandbox as default instance.')
Expand All @@ -280,7 +282,10 @@ program
var sync = ( options.sync ? options.sync : false );
var setAsDefault = ( options.default ? options.default : false );
var alias = ( options.setAlias ? options.setAlias : null );
require('./lib/sandbox').cli.create(realm, alias, ttl, asJson, sync, setAsDefault);
var ocapiSettings = ( options.ocapiSettings ? options.ocapiSettings : null );
var webdavSettings = ( options.webdavSettings ? options.webdavSettings : null );
require('./lib/sandbox').cli.create(realm, alias, ttl, ocapiSettings, webdavSettings, asJson, sync,
setAsDefault);
}).on('--help', function() {
console.log('');
console.log(' Details:');
Expand All @@ -305,6 +310,10 @@ program
console.log(' The TTL (time to live) in hours of the sandbox can be modified via the --ttl flag. The value');
console.log(' must adhere to the maximum TTL quotas) If absent the realms default sandbox TTL is used.');
console.log(' If the sandbox age reaches its TTL, it will be deleted automatically.');
console.log();
console.log(' Use --ocapi-settings and --webdav-settings to pass additional OCAPI and/or WebDAV settings to');
console.log(' the created sandbox as JSON. You may not overwrite the permissions for the CLI client but');
console.log(' amend its permissions or add permissions for other clients. The passed JSON must be valid.');
console.log('');
console.log(' Examples:');
console.log();
Expand Down
81 changes: 78 additions & 3 deletions lib/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,56 @@ function printInboundIPs(json) {
});
}

/**
* Attempts the merge API settings. Checks the passed settingsAsJSON string for validity.
* Checks if the JSON string is syntactically correct and does a basic semantic check for
* the same API client as used by the CLI client. Throws an error if a check failed.
*
* Note, we allow to pass API settings for the same API client as granted to in the base
* settings, since we amend additional API resources, we don't replace them.
*
* @param {Object} baseSettings the base API settings as object
* @param {String} resourceProp the property of the API permissions that holds the actual perm set
* @param {String} settingsAsJSON the settings to merge into the base settings as JSON string
* @return {Object} the merged API settings
*/
function mergeAPISettings(baseSettings, resourceProp, settingsAsJSON) {
var settingsToMerge;
// syntactical check
try {
settingsToMerge = JSON.parse(settingsAsJSON);
} catch (err) {
console.debug(`Invalid JSON: ${err.message}`);
throw new Error(`Invalid JSON`);
}

var finalSettings = [];
// sematical check
if (settingsToMerge['client_id'] && settingsToMerge.client_id === auth.getClient()) {
console.debug(`Patch existing permissions. Amending API resources.`);
baseSettings[0][resourceProp] = baseSettings[0][resourceProp].concat(settingsToMerge[resourceProp]);
finalSettings = baseSettings;
} else if (Array.isArray(settingsToMerge)) {
// in case of a multiple clients
settingsToMerge.forEach(function(client) {
if (client['client_id'] && client.client_id === auth.getClient()) {
console.debug(`Patch existing permissions. Amending API resources.`);
baseSettings[0][resourceProp] = baseSettings[0][resourceProp].concat(client[resourceProp]);
} else {
// simply concat
finalSettings = finalSettings.concat(client);
}
});
finalSettings = baseSettings.concat(finalSettings);
} else {
// simply concat
finalSettings = finalSettings.concat(settingsToMerge);
}

console.debug(`Merged API settings: ${JSON.stringify(finalSettings)}`);
return finalSettings;
}

/**
* Retrieves all realms and returns them as array.
*
Expand Down Expand Up @@ -329,24 +379,47 @@ function getSandboxHost(sandbox) {
*
* @param {String} realm the realm to create the sandbox for
* @param {String} ttl the ttl of the sandbox in hours
* @param {String} additionalOcapiSettings JSON string holding additonal OCAPI settings to pass
* @param {String} additionalWebdavSettings JSON string holding additonal WebDAV permissions to pass
* @param {Function} callback the callback to execute, the error and the created sandbox are available as arguments to the callback function
*/
function createSandbox(realm, ttl, callback) {
function createSandbox(realm, ttl, additionalOcapiSettings, additionalWebdavSettings, callback) {
if (!realm && dwjson['realm']) {
realm = dwjson['realm'];
console.debug('Using realm id %s from dw.json at %s', dwjson['realm'], process.cwd());
}

// build the request options
var options = ocapi.getOptions('POST', API_SANDBOXES);

// prep initial ocapi settings
var ocapiSettings = SANDBOX_OCAPI_SETTINGS;
ocapiSettings[0]['client_id'] = auth.getClient();

// amend with additional settings
if (additionalOcapiSettings) {
try {
ocapiSettings = mergeAPISettings(ocapiSettings, 'resources', additionalOcapiSettings);
} catch (err) {
callback(new Error(`Invalid OCAPI settings: ${err.message}`));
return;
}
}

// prep initial webdav permissions
var webdavPermissions = SANDBOX_WEBDAV_PERMISSIONS;
webdavPermissions[0]['client_id'] = auth.getClient();

// amend with additional settingss
if (additionalWebdavSettings) {
try {
webdavPermissions = mergeAPISettings(webdavPermissions, 'permissions', additionalWebdavSettings);
} catch (err) {
callback(new Error(`Invalid WebDAV settings: ${err.message}`));
return;
}
}

// the payload
options['body'] = {
realm : realm,
Expand Down Expand Up @@ -770,16 +843,18 @@ module.exports.cli = {
* @param {String} realm the realm to create the sandbox in
* @param {String} alias the alias to use for the created sandbox
* @param {Number} ttl number of hours, the sandbox will live (if absent the realm default ttl is used)
* @param {String} ocapiSettings additional ocapi settings
* @param {String} webdavPermissions additional webdav permissions
* @param {Boolean} asJson optional flag to force output in json, false by default
* @param {Boolean} sync whether to operate in synchronous mode, false by default
* * @param {Boolean} setAsDefault optional flag to set as new default instance, false by default
*/
create : function(realm, alias, ttl, asJson, sync, setAsDefault) {
create : function(realm, alias, ttl, ocapiSettings, webdavPermissions, asJson, sync, setAsDefault) {
// memorize the start time and duration
var startTime = Date.now();
var duration = 0;

createSandbox(realm, ttl, function(err, newSandbox) {
createSandbox(realm, ttl, ocapiSettings, webdavPermissions, function(err, newSandbox) {
if (err) {
if (asJson) {
console.json({error: err.message});
Expand Down

0 comments on commit dcd2ca7

Please sign in to comment.