Mercurial > prosody-modules
comparison mod_http_admin_api/mod_http_admin_api.lua @ 4343:ee313922b8d1
mod_http_admin_api: HTTP API for managing users and invites
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 17 Jan 2021 12:49:20 +0000 |
| parents | |
| children | 1bb08e9ffa82 |
comparison
equal
deleted
inserted
replaced
| 4342:84e60c3d6e61 | 4343:ee313922b8d1 |
|---|---|
| 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 }); |
