mod_unified_push/mod_unified_push.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 14 Jan 2023 14:31:37 +0000
changeset 5153 fa56ed2bacab
parent 5152 bf42f1401f1c
child 5154 2b6c543c4d3a
permissions -rw-r--r--
mod_unified_push: Add support for multiple token backends, including stoage Now that we have ACLs by default, it is no longer necessary to be completely stateless. On 0.12, using storage has benefits over JWT, because it does not expose client JIDs to the push apps/services. In trunk, PASETO is stateless and does not expose client JIDs.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
local unified_push_secret = assert(module:get_option_string("unified_push_secret"), "required option: unified_push_secret");
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
local push_registration_ttl = module:get_option_number("unified_push_registration_ttl", 86400);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local base64 = require "util.encodings".base64;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local datetime = require "util.datetime";
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
     6
local id = require "util.id";
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
     7
local jid = require "util.jid";
5143
449e4ca4de32 mod_unified_push: Remove dependency on trunk util.jwt (0.12 compat)
Matthew Wild <mwild1@gmail.com>
parents: 5140
diff changeset
     8
local jwt = require "util.jwt";
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
local st = require "util.stanza";
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local urlencode = require "util.http".urlencode;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local xmlns_up = "http://gultsch.de/xmpp/drafts/unified-push";
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
module:depends("http");
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
    15
module:depends("disco");
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
    16
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
    17
module:add_feature(xmlns_up);
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
5151
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    19
local acl = module:get_option_set("unified_push_acl", {
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    20
	module:get_host_type() == "local" and module.host or module.host:match("^[^%.]%.(.+)$")
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    21
});
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    22
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    23
local function is_jid_permitted(user_jid)
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    24
	for acl_entry in acl do
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    25
		if jid.compare(user_jid, acl_entry) then
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    26
			return true;
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    27
		end
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    28
	end
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    29
	return false;
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    30
end
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
    31
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
local function check_sha256(s)
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	if not s then return nil, "no value provided"; end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	local d = base64.decode(s);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	if not d then return nil, "invalid base64"; end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	if #d ~= 32 then return nil, "incorrect decoded length, expected 32"; end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	return s;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
5153
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    40
local push_store = module:open_store();
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    41
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    42
local backends = {
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    43
	jwt = {
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    44
		sign = function (data)
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    45
			return jwt.sign(unified_push_secret, data);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    46
		end;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    47
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    48
		verify = function (token)
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    49
			local ok, result = jwt.verify(unified_push_secret, token);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    50
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    51
			if not ok then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    52
				return ok, result;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    53
			end
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    54
			if result.exp and result.exp < os.time() then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    55
				return nil, "token-expired";
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    56
			end
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    57
			return ok, result;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    58
		end;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    59
	};
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    60
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    61
	storage = {
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    62
		sign = function (data)
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    63
			local reg_id = id.long();
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    64
			local user, host = jid.split(data.sub);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    65
			if host ~= module.host or not user then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    66
				return;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    67
			end
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    68
			push_store:set(reg_id, data);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    69
			return reg_id;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    70
		end;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    71
		verify = function (token)
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    72
			local data = push_store:get(token);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    73
			if not data then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    74
				return nil, "item-not-found";
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    75
			elseif data.exp and data.exp < os.time() then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    76
				push_store:set(token, nil);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    77
				return nil, "token-expired";
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    78
			end
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    79
			return data;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    80
		end;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    81
	};
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    82
};
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    83
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    84
if pcall(require, "util.paseto") then
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    85
	local sign, verify = require "util.paseto".init(unified_push_secret);
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    86
	backends.paseto = { sign = sign, verify = verify };
5143
449e4ca4de32 mod_unified_push: Remove dependency on trunk util.jwt (0.12 compat)
Matthew Wild <mwild1@gmail.com>
parents: 5140
diff changeset
    87
end
449e4ca4de32 mod_unified_push: Remove dependency on trunk util.jwt (0.12 compat)
Matthew Wild <mwild1@gmail.com>
parents: 5140
diff changeset
    88
5153
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    89
local backend = module:get_option_string("unified_push_backend", backends.paseto and "paseto" or "storage");
5143
449e4ca4de32 mod_unified_push: Remove dependency on trunk util.jwt (0.12 compat)
Matthew Wild <mwild1@gmail.com>
parents: 5140
diff changeset
    90
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
    91
local function register_route(params)
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
    92
	local expiry = os.time() + push_registration_ttl;
5153
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    93
	local token = backends[backend].sign({
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    94
		instance = params.instance;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    95
		application = params.application;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    96
		sub = params.jid;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    97
		exp = expiry;
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
    98
	});
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
    99
	return {
5153
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
   100
		url = module:http_url("push").."/"..urlencode(token);
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   101
		expiry = expiry;
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   102
	};
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   103
end
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   104
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
-- Handle incoming registration from XMPP client
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
function handle_register(event)
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
	local origin, stanza = event.origin, event.stanza;
5151
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
   108
	if not is_jid_permitted(stanza.attr.from) then
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
   109
		return st.error_reply(stanza, "auth", "forbidden");
658658ea9323 mod_unified_push: Add ACL option to restrict access
Matthew Wild <mwild1@gmail.com>
parents: 5150
diff changeset
   110
	end
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
	local instance, instance_err = check_sha256(stanza.tags[1].attr.instance);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
	if not instance then
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
		return st.error_reply(stanza, "modify", "bad-request", "instance: "..instance_err);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
	end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   115
	local application, application_err = check_sha256(stanza.tags[1].attr.application);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   116
	if not application then
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
		return st.error_reply(stanza, "modify", "bad-request", "application: "..application_err);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
	end
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   119
	local route = register_route({
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
		instance = instance;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
		application = application;
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   122
		jid = stanza.attr.from;
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   123
	});
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   124
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   125
	if not route then
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   126
		return st.error_reply(stanza, "wait", "internal-server-error");
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   127
	end
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   128
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
	module:log("debug", "New push registration successful");
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
	return origin.send(st.reply(stanza):tag("registered", {
5152
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   131
		expiration = datetime.datetime(route.expiry);
bf42f1401f1c mod_unified_push: Refactor in anticipation of other registration backends
Matthew Wild <mwild1@gmail.com>
parents: 5151
diff changeset
   132
		endpoint = route.url;
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
		xmlns = xmlns_up;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   134
	}));
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
module:hook("iq-set/host/"..xmlns_up..":register", handle_register);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
-- Handle incoming POST
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   140
function handle_push(event, subpath)
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   141
	module:log("debug", "Incoming push received!");
5153
fa56ed2bacab mod_unified_push: Add support for multiple token backends, including stoage
Matthew Wild <mwild1@gmail.com>
parents: 5152
diff changeset
   142
	local ok, data = backends[backend].verify(subpath);
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   143
	if not ok then
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   144
		module:log("debug", "Received push to unacceptable token (%s)", data);
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   145
		return 404;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
	end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
	local payload = event.request.body;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
	if not payload or payload == "" then
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   149
		module:log("warn", "Missing or empty push payload");
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
		return 400;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
	elseif #payload > 4096 then
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   152
		module:log("warn", "Push payload too large");
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
		return 413;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
	end
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   155
	local push_id = event.request.id or id.short();
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   156
	module:log("debug", "Push notification received [%s], relaying to device...", push_id);
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   157
	local push_iq = st.iq({ type = "set", to = data.sub, from = module.host, id = push_id })
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
		:text_tag("push", base64.encode(payload), { instance = data.instance, application = data.application, xmlns = xmlns_up });
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
	return module:send_iq(push_iq):next(function ()
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   160
		module:log("debug", "Push notification delivered [%s]", push_id);
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
		return 201;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
	end, function (error_event)
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
		local e_type, e_cond, e_text = error_event.stanza:get_error();
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
		if e_cond == "item-not-found" or e_cond == "feature-not-implemented" then
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   165
			module:log("debug", "Push rejected [%s]", push_id);
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
			return 404;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
		elseif e_cond == "service-unavailable" or e_cond == "recipient-unavailable" then
5140
67b2c982bea2 mod_unified_push: Various fixes, now working with Conversations
Matthew Wild <mwild1@gmail.com>
parents: 5132
diff changeset
   168
			module:log("debug", "Recipient temporarily unavailable [%s]", push_id);
5132
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
			return 503;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   170
		end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
		module:log("warn", "Unexpected push error response: %s/%s/%s", e_type, e_cond, e_text);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
		return 500;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
	end);
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
end
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   175
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
module:provides("http", {
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
	name = "push";
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
	route = {
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
		["GET /*"] = function (event)
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   180
			event.response.headers.content_type = "application/json";
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
			return [[{"unifiedpush":{"version":1}}]];
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
		end;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   183
		["POST /*"] = handle_push;
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
	};
7cc0f68b8715 mod_unified_push: Experimenal Unified Push provider
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   185
});