Mercurial > prosody-modules
annotate mod_devices/mod_devices.lua @ 4515:2e33eeafe962
mod_muc_markers: Prevent any markers from reaching the archive, even if untracked
Original intention was to leave alone things that this module isn't
handling. However markers in archives are just problematic without
more advanced logic about what is markable and what is not. It also
requires a more advanced query in mod_muc_rai to determine the latest
markable message instead of the latest archived message.
I'd rather keep the "is archivable" and "is markable" definition the
same for simplicity. I don't want to introduce yet another set of rules
for no reason.
No markers in MAM.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 22 Mar 2021 15:55:02 +0000 |
parents | 4cf65afd90f4 |
children |
rev | line source |
---|---|
3397
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local it = require "util.iterators"; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local new_id = require "util.id".medium; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local max_user_devices = module:get_option_number("max_user_devices", 5); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local device_store = module:open_store("devices"); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 local device_map_store = module:open_store("devices", "map"); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 --- Helper functions |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 local function _compare_device_timestamps(a, b) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 return (a.last_activity_at or 0) < (b.last_activity_at or 0); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 local function sorted_devices(devices) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 return it.sorted_pairs(devices, _compare_device_timestamps); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 local function new_device(username, alt_ids) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 local current_time = os.time(); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 local device = { |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 id = "dv-"..new_id(); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 created_at = current_time; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 last_activity = "created"; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 last_activity_at = current_time; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 alt_ids = alt_ids or {}; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 }; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 local devices = device_store:get(username); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 if not devices then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 devices = {}; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 devices[device.id] = device; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 local devices_ordered = {}; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 for id in sorted_devices(devices) do |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 table.insert(devices_ordered, id); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 if #devices_ordered > max_user_devices then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 -- Iterate through oldest devices that are above limit, backwards |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 for i = #devices_ordered, max_user_devices+1, -1 do |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 local id = table.remove(devices_ordered, i); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 devices[id] = nil; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 module:log("debug", "Removing old device for %s: %s", username, id); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 device_store:set(username, devices); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 return device; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 local function get_device_with_alt_id(username, alt_id_type, alt_id) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 local devices = device_store:get(username); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 if not devices then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 return nil; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 for _, device in pairs(devices) do |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 if device.alt_ids[alt_id_type] == alt_id then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 return device; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 local function set_device_alt_id(username, device_id, alt_id_type, alt_id) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 local devices = device_store:get(username); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 if not devices or not devices[device_id] then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 return nil, "no such device"; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 devices[device_id].alt_ids[alt_id_type] = alt_id; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 local function record_device_state(username, device_id, activity, time) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 local device = device_map_store:get(username, device_id); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 device.last_activity = activity; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 device.last_activity_at = time or os.time(); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 device_map_store:set(username, device_id, device); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 local function find_device(username, info) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 for _, alt_id_type in ipairs({ "resumption_token", "resource" }) do |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 local alt_id = info[alt_id_type]; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 if alt_id then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 local device = get_device_with_alt_id(username, alt_id_type, alt_id); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 if device then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 return device, alt_id_type; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 --- Information gathering |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 module:hook("pre-resource-bind", function (event) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 event.session.device_requested_resource = event.resource; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 end, 1000); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 local function store_resumption_token(session, stanza) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 session.device_requested_resume = stanza.attr.previd; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
99 module:hook_stanza("urn:xmpp:sm:2", "resume", store_resumption_token, 5); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 module:hook_stanza("urn:xmpp:sm:3", "resume", store_resumption_token, 5); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
101 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 --- Identify device after resource bind |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 module:hook("resource-bind", function (event) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 local info = { |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 resource = event.session.device_requested_resource; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 resumption_token = event.session.device_requested_resume; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 }; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 local device, source = find_device(event.session.username, info); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
110 if device then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 event.session.log("debug", "Associated with device %s (from %s)", device.id, source); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 event.session.device_id = device.id; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 else |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 device = new_device(event.session.username, info); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
115 event.session.log("debug", "Creating new device %s for session", device.id); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
116 event.session.device_id = device.id; |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
117 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
118 record_device_state(event.session.username, device.id, "login"); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
119 end, 1000); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
120 |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
121 module:hook("resource-unbind", function (event) |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
122 if event.session.device_id then |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
123 record_device_state(event.session.username, event.session.device_id, "logout"); |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 end |
4cf65afd90f4
mod_devices: New module for device identification
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
125 end); |