|
1 local json = require "util.json"; |
|
2 |
|
3 module:depends("http"); |
|
4 |
|
5 local invites = module:depends("invites"); |
|
6 local tokens = module:depends("tokenauth"); |
|
7 |
|
8 local json_content_type = "application/json"; |
|
9 |
|
10 local www_authenticate_header = ("Bearer realm=%q"):format(module.host.."/"..module.name); |
|
11 |
|
12 local function check_credentials(request) |
|
13 local auth_type, auth_data = string.match(request.headers.authorization or "", "^(%S+)%s(.+)$"); |
|
14 if not (auth_type and auth_data) then |
|
15 return false; |
|
16 end |
|
17 |
|
18 if auth_type == "Bearer" then |
|
19 local token_info = tokens.get_token_info(auth_data); |
|
20 if not token_info or not token_info.session then |
|
21 return false; |
|
22 end |
|
23 return token_info.session; |
|
24 end |
|
25 return nil; |
|
26 end |
|
27 |
|
28 function check_auth(routes) |
|
29 local function check_request_auth(event) |
|
30 local session = check_credentials(event.request); |
|
31 if not session then |
|
32 event.response.headers.authorization = www_authenticate_header; |
|
33 return false, 401; |
|
34 elseif session.auth_scope ~= "prosody:scope:admin" then |
|
35 return false, 403; |
|
36 end |
|
37 event.session = session; |
|
38 return true; |
|
39 end |
|
40 |
|
41 for route, handler in pairs(routes) do |
|
42 routes[route] = function (event, ...) |
|
43 local permit, code = check_request_auth(event); |
|
44 if not permit then |
|
45 return code; |
|
46 end |
|
47 return handler(event, ...); |
|
48 end; |
|
49 end |
|
50 return routes; |
|
51 end |
|
52 |
|
53 local function token_info_to_invite_info(token_info) |
|
54 return { |
|
55 id = token_info.token; |
|
56 type = token_info.type; |
|
57 inviter = token_info.inviter; |
|
58 jid = token_info.jid; |
|
59 landing_page = token_info.landing_page; |
|
60 created_at = token_info.created_at; |
|
61 expires = token_info.expires; |
|
62 }; |
|
63 end |
|
64 |
|
65 function list_invites(event) |
|
66 local invites_list = {}; |
|
67 for token, invite in invites.pending_account_invites() do --luacheck: ignore 213/token |
|
68 table.insert(invites_list, token_info_to_invite_info(invite)); |
|
69 end |
|
70 table.sort(invites_list, function (a, b) |
|
71 return a.created_at < b.created_at; |
|
72 end); |
|
73 |
|
74 event.response.headers["Content-Type"] = json_content_type; |
|
75 return json.encode(invites_list); |
|
76 end |
|
77 |
|
78 function get_invite_by_id(event, invite_id) |
|
79 local invite = invites.get_account_invite_info(invite_id); |
|
80 if not invite then |
|
81 return 404; |
|
82 end |
|
83 |
|
84 event.response.headers["Content-Type"] = json_content_type; |
|
85 return json.encode(token_info_to_invite_info(invite)); |
|
86 end |
|
87 |
|
88 function create_invite(event) |
|
89 local invite = invites.create_account(nil, { source = "admin_api/"..event.session.username }); |
|
90 if not invite then |
|
91 return 500; |
|
92 end |
|
93 |
|
94 event.response.headers["Content-Type"] = json_content_type; |
|
95 return json.encode(token_info_to_invite_info(invite)); |
|
96 end |
|
97 |
|
98 function delete_invite(event, invite_id) --luacheck: ignore 212/event |
|
99 if not invites.delete_account_invite(invite_id) then |
|
100 return 404; |
|
101 end |
|
102 return 200; |
|
103 end |
|
104 |
|
105 module:provides("http", { |
|
106 route = check_auth { |
|
107 ["GET /invites"] = list_invites; |
|
108 ["GET /invites/*"] = get_invite_by_id; |
|
109 ["PUT /invites"] = create_invite; |
|
110 ["DELETE /invites/*"] = delete_invite; |
|
111 }; |
|
112 }); |