comparison mod_http_oauth2/mod_http_oauth2.lua @ 4370:dee6b5098278

mod_http_oauth2: Add endpoint to revoke a key (RFC 7009 kinda)
author Matthew Wild <mwild1@gmail.com>
date Thu, 21 Jan 2021 18:06:12 +0000
parents 7cd3b7ec59e9
children d3434fd151b5
comparison
equal deleted inserted replaced
4369:29b7f445aec5 4370:dee6b5098278
155 assert(codes:set(client_owner, client_id .. "#" .. params.code, nil)); 155 assert(codes:set(client_owner, client_id .. "#" .. params.code, nil));
156 156
157 return json.encode(new_access_token(code.granted_jid, code.granted_scopes, nil)); 157 return json.encode(new_access_token(code.granted_jid, code.granted_scopes, nil));
158 end 158 end
159 159
160 local function check_credentials(request) 160 local function check_credentials(request, allow_token)
161 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); 161 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$");
162 162
163 if auth_type == "Basic" then 163 if auth_type == "Basic" then
164 local creds = base64.decode(auth_data); 164 local creds = base64.decode(auth_data);
165 if not creds then return false; end 165 if not creds then return false; end
169 if not username then return false; end 169 if not username then return false; end
170 if not usermanager.test_password(username, module.host, password) then 170 if not usermanager.test_password(username, module.host, password) then
171 return false; 171 return false;
172 end 172 end
173 return username; 173 return username;
174 elseif auth_type == "Bearer" and allow_token then
175 local token_info = tokens.get_token_info(auth_data);
176 if not token_info or not token_info.session or token_info.session.host ~= module.host then
177 return false;
178 end
179 return token_info.session.username;
174 end 180 end
175 return nil; 181 return nil;
176 end 182 end
177 183
178 if module:get_host_type() == "component" then 184 if module:get_host_type() == "component" then
242 return oauth_error("unsupported_response_type"); 248 return oauth_error("unsupported_response_type");
243 end 249 end
244 return response_handler(params, jid.join(user, module.host)); 250 return response_handler(params, jid.join(user, module.host));
245 end 251 end
246 252
253 local function handle_revocation_request(event)
254 local request, response = event.request, event.response;
255 if not request.headers.authorization then
256 response.headers.www_authenticate = string.format("Basic realm=%q", module.host.."/"..module.name);
257 return 401;
258 elseif request.headers.content_type ~= "application/x-www-form-urlencoded"
259 or not request.body or request.body == "" then
260 return 400;
261 end
262 local user = check_credentials(request, true);
263 if not user then
264 return 401;
265 end
266
267 local form_data = http.formdecode(event.request.body);
268 if not form_data or not form_data.token then
269 return 400;
270 end
271 local ok, err = tokens.revoke_token(form_data.token);
272 if not ok then
273 module:log("warn", "Unable to revoke token: %s", tostring(err));
274 return 500;
275 end
276 return 200;
277 end
278
247 module:depends("http"); 279 module:depends("http");
248 module:provides("http", { 280 module:provides("http", {
249 route = { 281 route = {
250 ["POST /token"] = handle_token_grant; 282 ["POST /token"] = handle_token_grant;
251 ["GET /authorize"] = handle_authorization_request; 283 ["GET /authorize"] = handle_authorization_request;
284 ["POST /revoke"] = handle_revocation_request;
252 }; 285 };
253 }); 286 });
254 287
255 local http_server = require "net.http.server"; 288 local http_server = require "net.http.server";
256 289