diff mod_http_oauth2/mod_http_oauth2.lua @ 5554:90449babaa48

mod_http_oauth2: Make allowed locales configurable Explicit > Implicit Instead of allowing anything after #, allow only the explicitly configured locales to be used. Default to empty list because using these is not supported yet. This potentially limits the size of the client_id, which is already quite large. Nothing prevents clients from registering a whole client_id per locale, which would not require translation support on this side.
author Kim Alvefur <zash@zash.se>
date Sat, 17 Jun 2023 19:03:32 +0200
parents 67152838afbc
children d7fb8b266663
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua	Sat Jun 17 18:15:00 2023 +0200
+++ b/mod_http_oauth2/mod_http_oauth2.lua	Sat Jun 17 19:03:32 2023 +0200
@@ -60,6 +60,9 @@
 	return data;
 end
 
+local allowed_locales = module:get_option_array("allowed_oauth2_locales", {});
+-- TODO Allow translations or per-locale templates somehow.
+
 local template_path = module:get_option_path("oauth2_template_path", "html");
 local templates = {
 	login = read_file(template_path, "login.html", true);
@@ -936,13 +939,22 @@
 		software_id = { type = "string"; format = "uuid" };
 		software_version = { type = "string" };
 	};
-	luaPatternProperties = {
-		-- Localized versions of descriptive properties and URIs
-		["^client_name#"] = { description = "Localized version of 'client_name'"; type = "string" };
-		["^[a-z_]+_uri#"] = { type = "string"; format = "uri" };
-	};
 }
 
+-- Limit per-locale fields to allowed locales, partly to keep size of client_id
+-- down, partly because we don't yet use them for anything.
+-- Only relevant for user-visible strings and URIs.
+if allowed_locales[1] then
+	local props = registration_schema.properties;
+	for _, locale in ipairs(allowed_locales) do
+		props["client_name#" .. locale] = props["client_name"];
+		props["client_uri#" .. locale] = props["client_uri"];
+		props["logo_uri#" .. locale] = props["logo_uri"];
+		props["tos_uri#" .. locale] = props["tos_uri"];
+		props["policy_uri#" .. locale] = props["policy_uri"];
+	end
+end
+
 local function redirect_uri_allowed(redirect_uri, client_uri, app_type)
 	local uri = url.parse(redirect_uri);
 	if not uri.scheme then
@@ -986,19 +998,6 @@
 		end
 	end
 
-	for k, v in pairs(client_metadata) do
-		local base_k = k:match"^([^#]+)#" or k;
-		if not registration_schema.properties[base_k] or k:find"^client_uri#" then
-			-- Ignore and strip unknown extra properties
-			client_metadata[k] = nil;
-		elseif k:find"_uri#" then
-			-- Localized URIs should be secure too
-			if not redirect_uri_allowed(v, client_uri, "web") then
-				return nil, oauth_error("invalid_client_metadata", "Invalid, insecure or inappropriate informative URI");
-			end
-		end
-	end
-
 	local grant_types = set.new(client_metadata.grant_types);
 	local response_types = set.new(client_metadata.response_types);
 
@@ -1204,6 +1203,7 @@
 		response_modes_supported = array(it.keys(response_type_handlers)):map(tmap { token = "fragment"; code = "query" });
 		authorization_response_iss_parameter_supported = true;
 		service_documentation = module:get_option_string("oauth2_service_documentation", "https://modules.prosody.im/mod_http_oauth2.html");
+		ui_locales_supported = allowed_locales[1] and allowed_locales;
 
 		-- OpenID
 		userinfo_endpoint = handle_register_request and module:http_url() .. "/userinfo" or nil;