Jelajahi Sumber

Added working access rule interface

Toby Chui 11 bulan lalu
induk
melakukan
3563ee5460
4 mengubah file dengan 186 tambahan dan 52 penghapusan
  1. 11 11
      accesslist.go
  2. 6 2
      mod/access/accessRule.go
  3. 156 37
      web/components/access.html
  4. 13 2
      web/snippet/accessRuleEditor.html

+ 11 - 11
accesslist.go

@@ -178,12 +178,12 @@ func handleCountryBlacklistAdd(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
 
-	comment, _ := utils.GetPara(r, "comment")
+	comment, _ := utils.PostPara(r, "comment")
 	p := bluemonday.StripTagsPolicy()
 	comment = p.Sanitize(comment)
 
@@ -206,7 +206,7 @@ func handleCountryBlacklistRemove(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -230,7 +230,7 @@ func handleIpBlacklistAdd(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -257,7 +257,7 @@ func handleIpBlacklistRemove(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -276,7 +276,7 @@ func handleIpBlacklistRemove(w http.ResponseWriter, r *http.Request) {
 
 func handleBlacklistEnable(w http.ResponseWriter, r *http.Request) {
 	enable, _ := utils.PostPara(r, "enable")
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -346,7 +346,7 @@ func handleCountryWhitelistAdd(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -373,7 +373,7 @@ func handleCountryWhitelistRemove(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -396,7 +396,7 @@ func handleIpWhitelistAdd(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -422,7 +422,7 @@ func handleIpWhitelistRemove(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}
@@ -440,7 +440,7 @@ func handleIpWhitelistRemove(w http.ResponseWriter, r *http.Request) {
 
 func handleWhitelistEnable(w http.ResponseWriter, r *http.Request) {
 	enable, _ := utils.PostPara(r, "enable")
-	ruleID, err := utils.GetPara(r, "id")
+	ruleID, err := utils.PostPara(r, "id")
 	if err != nil {
 		ruleID = "default"
 	}

+ 6 - 2
mod/access/accessRule.go

@@ -2,6 +2,7 @@ package access
 
 import (
 	"encoding/json"
+	"errors"
 	"net"
 	"os"
 	"path/filepath"
@@ -26,14 +27,14 @@ func (s *AccessRule) AllowConnectionAccess(conn net.Conn) bool {
 
 // Toggle black list
 func (s *AccessRule) ToggleBlacklist(enabled bool) {
-	s.parent.Options.Database.Write("blackwhitelist", "blacklistEnabled", enabled)
 	s.BlacklistEnabled = enabled
+	s.SaveChanges()
 }
 
 // Toggel white list
 func (s *AccessRule) ToggleWhitelist(enabled bool) {
-	s.parent.Options.Database.Write("blackwhitelist", "whitelistEnabled", enabled)
 	s.WhitelistEnabled = enabled
+	s.SaveChanges()
 }
 
 /*
@@ -105,6 +106,9 @@ func (s *AccessRule) IsWhitelisted(ipAddr string) bool {
 
 // Update the current access rule to json file
 func (s *AccessRule) SaveChanges() error {
+	if s.parent == nil {
+		return errors.New("save failed: access rule detached from controller")
+	}
 	saveTarget := filepath.Join(s.parent.Options.ConfigFolder, s.ID+".json")
 	js, err := json.MarshalIndent(s, "", " ")
 	if err != nil {

+ 156 - 37
web/components/access.html

@@ -9,27 +9,32 @@
 <div class="standardContainer">
     <div class="ui basic segment">
         <h2>Access Control</h2>
-        <p>Setup blacklist or whitelist based on estimated IP geographic location or IP address</p>
+        <p>Setup blacklist or whitelist based on estimated IP geographic location or IP address. <br>
+            To apply access control to a proxy hosts, create a "Access Rule" below and apply it to the proxy hosts in the HTTP Proxy tab.</p>
     </div>
     <div id="currentEditingAccessRule" class="ui basic segment">
         Select an access rule to start editing
     </div>
     <div class="ui stackable grid">
         <div class="four wide column">
-            <h4>Select an Access Rule</h4>
-            <p>All proxy hosts uses the "default" access rule</p>
-            <div class="ui selection fluid dropdown">
-                <input type="hidden" name="targetAccessRule" value="default">
+            <h4>Select a rule to configure</h4>
+            <p>All proxy hosts uses the "default" access rule if no rule is set.</p>
+            <div class="ui selection fluid dropdown" id="accessRuleSelector">
+                <input type="hidden" name="targetAccessRule" value="default" onchange="handleSelectedAccessRuleChange(this.value);">
                 <i class="dropdown icon"></i>
                 <div class="default text"></div>
-                <div class="menu">
+                <div class="menu" id="accessRuleList">
                   <div class="item" data-value="default"><i class="ui yellow star icon"></i> Default</div>
                 </div>
             </div>
+            <div class="ui message">
+                <p id="accessRuleDesc"></p>
+            </div>
+            
             <div class="ui divider"></div>
             <div style="width: 100%;" align="center">
                 <button class="ui basic circular icon button" onclick="openAccessRuleEditor();" title="Edit Access Rules"><i class="ui edit icon"></i></button>
-                <button class="ui basic circular icon button" onclick="reloadAccessRules();"><i class="ui green refresh icon"></i></button>
+                <button class="ui basic circular icon button" onclick="reloadAccessRulesWithFeedback();"><i class="ui green refresh icon"></i></button>
             </div>
         </div>
         <div class="twelve wide column">
@@ -704,16 +709,128 @@
     /*
         Access Control
     */
+   var currentEditingAccessRule = "default"; //ID of the current editing access rule
+   var currentListOfAccessRules = [];
+  
     $(".dropdown").dropdown();
     $('.menu .accesscontrol.item').tab();
     $('.menu .accesscontrol.item').addClass("activated");
 
+    /* Access Rule Selector */
     function openAccessRuleEditor(){
         showSideWrapper('snippet/accessRuleEditor.html');
     }
+
+    function reloadAccessRulesWithFeedback(){
+        reloadAccessRules(function(){
+            msgbox("Access Rules Reloaded", true);
+        });
+    }
     
-    function reloadAccessRules(){
+    function reloadAccessRules(callback=undefined){
+        initAccessRuleList(function(){
+            //Check if the previous access rule is still there
+            let stillExists = false;
+            for (var i = 0; i < currentListOfAccessRules.length; i++){
+                let thisAccessRule = currentListOfAccessRules[i];
+                if (thisAccessRule.ID == currentEditingAccessRule){
+                    stillExists = true;
+                    break;
+                }
+            }
 
+            if (stillExists){
+                handleSelectedAccessRuleChange(currentEditingAccessRule);
+                $("#accessRuleSelector").dropdown("set selected", currentEditingAccessRule);
+            }else{
+                handleSelectedAccessRuleChange("default");
+                $("#accessRuleSelector").dropdown("set selected", "default");
+            }
+
+            if (callback != undefined){
+                callback();
+            }
+            
+        });
+    }
+
+    function initAccessRuleList(callback=undefined){
+        $.get("/api/access/list", function(data){
+            if (data.error == undefined){
+                $("#accessRuleList").html("");
+                data.forEach(function(rule){
+                    let icon = `<i class="ui grey filter icon"></i>`;
+                    if (rule.ID == "default"){
+                        icon = `<i class="ui yellow star icon"></i>`;
+                    }else if (rule.BlacklistEnabled && !rule.WhitelistEnabled){
+                        //This is a blacklist filter
+                        icon = `<i class="ui red filter icon"></i>`;
+                    }else if (rule.WhitelistEnabled && !rule.BlacklistEnabled){
+                        //This is a whitelist filter
+                        icon = `<i class="ui green filter icon"></i>`;
+                    }
+                    $("#accessRuleList").append(`<div class="item" data-value="${rule.ID}">${icon} ${rule.Name}</div>`);
+                });
+                currentListOfAccessRules = data;
+                $(".dropdown").dropdown();
+                if (callback != undefined){
+                    callback();
+                }
+            }else{
+                msgbox("Access rule load failed: " + data.error, false);
+            }
+        })
+    }
+
+    //Load default when the page is first loaded
+    initAccessRuleList(function(){
+        $("#accessRuleSelector").dropdown("set selected", "default");
+        for (var i = 0; i < currentListOfAccessRules.length; i++){
+            let thisAccessRule = currentListOfAccessRules[i];
+            if (thisAccessRule.ID == "default"){
+                $("#currentEditingAccessRule").html(`Editing Access Rule: ${thisAccessRule.Name} <span style="font-weight: 300;">[${thisAccessRule.ID}]</span>`);
+                $("#accessRuleDesc").text(thisAccessRule.Desc);
+                break;
+            }
+        }
+        initBlackWhitelistTables();
+    });
+
+    //On dropdown change on access rule selection
+    function handleSelectedAccessRuleChange(newRuleUUID){
+        currentEditingAccessRule = newRuleUUID;
+        //Load the name and desc of this acess rule
+        let name = "";
+        let desc = "";
+        for (var i = 0; i < currentListOfAccessRules.length; i++){
+            let thisAccessRule = currentListOfAccessRules[i];
+            if (thisAccessRule.ID == newRuleUUID){
+                name = thisAccessRule.Name;
+                desc = thisAccessRule.Desc;
+                break;
+            }
+        }
+        $("#currentEditingAccessRule").html(`Editing Access Rule: ${name} <span style="font-weight: 300;">[${newRuleUUID}]</span>`);
+        $("#accessRuleDesc").text(desc);
+
+        initBlackWhitelistTables();
+    }
+    
+    //Load all the black white lists
+    function initBlackWhitelistTables(){
+        //Remove event listener on both toggle buttons
+        $("#enableWhitelist").off("change");
+        $("#enableBlacklist").off("change");
+
+        //Initialize the button states
+        initBlacklistEnableState();
+        initWhitelistEnableState();
+
+        //Update the lists
+        initBannedCountryList();
+        initIpBanTable()
+        initWhitelistCountryList();
+        initIpWhitelistTable();
     }
 
     /*
@@ -722,7 +839,7 @@
 
     //Blacklist country table
     function initBannedCountryList(){
-        $.get("/api/blacklist/list?type=country", function(data) {
+        $.get("/api/blacklist/list?type=country&id=" + currentEditingAccessRule, function(data) {
             let bannedListHtml = '';
             data.forEach((countryCode) => {
                 bannedListHtml += `
@@ -747,11 +864,10 @@
 
         });
     }
-    initBannedCountryList();
 
     //Blacklist ip table
     function initIpBanTable(){
-        $.get('/api/blacklist/list?type=ip', function(data) {
+        $.get('/api/blacklist/list?type=ip&id=' + currentEditingAccessRule, function(data) {
             $('#blacklistIpTable').html("");
             if (data.length === 0) {
                 $('#blacklistIpTable').append(`
@@ -779,28 +895,30 @@
             initBlacklistQuickBanTable();
         });
     }
-    initIpBanTable();
+
 
     //Init blacklist state
     function initBlacklistEnableState(){
-        $.get('/api/blacklist/enable', function(data){
+        $.get('/api/blacklist/enable?id=' + currentEditingAccessRule, function(data){
             if (data == true){
                 $('#enableBlacklist').parent().checkbox("set checked");
+                $("#ipTable").removeClass("disabled");
             }else{
+                $('#enableBlacklist').parent().checkbox("set unchecked");
                 $("#ipTable").addClass("disabled");
             }
 
             //Register on change event
-            $("#enableBlacklist").on("change", function(){
+            $("#enableBlacklist").off("change").on("change", function(){
                 enableBlacklist();
             })
         });
     }
-    initBlacklistEnableState();
+    
 
     //Whitelist country table
     function initWhitelistCountryList(){
-        $.get("/api/whitelist/list?type=country", function(data) {
+        $.get("/api/whitelist/list?type=country&id=" + currentEditingAccessRule, function(data) {
             let bannedListHtml = '';
             data.forEach((countryWhitelistEntry) => {
                 let countryCode = countryWhitelistEntry.CC;
@@ -826,11 +944,11 @@
 
         });
     }
-    initWhitelistCountryList();
+    
 
     //Whitelist ip table
     function initIpWhitelistTable(){
-        $.get('/api/whitelist/list?type=ip', function(data) {
+        $.get('/api/whitelist/list?type=ip&id=' + currentEditingAccessRule, function(data) {
             $('#whitelistIpTable').html("");
             if (data.length === 0) {
                 $('#whitelistIpTable').append(`
@@ -859,23 +977,24 @@
 
         });
     }
-    initIpWhitelistTable();
+    
 
     //Init whitelist state
     function initWhitelistEnableState(){
-        $.get('/api/whitelist/enable', function(data){
+        $.get('/api/whitelist/enable?id=' + currentEditingAccessRule, function(data){
             if (data == true){
                 $('#enableWhitelist').parent().checkbox("set checked");
+            }else{
+                $('#enableWhitelist').parent().checkbox("set unchecked");
             }
 
             //Register on change event
-            $("#enableWhitelist").on("change", function(){
+            $("#enableWhitelist").off("change").on("change", function(){
                 enableWhitelist();
             })
         });
     }
-    initWhitelistEnableState();
-
+    
     /*
         Blacklist API Calls
     */
@@ -884,7 +1003,7 @@
         $.ajax({
             type: 'POST',
             url: '/api/blacklist/enable',
-            data: { enable: isChecked },
+            data: { enable: isChecked, id: currentEditingAccessRule},
             success: function(data){
                 if (isChecked){
                     $("#ipTable").removeClass("disabled");
@@ -903,10 +1022,10 @@
         $.ajax({
             type: "POST",
             url: "/api/blacklist/country/add",
-            data: { cc: countryCode },
+            data: { cc: countryCode, id: currentEditingAccessRule},
             success: function(response) {
                 if (response.error != undefined){
-                    alert(response.error);
+                    msgbox(response.error, false);
                 }
                 initBannedCountryList();
             },
@@ -922,10 +1041,10 @@
             $.ajax({
                 url: "/api/blacklist/country/remove",
                 method: "POST",
-                data: { cc: countryCode },
+                data: { cc: countryCode, id: currentEditingAccessRule},
                 success: function(response) {
                     if (response.error != undefined){
-                        alert(response.error);
+                        msgbox(response.error, false);
                     }
                     initBannedCountryList();
                 },
@@ -952,7 +1071,7 @@
         $.ajax({
             url: "/api/blacklist/ip/add",
             type: "POST",
-            data: {ip: targetIp.toLowerCase()},
+            data: {ip: targetIp.toLowerCase(), id: currentEditingAccessRule},
             success: function(response) {
                 if (response.error !== undefined) {
                     msgbox(response.error, false, 6000);
@@ -974,7 +1093,7 @@
             $.ajax({
                 url: "/api/blacklist/ip/remove",
                 type: "POST",
-                data: {ip: ipaddr.toLowerCase()},
+                data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
                 success: function(response) {
                     if (response.error !== undefined) {
                         msgbox(response.error, false, 6000);
@@ -998,7 +1117,7 @@
         $.ajax({
             type: 'POST',
             url: '/api/whitelist/enable',
-            data: { enable: isChecked },
+            data: { enable: isChecked , id: currentEditingAccessRule},
             success: function(data){
                 $(".toggleSucc").stop().finish().fadeIn("fast").delay(3000).fadeOut("fast");
             }
@@ -1011,10 +1130,10 @@
         $.ajax({
             type: "POST",
             url: "/api/whitelist/country/add",
-            data: { cc: countryCode },
+            data: { cc: countryCode , id: currentEditingAccessRule},
             success: function(response) {
                 if (response.error != undefined){
-                    alert(response.error);
+                    msgbox(response.error, false);
                 }
                 initWhitelistCountryList();
             },
@@ -1030,10 +1149,10 @@
             $.ajax({
                 url: "/api/whitelist/country/remove",
                 method: "POST",
-                data: { cc: countryCode },
+                data: { cc: countryCode , id: currentEditingAccessRule},
                 success: function(response) {
                     if (response.error != undefined){
-                        alert(response.error);
+                        msgbox(response.error, false);
                     }
                     initWhitelistCountryList();
                 },
@@ -1061,7 +1180,7 @@
         $.ajax({
             url: "/api/whitelist/ip/add",
             type: "POST",
-            data: {ip: targetIp.toLowerCase(), "comment": remarks},
+            data: {ip: targetIp.toLowerCase(), "comment": remarks, id: currentEditingAccessRule},
             success: function(response) {
                 if (response.error !== undefined) {
                     msgbox(response.error, false, 6000);
@@ -1084,7 +1203,7 @@
             $.ajax({
                 url: "/api/whitelist/ip/remove",
                 type: "POST",
-                data: {ip: ipaddr.toLowerCase()},
+                data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
                 success: function(response) {
                     if (response.error !== undefined) {
                         msgbox(response.error, false, 6000);

+ 13 - 2
web/snippet/accessRuleEditor.html

@@ -72,7 +72,7 @@
         </form>
     </div>
     <br>
-    <button class="ui basic button"  style="float: right;" onclick="parent.hideSideWrapper();"><i class="remove icon"></i> Cancel</button>
+    <button class="ui basic button"  style="float: right;" onclick="parent.hideSideWrapper();"><i class="remove icon"></i> Close</button>
     <br><br><br>
   </div>
 
@@ -90,6 +90,9 @@
         console.log('Access Rule Name:', accessRuleName);
         console.log('Description:', description);
         
+        $("#accessRuleForm input[name='accessRuleName']").val("");
+        $("#accessRuleForm textarea[name='description']").val("");
+
         $.ajax({
             url: "/api/access/create",
             method: "POST",
@@ -103,6 +106,9 @@
                 }else{
                     parent.msgbox("Access Rule Created", true);
                     reloadAccessRuleList();
+                    if (parent != undefined && parent.reloadAccessRules != undefined){
+                        parent.reloadAccessRules();
+                    }
                 }
             }
         })
@@ -114,7 +120,6 @@
         console.log('Selected Value:', selectedValue);
         //Load the information from list
         loadAccessRuleInfoIntoEditFields(selectedValue);
-
     }
 
     //Load the access rules information into the fields
@@ -173,6 +178,9 @@
                         $("#accessRuleSelector").dropdown("set selected", accessRuleUUID);
                         loadAccessRuleInfoIntoEditFields(accessRuleUUID);
                     });
+                    if (parent != undefined && parent.reloadAccessRules != undefined){
+                        parent.reloadAccessRules();
+                    }
                 }
             }
         })
@@ -241,6 +249,9 @@
                     }else{
                         parent.msgbox("Access rule removed", true);
                         reloadAccessRuleList();
+                        if (parent != undefined && parent.reloadAccessRules != undefined){
+                            parent.reloadAccessRules();
+                        }
                     }
                 }
             })