commit aed812a: [WebUI] Add ability to compute fuzzy hashes

moisseev moiseev at mezonplus.ru
Sat May 27 11:14:05 UTC 2023


Author: moisseev
Date: 2023-05-26 16:12:23 +0300
URL: https://github.com/rspamd/rspamd/commit/aed812a7388be8fb9217e4c75a19d12f0e27c324 (refs/pull/4499/head)

[WebUI] Add ability to compute fuzzy hashes
from sample message source

---
 interface/index.html       | 37 ++++++++++++++++++++++++++-----
 interface/js/app/upload.js | 54 ++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/interface/index.html b/interface/index.html
index 2fad32b2f..ca991a8d2 100644
--- a/interface/index.html
+++ b/interface/index.html
@@ -427,11 +427,18 @@
 							</form>
 						</div>
 					</div>
-					<div class="card-footer">
-						<button type="submit" class="btn btn-primary" data-upload="scan"><i class="fas fa-search"></i> Scan message</button>
-						<div class="float-end">
-							<button class="btn btn-secondary d-inline-block" id="scanOptionsToggle" data-bs-toggle="collapse" data-bs-target="#scanOptions"><i class="fas fa-bars"></i> Options</button>
-							<button class="btn btn-secondary ms-2" id="scanClean"><i class="fas fa-trash-alt"></i> Clean form</button>
+					<div class="card-footer d-md-flex justify-content-between py-1">
+						<div class="input-group d-inline-flex w-auto my-1">
+							<button type="submit" class="btn btn-primary" data-upload="scan"><i class="fas fa-search"></i> Scan message</button>
+							<button class="btn btn-secondary d-inline-block" id="scanOptionsToggle" data-bs-toggle="collapse" data-bs-target="#scanOptions"><i class="fas 	fa-bars"></i> Options</button>
+						</div>
+						<div class="input-group d-inline-flex w-auto my-1">
+							<label for="fuzzy-flag" class="input-group-text">Flag</label>
+							<input id="fuzzy-flag" class="form-control" value="1" min="1" type="number">
+							<button class="btn btn-warning" data-upload="compute-fuzzy"><i class="fas fa-hashtag"></i> Compute fuzzy hashes</button>
+						</div>
+						<div class="float-end my-1">
+							<button class="btn btn-secondary" id="scanClean"><i class="fas fa-trash-alt"></i> Clean form</button>
 						</div>
 					</div>
 				</div>
@@ -480,6 +487,26 @@
 					</div>
 				</div>
 
+				<div id="hash-card" class="card bg-light shadow my-3" style="display: none;">
+					<div class="card-header text-secondary py-2">
+						<span class="icon me-3"><i class="fas fa-hashtag"></i></span>
+						<span class="h6 fw-bolder my-2">Fuzzy hashes</span>
+						<button type="button" class="card-close-btn btn-close float-end" aria-label="Close"></button>
+					</div>
+						<div class="card-body p-0 table-responsive">
+							<table class="table status-table table-sm table-bordered text-nowrap mb-0" id="hashTable">
+								<thead class="text-secondary">
+									<tr>
+										<th>Rule name</th>
+										<th>Hashes</th>
+									</tr>
+								</thead>
+								<tbody>
+								</tbody>
+							</table>
+						</div>
+				</div>
+
 				<div class="card bg-light shadow my-3">
 					<div class="card-header text-secondary py-1 d-flex">
 						<span class="icon me-3"><i class="fas fa-eye"></i></span>
diff --git a/interface/js/app/upload.js b/interface/js/app/upload.js
index f9f6c53c6..1145db785 100644
--- a/interface/js/app/upload.js
+++ b/interface/js/app/upload.js
@@ -139,8 +139,13 @@ define(["jquery"],
             }];
         }
 
+        function get_server(rspamd) {
+            var checked_server = rspamd.getSelector("selSrv");
+            return (checked_server === "All SERVERS") ? "local" : checked_server;
+        }
+
         // @upload text
-        function scanText(rspamd, tables, data, server, headers) {
+        function scanText(rspamd, tables, data, headers) {
             rspamd.query("checkv2", {
                 data: data,
                 params: {
@@ -195,7 +200,39 @@ define(["jquery"],
                         rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data");
                     }
                 },
-                server: server
+                server: get_server(rspamd)
+            });
+        }
+
+        function getFuzzyHashes(rspamd, data) {
+            function fillHashTable(rules) {
+                $("#hashTable tbody").empty();
+                for (const [rule, hashes] of Object.entries(rules)) {
+                    hashes.forEach(function (hash, i) {
+                        $("#hashTable tbody").append("<tr>" +
+                          (i === 0 ? '<td rowspan="' + Object.keys(hashes).length + '">' + rule + "</td>" : "") +
+                          "<td>" + hash + "</td></tr>");
+                    });
+                }
+                $("#hash-card").slideDown();
+            }
+
+            rspamd.query("plugins/fuzzy/hashes?flag=" + $("#fuzzy-flag").val(), {
+                data: data,
+                params: {
+                    processData: false,
+                },
+                method: "POST",
+                success: function (neighbours_status) {
+                    var json = neighbours_status[0].data;
+                    if (json.success) {
+                        rspamd.alertMessage("alert-success", "Message successfully processed");
+                        fillHashTable(json.hashes);
+                    } else {
+                        rspamd.alertMessage("alert-error", "Unexpected error processing message");
+                    }
+                },
+                server: get_server(rspamd)
             });
         }
 
@@ -230,22 +267,26 @@ define(["jquery"],
                 $("html, body").animate({scrollTop:0}, 1000);
                 return false;
             });
-            // @init upload
+
+            $(".card-close-btn").on("click", function () {
+                $(this).closest(".card").slideUp();
+            });
+
             $("[data-upload]").on("click", function () {
                 var source = $(this).data("upload");
                 var data = $("#scanMsgSource").val();
                 var headers = {};
                 if ($.trim(data).length > 0) {
                     if (source === "scan") {
-                        var checked_server = rspamd.getSelector("selSrv");
-                        var server = (checked_server === "All SERVERS") ? "local" : checked_server;
                         headers = ["IP", "User", "From", "Rcpt", "Helo", "Hostname"].reduce(function (o, header) {
                             var value = $("#scan-opt-" + header.toLowerCase()).val();
                             if (value !== "") o[header] = value;
                             return o;
                         }, {});
                         if ($("#scan-opt-pass-all").prop("checked")) headers.Pass = "all";
-                        scanText(rspamd, tables, data, server, headers);
+                        scanText(rspamd, tables, data, headers);
+                    } else if (source === "compute-fuzzy") {
+                        getFuzzyHashes(rspamd, data);
                     } else {
                         if (source === "fuzzy") {
                             headers = {
@@ -262,6 +303,5 @@ define(["jquery"],
             });
         };
 
-
         return ui;
     });


More information about the Commits mailing list