Diff

mod_http_oauth2/mod_http_oauth2.lua @ 5186:fa3059e653fa

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!
author Kim Alvefur <zash@zash.se>
date Thu, 02 Mar 2023 22:06:50 +0100
parent 5185:09d6bbd6c8a4
child 5187:6a3c1febd7be
line wrap: on
line diff
--- 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