]> source.dussan.org Git - rspamd.git/commitdiff
[WebUI] Add ability to compute fuzzy hashes 4499/head
authormoisseev <moiseev@mezonplus.ru>
Fri, 26 May 2023 13:12:23 +0000 (16:12 +0300)
committermoisseev <moiseev@mezonplus.ru>
Fri, 26 May 2023 13:12:23 +0000 (16:12 +0300)
from sample message source

interface/index.html
interface/js/app/upload.js

index 2fad32b2f7fd98ff8dba7a9c11c9e3a668c956bb..ca991a8d2e305d8262c06b87e70ffd34a549be6b 100644 (file)
                                                        </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>
                                        </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>
index f9f6c53c638578755a33a7dcb44090e7856488ee..1145db7854499a1c8f539f0909e2a313d94c87a3 100644 (file)
@@ -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;
     });