Software /
code /
prosody-modules
Comparison
mod_rest/jsonmap.lib.lua @ 3953:2c6d5734ae04
mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Example XEP-0157 payload:
{
"disco" : {
"extensions" : {
"http://jabber.org/network/serverinfo" : {
"abuse-addresses" : [
"mailto:abuse@shakespeare.lit",
"xmpp:abuse@shakespeare.lit"
],
"admin-addresses" : [
"mailto:admin@shakespeare.lit",
"xmpp:admin@shakespeare.lit"
],
"feedback-addresses" : [
"http://shakespeare.lit/feedback.php",
"mailto:feedback@shakespeare.lit",
"xmpp:feedback@shakespeare.lit"
],
"sales-addresses" : [
"xmpp:bard@shakespeare.lit"
],
"security-addresses" : [
"xmpp:security@shakespeare.lit"
],
"support-addresses" : [
"http://shakespeare.lit/support.php",
"xmpp:support@shakespeare.lit"
]
}
}
}
}
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 23 Mar 2020 19:03:04 +0100 |
parent | 3932:8b34222216f4 |
child | 4021:1925d63eec6b |
comparison
equal
deleted
inserted
replaced
3952:343dc9dd70dd | 3953:2c6d5734ae04 |
---|---|
73 | 73 |
74 -- XEP-0030 | 74 -- XEP-0030 |
75 disco = { | 75 disco = { |
76 type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query", | 76 type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query", |
77 st2json = function (s) --> array of features | 77 st2json = function (s) --> array of features |
78 local identities, features = array(), array(); | 78 local identities, features, extensions = array(), array(), {}; |
79 for tag in s:childtags() do | 79 for tag in s:childtags() do |
80 if tag.name == "identity" and tag.attr.category and tag.attr.type then | 80 if tag.name == "identity" and tag.attr.category and tag.attr.type then |
81 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name }); | 81 identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name }); |
82 elseif tag.name == "feature" and tag.attr.var then | 82 elseif tag.name == "feature" and tag.attr.var then |
83 features:push(tag.attr.var); | 83 features:push(tag.attr.var); |
84 end | 84 end |
85 end | 85 end |
86 return { node = s.attr.node, identities = identities, features = features, }; | 86 for form in s:childtags("x", "jabber:x:data") do |
87 local jform = field_mappings.formdata.st2json(form); | |
88 local form_type = jform["FORM_TYPE"]; | |
89 if jform then | |
90 jform["FORM_TYPE"] = nil; | |
91 extensions[form_type] = jform; | |
92 end | |
93 end | |
94 if next(extensions) == nil then extensions = nil; end | |
95 return { node = s.attr.node, identities = identities, features = features, extensions = extensions }; | |
87 end; | 96 end; |
88 json2st = function (s) | 97 json2st = function (s) |
89 if type(s) == "table" and s ~= json.null then | 98 if type(s) == "table" and s ~= json.null then |
90 local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s.node }); | 99 local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s.node }); |
91 if s.identities then | 100 if s.identities then |
94 end | 103 end |
95 end | 104 end |
96 if s.features then | 105 if s.features then |
97 for _, feature in ipairs(s.features) do | 106 for _, feature in ipairs(s.features) do |
98 disco:tag("feature", { var = feature }):up(); | 107 disco:tag("feature", { var = feature }):up(); |
108 end | |
109 end | |
110 if s.extensions then | |
111 for form_type, extension in pairs(s.extensions) do | |
112 extension["FORM_TYPE"] = form_type; | |
113 disco:add_child(field_mappings.formdata.json2st(extension)); | |
99 end | 114 end |
100 end | 115 end |
101 return disco; | 116 return disco; |
102 else | 117 else |
103 return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", }); | 118 return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", }); |
322 end; | 337 end; |
323 }; | 338 }; |
324 | 339 |
325 -- Simpler mapping of dataform from JSON map | 340 -- Simpler mapping of dataform from JSON map |
326 formdata = { type = "func", xmlns = "jabber:x:data", tagname = "", | 341 formdata = { type = "func", xmlns = "jabber:x:data", tagname = "", |
327 st2json = function () | 342 st2json = function (s) |
328 -- Tricky to do in a generic way without each form layout | 343 local r = {}; |
329 -- In the future, some well-known layouts might be understood | 344 for field in s:childtags("field") do |
330 return nil, "not-implemented"; | 345 if field.attr.var then |
346 local values = array(); | |
347 for value in field:childtags("value") do | |
348 values:push(value:get_text()); | |
349 end | |
350 if field.attr.type == "list-single" or field.attr.type == "list-multi" then | |
351 r[field.attr.var] = values; | |
352 elseif field.attr.type == "text-multi" then | |
353 r[field.attr.var] = values:concat("\n"); | |
354 elseif field.attr.type == "boolean" then | |
355 r[field.attr.var] = values[1] == "1" or values[1] == "true"; | |
356 elseif field.attr.type then | |
357 r[field.attr.var] = values[1] or json.null; | |
358 else -- type is optional, no way to know if multiple or single value is expected | |
359 r[field.attr.var] = values; | |
360 end | |
361 end | |
362 end | |
363 return r; | |
331 end, | 364 end, |
332 json2st = function (s, t) | 365 json2st = function (s, t) |
333 local form = st.stanza("x", { xmlns = "jabber:x:data", type = t }); | 366 local form = st.stanza("x", { xmlns = "jabber:x:data", type = t }); |
334 for k, v in pairs(s) do | 367 for k, v in pairs(s) do |
335 form:tag("field", { var = k }); | 368 form:tag("field", { var = k }); |