rpc.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
  3. -- Licensed to the public under the Apache License 2.0.
  4. local require = require
  5. local pairs = pairs
  6. local print = print
  7. local pcall = pcall
  8. local table = table
  9. local string = string
  10. module "luci.controller.rpc"
  11. function index()
  12. local function authenticator(validator, accs)
  13. local auth = luci.http.formvalue("auth", true)
  14. if auth then -- if authentication token was given
  15. local sdat = (luci.util.ubus("session", "get", { ubus_rpc_session = auth }) or { }).values
  16. if sdat then -- if given token is valid
  17. if sdat.user and luci.util.contains(accs, sdat.user) then
  18. return sdat.user, auth
  19. end
  20. end
  21. end
  22. luci.http.status(403, "Forbidden")
  23. end
  24. local rpc = node("rpc")
  25. rpc.sysauth = "root"
  26. rpc.sysauth_authenticator = authenticator
  27. rpc.notemplate = true
  28. entry({"rpc", "uci"}, call("rpc_uci"))
  29. entry({"rpc", "fs"}, call("rpc_fs"))
  30. entry({"rpc", "sys"}, call("rpc_sys"))
  31. entry({"rpc", "ipkg"}, call("rpc_ipkg"))
  32. entry({"rpc", "auth"}, call("rpc_auth")).sysauth = false
  33. entry({"rpc", "settheme"}, call("rpc_settheme")).sysauth = false
  34. entry({"rpc", "gettheme"}, call("rpc_gettheme")).sysauth = false
  35. end
  36. function rpc_auth()
  37. local jsonrpc = require "luci.jsonrpc"
  38. local http = require "luci.http"
  39. local sys = require "luci.sys"
  40. local ltn12 = require "luci.ltn12"
  41. local util = require "luci.util"
  42. local loginstat
  43. local server = {}
  44. server.challenge = function(user, pass)
  45. local sid, token, secret
  46. local config = require "luci.config"
  47. if sys.user.checkpasswd(user, pass) then
  48. local sdat = util.ubus("session", "create", { timeout = config.sauth.sessiontime })
  49. if sdat then
  50. sid = sdat.ubus_rpc_session
  51. token = sys.uniqueid(16)
  52. secret = sys.uniqueid(16)
  53. http.header("Set-Cookie", "sysauth="..sid.."; path=/")
  54. util.ubus("session", "set", {
  55. ubus_rpc_session = sid,
  56. values = {
  57. user = user,
  58. token = token,
  59. secret = secret
  60. }
  61. })
  62. end
  63. end
  64. return sid and {sid=sid, token=token, secret=secret}
  65. end
  66. server.login = function(...)
  67. local challenge = server.challenge(...)
  68. return challenge and challenge.sid
  69. end
  70. http.prepare_content("application/json")
  71. ltn12.pump.all(jsonrpc.handle(server, http.source()), http.write)
  72. end
  73. function rpc_uci()
  74. if not pcall(require, "luci.model.uci") then
  75. luci.http.status(404, "Not Found")
  76. return nil
  77. end
  78. local uci = require "luci.jsonrpcbind.uci"
  79. local jsonrpc = require "luci.jsonrpc"
  80. local http = require "luci.http"
  81. local ltn12 = require "luci.ltn12"
  82. http.prepare_content("application/json")
  83. ltn12.pump.all(jsonrpc.handle(uci, http.source()), http.write)
  84. end
  85. function rpc_fs()
  86. local util = require "luci.util"
  87. local io = require "io"
  88. local fs2 = util.clone(require "nixio.fs")
  89. local jsonrpc = require "luci.jsonrpc"
  90. local http = require "luci.http"
  91. local ltn12 = require "luci.ltn12"
  92. function fs2.readfile(filename)
  93. local stat, mime = pcall(require, "mime")
  94. if not stat then
  95. error("Base64 support not available. Please install LuaSocket.")
  96. end
  97. local fp = io.open(filename)
  98. if not fp then
  99. return nil
  100. end
  101. local output = {}
  102. local sink = ltn12.sink.table(output)
  103. local source = ltn12.source.chain(ltn12.source.file(fp), mime.encode("base64"))
  104. return ltn12.pump.all(source, sink) and table.concat(output)
  105. end
  106. function fs2.writefile(filename, data)
  107. local stat, mime = pcall(require, "mime")
  108. if not stat then
  109. error("Base64 support not available. Please install LuaSocket.")
  110. end
  111. local file = io.open(filename, "w")
  112. local sink = file and ltn12.sink.chain(mime.decode("base64"), ltn12.sink.file(file))
  113. return sink and ltn12.pump.all(ltn12.source.string(data), sink) or false
  114. end
  115. http.prepare_content("application/json")
  116. ltn12.pump.all(jsonrpc.handle(fs2, http.source()), http.write)
  117. end
  118. function rpc_sys()
  119. local sys = require "luci.sys"
  120. local jsonrpc = require "luci.jsonrpc"
  121. local http = require "luci.http"
  122. local ltn12 = require "luci.ltn12"
  123. http.prepare_content("application/json")
  124. ltn12.pump.all(jsonrpc.handle(sys, http.source()), http.write)
  125. end
  126. function rpc_ipkg()
  127. if not pcall(require, "luci.model.ipkg") then
  128. luci.http.status(404, "Not Found")
  129. return nil
  130. end
  131. local ipkg = require "luci.model.ipkg"
  132. local jsonrpc = require "luci.jsonrpc"
  133. local http = require "luci.http"
  134. local ltn12 = require "luci.ltn12"
  135. http.prepare_content("application/json")
  136. ltn12.pump.all(jsonrpc.handle(ipkg, http.source()), http.write)
  137. end
  138. function rpc_settheme()
  139. local http = require "luci.http"
  140. local config = require "luci.config"
  141. local msg = {}
  142. local uci = require "luci.model.uci".cursor()
  143. local theme = http.formvalue("theme")
  144. local set = false
  145. msg.ret = 1
  146. msg.result = "theme param is invalid"
  147. for k, v in pairs(config.themes) do
  148. if k:sub(1, 1) ~= "." and string.find(v, theme) then
  149. set = true
  150. end
  151. end
  152. if set == false then
  153. msg.ret = 1
  154. msg.result = "theme cann't be found"
  155. http.prepare_content("application/json")
  156. http.write_json(msg)
  157. return
  158. end
  159. if theme == "openwrt" then
  160. uci:set("luci", "main", "mediaurlbase", "/luci-static/openwrt.org")
  161. uci:commit("luci")
  162. msg.ret = 0
  163. msg.result = "Change to openwrt"
  164. end
  165. if theme == "avalon" then
  166. uci:set("luci", "main", "mediaurlbase", "/luci-static/avalon")
  167. uci:commit("luci")
  168. msg.ret = 0
  169. msg.result = "Change to avalon"
  170. end
  171. http.prepare_content("application/json")
  172. http.write_json(msg)
  173. end
  174. function rpc_gettheme()
  175. local http = require "luci.http"
  176. local msg = {}
  177. local uci = require "luci.model.uci".cursor()
  178. local theme = ""
  179. msg.ret = 0
  180. theme = uci:get("luci", "main", "mediaurlbase")
  181. if string.find(theme, "avalon") then
  182. msg.theme = "avalon"
  183. else
  184. msg.theme = "openwrt"
  185. end
  186. http.prepare_content("application/json")
  187. http.write_json(msg)
  188. end