From e0dee6003c80b77e2c42769de4e71906bcd475cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Schr=C3=B6der?= Date: Tue, 28 Apr 2015 16:59:06 +0200 Subject: [PATCH] - Port mapping support under internet > port mapping - Exposed host - Firewall: enable disable etc.. --- luciexpress/htdocs/css/app.css | 5 ++ luciexpress/htdocs/index.html | 1 + luciexpress/htdocs/js/app.js | 1 + luciexpress/htdocs/js/config.js | 3 + luciexpress/htdocs/js/rpc.js | 4 +- luciexpress/htdocs/js/uci.js | 65 +++++++++++++++-- .../lib/js/angular-modal-service.min.js | 3 + luciexpress/htdocs/plugins/core/plugin.json | 4 +- .../plugins/core/widgets/core.modal.html | 15 ++++ .../htdocs/plugins/core/widgets/core.modal.js | 59 ++++++++++++++++ .../widgets/uci.firewall.nat.rule.edit.html | 63 +++++++++++++++++ .../widgets/uci.firewall.nat.rule.edit.js | 33 +++++++++ .../router/pages/internet.exposed_host.js | 6 +- .../router/pages/internet.firewall.html | 4 +- .../plugins/router/pages/internet.firewall.js | 17 ++++- .../router/pages/internet.port_mapping.html | 31 +++++++- .../router/pages/internet.port_mapping.js | 70 ++++++++++++++++++- luciexpress/server.js | 8 ++- 18 files changed, 373 insertions(+), 19 deletions(-) create mode 100644 luciexpress/htdocs/lib/js/angular-modal-service.min.js create mode 100644 luciexpress/htdocs/plugins/core/widgets/core.modal.html create mode 100644 luciexpress/htdocs/plugins/core/widgets/core.modal.js create mode 100644 luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.html create mode 100644 luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.js diff --git a/luciexpress/htdocs/css/app.css b/luciexpress/htdocs/css/app.css index e8cf3de92..a67a1bb94 100644 --- a/luciexpress/htdocs/css/app.css +++ b/luciexpress/htdocs/css/app.css @@ -1 +1,6 @@ .nav, .pagination, .carousel, .panel-title a { cursor: pointer; } + +/* needed for modals */ +.modal-backdrop { + z-index: 0; +} diff --git a/luciexpress/htdocs/index.html b/luciexpress/htdocs/index.html index 1389c2a0f..ff4991075 100644 --- a/luciexpress/htdocs/index.html +++ b/luciexpress/htdocs/index.html @@ -36,6 +36,7 @@ + diff --git a/luciexpress/htdocs/js/app.js b/luciexpress/htdocs/js/app.js index cefec0933..000886ff1 100644 --- a/luciexpress/htdocs/js/app.js +++ b/luciexpress/htdocs/js/app.js @@ -78,6 +78,7 @@ angular.module("luci", [ "ui.bootstrap", "ui.router", 'ui.select', + 'angularModalService', "uiSwitch", "ngAnimate", "gettext" diff --git a/luciexpress/htdocs/js/config.js b/luciexpress/htdocs/js/config.js index 10dea2ea1..517c686a8 100644 --- a/luciexpress/htdocs/js/config.js +++ b/luciexpress/htdocs/js/config.js @@ -61,8 +61,11 @@ angular.module("luci") "luci2.ui.menu", "uci.state", "uci.set", + "uci.add", "uci.delete", "uci.commit", + "uci.rollback", + "uci.revert", "uci.configs" // the rest is automatically retreived from session now! /*"session.destroy", diff --git a/luciexpress/htdocs/js/rpc.js b/luciexpress/htdocs/js/rpc.js index 76ce0dbd2..39b28c223 100644 --- a/luciexpress/htdocs/js/rpc.js +++ b/luciexpress/htdocs/js/rpc.js @@ -38,7 +38,7 @@ angular.module("luci") // create the rpc method obj[path[0]] = function(data){ var func = (function(data){ - if(!data) data = {}; + if(!data) data = { }; var deferred = $.Deferred(); $.jsonRPC.withOptions({ namespace: "", @@ -46,7 +46,7 @@ angular.module("luci") }, function(){ var sid = "00000000000000000000000000000000"; if($rootScope.sid) sid = $rootScope.sid; - + //data.ubus_rpc_session = sid; this.request('call', { params: [ sid, namespace, method, data], success: function(result){ diff --git a/luciexpress/htdocs/js/uci.js b/luciexpress/htdocs/js/uci.js index 49a08cefc..90b0bf859 100644 --- a/luciexpress/htdocs/js/uci.js +++ b/luciexpress/htdocs/js/uci.js @@ -22,7 +22,7 @@ // uci module for interacting with uci tables angular.module("luci") -.factory('$uci', function($rpc){ +.factory('$uci', function($rpc, $rootScope){ function initReq(path){ var parts = path.split("."); var req = {}; @@ -50,11 +50,64 @@ angular.module("luci") var req = initReq(path); req.values = values; $rpc.uci.set(req).done(function(state){ - $rpc.uci.commit(req).done(function(){ - deferred.resolve(); - }).fail(function(){ - deferred.reject(); - }); + deferred.resolve(); + }).fail(function(){ + deferred.reject(); + }); + return deferred.promise(); + }, + // add a new rule to the uci config + add: function(config, type, values){ + var deferred = $.Deferred(); + $rpc.uci.add({ + "config": config, + "type": type, + "values": values + }).done(function(state){ + values[".name"] = state.section; + deferred.resolve(state.section); + }).fail(function(){ + deferred.reject(); + }); + return deferred.promise(); + }, + // commit config changes + commit: function(path, values){ + var deferred = $.Deferred(); + var req = initReq(path); + $rpc.uci.commit(req).done(function(state){ + deferred.resolve(); + }).fail(function(){ + deferred.reject(); + }); + return deferred.promise(); + }, + // revert uncommitted changes + revert: function(path, values){ + var deferred = $.Deferred(); + var req = initReq(path); + $rpc.uci.revert(req).done(function(state){ + deferred.resolve(); + }).fail(function(){ + deferred.reject(); + }); + return deferred.promise(); + }, + // rollback + rollback: function(){ + var deferred = $.Deferred(); + $rpc.uci.rollback().done(function(state){ + deferred.resolve(); + }).fail(function(){ + deferred.reject(); + }); + return deferred.promise(); + }, + delete: function(path){ + var deferred = $.Deferred(); + var req = initReq(path); + $rpc.uci.delete(req).done(function(state){ + deferred.resolve(); }).fail(function(){ deferred.reject(); }); diff --git a/luciexpress/htdocs/lib/js/angular-modal-service.min.js b/luciexpress/htdocs/lib/js/angular-modal-service.min.js new file mode 100644 index 000000000..4b2d4b0e6 --- /dev/null +++ b/luciexpress/htdocs/lib/js/angular-modal-service.min.js @@ -0,0 +1,3 @@ +/*angular-modal-service v0.6.6 - https://github.com/dwmkerr/angular-modal-service */ +!function(){"use strict";var e=angular.module("angularModalService",[]);e.factory("ModalService",["$document","$compile","$controller","$http","$rootScope","$q","$templateCache",function(e,n,l,t,o,r,a){function c(){var e=this,c=function(e,n){var l=r.defer();if(e)l.resolve(e);else if(n){var o=a.get(n);void 0!==o?l.resolve(o):t({method:"GET",url:n,cache:!0}).then(function(e){a.put(n,e.data),l.resolve(e.data)},function(e){l.reject(e)})}else l.reject("No template or templateUrl has been specified.");return l.promise};e.showModal=function(e){var t=r.defer(),a=e.controller;return a?(e.controllerAs&&(a=a+" as "+e.controllerAs),c(e.template,e.templateUrl).then(function(c){var u=o.$new(),s=r.defer(),p={$scope:u,close:function(e,n){(void 0===n||null===n)&&(n=0),window.setTimeout(function(){s.resolve(e),u.$destroy(),m.remove(),p.close=null,t=null,s=null,$=null,p=null,m=null,u=null},n)}};if(e.inputs)for(var d in e.inputs)p[d]=e.inputs[d];var f=angular.element(c),v=n(f),m=v(u);p.$element=m;var h=l(a,p);e.appendElement?e.appendElement.append(m):i.append(m);var $={controller:h,scope:u,element:m,close:s.promise};t.resolve($)}).then(null,function(e){t.reject(e)}),t.promise):(t.reject("No controller has been specified."),t.promise)}}var i=e.find("body");return new c}])}(); +//# sourceMappingURL=angular-modal-service.min.js.map \ No newline at end of file diff --git a/luciexpress/htdocs/plugins/core/plugin.json b/luciexpress/htdocs/plugins/core/plugin.json index 798994ac7..ccc313411 100644 --- a/luciexpress/htdocs/plugins/core/plugin.json +++ b/luciexpress/htdocs/plugins/core/plugin.json @@ -11,7 +11,9 @@ "widgets/luci.progress", "widgets/luci.table", "widgets/luci.top_bar", - "widgets/uci.wireless.interface" + "widgets/uci.wireless.interface", + "widgets/uci.firewall.nat.rule.edit", + "widgets/core.modal" ], "pages": { "overview": { diff --git a/luciexpress/htdocs/plugins/core/widgets/core.modal.html b/luciexpress/htdocs/plugins/core/widgets/core.modal.html new file mode 100644 index 000000000..787926d9d --- /dev/null +++ b/luciexpress/htdocs/plugins/core/widgets/core.modal.html @@ -0,0 +1,15 @@ + diff --git a/luciexpress/htdocs/plugins/core/widgets/core.modal.js b/luciexpress/htdocs/plugins/core/widgets/core.modal.js new file mode 100644 index 000000000..52d8db093 --- /dev/null +++ b/luciexpress/htdocs/plugins/core/widgets/core.modal.js @@ -0,0 +1,59 @@ +$juci.module("core") +.directive('modal', function () { + var plugin_root = $juci.module("core").plugin_root; + return { + templateUrl: plugin_root + "/widgets/core.modal.html", + restrict: 'E', + transclude: true, + replace:true, + scope: { + acceptLabel: "@acceptLabel", + dismissLabel: "@dismissLabel", + onAccept: "&onAccept", + onDismiss: "&onDismiss", + ngShow: "=ngShow", + title: "=title" + }, + controller: "ModalController", + link: function postLink(scope, element, attrs) { + //scope.title = attrs.title; + //scope.acceptLabel = attrs.acceptLabel; + //scope.dismissLabel = attrs.dismissLabel; + scope.element = element; + scope.$watch("ngShow", function(value){ + if(value == true) + $(element).modal('show'); + else + $(element).modal('hide'); + }); + + $(element).on('shown.bs.modal', function(){ + scope.$apply(function(){ + scope.$parent[attrs.ngShow] = true; + }); + }); + + $(element).on('hidden.bs.modal', function(){ + scope.$apply(function(){ + scope.$parent[attrs.ngShow] = false; + }); + }); + } + }; +}) +.controller('ModalController', function($scope) { + /*$scope.onDismiss = function(){ + console.log("Modal Dismissed"); + } + $scope.onAccept = function(){ + console.log("Modal accepted!"); + }*/ + /*console.log("controller: "+$scope.ngShow); + $scope.$watch("ngShow", function(value){ + console.log("visible: "+$scope.ngShow); + if(value == true) + $($scope.element).modal('show'); + else + $($scope.element).modal('hide'); + });*/ +}); diff --git a/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.html b/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.html new file mode 100644 index 000000000..86f429551 --- /dev/null +++ b/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.html @@ -0,0 +1,63 @@ +
+
+ +
+ + {{devices[$select.selected].hostname}} + +
{{devices[c].hostname}}
+
+
+
+
+
+ +
+
+
+ +
+ + {{$select.selected}} + +
{{c}}
+
+
+
+
+
+ +
+ Range + Single +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ + +
+
diff --git a/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.js b/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.js new file mode 100644 index 000000000..af67c84eb --- /dev/null +++ b/luciexpress/htdocs/plugins/core/widgets/uci.firewall.nat.rule.edit.js @@ -0,0 +1,33 @@ +$juci.module("core") +.directive("uciFirewallNatRuleEdit", function($compile, $parse){ + var plugin_root = $juci.module("core").plugin_root; + return { + templateUrl: plugin_root+"/widgets/uci.firewall.nat.rule.edit.html", + scope: { + rule: "=ngModel" + }, + controller: "uciFirewallNatRuleEdit", + replace: true, + require: "^ngModel" + }; +}).controller("uciFirewallNatRuleEdit", function($scope, $uci, $rpc){ + $scope.portIsRange = 1; + $scope.protocols = ["udp", "tcp"]; + $scope.patterns = { + ipaddress: /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/, + port: /^\d{1,5}$/ + } + $rpc.router.clients().done(function(clients){ + //alert(JSON.stringify(Object.keys(clients).map(function(x) { return clients[x]; }))); + $scope.clients = []; + $scope.devices = {}; + Object.keys(clients).map(function(x) { + var c = clients[x]; + if(c.connected){ + $scope.devices[c.ipaddr] = c; + $scope.clients.push(c.ipaddr); + } + }); + $scope.$apply(); + }); +}); diff --git a/luciexpress/htdocs/plugins/router/pages/internet.exposed_host.js b/luciexpress/htdocs/plugins/router/pages/internet.exposed_host.js index fabb84903..deb04dcb4 100644 --- a/luciexpress/htdocs/plugins/router/pages/internet.exposed_host.js +++ b/luciexpress/htdocs/plugins/router/pages/internet.exposed_host.js @@ -27,8 +27,10 @@ $juci.module("router") }; $scope.onSave = function(){ $uci.set("firewall.dmz", $scope.dmz).done(function(){ - $scope.info_message = $tr("STR_SETTINGSSAVED"); - $scope.$apply(); + $uci.commit("firewall.dmz").done(function(){ + $scope.info_message = $tr("STR_SETTINGSSAVED"); + $scope.$apply(); + }); }).fail(function(){ $scope.error_message = $tr("STR_SETTINGSSAVEFAILED"); }); diff --git a/luciexpress/htdocs/plugins/router/pages/internet.firewall.html b/luciexpress/htdocs/plugins/router/pages/internet.firewall.html index 192fb87c6..0ad5fefd7 100644 --- a/luciexpress/htdocs/plugins/router/pages/internet.firewall.html +++ b/luciexpress/htdocs/plugins/router/pages/internet.firewall.html @@ -6,13 +6,13 @@
Firewall
-
+
Allow Ping to WAN interface
-
+
diff --git a/luciexpress/htdocs/plugins/router/pages/internet.firewall.js b/luciexpress/htdocs/plugins/router/pages/internet.firewall.js index 08a7a7eec..ca5ea4c7a 100644 --- a/luciexpress/htdocs/plugins/router/pages/internet.firewall.js +++ b/luciexpress/htdocs/plugins/router/pages/internet.firewall.js @@ -1,5 +1,16 @@ $juci.module("router") -.controller("InternetFirewallPageCtrl", function($scope){ - $scope.firewallEnabled = 1; - $scope.allowWANPing = 1; +.controller("InternetFirewallPageCtrl", function($scope, $uci){ + + $uci.show("firewall.settings").done(function(settings){ + $scope.settings = settings; + settings.firewall = Number(settings.firewall); + settings.ping_wan = Number(settings.ping_wan); + + $scope.onSave = function(){ + $uci.set("firewall.settings", $scope.settings).done(function(){ + + }); + } + $scope.$apply(); + }); }); diff --git a/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.html b/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.html index 24438ecf8..79f2571ef 100644 --- a/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.html +++ b/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.html @@ -1,5 +1,34 @@
- Port mapping settings +

Port Mapping

+

Port mapping allows remote computers to connect to a specific device within your private network.

+ + + + + + + + + + + + + + + + + + +
Local IPProtocolLocal portPublic Port
{{ r.dest_ip }}{{ r.proto }}{{ r.dest_port }}{{ r.src_dport }}
+
+
+ + +
+
+ + +
diff --git a/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.js b/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.js index c6061dfdb..79986ec1c 100644 --- a/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.js +++ b/luciexpress/htdocs/plugins/router/pages/internet.port_mapping.js @@ -1,4 +1,72 @@ $juci.module("router") -.controller("InternetPortMappingPageCtrl", function($scope){ +.controller("InternetPortMappingPageCtrl", function($scope, $uci, ModalService, $rpc){ + function reload(){ + $uci.show("firewall").done(function(firewall){ + $scope.redirects = Object.keys(firewall).filter(function(x) { return firewall[x][".type"] == "redirect"; }).map(function(x){ return firewall[x]; }); + + $scope.$apply(); + }); + + + } reload(); + $scope.showModal = 0; + $scope.onAcceptModal = function(){ + var rule = $scope.rule; + Object.keys($scope.redirects).map(function(idx) { var x = $scope.redirects[idx]; if(x[".name"] == rule[".name"]) $scope.redirects[idx] = rule; }); + console.log(JSON.stringify(rule)); + if(!rule[".name"]){ + // set up the rule in uci + $uci.add("firewall", "redirect", rule).done(function(x){ + console.log("Added new section: "+x); + if(x.section) rule[".name"] = x.section; + }); + } else { + $uci.set("firewall."+rule[".name"], rule).always(function(firewall){ + + }); + } + $scope.showModal = 0; + } + $scope.onDismissModal = function(){ + $scope.showModal = 0; + } + $scope.onAddRule = function(){ + $scope.rule = {}; + $scope.redirects.push($scope.rule); + $scope.showModal = 1; + } + $scope.onEditRule = function(rule){ + $scope.rule = Object.create(rule); + $scope.modalTitle = "Edit port mapping ("+(rule['.name'] || 'new')+")"; + $scope.showModal = 1; + } + $scope.onDeleteRule = function(rule){ + function removeFromList(){ + if($scope.redirects) { + $scope.redirects = $scope.redirects.filter(function(x){ return x !== rule; }); + $scope.$apply(); + } + } + console.log("Deleting rule: "+rule[".name"]); + if(rule[".name"]){ + $uci.delete("firewall."+rule[".name"]).always(function(){ + removeFromList(); + }); + } else { + retmoveFromList(); + } + } + $scope.onCommit = function(){ + if(!$scope.redirects) return; + $uci.commit("firewall").always(function(){ + $scope.$apply(); + console.log("Saved firewall settings!"); + }); + } + $scope.onCancel = function(){ + $uci.rollback().always(function(){ + reload(); + }); + } }); diff --git a/luciexpress/server.js b/luciexpress/server.js index 34bb37461..b68e8c310 100644 --- a/luciexpress/server.js +++ b/luciexpress/server.js @@ -82,7 +82,13 @@ app.post('/ubus', function(req, res) { body: data }, function (error, response, body) { if(error){ - doLocalRPC(); + console.log("ERROR: "+error); + res.write(JSON.stringify({ + jsonrpc: "2.0", + result: [1, error] + })); + res.end(); + //doLocalRPC(); return; } var json = JSON.stringify(body);