Mercurial > prosody-hg
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 |
