mod_http_oauth2: Implement the Implicit flow
Everyone says this is insecure and bad, but it's also the only thing
that makes sense for e.g. pure JavaScript clients, but hey implement
this even more complicated thing instead!
--- a/mod_http_oauth2/mod_http_oauth2.lua Thu Mar 02 22:00:42 2023 +0100
+++ b/mod_http_oauth2/mod_http_oauth2.lua Thu Mar 02 22:06:50 2023 +0100
@@ -92,6 +92,8 @@
return json.encode(new_access_token(granted_jid, granted_scopes, nil));
end
+-- TODO response_type_handlers have some common boilerplate code, refactor?
+
function response_type_handlers.code(params, granted_jid)
if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
@@ -134,6 +136,35 @@
}
end
+-- Implicit flow
+function response_type_handlers.token(params, granted_jid)
+ if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
+
+ local client_owner, client_host, client_id = jid.prepped_split(params.client_id);
+ if client_host ~= module.host then
+ return oauth_error("invalid_client", "incorrect credentials");
+ end
+ local client, err = clients:get(client_owner, client_id);
+ if err then error(err); end
+ if not client then
+ return oauth_error("invalid_client", "incorrect credentials");
+ end
+
+ local granted_scopes = filter_scopes(client_owner, client_host, params.scope);
+ local token_info = new_access_token(granted_jid, granted_scopes, nil);
+
+ local redirect = url.parse(client.redirect_uri);
+ token_info.state = params.state;
+ redirect.fragment = http.formencode(token_info);
+
+ return {
+ status_code = 302;
+ headers = {
+ location = url.build(redirect);
+ };
+ }
+end
+
local pepper = module:get_option_string("oauth2_client_pepper", "");
local function verify_secret(stored, salt, i, secret)
@@ -217,6 +248,7 @@
-- TODO How would this make sense with components?
-- Have an admin authenticate maybe?
response_type_handlers.code = nil;
+ response_type_handlers.token = nil;
grant_type_handlers.authorization_code = nil;
check_credentials = function () return false end
end