Skip to content
This repository has been archived by the owner on Dec 13, 2024. It is now read-only.

Commit

Permalink
Merge branch '1.0-public' into 'public'
Browse files Browse the repository at this point in the history
Initial Release

See merge request mbx/mbee/plugins/sandbox!2
  • Loading branch information
Bieber, Austin J committed May 15, 2019
2 parents 6a5c746 + add9865 commit ea0fa90
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
yarn.lock
.idea/
node_modules/
.eslintrc
64 changes: 63 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,63 @@
# mbee-plugin-sandbox
## Sandbox Plugin

The Sandbox Plugin is designed to allow every user to have their own sandbox so
that they can experiment with MBEE however they choose, without affecting other
organizations or projects. When a user is created, a sandbox organization is
created for that specific user and they can do whatever they desire with it.
If and when that user is deleted, their sandbox organization (and any projects
and elements in the organization) is deleted.

#### Installation

Installation of the sandbox plugin is very simple. To install the plugin,
simply include the following bit of code in your running MBEE config in the
`server.plugins` section:

```json
{
"plugins": {
"enabled": true,
"plugins": [{
"name": "sandbox",
"source": "https://github.com/lmco/mbee-plugin-sandbox.git",
"title": "Sandbox"
}],
"sandbox": {
"retroactive": true
}
}

}
```

NOTE: Ensure "enabled" is set to true so that plugins are installed and built
upon restart of the server.

#### Running the Plugin

To run the plugin, simply restart the running instance of MBEE. The plugin code
will be copied, built and will start along with the server.

Nothing needs to be done to manage the plugin. When a user is created in the
system, a sandbox organization is created along with them. That user becomes an
admin of that organization, and can edit that org and add projects and users.

If/When the user is deleted, the organization is automatically deleted, along
with any projects stored in the org, and any elements in those projects.

#### Configuration Options

To change the default configuration options, visit the running MBEE config, and
go to the `server.plugins.sandbox` section. If this section does not exist, feel
free to add it.

Below are the supported config options, and a description of what they do.

* retroactive (boolean)
* If true, creates sandbox orgs for all existing users if they do not
currently have one upon startup of the server.


#### Public Release Info
This code is part of the MBEE source code, and is thus approved for public
release per PIRA #SSS201809050.
169 changes: 169 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* Classification: UNCLASSIFIED
*
* @module app
*
* @copyright Copyright (C) 2018, Lockheed Martin Corporation
*
* @license MIT
*
* @description The main file for creating and deleting sandbox organizations.
* NOTE: This file uses the models directly. This is not the recommended
* approach, rather it is recommended you use the controllers. The models should
* only be used directly if the controllers cannot provide the functionality
* desired.
*/

// Node Modules
const express = require('express');

// NPM Modules
const uuidv4 = require('uuid/v4');

// MBEE Modules
const Element = M.require('models.element');
const Organization = M.require('models.organization');
const Project = M.require('models.project');
const User = M.require('models.user');
const EventEmitter = M.require('lib.events');
const Middleware = M.require('lib.middleware');
const { authenticate } = M.require('lib.auth');

const app = express();

/* --------------------( Main )-------------------- */

/**
* @description Creates a sandbox organization for every user. Updates the user
* to have a reference to the sandbox org.
*
* @param {Object[]} users - An array of user objects to create sandbox orgs for
*/
function createSandbox(users) {
// Define an array of organizations to create
const orgsToCreate = [];

// For each user created
users.forEach((user) => {
// Generate a random uuid as the id
const id = uuidv4();
// Create the organization object
const org = new Organization({
_id: id,
name: `Sandbox (${user.username})`,
permissions: {},
createdBy: user.username,
lastModifiedBy: user.username,
createdOn: Date.now(),
updatedOn: Date.now(),
custom: {
sandbox: true
}
});

// Set the created user as the org admin
org.permissions[user.username] = ['read', 'write', 'admin'];

// Add org to array to be created
orgsToCreate.push(org);

// Store the sandbox org id in custom data
user.custom.sandbox = id;
});

// Create all of the organizations
Organization.insertMany(orgsToCreate)
.then(() => {
const promises = [];

// Loop through each user
users.forEach((user) => {
// Log creation of sandbox
M.log.info(`Sandbox Plugin: ${user.username}'s sandbox org was created.`);

// Update the custom data for each user
promises.push(User.updateOne({ _id: user.username }, { custom: user.custom }))
});

// Return when all promises have completed
return Promise.all(promises);
})
.catch((err) => M.log.warn(`Sandbox Plugin: ${err}`));
}

/**
* @description Deletes sandbox orgs and any projects/elements name-spaced under
* those orgs for multiple users.
*
* @param {Object[]} users - An array of user objects to delete sandbox orgs for
*/
function deleteSandbox(users) {
let projectIDs = [];
// For each user who was deleted
users.forEach((user) => {
// Delete the user's sandbox organization
Organization.deleteOne(
{ _id: user.custom.sandbox,
createdBy: user.username, // Point of consistency, cannot be changed via controller
'custom.sandbox': true
}
)
.then((query) => {
// If the org was not deleted correctly
if (query.ok !== 1 && query.deletedCount !== 1) {
// Log a warning saying the users sandbox org was not deleted.
M.log.warn(`Sandbox Plugin: ${user.username}'s sandbox org was not deleted...`);
return [];
}

// If the org was deleted, find all of its projects
return Project.find({ org: user.custom.sandbox });
})
.then((projects) => {
// Save all projects ids for later element deletion
projectIDs = projects.map(p => p._id);

// Delete all projects that were found
return Project.deleteMany({ org: user.custom.sandbox });
})
// Delete all elements name-spaced under the deleted projects
.then(() => Element.deleteMany({ project: { $in: projectIDs } }))
// Log deletion of sandbox org
.then(() => M.log.info(`Sandbox Plugin: ${user.username}'s sandbox org was deleted.`))
.catch((err) => M.log.warn(`Sandbox Plugin: ${err}`));
});
}

/**
* @description Adds an event listener which listens for the event
* 'users-created'. Upon triggering of the event, the createSandbox() function
* is called.
*/
EventEmitter.addListener('users-created', (users) => {
createSandbox(users);
});

/**
* @description Adds an event listener which listens for the event
* 'users-deleted'. Upon triggering of the event, the deleteSandbox() function
* is called.
*/
EventEmitter.addListener('users-deleted', (users) => {
deleteSandbox(users);
});

// If the retroactive setting in the config is true, create sandbox orgs for all
// users who currently don't have one
if (M.config.server.plugins.sandbox.retroactive) {
// Find all users who don't have a sandbox org
User.find({ 'custom.sandbox': { $exists: false } })
.then((users) => createSandbox(users));
}

// Redirects the plugin homepage to the users sandbox org homepage
app.get('/', authenticate, Middleware.logRoute, function(req, res) {
return res.redirect(`/${req.user.custom.sandbox || ''}`);
});

// Export the express app
module.exports = app;
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "sandbox",
"version": "1.0.0",
"main": "app.js",
"repository": "https://github.com/lmco/mbee-plugin-sandbox.git",
"author": "Lockheed Martin",
"license": "MIT",
"private": true,
"dependencies": {
"express": "^4.16.4",
"uuid": "^3.3.2"
}
}

0 comments on commit ea0fa90

Please sign in to comment.