openmct/platform/policy/src/PolicyProvider.js

106 lines
4.6 KiB
JavaScript
Raw Normal View History

/*****************************************************************************
* 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";
/**
* Provides an implementation of `policyService` which consults
* various policy extensions to determine whether or not a specific
* decision should be allowed.
* @constructor
*/
function PolicyProvider(policies) {
var policyMap = {};
// Instantiate a policy. Mostly just a constructor call, but
// we also track the message (which was provided as metadata
// along with the constructor) so that we can expose this later.
function instantiate(Policy) {
var policy = Object.create(new Policy());
policy.message = Policy.message;
return policy;
}
// Add a specific policy to the map for later lookup,
// according to its category. Note that policy extensions are
// provided as constructors, so they are instantiated here.
function addToMap(Policy) {
var category = (Policy || {}).category;
if (category) {
// Create a new list for that category if needed...
policyMap[category] = policyMap[category] || [];
// ...and put an instance of this policy in that list.
policyMap[category].push(instantiate(Policy));
}
}
// Populate the map for subsequent lookup
policies.forEach(addToMap);
return {
/**
* Check whether or not a certain decision is allowed by
* policy.
* @param {string} category a machine-readable identifier
* for the kind of decision being made
* @param candidate the object about which the decision is
* being made
* @param context the context in which the decision occurs
* @param {Function} [callback] callback to invoke with a
* string message describing the reason a decision
* was disallowed (if its disallowed)
* @returns {boolean} true if the decision is allowed,
* otherwise false.
*/
allow: function (category, candidate, context, callback) {
var policyList = policyMap[category] || [],
i;
// Iterate through policies. We do this instead of map or
// forEach so that we can return immediately if a policy
// chooses to disallow this decision.
for (i = 0; i < policyList.length; i += 1) {
// Consult the policy...
if (!policyList[i].allow(candidate, context)) {
// ...it disallowed, so pass its message to
// the callback (if any)
if (callback) {
callback(policyList[i].message);
}
// And return the failed result.
return false;
}
}
// No policy disallowed this decision.
return true;
}
};
}
return PolicyProvider;
}
);