gpii-universal
Version:
Cross platform, core components of the GPII personalization infrastructure.
118 lines (106 loc) • 5.56 kB
JavaScript
/*
* GPII Untrusted Settings Put Handler
*
* Copyright 2017 OCAD University
* Copyright 2019 OCAD University
*
* Licensed under the New BSD license. You may not use this file except in
* compliance with this License.
*
* You may obtain a copy of the License at
* https://github.com/GPII/universal/blob/master/LICENSE.txt
*/
;
var fluid = require("infusion"),
gpii = fluid.registerNamespace("gpii");
require("../../solutionsRegistry/src/js/sr-validation-middleware");
// Update preferences by first ensuring the client that requests the update action does have the privilege
// to update, by verifying the access token embedded in the request "Authorization" header.
fluid.defaults("gpii.flowManager.cloudBased.settings.put.handler", {
gradeNames: ["gpii.universal.solutionsRegistry.requestHandlers.preferences"],
members: {
prefsServerDataSource: "{flowManager}.prefsServerDataSource",
authGrantFinder: "{gpii.flowManager.cloudBased}.authGrantFinder",
dataStore: "{gpii.flowManager.cloudBased}.oauth2DataStore"
},
invokers: {
handleRequest: {
funcName: "gpii.flowManager.cloudBased.settings.put.handleRequest",
args: [
"{that}",
"{that}.req.params.gpiiKey",
"{that}.req.body"
]
},
reject: {
funcName: "gpii.flowManager.cloudBased.settings.put.reject",
args: ["{that}", "{arguments}.0"]
}
}
});
gpii.flowManager.cloudBased.settings.put.messages = {
success: "Successfully updated."
};
gpii.flowManager.cloudBased.settings.put.handleRequest = function (that, gpiiKey, preferences) {
var accessToken = gpii.oauth2.parseAccessTokenFromRequest(that.req);
var authorizationPromise = gpii.oauth2.getAuthorization(accessToken, that.authGrantFinder);
authorizationPromise.then(function (authorization) {
if (authorization && authorization.gpiiKey === gpiiKey && authorization.allowSettingsPut) {
var prefs = fluid.get(preferences, ["contexts", "gpii-default", "preferences"]);
// GPII-3717: Verify incoming preferences are in the allowed list when "allowedPrefsToWrite" array is
// provided. If allowedPrefsToWrite === null, skip this verification and save preferences.
if (authorization.allowedPrefsToWrite) {
if (Array.isArray(authorization.allowedPrefsToWrite) && gpii.flowManager.cloudBased.settings.isPrefsAllowedToWrite(prefs, authorization.allowedPrefsToWrite)) {
gpii.flowManager.cloudBased.settings.put.savePrefs(that, gpiiKey, preferences);
} else {
that.reject("unauthorized request due to one of these reasons: 1. allowedPrefsToWrite field holds a non-array value; 2. one or more preference keys in the preferences - ", preferences, " - are not in the allowed list: ", authorization.allowedPrefsToWrite);
return;
}
} else {
gpii.flowManager.cloudBased.settings.put.savePrefs(that, gpiiKey, preferences);
}
} else {
that.reject("unauthorized request due to one of these reasons: 1. authorization record is missing; 2. gpiiKey associated with the authorization does not match the in-used token " + gpiiKey + "; 3. the access token is unauthorized for using PUT method at /settings endpoint.");
return;
}
}, function (error) {
that.reject(error);
return;
});
};
gpii.flowManager.cloudBased.settings.put.savePrefs = function (that, gpiiKey, preferences) {
var handlerPromise;
var gpiiKeyPromise = that.dataStore.findGpiiKey(gpiiKey);
gpiiKeyPromise.then(function (data) {
// GPII-3721: If the GPII key already exists, update its prefs safe. Otherwise, create the GPII key and its prefs safe.
if (data) {
handlerPromise = that.prefsServerDataSource.update(gpiiKey, true, preferences);
} else {
handlerPromise = that.prefsServerDataSource.create(gpiiKey, preferences);
}
fluid.log("CloudBased flowManager: SettingsPutHandler - Save the GPII key (", gpiiKey ,") with a preference set: ", preferences);
handlerPromise.then(function (response) {
// The default success response from the preference server contains the updated preferences,
that.events.onSuccess.fire({
gpiiKey: response.gpiiKey,
message: gpii.flowManager.cloudBased.settings.put.messages.success
});
}, that.events.onError.fire);
}, that.events.onError.fire);
};
gpii.flowManager.cloudBased.settings.put.reject = function (that, errorMsg) {
fluid.log("CloudBased flowManager: PUT request at /settings failed with error: ", errorMsg);
that.events.onError.fire(gpii.dbOperation.errors.unauthorized);
};
/**
* This function verifies if all preference keys are in the allowed list.
*
* @param {Object} prefs - The object that is in the path of "contexts.gpii-defaults.preferences" of a prefs safe.
* @param {Array} allowedPrefs - An array of preference keys that are allowed.
* @return {Boolean} - If all preference keys are in the allowed list, return true. Otherwise, return false.
*/
gpii.flowManager.cloudBased.settings.isPrefsAllowedToWrite = function (prefs, allowedPrefs) {
var actualPrefKeys = fluid.keys(prefs);
gpii.arrayDifference(actualPrefKeys, allowedPrefs);
return actualPrefKeys.length === 0;
};