Created
December 3, 2013 04:29
-
-
Save legastero/7763879 to your computer and use it in GitHub Desktop.
Combine the Prosody extdisco modules.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local st = require "util.stanza"; | |
local hmac_sha1 = require "util.hashes".hmac_sha1; | |
local base64 = require "util.encodings".base64; | |
local os_time = os.time; | |
local services = module:get_option("external_services"); | |
local xmlns_extdisco = "urn:xmpp:extdisco:1"; | |
local function gencreds(secret, ttl) | |
ttl = ttl or 86400; | |
local now = os_time() + ttl; | |
local userpart = tostring(now); | |
local nonce = base64.encode(hmac_sha1(secret, tostring(userpart), false)); | |
return { | |
username = userpart; | |
password = nonce; | |
ttl = ttl; | |
}; | |
end | |
module:add_feature(xmlns_extdisco); | |
module:hook("iq-get/host/"..xmlns_extdisco..":services", function (event) | |
local origin, stanza = event.origin, event.stanza; | |
local service = stanza:get_child("service", xmlns_extdisco); | |
local service_type = service and service.attr.type; | |
local reply = st.reply(stanza); | |
if origin.type ~= "c2s" then | |
return; | |
end | |
for host, service_info in pairs(services) do | |
if not(service_type) or service_info.type == service_type then | |
local settings = { | |
host = host; | |
port = service_info.port; | |
transport = service_info.transport; | |
type = service_info.type; | |
}; | |
if service_info.gen_shared_secret then | |
local creds = gencreds(service_info.gen_shared_secret, service_info.gen_ttl); | |
settings.username = creds.username; | |
settings.password = creds.password; | |
else | |
settings.username = service_info.username; | |
settings.password = service_info.password; | |
end | |
reply:tag("service", settings):up(); | |
end | |
end | |
origin.send(reply); | |
return true; | |
end); | |
module:hook("iq-get/host/"..xmlns_extdisco..":credentials", function (event) | |
local origin, stanza = event.origin, event.stanza; | |
local credentials = stanza:get_child("credentials", xmlns_extdisco); | |
local service = credentials and credentials:get_child("service", xmlns_extdisco); | |
local host = service and service.attr.host; | |
if origin.type ~= "c2s" then | |
return; | |
end | |
if not host then | |
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No host specified")); | |
return true; | |
end | |
local service_info = services[host]; | |
if not service_info then | |
origin.send(st.error_reply(stanza, "cancel", "item-not-found", "No such service known")); | |
return true; | |
end | |
local service_creds = { host = host }; | |
if service_info.gen_shared_secret then | |
local creds = gencreds(service_info.gen_shared_secret, service_info.gen_ttl); | |
service_creds.username = creds.username; | |
service_creds.password = creds.password; | |
service_creds.ttl = creds.ttl; | |
else | |
service_creds.username = service_info.username; | |
service_creds.password = service_info.password; | |
end | |
local reply = st.reply(stanza) | |
:tag("credentials") | |
:tag("service", service_creds):up(); | |
origin.send(reply); | |
return true; | |
end); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment