Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/mod_security/services/configService.js

/*
# mod_security/services/configService.js          Copyright(c) 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

/* global define: false */

define(
    [

        // Libraries
        "angular",

        // CJT
        "cjt/util/locale",
        "cjt/util/parse",
        "cjt/io/api",
        "cjt/io/whm-v1-request",
        "cjt/io/whm-v1", // IMPORTANT: Load the driver so its ready

        // Angular components
        "cjt/services/APIService"
    ],
    function(angular, LOCALE, PARSE, API, APIREQUEST, APIDRIVER) {

        // Constants
        var NO_MODULE = "";

        // Fetch the current application
        var app = angular.module("App");

        /**
         * Apply the defaults to the config if needed.
         * @param  {Array} configs
         */
        function applyDefaults(config) {
            if (config.default && config.missing) {
                if (config.type === "number") {
                    config.state = parseInt(config.default, 10);
                } else {
                    config.state = config.default;
                }
            }
        }

        /**
         * Converts the response to our application data structure
         * @method convertResponseToList
         * @private
         * @param  {Object} response
         * @return {Object} Sanitized data structure.
         */
        function convertResponseToList(response) {
            var items = [];
            if (response.status) {
                var data = response.data;
                for (var i = 0, length = data.length; i < length; i++) {
                    var config = data[i];

                    // Clean up the boolean data
                    if (typeof (config.engine) !== "undefined") {
                        config.engine = PARSE.parsePerlBoolean(config.engine);
                    }

                    // Apply the default if the config is missing
                    applyDefaults(config);

                    // Mark the record as unchanged
                    config.changed = false;

                    items.push(
                        config
                    );
                }

                return items;
            } else {
                return [];
            }
        }

        /**
         * Setup the configuration models API service
         */
        app.factory("configService", ["$q", "APIService", function($q, APIService) {

            // Set up the service's constructor and parent
            var ConfigService = function() {};
            ConfigService.prototype = new APIService();

            // Extend the prototype with any class-specific functionality
            angular.extend(ConfigService.prototype, {

                /**
                 * Get a list of mod_security rule hits that match the selection criteria passed in meta parameter
                 * @return {Promise} Promise that will fulfill the request.
                 */
                fetchList: function() {
                    var apiCall = new APIREQUEST.Class();
                    apiCall.initialize(NO_MODULE, "modsec_get_settings");
                    var deferred = this.deferred(apiCall, { transformAPISuccess: convertResponseToList });
                    return deferred.promise;
                },

                /**
                 * Save the changed configurations.
                 * @param  {Array} configs
                 * @return {Promise} Promise that will fulfill the request.
                 */
                save: function(configs) {
                    if (!configs) {
                        return;
                    }

                    var toSave = [];
                    for (var i = 0, l = configs.length; i < l; i++) {
                        if (configs[i].changed) {
                            toSave.push(configs[i]);
                        }
                    }

                    if (toSave.length > 0 ) {

                        var apiCall = new APIREQUEST.Class();
                        apiCall.initialize(NO_MODULE, "modsec_batch_settings");
                        for (var j = 0, jl = toSave.length; j < jl; j++) {
                            var item = toSave[j];
                            if (
                                (!item.engine && item.default && (                                                        // Not an engine and has a default
                                    ((item.type === "text" || item.type === "radio") && (item.state === item.default)) || // Text or radio field with a default set to default, but not missing from file
                                    (item.type === "number" && (parseInt(item.state, 10) === item.default))               // Number field with a default set to default, but not missing from file
                                )) ||
                                (item.state === "") // Text or number that has been cleared, but isn't missing from file
                            ) {
                                if (!item.missing) {
                                    apiCall.addArgument("setting_id", toSave[j].setting_id, true);
                                    apiCall.addArgument("remove", 1, true);

                                    // Otherwise, nothing to do here.
                                }
                            } else {
                                apiCall.addArgument("setting_id", toSave[j].setting_id, true);
                                apiCall.addArgument("state", item.state, true);
                            }
                            apiCall.incrementAuto();
                        }
                        apiCall.addArgument("commit", 1);

                        var deferred = this.deferred(apiCall, {
                            apiSuccess: function(response, deferred) {
                                for (var i = 0, l = configs.length; i < l; i++) {
                                    if (configs[i].changed) {
                                        configs[i].changed = false;
                                    }
                                }

                                deferred.resolve(response.data);
                            },
                            apiFailure: function(response) {

                                // TODO: Get the list from the data
                                deferred.reject(response.error);
                            }
                        });

                        // pass the promise back to the controller
                        return deferred.promise;
                    }
                },

                /**
                *  Helper method that calls convertResponseToList to prepare the data structure
                * @param  {Object} response
                * @return {Object} Sanitized data structure.
                */
                prepareList: function(response) {

                    // Since this is coming from the backend, but not through the api.js layer,
                    // we need to parse it to the frontend format.
                    response = APIDRIVER.parse_response(response).parsedResponse;
                    return convertResponseToList(response);
                },

                /**
                 * Apply the defaults to the config if needed.
                 * @param  {Array} configs
                 */
                applyDefaults: applyDefaults
            });

            return new ConfigService();
        }]);
    }
);
Back to Directory File Manager