From 0530f0edbf57db8f8765be523bd1ad8f2f3deac8 Mon Sep 17 00:00:00 2001
From: Eric P
Date: Thu, 9 Feb 2023 09:14:36 +0100
Subject: [PATCH] gui: Add xattr filter editor (fixes #8660) (#8734)
---
gui/default/assets/css/overrides.css | 4 +
.../syncthing/core/syncthingController.js | 79 +++++++++++++++++++
.../syncthing/folder/editFolderModalView.html | 56 +++++++++++++
3 files changed, 139 insertions(+)
diff --git a/gui/default/assets/css/overrides.css b/gui/default/assets/css/overrides.css
index 47147f3d2..06f705629 100644
--- a/gui/default/assets/css/overrides.css
+++ b/gui/default/assets/css/overrides.css
@@ -144,6 +144,10 @@ table.table-auto td {
max-width: 0px;
}
+td input[type="checkbox"] {
+ margin-top: 13px;
+}
+
/* Remote Devices connection-quality indicator */
.reception-0 {
background: url('../../vendor/bootstrap/fonts/reception-0.svg') no-repeat;
diff --git a/gui/default/syncthing/core/syncthingController.js b/gui/default/syncthing/core/syncthingController.js
index f61f0b0cf..495e4e1b0 100755
--- a/gui/default/syncthing/core/syncthingController.js
+++ b/gui/default/syncthing/core/syncthingController.js
@@ -2301,6 +2301,7 @@ angular.module('syncthing.core')
return;
}
+ $scope.validateXattrFilter();
var folderCfg = angular.copy($scope.currentFolder);
$scope.currentSharing.selected[$scope.myID] = true;
var newDevices = [];
@@ -3330,6 +3331,84 @@ angular.module('syncthing.core')
$scope.showTemporaryTooltip(event, message);
};
+
+ $scope.newXattrEntry = function () {
+ var entries = $scope.currentFolder.xattrFilter.entries;
+ var newEntry = {match: '', permit: false};
+
+ if (entries.some(function (n) {
+ return n.match == '';
+ })) {
+ return;
+ }
+
+ if (entries.length > 0 && entries[entries.length -1].match === '*') {
+ if (newEntry.match !== '*') {
+ entries.splice(entries.length - 1, 0, newEntry);
+ }
+
+ return;
+ }
+
+ entries.push(newEntry);
+ };
+
+ $scope.removeXattrEntry = function (entry) {
+ $scope.currentFolder.xattrFilter.entries = $scope.currentFolder.xattrFilter.entries.filter(function (n) {
+ return n !== entry;
+ });
+ };
+
+ $scope.getXattrHint = function () {
+ var xattrFilter = $scope.currentFolder.xattrFilter;
+ if (xattrFilter == null || xattrFilter == {}) {
+ return '';
+ }
+ var filterEntries = xattrFilter.entries;
+ if (filterEntries.length === 0) {
+ return '';
+ }
+
+ // When the user explicitely added a wild-card, we don't show hints.
+ if (filterEntries.length === 1 && filterEntries[0].match === '*') {
+ return '';
+ }
+ // If all the filter entries are 'deny', we suggest adding a permit-any
+ // rule in the end since the default is already deny in that case.
+ if (filterEntries.every(function (entry) {
+ return entry.permit === false;
+ })) {
+ return $translate.instant('Hint: only deny-rules detected while the default is deny. Consider adding "permit any" as last rule.');
+ }
+
+ return '';
+ };
+
+ $scope.getXattrDefault = function () {
+ var xattrFilter = $scope.currentFolder.xattrFilter;
+ if (xattrFilter == null || xattrFilter == {}) {
+ return '';
+ }
+
+ var filterEntries = xattrFilter.entries;
+ // No entries present, default is thus 'allow'
+ if (filterEntries.length === 0) {
+ return $translate.instant('permit');
+ }
+ // If any rule is present and the last entry isn't a wild-card, the default is deny.
+ if (filterEntries[filterEntries.length -1].match !== '*') {
+ return $translate.instant('deny');
+ }
+
+ return '';
+ };
+
+ $scope.validateXattrFilter = function () {
+ // Fitlering out empty rules when saving the config
+ $scope.currentFolder.xattrFilter.entries = $scope.currentFolder.xattrFilter.entries.filter(function (n) {
+ return n.match !== "";
+ });
+ };
})
.directive('shareTemplate', function () {
return {
diff --git a/gui/default/syncthing/folder/editFolderModalView.html b/gui/default/syncthing/folder/editFolderModalView.html
index a21c45472..6564479d0 100644
--- a/gui/default/syncthing/folder/editFolderModalView.html
+++ b/gui/default/syncthing/folder/editFolderModalView.html
@@ -323,7 +323,63 @@
+
+
+
+
+
+ Help
+
+
+
+
+ To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.
+
+
+
+
+
+
+
+ No rules set
+
+
+ Default: {{getXattrDefault()}}
+
+
+ {{getXattrHint()}}
+
+
+
+
+
+
+
+
+
+
+
+