Software /
code /
prosody-modules
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 |
parent | 4340:7cd3b7ec59e9 |
child | 4669: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 |