mod_rest/jsonmap.lib.lua
author Kim Alvefur <zash@zash.se>
Sat, 25 Jan 2020 00:17:44 +0100
changeset 3852 1b9834500123
parent 3827 31b1797a78e1
child 3853 11c34e97fe1a
permissions -rw-r--r--
mod_rest: Fix iteration over disco#info identities
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local array = require "util.array";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local jid = require "util.jid";
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
     3
local json = require "util.json";
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local st = require "util.stanza";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local xml = require "util.xml";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local simple_types = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
	-- basic message
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
	body = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
	subject = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	thread = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
	-- basic presence
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
	show = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
	status = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
	priority = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
	state = {"name", "http://jabber.org/protocol/chatstates"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	nick = {"text_tag", "http://jabber.org/protocol/nick", "nick"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
	delay = {"attr", "urn:xmpp:delay", "delay", "stamp"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
	replace = {"attr", "urn:xmpp:message-correct:0", "replace", "id"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
	-- XEP-0045 MUC
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
	-- TODO history, password, ???
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
	join = {"bool_tag", "http://jabber.org/protocol/muc", "x"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
	-- XEP-0071
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	-- FIXME xmlns is awkward
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
	html = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
		"func", "http://jabber.org/protocol/xhtml-im", "html",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
		function (s) --> json string
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
			return tostring(s:get_child("body", "http://www.w3.org/1999/xhtml"));
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
		function (s) --> xml
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
    35
			if type(s) == "string" then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
    36
				return xml.parse([[<html xmlns='http://jabber.org/protocol/xhtml-im'>]]..s..[[</html>]]);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
    37
			end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	-- XEP-0199
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	ping = {"bool_tag", "urn:xmpp:ping", "ping"},
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
	-- XEP-0030
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	disco = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
		"func", "http://jabber.org/protocol/disco#info", "query",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
		function (s) --> array of features
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
			local identities, features = array(), array();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
			for tag in s:childtags() do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
				if tag.name == "identity" and tag.attr.category and tag.attr.type then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
					identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
				elseif tag.name == "feature" and tag.attr.var then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
					features:push(tag.attr.var);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
			end
3826
f0a1d113dce4 mod_rest: Add support for mapping 'node' attr in disco#info
Kim Alvefur <zash@zash.se>
parents: 3823
diff changeset
    56
			return { node = s.attr.node, identities = identities, features = features, };
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		function  (s)
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
			local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info" });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
			if type(s) == "table" then
3826
f0a1d113dce4 mod_rest: Add support for mapping 'node' attr in disco#info
Kim Alvefur <zash@zash.se>
parents: 3823
diff changeset
    61
				disco.attr.node = tostring(s.node);
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
				if s.identities then
3852
1b9834500123 mod_rest: Fix iteration over disco#info identities
Kim Alvefur <zash@zash.se>
parents: 3827
diff changeset
    63
					for _, identity in ipairs(s.identities) do
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
						disco:tag("identity", { category = identity[1], type = identity[2] }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
					end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
				if s.features then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
					for feature in ipairs(s.features) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
						disco:tag("feature", { var = feature }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
					end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
			return disco;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
	items = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
		"func", "http://jabber.org/protocol/disco#items", "query",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
		function (s) --> array of features
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
			local items = array();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
			for item in s:childtags("item") do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
				items:push({ jid = item.attr.jid, node = item.attr.node, name = item.attr.name });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
			return items;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
		function  (s)
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
			local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#items" });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
			if type(s) == "table" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
				for _, item in ipairs(s) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
					disco:tag("item", item);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
			return disco;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	oob_url = {"func", "jabber:iq:oob", "query",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
		function (s)
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
			return s:get_child_text("url");
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
		function (s)
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   102
			if type(s) == "string" then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   103
				return st.stanza("query", { xmlns = "jabber:iq:oob" }):text_tag("url", s);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   104
			end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
	};
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   107
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   108
	-- XEP-XXXX: User-defined Data Transfer
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   109
	payload = {"func", "urn:xmpp:udt:0", "payload",
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   110
		function (s)
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   111
			local rawjson = s:get_child_text("json", "urn:xmpp:json:0");
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   112
			if not rawjson then return nil, "missing-json-payload"; end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   113
			local parsed, err = json.decode(rawjson);
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   114
			if not parsed then return nil, err; end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   115
			return {
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   116
				datatype = s.attr.datatype;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   117
				data = parsed;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   118
			};
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   119
		end;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   120
		function (s)
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   121
			if type(s) == "table" then
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   122
				return st.stanza("payload", { xmlns = "urn:xmpp:udt:0", datatype = s.datatype })
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   123
					:tag("json", { xmlns = "urn:xmpp:json:0" }):text(json.encode(s.data));
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   124
			end;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   125
		end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   126
	};
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   127
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
local implied_kinds = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
	disco = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
	items = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
	ping = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
	body = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
	html = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
	replace = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
	state = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	subject = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
	thread = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
	join = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
	priority = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
	show = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
	status = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
}
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
local kind_by_type = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
	get = "iq", set = "iq", result = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
	normal = "message", chat = "message", headline = "message", groupchat = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	available = "presence", unavailable = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
	subscribe = "presence", unsubscribe = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
	subscribed = "presence", unsubscribed = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
}
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
local function st2json(s)
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
	local t = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
		kind = s.name,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
		type = s.attr.type,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
		to = s.attr.to,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
		from = s.attr.from,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
		id = s.attr.id,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
	if s.name == "presence" and not s.attr.type then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
		t.type = "available";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
	if t.to then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
		t.to = jid.prep(t.to);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
		if not t.to then return nil, "invalid-jid-to"; end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
	if t.from then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
		t.from = jid.prep(t.from);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
		if not t.from then return nil, "invalid-jid-from"; end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
	if t.type == "error" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
		local err_typ, err_condition, err_text = s:get_error();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
		t.error = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
			type = err_typ,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
			condition = err_condition,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   182
			text = err_text
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
		};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
		return t;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
	for k, typ in pairs(simple_types) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
		if typ == "text_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
			t[k] = s:get_child_text(k);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
		elseif typ[1] == "text_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
			t[k] = s:get_child_text(typ[3], typ[2]);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
		elseif typ[1] == "name" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
			local child = s:get_child(nil, typ[2]);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
			if child then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
				t[k] = child.name;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
		elseif typ[1] == "attr" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   198
			local child = s:get_child(typ[3], typ[2])
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
			if child then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
				t[k] = child.attr[typ[4]];
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
		elseif typ[1] == "bool_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
			if s:get_child(typ[3], typ[2]) then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   204
				t[k] = true;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
		elseif typ[1] == "func" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
			local child = s:get_child(typ[3], typ[2] or k);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
			-- TODO handle err
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
			if child then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
				t[k] = typ[4](child);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
	return t;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   218
local function str(s)
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   219
	if type(s) == "string" then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   220
		return s;
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   221
	end
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   222
end
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   223
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
local function json2st(t)
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   225
	if type(t) ~= "table" or not str(next(t)) then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   226
		return nil, "invalid-json";
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   227
	end
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   228
	local kind = str(t.kind) or kind_by_type[str(t.type)];
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
	if not kind then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
		for k, implied in pairs(implied_kinds) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
			if t[k] then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   232
				kind = implied;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
				break
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
	local s = st.stanza(kind or "message", {
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   239
		type = t.type ~= "available" and str(t.type) or nil,
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   240
		to = str(t.to) and jid.prep(t.to);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   241
		from = str(t.to) and jid.prep(t.from);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   242
		id = str(t.id),
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
	});
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
	if t.to and not s.attr.to then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
		return nil, "invalid-jid-to";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
	if t.from and not s.attr.from then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
		return nil, "invalid-jid-from";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
	end
3823
1bab6f67eb5f mod_rest: Fix previous commit
Kim Alvefur <zash@zash.se>
parents: 3822
diff changeset
   251
	if kind == "iq" and not s.attr.type then
1bab6f67eb5f mod_rest: Fix previous commit
Kim Alvefur <zash@zash.se>
parents: 3822
diff changeset
   252
		s.attr.type = "get";
3822
a607c69d0804 mod_rest: Guess 'get' as default type for 'iq' stanzas in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3821
diff changeset
   253
	end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   255
	if type(t.error) == "table" then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   256
		return st.error_reply(st.reply(s), str(t.error.type), str(t.error.condition), str(t.error.text));
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
	elseif t.type == "error" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   258
		s:text_tag("error", t.body, { code = t.error_code and tostring(t.error_code) });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
		return s;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   260
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
	for k, v in pairs(t) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
		local typ = simple_types[k];
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
		if typ then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
			if typ == "text_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
				s:text_tag(k, v);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   267
			elseif typ[1] == "text_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   268
				s:text_tag(typ[3] or k, v, typ[2] and { xmlns = typ[2] });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   269
			elseif typ[1] == "name" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   270
				s:tag(v, { xmlns = typ[2] }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   271
			elseif typ[1] == "attr" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   272
				s:tag(typ[3] or k, { xmlns = typ[2], [ typ[4] or k ] = v }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   273
			elseif typ[1] == "bool_tag" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   274
				s:tag(typ[3] or k, { xmlns = typ[2] }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   275
			elseif typ[1] == "func" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   276
				s:add_child(typ[5](v)):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   277
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   278
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   279
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   280
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   281
	s:reset();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   282
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   283
	return s;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   284
end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   285
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   286
return {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   287
	st2json = st2json;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   288
	json2st = json2st;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   289
};