index.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. module("luci.controller.admin.index", package.seeall)
  4. function action_logout()
  5. local dsp = require "luci.dispatcher"
  6. local utl = require "luci.util"
  7. local sid = dsp.context.authsession
  8. if sid then
  9. utl.ubus("session", "destroy", { ubus_rpc_session = sid })
  10. luci.http.header("Set-Cookie", "sysauth=%s; expires=%s; path=%s" %{
  11. '', 'Thu, 01 Jan 1970 01:00:00 GMT', dsp.build_url()
  12. })
  13. end
  14. luci.http.redirect(dsp.build_url())
  15. end
  16. function action_translations(lang)
  17. local i18n = require "luci.i18n"
  18. local http = require "luci.http"
  19. local fs = require "nixio".fs
  20. if lang and #lang > 0 then
  21. lang = i18n.setlanguage(lang)
  22. if lang then
  23. local s = fs.stat("%s/base.%s.lmo" %{ i18n.i18ndir, lang })
  24. if s then
  25. http.header("Cache-Control", "public, max-age=31536000")
  26. http.header("ETag", "%x-%x-%x" %{ s["ino"], s["size"], s["mtime"] })
  27. end
  28. end
  29. end
  30. http.prepare_content("application/javascript; charset=utf-8")
  31. http.write("window.TR=")
  32. http.write_json(i18n.dump())
  33. end
  34. local function ubus_reply(id, data, code, errmsg)
  35. local reply = { jsonrpc = "2.0", id = id }
  36. if errmsg then
  37. reply.error = {
  38. code = code,
  39. message = errmsg
  40. }
  41. elseif type(code) == "table" then
  42. reply.result = code
  43. else
  44. reply.result = { code, data }
  45. end
  46. return reply
  47. end
  48. local ubus_types = {
  49. nil,
  50. "array",
  51. "object",
  52. "string",
  53. nil, -- INT64
  54. "number",
  55. nil, -- INT16,
  56. "boolean",
  57. "double"
  58. }
  59. local function ubus_access(sid, obj, fun)
  60. local res, code = luci.util.ubus("session", "access", {
  61. ubus_rpc_session = sid,
  62. scope = "ubus",
  63. object = obj,
  64. ["function"] = fun
  65. })
  66. return (type(res) == "table" and res.access == true)
  67. end
  68. local function ubus_request(req)
  69. if type(req) ~= "table" or type(req.method) ~= "string" or req.jsonrpc ~= "2.0" or req.id == nil then
  70. return ubus_reply(nil, nil, -32600, "Invalid request")
  71. elseif req.method == "call" then
  72. if type(req.params) ~= "table" or #req.params < 3 then
  73. return ubus_reply(nil, nil, -32600, "Invalid parameters")
  74. end
  75. local sid, obj, fun, arg =
  76. req.params[1], req.params[2], req.params[3], req.params[4] or {}
  77. if type(arg) ~= "table" or arg.ubus_rpc_session ~= nil then
  78. return ubus_reply(req.id, nil, -32602, "Invalid parameters")
  79. end
  80. if sid == "00000000000000000000000000000000" and luci.dispatcher.context.authsession then
  81. sid = luci.dispatcher.context.authsession
  82. end
  83. if not ubus_access(sid, obj, fun) then
  84. return ubus_reply(req.id, nil, -32002, "Access denied")
  85. end
  86. arg.ubus_rpc_session = sid
  87. local res, code = luci.util.ubus(obj, fun, arg)
  88. return ubus_reply(req.id, res, code or 0)
  89. elseif req.method == "list" then
  90. if req.params == nil or (type(req.params) == "table" and #req.params == 0) then
  91. local objs = luci.util.ubus()
  92. return ubus_reply(req.id, nil, objs)
  93. elseif type(req.params) == "table" then
  94. local n, rv = nil, {}
  95. for n = 1, #req.params do
  96. if type(req.params[n]) ~= "string" then
  97. return ubus_reply(req.id, nil, -32602, "Invalid parameters")
  98. end
  99. local sig = luci.util.ubus(req.params[n])
  100. if sig and type(sig) == "table" then
  101. rv[req.params[n]] = {}
  102. local m, p
  103. for m, p in pairs(sig) do
  104. if type(p) == "table" then
  105. rv[req.params[n]][m] = {}
  106. local pn, pt
  107. for pn, pt in pairs(p) do
  108. rv[req.params[n]][m][pn] = ubus_types[pt] or "unknown"
  109. end
  110. end
  111. end
  112. end
  113. end
  114. return ubus_reply(req.id, nil, rv)
  115. else
  116. return ubus_reply(req.id, nil, -32602, "Invalid parameters")
  117. end
  118. end
  119. return ubus_reply(req.id, nil, -32601, "Method not found")
  120. end
  121. function action_ubus()
  122. local parser = require "luci.jsonc".new()
  123. luci.http.context.request:setfilehandler(function(_, s)
  124. if not s then
  125. return nil
  126. end
  127. local ok, err = parser:parse(s)
  128. return (not err or nil)
  129. end)
  130. luci.http.context.request:content()
  131. local json = parser:get()
  132. if json == nil or type(json) ~= "table" then
  133. luci.http.prepare_content("application/json")
  134. luci.http.write_json(ubus_reply(nil, nil, -32700, "Parse error"))
  135. return
  136. end
  137. local response
  138. if #json == 0 then
  139. response = ubus_request(json)
  140. else
  141. response = {}
  142. local _, request
  143. for _, request in ipairs(json) do
  144. response[_] = ubus_request(request)
  145. end
  146. end
  147. luci.http.prepare_content("application/json")
  148. luci.http.write_json(response)
  149. end
  150. function action_menu()
  151. local dsp = require "luci.dispatcher"
  152. local utl = require "luci.util"
  153. local http = require "luci.http"
  154. local acls = utl.ubus("session", "access", { ubus_rpc_session = http.getcookie("sysauth") })
  155. local menu = dsp.menu_json(acls or {}) or {}
  156. http.prepare_content("application/json")
  157. http.write_json(menu)
  158. end