This repository has been archived by the owner on Dec 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '1.0-public' into 'public'
Initial Release See merge request mbx/mbee/plugins/sandbox!2
- Loading branch information
Showing
4 changed files
with
249 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
yarn.lock | ||
.idea/ | ||
node_modules/ | ||
.eslintrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |