Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/mod_security/views/addRuleController.js

/*
# templates/mod_security/views/addRuleController.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(
    [
        "angular",
        "lodash",
        "jquery",
        "cjt/util/locale",
        "cjt/util/parse",
        "uiBootstrap",
        "cjt/directives/autoFocus",
        "cjt/directives/spinnerDirective",
        "cjt/services/alertService",
        "app/services/ruleService",
    ],
    function(angular, _, $, LOCALE, PARSE) {
        "use strict";

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

        var controller = app.controller(
            "addRuleController",
            ["$scope", "$location", "$anchorScroll", "$routeParams", "$q", "spinnerAPI", "alertService", "ruleService", "PAGE",
                function($scope, $location, $anchorScroll, $routeParams, $q, spinnerAPI, alertService, ruleService, PAGE) {

                    /**
                 * Disable the save button based on form state
                 *
                 * @method disableSave
                 * @param  {FormController} form
                 * @return {Boolean}
                 */
                    $scope.disableSave = function(form) {
                        return (form.rule.$pristine && form.enabled.$pristine) || (form.$dirty && form.$invalid);
                    };

                    /**
                 * Clear the form
                 *
                 * @method clearForm
                 */
                    $scope.clearForm = function() {
                        $scope.enabled = true;
                        $scope.rule = "";
                        $scope.deploy = false;
                        $scope.clearNotices();
                    };

                    /**
                 * Clear the notices
                 *
                 * @method clearNotices
                 */
                    $scope.clearNotices = function() {
                        alertService.clear();
                        $scope.notice = "";
                    };

                    /**
                 * Navigate to the previous view.
                 *
                 * @method  cancel
                 */
                    $scope.cancel = function() {
                        $scope.clearNotices();
                        $scope.loadView("rulesList");
                    };

                    /**
                 * Save the form and navigate or clean depending on the users choices.
                 *
                 * @method save
                 * @param  {FormController} form
                 * @param  {Boolean} exit If true, will navigate back on completion, if false,
                 * will clear the form and let you add another rule.
                 * @return {Promise}
                 */
                    $scope.save = function(form, exit) {
                        $scope.clearNotices();

                        if (!form.$valid) {
                            return;
                        }

                        spinnerAPI.start("loadingSpinner");
                        return ruleService
                            .addRule($scope.rule, $scope.enabled, $scope.deploy)
                            .then(

                                /**
                                 * Handle successfully adding the rule
                                 * @method success
                                 * @private
                                 * @param  {Rule} rule Rule added to the system
                                 */
                                function success(rule) {
                                    $scope.clearNotices();
                                    form.$setPristine();
                                    spinnerAPI.stop("loadingSpinner");
                                    $scope.clearForm();

                                    alertService.add({
                                        type: "success",
                                        message: LOCALE.maketext("You have successfully saved your [asis,ModSecurity™] rule with the following ID: [_1].", _.escape(rule.id)),
                                        id: "alertAddSuccess",
                                        replace: true,
                                    });

                                    if (exit) {
                                        $scope.loadView("rulesList");
                                    } else {

                                        if ( $scope.isCopy ) {
                                            $scope.getClonedRule(rule);
                                        }

                                        // refocus the user for the next add
                                        $scope.scrollTo("top");
                                        document.getElementById("txtRuleText").focus();
                                    }
                                },

                                /**
                                 * Handle failure of adding the rule
                                 * @method failure
                                 * @private
                                 * @param  {Object} error Error from the backend.
                                 *   @param {String} message
                                 *   @param {Boolean} duplicate true if this is a duplicate queue item, false otherwise.
                                 */
                                function failure(error) {
                                    $scope.notice = "";
                                    if (error && error.duplicate) {
                                        alertService.add({
                                            type: "warning",
                                            message: LOCALE.maketext("There is a duplicate [asis,ModSecurity™] rule in the staged configuration file. You cannot add a duplicate rule."),
                                            id: "alertAddWarning",
                                        });
                                    } else {
                                        var message = error.message || error; // It can come from either structured or unstructured errors
                                        alertService.add({
                                            type: "danger",
                                            message: _.escape(message),
                                            id: "alertAddFailure",
                                        });
                                    }

                                    // ensure the error is in view and focus is in the rule field
                                    $scope.scrollTo("top");
                                    document.getElementById("txtRuleText").focus();
                                },

                                /**
                                 * Handle step wise updating
                                 * @method notify
                                 * @private
                                 * @param  {Rule} rule Rule added to the system
                                 */
                                function notify(notice) {
                                    $scope.notice += notice + "\n";
                                }
                            ).finally(function() {
                                spinnerAPI.stop("loadingSpinner");
                            });
                    };

                    /**
                 * Disable the rule that
                 *
                 * @method disableOriginalRule
                 * @param  {object}  rule            The original rule to be disabled
                 * @param  {string}  rule.id         The id of the original rule
                 * @param  {string}  rule.config     The configuration file of the original file
                 * @param  {Boolean} rule.disabled   Is the rule disabled?
                 * @return {Promise}
                 */
                    $scope.disableOriginalRule = function(rule) {
                        return ruleService
                            .disableRule(rule.config, rule.id, false)
                            .then(

                                /**
                                 * Handle successfully disabling the original rule
                                 * @method success
                                 * @private
                                 */
                                function success() {
                                    rule.disabled = true;
                                    alertService.add({
                                        type: "success",
                                        message: LOCALE.maketext("You successfully disabled the [asis,ModSecurity™] rule with the following ID: [_1]", _.escape(rule.id)),
                                        id: "alertDisableSuccess",
                                    });
                                },

                                /**
                                 * Handle failure of cloning the rule
                                 * @method failure
                                 * @private
                                 * @param  {Object} error Error from the backend.
                                 *   @param {String} message
                                 */
                                function failure(error) {
                                    var message = error.message || error;
                                    alertService.add({
                                        type: "danger",
                                        message: message,
                                        id: "alertDisableFailure",
                                    });
                                }
                            ).finally(function() {

                                // ensure the alert is in view and focus is in the rule field
                                $scope.scrollTo("top");
                                document.getElementById("txtRuleText").focus();
                            });
                    };

                    /**
                 * Retrieve a copy of the rule with a unique id
                 *
                 * @method getClonedRule
                 * @param  {object}  rule            The original rule to be cloned
                 * @param  {string}  rule.id         The id of the original rule
                 * @param  {string}  rule.config     The configuration file of the original file
                 * @param  {Boolean} rule.disabled   Is the rule disabled?
                 * @return {Promise}
                 */
                    $scope.getClonedRule = function(rule) {
                        spinnerAPI.start("loadingSpinner");
                        return ruleService
                            .cloneRule(rule.id, rule.config)
                            .then(

                                /**
                                 * Handle successfully cloning the rule
                                 * @method success
                                 * @private
                                 * @param  {Rule} rule The cloned rule with a unique id ready to be saved
                                 */
                                function success(rule) {
                                    $scope.id = rule.id;
                                    $scope.enabled = !rule.disabled;
                                    $scope.rule = rule.rule;

                                    // activate the save buttons
                                    $scope.form.rule.$pristine = false;
                                },

                                /**
                                 * Handle failure of cloning the rule
                                 * @method failure
                                 * @private
                                 * @param {Object} error           Error from the backend.
                                 * @param {String} error.message   The error message.
                                 */
                                function failure(error) {
                                    var message = error.message || error;
                                    alertService.add({
                                        type: "danger",
                                        message: _.escape(message),
                                        id: "alertCopyFailure",
                                    });

                                    // ensure the error is in view and focus is in the rule field
                                    $scope.scrollTo("top");
                                    document.getElementById("txtRuleText").focus();
                                }
                            ).finally(function() {
                                spinnerAPI.stop("loadingSpinner");
                            });
                    };

                    // Setup the installed bit...
                    $scope.isInstalled = PAGE.installed;

                    if (!$scope.isInstalled) {
                        $scope.loadView("hitList");
                    }

                    // Initialize the form on first load.
                    $scope.clearForm();

                    // check for copy of existing rule
                    if ( $location.$$path.indexOf("copy") !== -1 ) {
                        $scope.originalRule = {
                            id: $routeParams["id"],
                            config: $routeParams["config"],
                            disabled: $routeParams["disabled"],
                        };
                        if ( $scope.originalRule.id && $scope.originalRule.config ) {
                            $scope.isCopy = true;
                            $scope.getClonedRule($scope.originalRule);
                        }
                    }
                },
            ]);

        return controller;
    }
);
Back to Directory File Manager