comparison plugins/mod_roster.lua @ 13584:0f265142117a

mod_roster: Add basic roster management shell commands
author Matthew Wild <mwild1@gmail.com>
date Tue, 07 Jan 2025 12:26:03 +0000
parents 2fb4ce131131
children 35819bc9471a
comparison
equal deleted inserted replaced
13583:e77ef9a4604f 13584:0f265142117a
13 local jid_resource = require "prosody.util.jid".resource; 13 local jid_resource = require "prosody.util.jid".resource;
14 local jid_prep = require "prosody.util.jid".prep; 14 local jid_prep = require "prosody.util.jid".prep;
15 local tonumber = tonumber; 15 local tonumber = tonumber;
16 local pairs = pairs; 16 local pairs = pairs;
17 17
18 local rm_load_roster = require "prosody.core.rostermanager".load_roster; 18 local rostermanager = require "prosody.core.rostermanager";
19 local rm_remove_from_roster = require "prosody.core.rostermanager".remove_from_roster; 19 local rm_load_roster = rostermanager.load_roster;
20 local rm_add_to_roster = require "prosody.core.rostermanager".add_to_roster; 20 local rm_remove_from_roster = rostermanager.remove_from_roster;
21 local rm_roster_push = require "prosody.core.rostermanager".roster_push; 21 local rm_add_to_roster = rostermanager.add_to_roster;
22 local rm_roster_push = rostermanager.roster_push;
22 23
23 module:add_feature("jabber:iq:roster"); 24 module:add_feature("jabber:iq:roster");
24 25
25 local rosterver_stream_feature = st.stanza("ver", {xmlns="urn:xmpp:features:rosterver"}); 26 local rosterver_stream_feature = st.stanza("ver", {xmlns="urn:xmpp:features:rosterver"});
26 module:hook("stream-features", function(event) 27 module:hook("stream-features", function(event)
145 }); 146 });
146 end 147 end
147 end 148 end
148 end 149 end
149 end, 300); 150 end, 300);
151
152 -- API/commands
153
154 -- Make a *one-way* subscription. User will see when contact is online,
155 -- contact will not see when user is online.
156 function subscribe(user_jid, contact_jid)
157 local user_username, user_host = jid_split(user_jid);
158 local contact_username, contact_host = jid_split(contact_jid);
159
160 -- Update user's roster to say subscription request is pending. Bare hosts (e.g. components) don't have rosters.
161 if user_username ~= nil then
162 rostermanager.set_contact_pending_out(user_username, user_host, contact_jid);
163 end
164
165 if prosody.hosts[contact_host] then -- Sending to a local host?
166 -- Update contact's roster to say subscription request is pending...
167 rostermanager.set_contact_pending_in(contact_username, contact_host, user_jid);
168 -- Update contact's roster to say subscription request approved...
169 rostermanager.subscribed(contact_username, contact_host, user_jid);
170 -- Update user's roster to say subscription request approved. Bare hosts (e.g. components) don't have rosters.
171 if user_username ~= nil then
172 rostermanager.process_inbound_subscription_approval(user_username, user_host, contact_jid);
173 end
174 else
175 -- Send a subscription request
176 local sub_request = st.presence({ from = user_jid, to = contact_jid, type = "subscribe" });
177 module:send(sub_request);
178 end
179
180 return true;
181 end
182
183 -- Make a mutual subscription between jid1 and jid2. Each JID will see
184 -- when the other one is online.
185 function subscribe_both(jid1, jid2)
186 local ok1, err1 = subscribe(jid1, jid2);
187 local ok2, err2 = subscribe(jid2, jid1);
188 return ok1 and ok2, err1 or err2;
189 end
190
191 -- Unsubscribes user from contact (not contact from user, if subscribed).
192 function unsubscribe(user_jid, contact_jid)
193 local user_username, user_host = jid_split(user_jid);
194 local contact_username, contact_host = jid_split(contact_jid);
195
196 -- Update user's roster to say subscription is cancelled...
197 rostermanager.unsubscribe(user_username, user_host, contact_jid);
198 if prosody.hosts[contact_host] then -- Local host?
199 -- Update contact's roster to say subscription is cancelled...
200 rostermanager.unsubscribed(contact_username, contact_host, user_jid);
201 end
202 return true;
203 end
204
205 -- Cancel any subscription in either direction.
206 function unsubscribe_both(jid1, jid2)
207 local ok1 = unsubscribe(jid1, jid2);
208 local ok2 = unsubscribe(jid2, jid1);
209 return ok1 and ok2;
210 end
211
212 module:add_item("shell-command", {
213 section = "roster";
214 section_desc = "View and manage user rosters (contact lists)";
215 name = "show";
216 desc = "Show a user's current roster";
217 args = {
218 { name = "jid", type = "string" };
219 { name = "sub", type = "string" };
220 };
221 host_selector = "jid";
222 handler = function(self, jid, sub) --luacheck: ignore 212/self
223 local print = self.session.print;
224 local it = require "prosody.util.iterators";
225
226 local roster = assert(rm_load_roster(jid_split(jid)));
227
228 local function sort_func(a, b)
229 if type(a) == "string" and type(b) == "string" then
230 return a < b;
231 else
232 return a == false;
233 end
234 end
235
236 local count = 0;
237 if sub == "pending" then
238 local pending_subs = roster[false].pending or {};
239 for pending_jid in it.sorted_pairs(pending_subs) do
240 print(pending_jid);
241 end
242 else
243 for contact, item in it.sorted_pairs(roster, sort_func) do
244 if contact and (not sub or sub == item.subscription) then
245 count = count + 1;
246 print(contact, ("sub=%s\task=%s"):format(item.subscription or "none", item.ask or "none"));
247 end
248 end
249 end
250
251 return true, ("Showing %d entries"):format(count);
252 end;
253 });
254
255 module:add_item("shell-command", {
256 section = "roster";
257 section_desc = "View and manage user rosters (contact lists)";
258 name = "subscribe";
259 desc = "Subscribe a user to another JID";
260 args = {
261 { name = "jid", type = "string" };
262 { name = "contact", type = "string" };
263 };
264 host_selector = "jid";
265 handler = function(self, jid, contact) --luacheck: ignore 212/self
266 return subscribe(jid, contact);
267 end;
268 });
269
270 module:add_item("shell-command", {
271 section = "roster";
272 section_desc = "View and manage user rosters (contact lists)";
273 name = "subscribe_both";
274 desc = "Subscribe a user and a contact JID to each other";
275 args = {
276 { name = "jid", type = "string" };
277 { name = "contact", type = "string" };
278 };
279 host_selector = "jid";
280 handler = function(self, jid, contact) --luacheck: ignore 212/self
281 return subscribe_both(jid, contact);
282 end;
283 });
284
285
286 module:add_item("shell-command", {
287 section = "roster";
288 section_desc = "View and manage user rosters (contact lists)";
289 name = "unsubscribe";
290 desc = "Unsubscribe a user from another JID";
291 args = {
292 { name = "jid", type = "string" };
293 { name = "contact", type = "string" };
294 };
295 host_selector = "jid";
296 handler = function(self, jid, contact) --luacheck: ignore 212/self
297 return unsubscribe(jid, contact);
298 end;
299 });
300
301 module:add_item("shell-command", {
302 section = "roster";
303 section_desc = "View and manage user rosters (contact lists)";
304 name = "unsubscribe_both";
305 desc = "Unubscribe a user and a contact JID from each other";
306 args = {
307 { name = "jid", type = "string" };
308 { name = "contact", type = "string" };
309 };
310 host_selector = "jid";
311 handler = function(self, jid, contact) --luacheck: ignore 212/self
312 return unsubscribe_both(jid, contact);
313 end;
314 });
315