author | Kim Alvefur <zash@zash.se> |
Sat, 29 Oct 2011 13:34:15 +0200 | |
changeset 461 | bbea8081c865 |
parent 455 | 52f2188ec47d |
child 486 | b84493ef1d1d |
permissions | -rw-r--r-- |
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 |
-- HTTP Access to datamanager |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 |
-- By Kim Alvefur <zash@zash.se> |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 |
local jid_prep = require "util.jid".prep; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 |
local jid_split = require "util.jid".split; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
local um_test_pw = require "core.usermanager".test_password; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 |
local is_admin = require "core.usermanager".is_admin |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 |
local dm_load = require "util.datamanager".load; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 |
local dm_list_load = require "util.datamanager".list_load; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 |
local b64_decode = require "util.encodings".base64.decode; |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
11 |
--local urldecode = require "net.http".urldecode; |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
12 |
--[[local urlparams = --require "net.http".getQueryParams or whatever MattJ names it |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
13 |
function(s) |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
14 |
if not s:match("=") then return urldecode(s); end |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
15 |
local r = {} |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
16 |
s:gsub("([^=&]*)=([^&]*)", function(k,v) |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
17 |
r[ urldecode(k) ] = urldecode(v); |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
18 |
return nil |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
19 |
end) |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
20 |
return r |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
21 |
end; |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
22 |
--]] |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
23 |
|
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
24 |
local function http_response(code, message, extra_headers) |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
25 |
local response = { |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
26 |
status = code .. " " .. message; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
27 |
body = message .. "\n"; } |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
28 |
if extra_headers then response.headers = extra_headers; end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
29 |
return response |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
30 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
31 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
32 |
local encoders = { |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
33 |
lua = require "util.serialization".serialize, |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
34 |
json = require "util.json".encode |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
35 |
}; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
36 |
--[[ |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
37 |
encoders.xml = function(data) |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
38 |
return "<?xml version='1.0' encoding='utf-8'?><todo:write-this-serializer/>"; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
39 |
end --]] |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
40 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
41 |
local function handle_request(method, body, request) |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
42 |
if request.method ~= "GET" then |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
43 |
return http_response(405, "Method Not Allowed", {["Allow"] = "GET"}); |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
44 |
end -- TODO Maybe PUT? |
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
46 |
if not request.headers["authorization"] then |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
47 |
return http_response(401, "Unauthorized", |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
48 |
{["WWW-Authenticate"]='Basic realm="WallyWorld"'}) |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 |
local user, password = b64_decode(request.headers.authorization |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
51 |
:match("[^ ]*$") or ""):match("([^:]*):(.*)"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
52 |
user = jid_prep(user); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
53 |
if not user or not password then return http_response(400, "Bad Request"); end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
54 |
local user_node, user_host = jid_split(user) |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
55 |
if not hosts[user_host] then return http_response(401, "Unauthorized"); end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
56 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 |
module:log("debug", "authz %s", user) |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
58 |
if not um_test_pw(user_node, user_host, password) then |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
59 |
return http_response(401, "Unauthorized"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
61 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 |
module:log("debug", "spliting path"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
63 |
local path = {}; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 |
for i in string.gmatch(request.url.path, "[^/]+") do |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 |
table.insert(path, i); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 |
table.remove(path, 1); -- the first /data |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 |
module:log("debug", "split path, got %d parts: %s", #path, table.concat(path, ", ")); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 |
if #path < 3 then |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 |
module:log("debug", "since we need at least 3 parts, adding %s/%s", user_host, user_node); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 |
table.insert(path, 1, user_node); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
73 |
table.insert(path, 1, user_host); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 |
--return http_response(400, "Bad Request"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
76 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 |
if #path < 3 then |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
78 |
return http_response(404, "Not Found"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
79 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
80 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
81 |
if user_host ~= path[1] or user_node ~= path[2] then |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
82 |
-- To only give admins acces to anything, move the inside of this block after authz |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
83 |
module:log("debug", "%s wants access to %s@%s[%s], is admin?", user, path[2], path[1], path[3]) |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
84 |
if not is_admin(user, path[1]) then |
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
85 |
return http_response(403, "Forbidden"); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
88 |
|
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
89 |
local data = dm_load(path[2], path[1], path[3]); |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
90 |
|
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
91 |
data = data or dm_list_load(path[2], path[1], path[3]); |
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
92 |
|
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
93 |
if data and encoders[path[4] or "json"] then |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
94 |
return { |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
95 |
status = "200 OK", |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
96 |
body = encoders[path[4] or "json"](data) .. "\n", |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
97 |
headers = {["content-type"] = "text/plain; charset=utf-8"} |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
98 |
--headers = {["content-type"] = encoders[data[4] or "json"].mime .. "; charset=utf-8"} |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
99 |
-- FIXME a little nicer that the above |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
100 |
-- Also, would be cooler to use the Accept header, but parsing it ... |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
101 |
}; |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
102 |
else |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
103 |
return http_response(404, "Not Found"); |
318
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
104 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
105 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
106 |
|
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
107 |
local function setup() |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
108 |
local ports = module:get_option("data_access_ports") or { 5280 }; |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
109 |
require "net.httpserver".new_from_config(ports, handle_request, { base = "data" }); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
110 |
end |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
111 |
if prosody.start_time then -- already started |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
112 |
setup(); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
113 |
else |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
114 |
prosody.events.add_handler("server-started", setup); |
84caab2bc02c
mod_data_access: New plugin providing a HTTP interface to Prosodys datamanager
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
115 |
end |