diff mod_vjud/mod_vjud.lua @ 927:a9dfa7232d88

Merge
author Matthew Wild <mwild1@gmail.com>
date Tue, 12 Mar 2013 12:10:25 +0000
parents 4939788a47ea
children b1a92a87309c
line wrap: on
line diff
--- a/mod_vjud/mod_vjud.lua	Thu Nov 22 18:59:10 2012 +0000
+++ b/mod_vjud/mod_vjud.lua	Tue Mar 12 12:10:25 2013 +0000
@@ -6,6 +6,8 @@
 local jid_split = require "util.jid".prepped_split;
 local vcard = module:require "vcard";
 local rawget, rawset = rawget, rawset;
+local s_lower = string.lower;
+local s_find = string.find;
 
 local st = require "util.stanza";
 local template = require "util.template";
@@ -28,6 +30,8 @@
 </item>
 ]];
 
+local search_mode = module:get_option_string("vjud_mode", "opt-in");
+local allow_remote = module:get_option_boolean("allow_remote_searches", search_mode ~= "all");
 local base_host = module:get_option_string("vjud_search_domain",
 	module:get_host_type() == "component"
 		and module.host:gsub("^[^.]+%.","")
@@ -36,23 +40,6 @@
 module:depends"disco";
 module:add_feature("jabber:iq:search");
 
-local opted_in;
-function module.load()
-	opted_in = dm_load(nil, module.host, "user_index") or {};
-end
-function module.unload()
-	dm_store(nil, module.host, "user_index", opted_in);
-end
-
-local opt_in_layout = dataforms_new{
-	title = "Search settings";
-	instructions = "Do you want to appear in search results?";
-	{
-		name = "searchable",
-		label = "Appear in search results?",
-		type = "boolean",
-	},
-};
 local vCard_mt = {
 	__index = function(t, k)
 		if type(k) ~= "string" then return nil end
@@ -77,21 +64,32 @@
 
 local at_host = "@"..base_host;
 
+local users; -- The user iterator
+
 module:hook("iq/host/jabber:iq:search:query", function(event)
 	local origin, stanza = event.origin, event.stanza;
 
+	if not (allow_remote or origin.type == "c2s") then
+		origin.send(st.error_reply(stanza, "cancel", "not-allowed"))
+		return true;
+	end
+
 	if stanza.attr.type == "get" then
 		origin.send(st.reply(stanza):add_child(get_reply));
 	else -- type == "set"
 		local query = stanza.tags[1];
 		local first, last, nick, email =
-			(query:get_child_text"first" or false),
-			(query:get_child_text"last" or false),
-			(query:get_child_text"nick" or false),
-			(query:get_child_text"email" or false);
+			s_lower(query:get_child_text"first" or ""),
+			s_lower(query:get_child_text"last" or ""),
+			s_lower(query:get_child_text"nick" or ""),
+			s_lower(query:get_child_text"email" or "");
 
+		first = #first >= 2 and first;
+		last  = #last  >= 2 and last;
+		nick  = #nick  >= 2 and nick;
+		email = #email >= 2 and email;
 		if not ( first or last or nick or email ) then
-			origin.send(st.error_reply(stanza, "modify", "not-acceptable", "All fields were empty"));
+			origin.send(st.error_reply(stanza, "modify", "not-acceptable", "All fields were empty or too short"));
 			return true;
 		end
 
@@ -110,13 +108,13 @@
 				});
 			end
 		else
-			for username in pairs(opted_in) do
+			for username in users() do
 				local vCard = get_user_vcard(username);
-				if vCard and (
-				(vCard.N and vCard.N[2] == first) or
-				(vCard.N and vCard.N[1] == last) or
-				(vCard.NICKNAME and vCard.NICKNAME[1] == nick) or
-				(vCard.EMAIL and vCard.EMAIL[1] == email)) then
+				if vCard
+				and ((first and vCard.N and s_find(s_lower(vCard.N[2]), first, nil, true))
+				or (last and vCard.N and s_find(s_lower(vCard.N[1]), last, nil, true))
+				or (nick and vCard.NICKNAME and s_find(s_lower(vCard.NICKNAME[1]), nick, nil, true))
+				or (email and vCard.EMAIL and s_find(s_lower(vCard.EMAIL[1]), email, nil, true))) then
 					reply:add_child(item_template.apply{
 						jid = username..at_host;
 						first = vCard.N and vCard.N[2] or nil;
@@ -132,30 +130,55 @@
 	return true;
 end);
 
-local function opt_in_handler(self, data, state)
-	local username, hostname = jid_split(data.from);
-	if state then -- the second return value
-		if data.action == "cancel" then
-			return { status = "canceled" };
-		end
-
-		if not username or not hostname or hostname ~= base_host then
-			return { status = "error", error = { type = "cancel",
-				condition = "forbidden", message = "Invalid user or hostname." } };
-		end
+if search_mode == "all" then
+	function users()
+		return usermanager.users(base_host);
+	end
+else -- if "opt-in", default
+	local opted_in;
+	function module.load()
+		opted_in = dm_load(nil, module.host, "user_index") or {};
+	end
+	function module.unload()
+		dm_store(nil, module.host, "user_index", opted_in);
+	end
+	function users()
+		return pairs(opted_in);
+	end
+	local opt_in_layout = dataforms_new{
+		title = "Search settings";
+		instructions = "Do you want to appear in search results?";
+		{
+			name = "searchable",
+			label = "Appear in search results?",
+			type = "boolean",
+		},
+	};
+	local function opt_in_handler(self, data, state)
+		local username, hostname = jid_split(data.from);
+		if state then -- the second return value
+			if data.action == "cancel" then
+				return { status = "canceled" };
+			end
 
-		local fields = opt_in_layout:data(data.form);
-		opted_in[username] = fields.searchable or nil
+			if not username or not hostname or hostname ~= base_host then
+				return { status = "error", error = { type = "cancel",
+				condition = "forbidden", message = "Invalid user or hostname." } };
+			end
 
-		return { status = "completed" }
-	else -- No state, send the form.
-		return { status = "executing", actions  = { "complete" },
+			local fields = opt_in_layout:data(data.form);
+			opted_in[username] = fields.searchable or nil
+
+			return { status = "completed" }
+		else -- No state, send the form.
+			return { status = "executing", actions  = { "complete" },
 			form = { layout = opt_in_layout, values = { searchable = opted_in[username] } } }, true;
+		end
 	end
-end
 
-local adhoc_new = module:require "adhoc".new;
-local adhoc_vjudsetup = adhoc_new("Search settings", "vjudsetup", opt_in_handler);--, "self");-- and nil);
-module:depends"adhoc";
-module:provides("adhoc", adhoc_vjudsetup);
+	local adhoc_new = module:require "adhoc".new;
+	local adhoc_vjudsetup = adhoc_new("Search settings", "vjudsetup", opt_in_handler);--, "self");-- and nil);
+	module:depends"adhoc";
+	module:provides("adhoc", adhoc_vjudsetup);
 
+end