[Persistence] Suppress Move/Copy/Link

Disallow move/copy/link when crossing persistence spaces,
nasa/openmctweb#245
This commit is contained in:
Victor Woeltjen 2015-11-10 10:44:21 -08:00
parent 87684e0945
commit 0c096db8bd
6 changed files with 121 additions and 14 deletions

View File

@ -11,7 +11,7 @@
"glyph": "f", "glyph": "f",
"category": "contextual", "category": "contextual",
"implementation": "actions/MoveAction.js", "implementation": "actions/MoveAction.js",
"depends": ["locationService", "moveService"] "depends": ["policyService", "locationService", "moveService"]
}, },
{ {
"key": "copy", "key": "copy",
@ -20,7 +20,7 @@
"glyph": "+", "glyph": "+",
"category": "contextual", "category": "contextual",
"implementation": "actions/CopyAction.js", "implementation": "actions/CopyAction.js",
"depends": ["$log", "locationService", "copyService", "depends": ["$log", "policyService", "locationService", "copyService",
"dialogService", "notificationService"] "dialogService", "notificationService"]
}, },
{ {
@ -30,7 +30,7 @@
"glyph": "\u00E8", "glyph": "\u00E8",
"category": "contextual", "category": "contextual",
"implementation": "actions/LinkAction.js", "implementation": "actions/LinkAction.js",
"depends": ["locationService", "linkService"] "depends": ["policyService", "locationService", "linkService"]
}, },
{ {
"key": "follow", "key": "follow",
@ -54,7 +54,11 @@
"depends": ["contextualize", "$q", "$log"] "depends": ["contextualize", "$q", "$log"]
} }
], ],
"controllers": [ "policies": [
{
"category": "action",
"implementation": "policies/CrossSpacePolicy.js"
}
], ],
"capabilities": [ "capabilities": [
{ {

View File

@ -71,7 +71,14 @@ define(
* @param {string} [suffix] a string to display in the dialog title; * @param {string} [suffix] a string to display in the dialog title;
* default is "to a new location" * default is "to a new location"
*/ */
function AbstractComposeAction(locationService, composeService, context, verb, suffix) { function AbstractComposeAction(
policyService,
locationService,
composeService,
context,
verb,
suffix
) {
if (context.selectedObject) { if (context.selectedObject) {
this.newParent = context.domainObject; this.newParent = context.domainObject;
this.object = context.selectedObject; this.object = context.selectedObject;
@ -83,16 +90,27 @@ define(
.getCapability('context') .getCapability('context')
.getParent(); .getParent();
this.context = context;
this.policyService = policyService;
this.locationService = locationService; this.locationService = locationService;
this.composeService = composeService; this.composeService = composeService;
this.verb = verb || "Compose"; this.verb = verb || "Compose";
this.suffix = suffix || "to a new location"; this.suffix = suffix || "to a new location";
} }
AbstractComposeAction.prototype.cloneContext = function () {
var clone = {}, original = this.context;
Object.keys(original).forEach(function (k) {
clone[k] = original[k];
});
return clone;
};
AbstractComposeAction.prototype.perform = function () { AbstractComposeAction.prototype.perform = function () {
var dialogTitle, var dialogTitle,
label, label,
validateLocation, validateLocation,
self = this,
locationService = this.locationService, locationService = this.locationService,
composeService = this.composeService, composeService = this.composeService,
currentParent = this.currentParent, currentParent = this.currentParent,
@ -109,7 +127,11 @@ define(
label = this.verb + " To"; label = this.verb + " To";
validateLocation = function (newParent) { validateLocation = function (newParent) {
return composeService.validate(object, newParent); var newContext = self.cloneContext();
newContext.selectedObject = object;
newContext.domainObject = newParent;
return composeService.validate(object, newParent) &&
self.policyService.allow("action", self, newContext);
}; };
return locationService.getLocationFromUser( return locationService.getLocationFromUser(

View File

@ -34,16 +34,30 @@ define(
* @constructor * @constructor
* @memberof platform/entanglement * @memberof platform/entanglement
*/ */
function CopyAction($log, locationService, copyService, dialogService, function CopyAction(
notificationService, context) { $log,
policyService,
locationService,
copyService,
dialogService,
notificationService,
context
) {
this.dialog = undefined; this.dialog = undefined;
this.notification = undefined; this.notification = undefined;
this.dialogService = dialogService; this.dialogService = dialogService;
this.notificationService = notificationService; this.notificationService = notificationService;
this.$log = $log; this.$log = $log;
//Extend the behaviour of the Abstract Compose Action //Extend the behaviour of the Abstract Compose Action
AbstractComposeAction.call(this, locationService, copyService, AbstractComposeAction.call(
context, "Duplicate", "to a location"); this,
policyService,
locationService,
copyService,
context,
"Duplicate",
"to a location"
);
} }
/** /**
@ -87,8 +101,8 @@ define(
}; };
/** /**
* Executes the CopyAction. The CopyAction uses the default behaviour of * Executes the CopyAction. The CopyAction uses the default behaviour of
* the AbstractComposeAction, but extends it to support notification * the AbstractComposeAction, but extends it to support notification
* updates of progress on copy. * updates of progress on copy.
*/ */
CopyAction.prototype.perform = function() { CopyAction.prototype.perform = function() {

View File

@ -34,8 +34,9 @@ define(
* @constructor * @constructor
* @memberof platform/entanglement * @memberof platform/entanglement
*/ */
function LinkAction(locationService, linkService, context) { function LinkAction(policyService, locationService, linkService, context) {
return new AbstractComposeAction( return new AbstractComposeAction(
policyService,
locationService, locationService,
linkService, linkService,
context, context,

View File

@ -34,8 +34,9 @@ define(
* @constructor * @constructor
* @memberof platform/entanglement * @memberof platform/entanglement
*/ */
function MoveAction(locationService, moveService, context) { function MoveAction(policyService, locationService, moveService, context) {
return new AbstractComposeAction( return new AbstractComposeAction(
policyService,
locationService, locationService,
moveService, moveService,
context, context,

View File

@ -0,0 +1,65 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define */
define(
[],
function () {
'use strict';
var DISALLOWED_ACTIONS = [
"move",
"copy",
"link",
"compose"
];
function CrossSpacePolicy() {
}
function lookupSpace(domainObject) {
var persistence = domainObject &&
domainObject.getCapability("persistence");
return persistence && persistence.getSpace();
}
function isCrossSpace(context) {
var domainObject = context.domainObject,
selectedObject = context.selectedObject,
spaces = [ domainObject, selectedObject ].map(lookupSpace);
return spaces[0] === spaces[1];
}
CrossSpacePolicy.prototype.allow = function (action, context) {
var key = action.getMetadata().key;
if (DISALLOWED_ACTIONS.indexOf(key) !== -1) {
return !isCrossSpace(context);
}
return true;
};
return CrossSpacePolicy;
}
);