plugins/mod_storage_xep0227.lua
author Jonas Schäfer <jonas@wielicki.name>
Mon, 10 Jan 2022 18:23:54 +0100
branch0.11
changeset 12185 783056b4e448
parent 8355 6ff50541d2a6
child 11793 f3085620b6ff
permissions -rw-r--r--
util.xml: Do not allow doctypes, comments or processing instructions Yes. This is as bad as it sounds. CVE pending. In Prosody itself, this only affects mod_websocket, which uses util.xml to parse the <open/> frame, thus allowing unauthenticated remote DoS using Billion Laughs. However, third-party modules using util.xml may also be affected by this. This commit installs handlers which disallow the use of doctype declarations and processing instructions without any escape hatch. It, by default, also introduces such a handler for comments, however, there is a way to enable comments nontheless. This is because util.xml is used to parse human-facing data, where comments are generally a desirable feature, and also because comments are generally harmless.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     2
local ipairs, pairs = ipairs, pairs;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     3
local setmetatable = setmetatable;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     4
local tostring = tostring;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
local next = next;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     6
local t_remove = table.remove;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
local os_remove = os.remove;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
local io_open = io.open;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
6700
3d27f5855f4b mod_storage_xep0227: Use configured storage path
Kim Alvefur <zash@zash.se>
parents: 6699
diff changeset
    10
local paths = require"util.paths";
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    11
local st = require "util.stanza";
5219
060d7fc6caf4 plugins/storage/mod_xep0227: Use util.xml.
Waqas Hussain <waqas20@gmail.com>
parents: 5121
diff changeset
    12
local parse_xml_real = require "util.xml".parse;
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    13
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    14
local function getXml(user, host)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    15
	local jid = user.."@"..host;
6700
3d27f5855f4b mod_storage_xep0227: Use configured storage path
Kim Alvefur <zash@zash.se>
parents: 6699
diff changeset
    16
	local path = paths.join(prosody.paths.data, jid..".xml");
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    17
	local f = io_open(path);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    18
	if not f then return; end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    19
	local s = f:read("*a");
6701
95a8aeca1fc9 mod_storage_xep0227: Close file handle after reading
Kim Alvefur <zash@zash.se>
parents: 6700
diff changeset
    20
	f:close();
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    21
	return parse_xml_real(s);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    23
local function setXml(user, host, xml)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
	local jid = user.."@"..host;
6700
3d27f5855f4b mod_storage_xep0227: Use configured storage path
Kim Alvefur <zash@zash.se>
parents: 6699
diff changeset
    25
	local path = paths.join(prosody.paths.data, jid..".xml");
6703
0103dc8fa179 mod_storage_xep0227: Return error from io.open if unable to open file for writing
Kim Alvefur <zash@zash.se>
parents: 6702
diff changeset
    26
	local f, err = io_open(path, "w");
0103dc8fa179 mod_storage_xep0227: Return error from io.open if unable to open file for writing
Kim Alvefur <zash@zash.se>
parents: 6702
diff changeset
    27
	if not f then return f, err; end
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    28
	if xml then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    29
		local s = tostring(xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    30
		f:write(s);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    31
		f:close();
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    32
		return true;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    33
	else
6702
ccdd0b615106 mod_storage_xep0227: Open file for writing even if removing so os.remove has a file to delete
Kim Alvefur <zash@zash.se>
parents: 6701
diff changeset
    34
		f:close();
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    35
		return os_remove(path);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    36
	end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    37
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    38
local function getUserElement(xml)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    39
	if xml and xml.name == "server-data" then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    40
		local host = xml.tags[1];
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    41
		if host and host.name == "host" then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    42
			local user = host.tags[1];
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    43
			if user and user.name == "user" then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    44
				return user;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    45
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    46
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    47
	end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    48
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    49
local function createOuterXml(user, host)
6705
6a5c6c95cf78 mod_storage_xep0227: Use the registered namespace
Kim Alvefur <zash@zash.se>
parents: 6704
diff changeset
    50
	return st.stanza("server-data", {xmlns='urn:xmpp:pie:0'})
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    51
		:tag("host", {jid=host})
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    52
			:tag("user", {name = user});
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    53
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    54
local function removeFromArray(array, value)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    55
	for i,item in ipairs(array) do
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    56
		if item == value then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    57
			t_remove(array, i);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    58
			return;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    59
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    60
	end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    61
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    62
local function removeStanzaChild(s, child)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    63
	removeFromArray(s.tags, child);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    64
	removeFromArray(s, child);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    65
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    66
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    67
local handlers = {};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    68
6706
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    69
-- In order to support mod_auth_internal_hashed
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    70
local extended = "http://prosody.im/protocol/extended-xep0227\1";
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    71
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    72
handlers.accounts = {
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    73
	get = function(self, user)
6707
03afecdf2e3c mod_storage_xep0227: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 6706
diff changeset
    74
		user = getUserElement(getXml(user, self.host));
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    75
		if user and user.attr.password then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    76
			return { password = user.attr.password };
6706
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    77
		elseif user then
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    78
			local data = {};
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    79
			for k, v in pairs(user.attr) do
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    80
				if k:sub(1, #extended) == extended then
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    81
					data[k:sub(#extended+1)] = v;
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    82
				end
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    83
			end
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    84
			return data;
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    85
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    86
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    87
	set = function(self, user, data)
6706
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    88
		if data then
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    89
			local xml = getXml(user, self.host);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    90
			if not xml then xml = createOuterXml(user, self.host); end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    91
			local usere = getUserElement(xml);
6706
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    92
			for k, v in pairs(data) do
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    93
				if k == "password" then
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    94
					usere.attr.password = v;
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    95
				else
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    96
					usere.attr[extended..k] = v;
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    97
				end
353a7d4dfdc2 mod_storage_xep0227: Store data from mod_auth_internal_hashed in a private namespace
Kim Alvefur <zash@zash.se>
parents: 6705
diff changeset
    98
			end
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    99
			return setXml(user, self.host, xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   100
		else
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   101
			return setXml(user, self.host, nil);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   102
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   103
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   104
};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   105
handlers.vcard = {
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   106
	get = function(self, user)
6707
03afecdf2e3c mod_storage_xep0227: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 6706
diff changeset
   107
		user = getUserElement(getXml(user, self.host));
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   108
		if user then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   109
			local vcard = user:get_child("vCard", 'vcard-temp');
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   110
			if vcard then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   111
				return st.preserialize(vcard);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   112
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   113
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   114
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   115
	set = function(self, user, data)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   116
		local xml = getXml(user, self.host);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   117
		local usere = xml and getUserElement(xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   118
		if usere then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   119
			local vcard = usere:get_child("vCard", 'vcard-temp');
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   120
			if vcard then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   121
				removeStanzaChild(usere, vcard);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   122
			elseif not data then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   123
				return true;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   124
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   125
			if data then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   126
				vcard = st.deserialize(data);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   127
				usere:add_child(vcard);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   128
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   129
			return setXml(user, self.host, xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   130
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   131
		return true;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   132
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   133
};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   134
handlers.private = {
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   135
	get = function(self, user)
6707
03afecdf2e3c mod_storage_xep0227: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 6706
diff changeset
   136
		user = getUserElement(getXml(user, self.host));
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   137
		if user then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   138
			local private = user:get_child("query", "jabber:iq:private");
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   139
			if private then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   140
				local r = {};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   141
				for _, tag in ipairs(private.tags) do
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   142
					r[tag.name..":"..tag.attr.xmlns] = st.preserialize(tag);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   143
				end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   144
				return r;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   145
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   146
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   147
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   148
	set = function(self, user, data)
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   149
		local xml = getXml(user, self.host);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   150
		local usere = xml and getUserElement(xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   151
		if usere then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   152
			local private = usere:get_child("query", 'jabber:iq:private');
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   153
			if private then removeStanzaChild(usere, private); end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   154
			if data and next(data) ~= nil then
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   155
				private = st.stanza("query", {xmlns='jabber:iq:private'});
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   156
				for _,tag in pairs(data) do
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   157
					private:add_child(st.deserialize(tag));
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   158
				end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   159
				usere:add_child(private);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   160
			end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   161
			return setXml(user, self.host, xml);
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   162
		end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   163
		return true;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   164
	end;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   165
};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   166
8354
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   167
handlers.roster = {
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   168
	get = function(self, user)
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   169
		user = getUserElement(getXml(user, self.host));
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   170
		if user then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   171
			local roster = user:get_child("query", "jabber:iq:roster");
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   172
			if roster then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   173
				local r = {
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   174
					[false] = {
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   175
						version = roster.attr.version;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   176
						pending = {};
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   177
					}
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   178
				};
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   179
				for item in roster:childtags("item") do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   180
					r[item.attr.jid] = {
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   181
						jid = item.attr.jid,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   182
						subscription = item.attr.subscription,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   183
						ask = item.attr.ask,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   184
						name = item.attr.name,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   185
						groups = {};
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   186
					};
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   187
					for group in item:childtags("group") do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   188
						r[item.attr.jid].groups[group:get_text()] = true;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   189
					end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   190
					for pending in user:childtags("presence", "jabber:client") do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   191
						r[false].pending[pending.attr.from] = true;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   192
					end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   193
				end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   194
				return r;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   195
			end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   196
		end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   197
	end;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   198
	set = function(self, user, data)
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   199
		local xml = getXml(user, self.host);
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   200
		local usere = xml and getUserElement(xml);
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   201
		if usere then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   202
			local roster = usere:get_child("query", 'jabber:iq:roster');
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   203
			if roster then removeStanzaChild(usere, roster); end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   204
			usere:maptags(function (tag)
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   205
				if tag.attr.xmlns == "jabber:client" and tag.name == "presence" and tag.attr.type == "subscribe" then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   206
					return nil;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   207
				end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   208
				return tag;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   209
			end);
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   210
			if data and next(data) ~= nil then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   211
				roster = st.stanza("query", {xmlns='jabber:iq:roster'});
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   212
				usere:add_child(roster);
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   213
				for jid, item in pairs(data) do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   214
					if jid then
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   215
						roster:tag("item", {
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   216
							jid = jid,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   217
							subscription = item.subscription,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   218
							ask = item.ask,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   219
							name = item.name,
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   220
						});
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   221
						for group in pairs(item.groups) do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   222
							roster:tag("group"):text(group):up();
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   223
						end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   224
						roster:up(); -- move out from item
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   225
					else
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   226
						roster.attr.version = item.version;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   227
						for pending_jid in pairs(item.pending) do
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   228
							usere:add_child(st.presence({ from = pending_jid, type = "subscribe" }));
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   229
						end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   230
					end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   231
				end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   232
			end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   233
			return setXml(user, self.host, xml);
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   234
		end
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   235
		return true;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   236
	end;
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   237
};
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   238
cc05b6366576 mod_storage_xep0227: Add roster storage (fixes #1023)
Kim Alvefur <zash@zash.se>
parents: 8353
diff changeset
   239
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   240
-----------------------------
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   241
local driver = {};
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   242
8355
6ff50541d2a6 mod_storage_xep0227: Ignore unused 'self' argument [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8354
diff changeset
   243
function driver:open(datastore, typ) -- luacheck: ignore 212/self
8353
3ca11d408382 mod_storage_xep0227: Correctly report that only key-value stores are supported
Kim Alvefur <zash@zash.se>
parents: 6707
diff changeset
   244
	if typ and typ ~= "keyval" then return nil, "unsupported-store"; end
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   245
	local handler = handlers[datastore];
6704
88a25c364a14 mod_storage_xep0227: Update open method for current API
Kim Alvefur <zash@zash.se>
parents: 6703
diff changeset
   246
	if not handler then return nil, "unsupported-datastore"; end
88a25c364a14 mod_storage_xep0227: Update open method for current API
Kim Alvefur <zash@zash.se>
parents: 6703
diff changeset
   247
	local instance = setmetatable({ host = module.host; datastore = datastore; }, { __index = handler });
3414
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   248
	if instance.init then instance:init(); end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   249
	return instance;
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   250
end
9a1f6239b63c storage/mod_xep0227: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   251
5121
b5a5643f8572 core.storagemanager, mod_storage_*: "data-driver" -> "storage-provider", to allow using module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 3414
diff changeset
   252
module:provides("storage", driver);