mirror of
https://github.com/openwrt/luci.git
synced 2025-02-23 18:15:09 +00:00
161 lines
3.9 KiB
Ucode
161 lines
3.9 KiB
Ucode
// Copyright 2022 Jo-Philipp Wich <jo@mein.io>
|
|
// Licensed to the public under the Apache License 2.0.
|
|
|
|
import { load_catalog, change_catalog, get_translations } from 'luci.core';
|
|
|
|
const ubus_types = [
|
|
null,
|
|
'array',
|
|
'object',
|
|
'string',
|
|
null, // INT64
|
|
'number',
|
|
null, // INT16,
|
|
'boolean',
|
|
'double'
|
|
];
|
|
|
|
|
|
function ubus_reply(id, data, code, errmsg) {
|
|
const reply = { jsonrpc: '2.0', id };
|
|
|
|
if (errmsg)
|
|
reply.error = { code, message: errmsg };
|
|
else if (type(code) == 'object')
|
|
reply.result = code;
|
|
else if (data != null)
|
|
reply.result = [ code, data ];
|
|
else
|
|
reply.result = [ code ];
|
|
|
|
return reply;
|
|
}
|
|
|
|
function ubus_access(sid, obj, fun) {
|
|
return (ubus.call('session', 'access', {
|
|
ubus_rpc_session: sid,
|
|
scope: 'ubus',
|
|
object: obj,
|
|
function: fun
|
|
})?.access == true);
|
|
}
|
|
|
|
function ubus_request(req) {
|
|
if (type(req?.method) != 'string' || req?.jsonrpc != '2.0' || req?.id == null)
|
|
return ubus_reply(null, null, -32600, 'Invalid request');
|
|
|
|
if (req.method == 'call') {
|
|
if (type(req?.params) != 'array' || length(req.params) < 3)
|
|
return ubus_reply(null, null, -32600, 'Invalid parameters');
|
|
|
|
let sid = req.params[0],
|
|
obj = req.params[1],
|
|
fun = req.params[2],
|
|
arg = req.params[3] ?? {};
|
|
|
|
if (type(arg) != 'object' || exists(arg, 'ubus_rpc_session'))
|
|
return ubus_reply(req.id, null, -32602, 'Invalid parameters');
|
|
|
|
if (sid == '00000000000000000000000000000000' && ctx.authsession)
|
|
sid = ctx.authsession;
|
|
|
|
if (!ubus_access(sid, obj, fun))
|
|
return ubus_reply(req.id, null, -32002, 'Access denied');
|
|
|
|
arg.ubus_rpc_session = sid;
|
|
|
|
|
|
// clear error
|
|
ubus.error();
|
|
|
|
const res = ubus.call(obj, fun, arg);
|
|
|
|
return ubus_reply(req.id, res, ubus.error(true) ?? 0);
|
|
}
|
|
|
|
if (req.method == 'list') {
|
|
if (req?.params == null || (type(req.params) == 'array' && length(req.params) == 0)) {
|
|
return ubus_reply(req.id, null, ubus.list());
|
|
}
|
|
else if (type(req.params) == 'array') {
|
|
const rv = {};
|
|
|
|
for (let param in req.params) {
|
|
if (type(param) != 'string')
|
|
return ubus_reply(req.id, null, -32602, 'Invalid parameters');
|
|
|
|
for (let m, p in ubus.list(param)?.[0]) {
|
|
for (let pn, pt in p) {
|
|
rv[param] ??= {};
|
|
rv[param][m] ??= {};
|
|
rv[param][m][pn] = ubus_types[pt] ?? 'unknown';
|
|
}
|
|
}
|
|
}
|
|
|
|
return ubus_reply(req.id, null, rv);
|
|
}
|
|
else {
|
|
return ubus_reply(req.id, null, -32602, 'Invalid parameters')
|
|
}
|
|
}
|
|
|
|
return ubus_reply(req.id, null, -32601, 'Method not found')
|
|
}
|
|
|
|
|
|
return {
|
|
action_ubus: function() {
|
|
let request;
|
|
|
|
try { request = json(http.content()); }
|
|
catch { request = null; }
|
|
|
|
http.prepare_content('application/json; charset=UTF-8');
|
|
|
|
if (type(request) == 'object')
|
|
http.write_json(ubus_request(request));
|
|
else if (type(request) == 'array')
|
|
http.write_json(map(request, ubus_request));
|
|
else
|
|
http.write_json(ubus_reply(null, null, -32700, 'Parse error'))
|
|
},
|
|
|
|
action_translations: function(reqlang) {
|
|
if (reqlang != null && reqlang != dispatcher.lang) {
|
|
load_catalog(reqlang, '/usr/lib/lua/luci/i18n');
|
|
change_catalog(reqlang);
|
|
}
|
|
|
|
http.prepare_content('application/javascript; charset=UTF-8');
|
|
http.write('window.TR={');
|
|
|
|
get_translations((key, val) => http.write(sprintf('"%08x":%J,', key, val)));
|
|
|
|
http.write('};');
|
|
},
|
|
|
|
action_logout: function() {
|
|
const url = dispatcher.build_url();
|
|
|
|
if (ctx.authsession) {
|
|
ubus.call('session', 'destroy', { ubus_rpc_session: ctx.authsession });
|
|
|
|
if (http.getenv('HTTPS') == 'on')
|
|
http.header('Set-Cookie', `sysauth_https=; expires=Thu, 01 Jan 1970 01:00:00 GMT; path=${url}`);
|
|
else
|
|
http.header('Set-Cookie', `sysauth_http=; expires=Thu, 01 Jan 1970 01:00:00 GMT; path=${url}`);
|
|
}
|
|
|
|
http.redirect(url);
|
|
},
|
|
|
|
action_menu: function() {
|
|
const session = dispatcher.is_authenticated({ methods: [ 'cookie:sysauth_https', 'cookie:sysauth_http' ] });
|
|
const menu = dispatcher.menu_json(session?.acls ?? {}) ?? {};
|
|
|
|
http.prepare_content('application/json; charset=UTF-8');
|
|
http.write_json(menu);
|
|
}
|
|
};
|