UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

118 lines (106 loc) 5.56 kB
/* * 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 */ "use strict"; 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; };