luci-app-banip: sync with banIP-1.6.0-1 master
authorDirk Brenken <[email protected]>
Thu, 4 Dec 2025 19:28:42 +0000 (20:28 +0100)
committerDirk Brenken <[email protected]>
Thu, 4 Dec 2025 19:29:01 +0000 (20:29 +0100)
Signed-off-by: Dirk Brenken <[email protected]>
applications/luci-app-banip/Makefile
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/custom.css
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/firewall_log.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/logtemplate.js
applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js
applications/luci-app-banip/root/usr/share/rpcd/acl.d/luci-app-banip.json

index 6b00a4cc02a33f7ce715e339207412d25df5e923..ce20f7740e09953972849e4bb632a62e086043fb 100644 (file)
@@ -6,6 +6,8 @@ include $(TOPDIR)/rules.mk
 LUCI_TITLE:=LuCI support for banIP
 LUCI_DEPENDS:=+luci-base +banip
 
+PKG_VERSION:=1.6.0
+PKG_RELEASE:=1
 PKG_LICENSE:=Apache-2.0
 PKG_MAINTAINER:=Dirk Brenken <[email protected]>
 
index 24d9438b765e04fca07fc3bbf9e4e6d7007d3fdd..43f62cd8db606cffd156372706941752958bf631 100644 (file)
@@ -3,25 +3,29 @@
 'require fs';
 'require ui';
 
-let localFile = '/etc/banip/banip.allowlist';
-let notMsg, errMsg;
+const localFile = '/etc/banip/banip.allowlist';
+let notMsg = false, errMsg = false;
+
+const resetScroll = () => {
+       document.body.scrollTop = document.documentElement.scrollTop = 0;
+};
 
 return view.extend({
        load: function () {
                return L.resolveDefault(fs.stat(localFile), "")
-                       .then(function (stat) {
-                               if (!stat) {
-                                       return fs.write(localFile, "");
-                               }
-                               return Promise.all([
-                                       L.resolveDefault(fs.stat(localFile), ""),
-                                       L.resolveDefault(fs.read_direct(localFile), "")
-                               ]);
-                       });
+               .then(function (stat) {
+                       if (!stat) {
+                               return fs.write(localFile, "");
+                       }
+                       return Promise.all([
+                               L.resolveDefault(fs.stat(localFile), ""),
+                               L.resolveDefault(fs.read_direct(localFile), "")
+                       ]);
+               });
        },
        render: function (allowlist) {
                if (allowlist[0].size >= 100000) {
-                       document.body.scrollTop = document.documentElement.scrollTop = 0;
+                       resetScroll();
                        ui.addNotification(null, E('p', _('The allowlist is too big, unable to save modifications.')), 'error');
                }
                return E('div', { 'class': 'cbi-section cbi-section-descr' }, [
@@ -36,22 +40,22 @@ return view.extend({
                ]);
        },
        handleSave: function (ev) {
-               let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
-               return fs.write(localFile, value)
-                       .then(function () {
-                               document.querySelector('textarea').value = value;
-                               document.body.scrollTop = document.documentElement.scrollTop = 0;
-                               if (!notMsg) {
-                                       ui.addNotification(null, E('p', _('Allowlist modifications have been saved, reload banIP that changes take effect.')), 'info');
-                                       notMsg = true;
-                               }
-                       }).catch(function (e) {
-                               document.body.scrollTop = document.documentElement.scrollTop = 0;
-                               if (!errMsg) {
-                                       ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
-                                       errMsg = true;
-                               }
-                       });
+               let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n?/g, '\n'));
+               return fs.write(localFile, value + "\n")
+               .then(function () {
+                       document.querySelector('textarea').value = value;
+                       resetScroll();
+                       if (!notMsg) {
+                               ui.addNotification(null, E('p', _('Allowlist modifications have been saved, reload banIP that changes take effect.')), 'info');
+                               notMsg = true;
+                       }
+               }).catch(function (e) {
+                       resetScroll();
+                       if (!errMsg) {
+                               ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
+                               errMsg = true;
+                       }
+               });
        },
        handleSaveApply: null,
        handleReset: null
index 3a9c478da865028eedb691b61d01933ce45b359a..a676bc8cc56d56e19119cb03ee872d499ba53e6d 100644 (file)
@@ -3,25 +3,29 @@
 'require fs';
 'require ui';
 
-let localFile = '/etc/banip/banip.blocklist';
-let notMsg, errMsg;
+const localFile = '/etc/banip/banip.blocklist';
+let notMsg = false, errMsg = false;
+
+const resetScroll = () => {
+       document.body.scrollTop = document.documentElement.scrollTop = 0;
+};
 
 return view.extend({
        load: function () {
                return L.resolveDefault(fs.stat(localFile), "")
-                       .then(function (stat) {
-                               if (!stat) {
-                                       return fs.write(localFile, "");
-                               }
-                               return Promise.all([
-                                       L.resolveDefault(fs.stat(localFile), ""),
-                                       L.resolveDefault(fs.read_direct(localFile), "")
-                               ]);
-                       });
+               .then(function (stat) {
+                       if (!stat) {
+                               return fs.write(localFile, "");
+                       }
+                       return Promise.all([
+                               L.resolveDefault(fs.stat(localFile), ""),
+                               L.resolveDefault(fs.read_direct(localFile), "")
+                       ]);
+               });
        },
        render: function (blocklist) {
                if (blocklist[0].size >= 100000) {
-                       document.body.scrollTop = document.documentElement.scrollTop = 0;
+                       resetScroll();
                        ui.addNotification(null, E('p', _('The blocklist is too big, unable to save modifications.')), 'error');
                }
                return E('div', { 'class': 'cbi-section cbi-section-descr' }, [
@@ -36,22 +40,22 @@ return view.extend({
                ]);
        },
        handleSave: function (ev) {
-               let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
-               return fs.write(localFile, value)
-                       .then(function () {
-                               document.querySelector('textarea').value = value;
-                               document.body.scrollTop = document.documentElement.scrollTop = 0;
-                               if (!notMsg) {
-                                       ui.addNotification(null, E('p', _('Blocklist modifications have been saved, reload banIP that changes take effect.')), 'info');
-                                       notMsg = true;
-                               }
-                       }).catch(function (e) {
-                               document.body.scrollTop = document.documentElement.scrollTop = 0;
-                               if (!errMsg) {
-                                       ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
-                                       errMsg = true;
-                               }
-                       });
+               let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n?/g, '\n'));
+               return fs.write(localFile, value + "\n")
+               .then(function () {
+                       document.querySelector('textarea').value = value;
+                       resetScroll();
+                       if (!notMsg) {
+                               ui.addNotification(null, E('p', _('Blocklist modifications have been saved, reload banIP that changes take effect.')), 'info');
+                               notMsg = true;
+                       }
+               }).catch(function (e) {
+                       resetScroll();
+                       if (!errMsg) {
+                               ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
+                               errMsg = true;
+                       }
+               });
        },
        handleSaveApply: null,
        handleReset: null
index d79e6f987b46ffd29bea030b784995121e2c18b5..8895f27dfa1d5b653e56c26329058796f4a914dc 100644 (file)
@@ -3,7 +3,6 @@
        margin-bottom: -5px;
        padding-top: 0rem;
 }
-
 .cbi-input-select {
        margin-bottom: -5px;
        padding-top: 0rem;
index 7ed6580bc05c5a1eacf63c147d00bafb6d6ad1d0..5f54db7debe8afd971774288e6b4a0f63c53ef64 100644 (file)
@@ -1,4 +1,4 @@
 'use strict';
 'require view.banip.logtemplate as LogTemplate';
 
-return LogTemplate.Logview('banIP/', 'banIP');
+return LogTemplate.Logview(' banIP/', 'banIP');
index 23a8fbebe77245c4cdf6b42b905ae6f594793b91..10c552721f3fee1f2134633f4305b07070cd33b6 100644 (file)
@@ -1,33 +1,54 @@
 'use strict';
-'require fs';
+'require rpc';
+
+const callLogRead = rpc.declare({
+       object: 'log',
+       method: 'read',
+       params: ['lines', 'stream', 'oneshot'],
+       expect: {}
+});
 
 function Logview(logtag, name) {
        return L.view.extend({
-               load: function() {
-                       return Promise.all([
-                               L.resolveDefault(fs.stat('/sbin/logread'), null),
-                               L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
-                       ]);
-               },
+               load: () => Promise.resolve(),
 
-               render: function(stat) {
-                       let logger = stat[0]?.path || stat[1]?.path || null;
+               render: () => {
+                       L.Poll.add(() => {
+                               return callLogRead(1000, false, true).then(res => {
+                                       const logEl = document.getElementById('logfile');
+                                       if (!logEl) return;
 
-                       if (!logger) {
-                               return E('div', { class: 'error' }, _('logread not found on system.'));
-                       }
-                       L.Poll.add(function() {
-                               return L.resolveDefault(fs.exec_direct(logger, ['-e', logtag])).then(function(res) {
-                                       var log = document.getElementById('logfile');
-                                       if (log) {
-                                               log.value = res ? res.trim() : _('No %s related logs yet!').format(name);
-                                               log.scrollTop = log.scrollHeight;
+                                       const entries = res?.log ?? [];
+                                       if (entries.length > 0) {
+                                               const filtered = entries
+                                                       .filter(entry => !logtag || entry.msg.includes(logtag))
+                                                       .map(entry => {
+                                                               const d = new Date(entry.time);
+                                                               const date = d.toLocaleDateString([], {
+                                                                       year: 'numeric',
+                                                                       month: '2-digit',
+                                                                       day: '2-digit'
+                                                               });
+                                                               const time = d.toLocaleTimeString([], {
+                                                                       hour: '2-digit',
+                                                                       minute: '2-digit',
+                                                                       second: '2-digit',
+                                                                       hour12: false
+                                                               });
+                                                               return `[${date}-${time}] ${entry.msg}`;
+                                                       });
+                                               logEl.value = filtered.join('\n');
+                                       } else {
+                                               logEl.value = _('No %s related logs yet!').format(name);
                                        }
+                                       logEl.scrollTop = logEl.scrollHeight;
                                });
                        });
+
                        return E('div', { class: 'cbi-map' }, [
                                E('div', { class: 'cbi-section' }, [
-                                       E('div', { class: 'cbi-section-descr' }, _('The syslog output, pre-filtered for messages related to: %s').format(name)),
+                                       E('div', { class: 'cbi-section-descr' },
+                                               _('The syslog output, pre-filtered for messages related to: %s').format(name)),
                                        E('textarea', {
                                                id: 'logfile',
                                                style: 'min-height: 500px; max-height: 90vh; width: 100%; padding: 5px; font-family: monospace; resize: vertical;',
@@ -37,12 +58,11 @@ function Logview(logtag, name) {
                                ])
                        ]);
                },
+
                handleSaveApply: null,
                handleSave: null,
                handleReset: null
        });
 }
 
-return L.Class.extend({
-       Logview: Logview
-});
+return L.Class.extend({ Logview });
index 27707da34077c64980aaef40c0c21307dff9724c..642f82ee6df636101a7cdf393c2a0d4eb2c186d8 100644 (file)
@@ -41,116 +41,77 @@ return view.extend({
                        For further information please check the <a style="color:#37c;font-weight:bold;" href="https://github.com/openwrt/packages/blob/master/net/banip/files/README.md" target="_blank" rel="noreferrer noopener" >online documentation</a>'));
 
                /*
-                       poll runtime information
+                       set text content helper function
                */
-               let buttons, rtRes, infStat, infVer, infElements, infFeeds, infDevices, infUplink, infSys, infNft, infRun, infFlags, infLast
+               const setText = (id, value) => {
+                       const el = document.getElementById(id);
+                       if (el) {
+                               el.textContent = value || '-';
+                       }
+               };
 
+               /*
+                       poll runtime information
+               */
                pollData: poll.add(function () {
-                       return L.resolveDefault(fs.stat('/var/run/banip.lock')).then(function (stat) {
-                               buttons = document.querySelectorAll('.cbi-button');
-                               infStat = document.getElementById('status');
-                               if (stat) {
-                                       for (let i = 0; i < buttons.length; i++) {
-                                               buttons[i].setAttribute('disabled', 'true');
-                                       }
-                                       if (infStat && !infStat.classList.contains('spinning')) {
-                                               infStat.classList.add('spinning');
-                                       }
-                               } else {
-                                       for (let i = 0; i < buttons.length; i++) {
-                                               buttons[i].removeAttribute('disabled');
-                                       }
-                                       if (infStat && infStat.classList.contains('spinning')) {
-                                               infStat.classList.remove('spinning');
+                       return L.resolveDefault(fs.read_direct('/var/run/banip_runtime.json'), 'null').then(function (res) {
+                               const status = document.getElementById('status');
+                               const buttons = document.querySelectorAll('.cbi-page-actions button');
+                               try {
+                                       var info = JSON.parse(res);
+                               } catch (e) {
+                                       status.textContent = '-';
+                                       poll.stop();
+                                       if (status.classList.contains('spinning')) {
+                                               buttons.forEach(function (btn) {
+                                                       btn.disabled = false;
+                                               })
+                                               status.classList.remove('spinning');
                                        }
+                                       ui.addNotification(null, E('p', _('Unable to parse the runtime information!')), 'error');
                                }
-                               L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['status'])).then(function (result) {
-                                       if (result) {
-                                               rtRes = result.trim().split('\n');
-                                               if (rtRes) {
-                                                       for (let i = 0; i < rtRes.length; i++) {
-                                                               if (rtRes[i].match(/^\s+\+\sstatus\s+\:\s+(.*)$/)) {
-                                                                       rtRes.status = rtRes[i].match(/^\s+\+\sstatus\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\sversion\s+\:\s+(.*)$/)) {
-                                                                       rtRes.version = rtRes[i].match(/^\s+\+\sversion\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\selement_count\s+\:\s+(.*)$/)) {
-                                                                       rtRes.elementCount = rtRes[i].match(/^\s+\+\selement_count\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\sactive_feeds\s+\:\s+(.*)$/)) {
-                                                                       rtRes.activeFeeds = rtRes[i].match(/^\s+\+\sactive_feeds\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\sactive_devices\s+\:\s+(.*)$/)) {
-                                                                       rtRes.activeDevices = rtRes[i].match(/^\s+\+\sactive_devices\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\sactive_uplink\s+\:\s+(.*)$/)) {
-                                                                       rtRes.activeUplink = rtRes[i].match(/^\s+\+\sactive_uplink\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\snft_info\s+\:\s+(.*)$/)) {
-                                                                       rtRes.nftInfo = rtRes[i].match(/^\s+\+\snft_info\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\srun_info\s+\:\s+(.*)$/)) {
-                                                                       rtRes.runInfo = rtRes[i].match(/^\s+\+\srun_info\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\srun_flags\s+\:\s+(.*)$/)) {
-                                                                       rtRes.runFlags = rtRes[i].match(/^\s+\+\srun_flags\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\slast_run\s+\:\s+(.*)$/)) {
-                                                                       rtRes.lastRun = rtRes[i].match(/^\s+\+\slast_run\s+\:\s+(.*)$/)[1];
-                                                               } else if (rtRes[i].match(/^\s+\+\ssystem_info\s+\:\s+(.*)$/)) {
-                                                                       rtRes.sysInfo = rtRes[i].match(/^\s+\+\ssystem_info\s+\:\s+(.*)$/)[1];
-                                                               }
-                                                       }
-                                               }
-                                               if (rtRes) {
-                                                       infStat = document.getElementById('status');
-                                                       if (infStat) {
-                                                               infStat.textContent = rtRes.status || '-';
-                                                       }
-                                                       infVer = document.getElementById('version');
-                                                       if (infVer) {
-                                                               infVer.textContent = rtRes.version || '-';
-                                                       }
-                                                       infElements = document.getElementById('elements');
-                                                       if (infElements) {
-                                                               infElements.textContent = rtRes.elementCount || '-';
-                                                       }
-                                                       infFeeds = document.getElementById('feeds');
-                                                       if (infFeeds) {
-                                                               infFeeds.textContent = rtRes.activeFeeds || '-';
-                                                       }
-                                                       infDevices = document.getElementById('devices');
-                                                       if (infDevices) {
-                                                               infDevices.textContent = rtRes.activeDevices || '-';
-                                                       }
-                                                       infUplink = document.getElementById('uplink');
-                                                       if (infUplink) {
-                                                               infUplink.textContent = rtRes.activeUplink || '-';
-                                                       }
-                                                       infNft = document.getElementById('nft');
-                                                       if (infNft) {
-                                                               infNft.textContent = rtRes.nftInfo || '-';
-                                                       }
-                                                       infRun = document.getElementById('run');
-                                                       if (infRun) {
-                                                               infRun.textContent = rtRes.runInfo || '-';
-                                                       }
-                                                       infFlags = document.getElementById('flags');
-                                                       if (infFlags) {
-                                                               infFlags.textContent = rtRes.runFlags || '-';
-                                                       }
-                                                       infLast = document.getElementById('last');
-                                                       if (infLast) {
-                                                               infLast.textContent = rtRes.lastRun || '-';
-                                                       }
-                                                       infSys = document.getElementById('sys');
-                                                       if (infSys) {
-                                                               infSys.textContent = rtRes.sysInfo || '-';
-                                                       }
+                               if (status && info) {
+                                       status.textContent = `${info.status || '-'} (frontend: ${info.frontend_ver || '-'} / backend: ${info.backend_ver || '-'})`;
+                                       if (info.status === "processing") {
+                                               if (!status.classList.contains("spinning")) {
+                                                       status.classList.add("spinning");
                                                }
+                                               buttons.forEach(function (btn) {
+                                                       btn.disabled = true;
+                                                       btn.blur();
+                                               })
                                        } else {
-                                               infStat = document.getElementById('status');
-                                               if (infStat) {
-                                                       infStat.textContent = '-';
-                                                       poll.stop();
-                                                       if (infStat.classList.contains('spinning')) {
-                                                               infStat.classList.remove('spinning');
-                                                       }
+                                               if (status.classList.contains("spinning")) {
+                                                       buttons.forEach(function (btn) {
+                                                               btn.disabled = false;
+                                                       })
+                                                       status.classList.remove("spinning");
                                                }
                                        }
-                               });
+                               } else if (status) {
+                                       status.textContent = '-';
+                                       poll.stop();
+                                       if (status.classList.contains('spinning')) {
+                                               buttons.forEach(function (btn) {
+                                                       btn.disabled = false;
+                                               })
+                                               status.classList.remove('spinning');
+                                       }
+                               }
+                               if (info) {
+                                       setText('elements', info.element_count);
+                                       setText('feeds', info.active_feeds?.join(', '));
+                                       setText('devices', `wan-dev: ${info.wan_devices?.join(', ') || '-'} /
+                                                       wan-if: ${info.wan_interfaces?.join(', ') || '-'} /
+                                                       vlan-allow: ${info.vlan_allow?.join(', ') || '-'} /
+                                                       vlan-block: ${info.vlan_block?.join(', ') || '-'}`);
+                                       setText('uplink', info.active_uplink?.join(', ') || '-');
+                                       setText('nft', info.nft_info);
+                                       setText('run', info.run_info);
+                                       setText('flags', info.run_flags);
+                                       setText('last', info.last_run);
+                                       setText('sys', info.system_info);
+                               }
                        });
                }, 2);
 
@@ -165,10 +126,6 @@ return view.extend({
                                        E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Status')),
                                        E('div', { 'class': 'cbi-value-field spinning', 'id': 'status', 'style': 'margin-bottom:-5px;color:#37c;' }, '\xa0')
                                ]),
-                               E('div', { 'class': 'cbi-value' }, [
-                                       E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Version')),
-                                       E('div', { 'class': 'cbi-value-field', 'id': 'version', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
-                               ]),
                                E('div', { 'class': 'cbi-value' }, [
                                        E('label', { 'class': 'cbi-value-title', 'style': 'margin-bottom:-5px;padding-top:0rem;' }, _('Element Count')),
                                        E('div', { 'class': 'cbi-value-field', 'id': 'elements', 'style': 'margin-bottom:-5px;color:#37c;' }, '-')
index 51a1d632227a330f76d9a7d25df5de12eb1c5bf8..b74902cdf0aefffd561aaa4df113ff1262e88c53 100644 (file)
@@ -3,76 +3,30 @@
                "description": "Grant access to LuCI app banIP",
                "write": {
                        "file": {
-                               "/etc/banip/*": [
-                                       "read",
-                                       "write"
-                               ],
-                               "/etc/banip/banip.allowlist": [
-                                       "write"
-                               ],
-                               "/etc/banip/banip.blocklist": [
-                                       "write"
-                               ],
-                               "/etc/banip/banip.custom.feeds": [
-                                       "read",
-                                       "write"
-                               ]
+                               "/etc/banip/*": [ "read", "write" ],
+                               "/etc/banip/banip.allowlist": [ "write" ],
+                               "/etc/banip/banip.blocklist": [ "write" ],
+                               "/etc/banip/banip.custom.feeds": [ "read", "write" ]
                        },
-                       "uci": [
-                               "banip"
-                       ]
+                       "uci": [ "banip" ]
                },
                "read": {
-                       "cgi-io": [
-                               "exec"
-                       ],
+                       "cgi-io": [ "exec" ],
                        "file": {
-                               "/var/run/banip.lock": [
-                                       "read"
-                               ],
-                               "/sbin/logread -e banIP-": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/logread -e banIP-": [
-                                       "exec"
-                               ],
-                               "/sbin/logread -e banIP/": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/logread -e banIP/": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/nft -tj list sets": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip stop": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip reload": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip restart": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip report json": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip report gen": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip search [A-Za-z0-9:.]*": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip content [A-Za-z0-9]* *": [
-                                       "exec"
-                               ],
-                               "/etc/init.d/banip status": [
-                                       "exec"
-                               ]
+                               "/var/run/banip.lock": [ "read" ],
+                               "/var/run/banip_runtime.json": [ "read" ],
+                               "/usr/sbin/nft -tj list sets": [ "exec" ],
+                               "/etc/init.d/banip stop": [ "exec" ],
+                               "/etc/init.d/banip reload": [ "exec" ],
+                               "/etc/init.d/banip restart": [ "exec" ],
+                               "/etc/init.d/banip report json": [ "exec" ],
+                               "/etc/init.d/banip report gen": [ "exec" ],
+                               "/etc/init.d/banip search [A-Za-z0-9:.]*": [ "exec" ],
+                               "/etc/init.d/banip content [A-Za-z0-9]* *": [ "exec" ],
+                               "/etc/init.d/banip status": [ "exec" ]
                        },
-                       "uci": [
-                               "banip"
-                       ]
+                       "uci": [ "banip"],
+                       "log": [ "read" ]
                }
        }
 }
\ No newline at end of file