Auto adding of rpc calls based on acls

This commit is contained in:
Martin Schröder 2015-04-27 09:57:48 +02:00 committed by Martin Schröder
parent 4215177ebc
commit 834f9eed2f
9 changed files with 110 additions and 93 deletions

View file

@ -137,7 +137,13 @@ angular.module("luci", [
});*/
var path = $location.path().replace("/", "").replace(".", "_");
$state.go("init", {"redirect": path});
$session.init().done(function(){
$state.go("init", {"redirect": path});
}).fail(function(){
console.log("Failed to verify session.");
$state.go("init", {"redirect": "login"});
//$state.go("login");
});
})
//window.app = angular.module("luci");

View file

@ -53,24 +53,28 @@ angular.module("luci")
],
rpc: {
//host: "", not used anymore because we now instead do rpc forwarding in server.js!
exposed_calls: [
exposed_calls: [ // TODO: only login and access calls should always be available
"session.login",
"session.access",
"session.destroy",
"luci2.ui.menu",
"session.access",
// TODO: these calls use wildcards in acl so we need to somehow get them automatically
// for now I defined them manually here.
"luci2.ui.menu",
"uci.state",
"uci.set",
"uci.delete",
"uci.commit",
"uci.configs"
// the rest is automatically retreived from session now!
/*"session.destroy",
"luci2.network.conntrack_count",
"luci2.network.dhcp_leases",
"luci2.system.diskfree",
"router.dslstats",
"router.info",
"router.clients",
"uci.state",
"uci.set",
"uci.delete",
"uci.commit",
"uci.configs",
"network.interface.status",
"system.info"
"system.info"*/
]
}
};

View file

@ -123,15 +123,6 @@ angular.module("luci")
next();
});
},
function(next){
progress("Validating session..", 100);
$session.init().done(function(){
next();
}).fail(function(){
console.log("Failed to verify session.");
$state.go("login");
});
},
function(next){
progress("Getting navigation..", 100);
@ -159,6 +150,8 @@ angular.module("luci")
});
//$rootScope.$apply();
next();
}).fail(function(){
next();
});
}
], function(err){

View file

@ -23,67 +23,75 @@
// luci rpc module for communicating with the server
angular.module("luci")
.factory('$rpc', function($rootScope, $config){
var calls = $config.rpc.exposed_calls;
var ret = {};
calls.forEach(function(call){
function _find(path, obj){
if(!obj.hasOwnProperty(path[0])){
obj[path[0]] = {};
}
if(path.length == 1) {
var namespace = call.split(".");
namespace.pop(); namespace = namespace.join(".");
(function(namespace, method){
// create the rpc method
obj[path[0]] = function(data){
var func = (function(data){
if(!data) data = {};
var deferred = $.Deferred();
$.jsonRPC.withOptions({
namespace: "",
endPoint: (($config.rpc.host)?$config.rpc.host:"")+"/ubus"
}, function(){
var sid = "00000000000000000000000000000000";
if($rootScope.sid) sid = $rootScope.sid;
this.request('call', {
params: [ sid, namespace, method, data],
success: function(result){
//alert("SID: "+sid + " :: "+ JSON.stringify(result));
if(result && result.result) {
// TODO: modify all rpc UCI services so that they ALWAYS return at least
// an empty json object. Otherwise we have no way to differentiate success
// from failure of a request. This has to be done on the host side.
if(result.result[0] != 0){ // || result.result[1] == undefined) {
console.log("RPC succeeded, but returned error: "+JSON.stringify(result));
deferred.reject(result.result[0]);
var rpc = {
register_method: function(call){
//console.log("registering: "+call);
var self = this;
function _find(path, obj){
if(!obj.hasOwnProperty(path[0])){
obj[path[0]] = {};
}
if(path.length == 1) {
var namespace = call.split(".");
namespace.pop(); namespace = namespace.join(".");
(function(namespace, method){
// create the rpc method
obj[path[0]] = function(data){
var func = (function(data){
if(!data) data = {};
var deferred = $.Deferred();
$.jsonRPC.withOptions({
namespace: "",
endPoint: (($config.rpc.host)?$config.rpc.host:"")+"/ubus"
}, function(){
var sid = "00000000000000000000000000000000";
if($rootScope.sid) sid = $rootScope.sid;
this.request('call', {
params: [ sid, namespace, method, data],
success: function(result){
//alert("SID: "+sid + " :: "+ JSON.stringify(result));
if(result && result.result) {
// TODO: modify all rpc UCI services so that they ALWAYS return at least
// an empty json object. Otherwise we have no way to differentiate success
// from failure of a request. This has to be done on the host side.
if(result.result[0] != 0){ // || result.result[1] == undefined) {
console.log("RPC succeeded, but returned error: "+JSON.stringify(result));
deferred.reject(result.result[0]);
} else {
deferred.resolve(result.result[1]);
}
} else {
deferred.resolve(result.result[1]);
deferred.reject();
}
},
error: function(result){
console.log("RPC error: "+JSON.stringify(result));
if(result && result.error){
deferred.reject(result.error);
}
} else {
deferred.reject();
}
},
error: function(result){
console.log("RPC error: "+JSON.stringify(result));
if(result && result.error){
deferred.reject(result.error);
}
}
})
});
return deferred.promise();
});
return func(data);
}
})(namespace, path[0]);
} else {
var child = path[0];
path.shift();
_find(path, obj[child]);
})
});
return deferred.promise();
});
return func(data);
}
})(namespace, path[0]);
} else {
var child = path[0];
path.shift();
_find(path, obj[child]);
}
}
_find(call.split("."), self);
}
_find(call.split("."), ret);
});
return ret;
};
// setup default rpcs
if($config.rpc && $config.rpc.exposed_calls){
$config.rpc.exposed_calls.forEach(function(call){
rpc.register_method(call);
});
}
return rpc;
});

View file

@ -22,12 +22,21 @@
// service for managing session data
angular.module("luci")
.factory('$session', function($rpc, $rootScope) {
var saved_sid = localStorage.getItem("sid");
.factory('$session', function($rpc, $rootScope, $localStorage, $rpc) {
var saved_sid = $localStorage.getItem("sid");
var default_sid = "00000000000000000000000000000000";
if(saved_sid){
$rootScope.sid = saved_sid;
}
function setupUbusRPC(acls){
Object.keys(acls).map(function(key){
acls[key].map(function(func){
$rpc.register_method(key+"."+func);
});
});
}
return {
sid: (saved_sid)?saved_sid:default_sid,
data: {},
@ -45,13 +54,14 @@ angular.module("luci")
console.log("Session: Not authenticated!");
deferred.reject();
} else {
console.log("Session: Loggedin!");
if(result && result.ubus) setupUbusRPC(result.ubus);
self.data = result;
console.log("Session: Loggedin!");
deferred.resolve(result);
}
}).fail(function err(result){
$rootScope.sid = self.sid = default_sid;
localStorage.setItem("sid", self.sid);
$localStorage.setItem("sid", self.sid);
deferred.reject();
});
return deferred.promise();
@ -65,7 +75,8 @@ angular.module("luci")
}).done(function(result){
$rootScope.sid = self.sid = result.ubus_rpc_session;
self.data = result;
localStorage.setItem("sid", self.sid);
$localStorage.setItem("sid", self.sid);
if(result && result.acls && result.acls.ubus) setupUbusRPC(result.acls.ubus);
deferred.resolve(self.sid);
}).fail(function(result){
deferred.reject();

View file

@ -1,4 +1,4 @@
<luci-layout-single-column>
<luci-layout-naked>
<div ng-controller="LoginPageCtrl">
<table class="table">
<tr>
@ -7,4 +7,4 @@
<td class="col-md-4"></td></tr>
</table>
</div>
</luci-layout-single-column>
</luci-layout-naked>

View file

@ -38,6 +38,7 @@ $juci.module("core")
$scope.setLanguage = function(lang){
$languages.setLanguage(lang.short_code);
};
$rpc.network.interface.status({
"interface": "wan"
}).done(function(wan){
@ -46,7 +47,5 @@ $juci.module("core")
$scope.wanip = wan["ipv4-address"][0].address;
$scope.$apply();
});
});
});
});

View file

@ -1,3 +1,4 @@
<luci-top-bar></luci-top-bar>
<div class="container" role="main">
<div class="row">
<luci-navbar></luci-navbar>
@ -8,9 +9,4 @@
<ng-transclude></ng-transclude>
</div>
</div>
<div class="row">
<div class="col-md-12">
<luci-footer></luci-footer>
</div>
</div>
</div>