mod_http_admin_api/mod_http_admin_api.lua
changeset 4347 ee313922b8d1
child 4349 1bb08e9ffa82
equal deleted inserted replaced
4346:84e60c3d6e61 4347: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 });