mod_isr/mod_isr.lua
changeset 5028 1cb762f72a91
equal deleted inserted replaced
5027:90772a9c92a0 5028:1cb762f72a91
       
     1 local st = require "util.stanza";
       
     2 
       
     3 local mod_smacks = module:depends("smacks");
       
     4 
       
     5 local xmlns_sasl2 = "urn:xmpp:sasl:1";
       
     6 local xmlns_sm = "urn:xmpp:sm:3";
       
     7 local xmlns_isr = "https://xmpp.org/extensions/isr/0";
       
     8 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas";
       
     9 
       
    10 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
       
    11 	local isr_resume = auth:get_child("inst-resume", xmlns_isr);
       
    12 	if not isr_resume then return end
       
    13 	local is_using_token = isr_resume.attr["with-isr-token"] ~= "false";
       
    14 	if is_using_token then
       
    15 		-- TODO: If authing with token, set session.sasl_handler to our own
       
    16 		-- event.session.sasl_handler = ...
       
    17 		error("not yet implemented");
       
    18 	end
       
    19 
       
    20 	-- Cache resume element for future processing after SASL success
       
    21 	session.isr_sm_resume = isr_resume:get_child("resume", "urn:xmpp:sm:3");
       
    22 end, 100);
       
    23 
       
    24 module:hook("sasl2/c2s/success", function (event)
       
    25 	local session = event.session;
       
    26 	local sm_resume = session.isr_sm_resume;
       
    27 	if sm_resume then
       
    28 		session.isr_sm_resume = nil;
       
    29 		local resumed, err = mod_smacks.do_resume(session, sm_resume);
       
    30 		if not resumed then
       
    31 			local failed = st.stanza("failed", { xmlns = xmlns_sm, h = ("%d"):format(err.context.h) })
       
    32 				:tag(err.condition, { xmlns = xmlns_errors });
       
    33 			event.success:add_child(failed);
       
    34 		else
       
    35 			event.session = resumed.session;
       
    36 			event.isr_resumed = resumed;
       
    37 			event.success:tag("resumed", { xmlns = xmlns_sm,
       
    38 				h = ("%d"):format(event.session.handled_stanza_count);
       
    39 				previd = resumed.id; }):up();
       
    40 		end
       
    41 	end
       
    42 end, 100);
       
    43 
       
    44 module:hook("sasl2/c2s/success", function (event)
       
    45 	-- The authenticate response has already been sent at this point
       
    46 	local resumed = event.isr_resumed;
       
    47 	if resumed then
       
    48 		resumed.finish(); -- Finish resume and sync stanzas
       
    49 	end
       
    50 end, -1100);
       
    51 
       
    52 module:hook("sasl2/c2s/failure", function (event)
       
    53 	event.session.isr_sm_resume = nil;
       
    54 end);
       
    55