Changeset

5043:2856e1cfbe95

Merge with Zash
author Matthew Wild <mwild1@gmail.com>
date Sat, 28 Jul 2012 20:59:03 +0100
parents 5031:28d56268a72d (current diff) 5042:ce823b32225e (diff)
children 5044:4ef0dbfead53
files
diffstat 5 files changed, 102 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/core/storagemanager.lua	Sat Jul 28 18:50:04 2012 +0100
+++ b/core/storagemanager.lua	Sat Jul 28 20:59:03 2012 +0100
@@ -58,7 +58,7 @@
 	return stores_available:get(host, driver_name);
 end
 
-function open(host, store, typ)
+function get_driver(host, store)
 	local storage = config.get(host, "core", "storage");
 	local driver_name;
 	local option_type = type(storage);
@@ -77,7 +77,11 @@
 		driver_name = "null";
 		driver = null_storage_driver;
 	end
+	return driver, driver_name;
+	end
 	
+function open(host, store, typ)
+	local driver, driver_name = get_driver(host, store);
 	local ret, err = driver:open(store, typ);
 	if not ret then
 		if err == "unsupported-store" then
@@ -96,5 +100,11 @@
 function datamanager.store(username, host, datastore, data)
 	return open(host, datastore):set(username, data);
 end
+function datamanager.list_stores(username, host)
+	return get_driver(host):list_stores(username, host);
+end
+function datamanager.purge(username, host)
+	return get_driver(host):purge(username, host);
+end
 
 return _M;
--- a/core/usermanager.lua	Sat Jul 28 18:50:04 2012 +0100
+++ b/core/usermanager.lua	Sat Jul 28 20:59:03 2012 +0100
@@ -10,11 +10,13 @@
 local log = require "util.logger".init("usermanager");
 local type = type;
 local ipairs = ipairs;
+local pairs = pairs;
 local jid_bare = require "util.jid".bare;
 local jid_prep = require "util.jid".prep;
 local config = require "core.configmanager";
 local hosts = hosts;
 local sasl_new = require "util.sasl".new;
+local storagemanager = require "core.storagemanager";
 
 local prosody = _G.prosody;
 
@@ -88,7 +90,15 @@
 end
 
 function delete_user(username, host)
-	return hosts[host].users.delete_user(username);
+	local user = hosts[host].sessions[username];
+	if user and user.sessions then
+		for jid, session in pairs(user.sessions) do
+			session:close{ condition = "not-authorized", text = "Account deleted" };
+		end
+	end
+	local ok, err = hosts[host].users.delete_user(username);
+	if not ok then return nil, err; end
+	return storagemanager.get_driver(host):purge(username);
 end
 
 function get_sasl_handler(host, session)
--- a/plugins/mod_storage_internal.lua	Sat Jul 28 18:50:04 2012 +0100
+++ b/plugins/mod_storage_internal.lua	Sat Jul 28 20:59:03 2012 +0100
@@ -16,4 +16,12 @@
 	return datamanager.store(user, host, self.store, data);
 end
 
+function driver:list_stores(username)
+	return datamanager.list_stores(username, host);
+end
+
+function driver:purge(user)
+	return datamanager.purge(user, host);
+end
+
 module:add_item("data-driver", driver);
--- a/plugins/mod_storage_sql.lua	Sat Jul 28 18:50:04 2012 +0100
+++ b/plugins/mod_storage_sql.lua	Sat Jul 28 20:59:03 2012 +0100
@@ -175,7 +175,7 @@
 	end
 end
 
-local function getsql(sql, ...)
+local function dosql(sql, ...)
 	if params.driver == "PostgreSQL" then
 		sql = sql:gsub("`", "\"");
 	end
@@ -184,12 +184,15 @@
 	if not stmt and not test_connection() then error("connection failed"); end
 	if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
 	-- run query
-	local ok, err = stmt:execute(host or "", user or "", store or "", ...);
+	local ok, err = stmt:execute(...);
 	if not ok and not test_connection() then error("connection failed"); end
 	if not ok then return nil, err; end
 	
 	return stmt;
 end
+local function getsql(sql, ...)
+	return dosql(sql, host or "", user or "", store or "", ...);
+end
 local function setsql(sql, ...)
 	local stmt, err = getsql(sql, ...);
 	if not stmt then return stmt, err; end
@@ -349,4 +352,30 @@
 	return nil, "unsupported-store";
 end
 
+function driver:list_stores(username) -- Not to be confused with the list store type
+	local sql = (username == true
+		and "SELECT DISTINCT `store` FROM `prosody` WHERE `host`=? AND `user`!=?"
+		or  "SELECT DISTINCT `store` FROM `prosody` WHERE `host`=? AND `user`=?");
+	if username == true or not username then
+		username = "";
+	end
+	local stmt, err = dosql(sql, host, username);
+	if not stmt then
+		return nil, err;
+	end
+	local stores = {};
+	for row in stmt:rows() do
+		stores[#stores+1] = row[1];
+	end
+	return stores;
+end
+
+function driver:purge(username)
+	local stmt, err = dosql("DELETE FROM `prosody` WHERE `host`=? AND `user`=?", host, username);
+	if not stmt then return stmt, err; end
+	local changed, err = stmt:affected();
+	if not changed then return changed, err; end
+	return true, changed;
+end
+
 module:add_item("data-driver", driver);
--- a/util/datamanager.lua	Sat Jul 28 18:50:04 2012 +0100
+++ b/util/datamanager.lua	Sat Jul 28 20:59:03 2012 +0100
@@ -226,4 +226,45 @@
 	return items;
 end
 
+function list_stores(username, host)
+	if not host then
+		return nil, "bad argument #2 to 'list_stores' (string expected, got nothing)";
+	end
+	local list = {};
+	local host_dir = format("%s/%s/", data_path, encode(host));
+	for node in lfs.dir(host_dir) do
+		if not node:match"^%." then -- dots should be encoded, this is probably . or ..
+			local store = decode(node);
+			local path = host_dir..node;
+			if username == true then
+				if lfs.attributes(path, "mode") == "directory" then
+					list[#list+1] = store;
+				end
+			elseif username then
+				if lfs.attributes(getpath(username, host, store), "mode")
+					or lfs.attributes(getpath(username, host, store, "list"), "mode") then
+					list[#list+1] = store;
+				end
+			elseif lfs.attributes(path, "mode") == "file" then
+				list[#list+1] = store:gsub("%.[dalist]+$","");
+			end
+		end
+	end
+	return list;
+end
+
+function purge(username, host)
+	local host_dir = format("%s/%s/", data_path, encode(host));
+	local deleted = 0;
+	for file in lfs.dir(host_dir) do
+		if lfs.attributes(host_dir..file, "mode") == "directory" then
+			local store = decode(file);
+			deleted = deleted + (os_remove(getpath(username, host, store)) and 1 or 0);
+			deleted = deleted + (os_remove(getpath(username, host, store, "list")) and 1 or 0);
+			-- We this will generate loads of "No such file or directory", but do we care?
+		end
+	end
+	return deleted > 0, deleted;
+end
+
 return _M;