1----------------------------------------------------------- 2-- mod_roster_command: Manage rosters through prosodyctl 3-- version 0.02 4----------------------------------------------------------- 5-- Copyright (C) 2011 Matthew Wild 6-- Copyright (C) 2011 Adam Nielsen 7-- 8-- This project is MIT/X11 licensed. Please see the 9-- COPYING file in the source package for more information. 10----------------------------------------------------------- 11 12if module.host ~= "*" then 13 module:log("error", "Do not load this module in Prosody, for correct usage see: https://modules.prosody.im/mod_roster_command.html"); 14 return; 15end 16 17 18-- Workaround for lack of util.startup... 19local prosody = _G.prosody; 20local hosts = prosody.hosts; 21prosody.bare_sessions = prosody.bare_sessions or {}; 22_G.bare_sessions = _G.bare_sessions or prosody.bare_sessions; 23 24local usermanager = require "core.usermanager"; 25local rostermanager = require "core.rostermanager"; 26local storagemanager = require "core.storagemanager"; 27local jid = require "util.jid"; 28local warn = require"util.prosodyctl".show_warning; 29 30-- Make a *one-way* subscription. User will see when contact is online, 31-- contact will not see when user is online. 32function subscribe(user_jid, contact_jid) 33 local user_username, user_host = jid.split(user_jid); 34 local contact_username, contact_host = jid.split(contact_jid); 35 if not hosts[user_host] then 36 warn("The host '%s' is not configured for this server.", user_host); 37 return; 38 end 39 if hosts[user_host].users.name == "null" then 40 storagemanager.initialize_host(user_host); 41 usermanager.initialize_host(user_host); 42 end 43 -- Update user's roster to say subscription request is pending. Bare hosts (e.g. components) don't have rosters. 44 if user_username ~= nil then 45 rostermanager.set_contact_pending_out(user_username, user_host, contact_jid); 46 end 47 if hosts[contact_host] then 48 if contact_host ~= user_host and hosts[contact_host].users.name == "null" then 49 storagemanager.initialize_host(contact_host); 50 usermanager.initialize_host(contact_host); 51 end 52 -- Update contact's roster to say subscription request is pending... 53 rostermanager.set_contact_pending_in(contact_username, contact_host, user_jid); 54 -- Update contact's roster to say subscription request approved... 55 rostermanager.subscribed(contact_username, contact_host, user_jid); 56 -- Update user's roster to say subscription request approved. Bare hosts (e.g. components) don't have rosters. 57 if user_username ~= nil then 58 rostermanager.process_inbound_subscription_approval(user_username, user_host, contact_jid); 59 end 60 end 61end 62 63-- Make a mutual subscription between jid1 and jid2. Each JID will see 64-- when the other one is online. 65function subscribe_both(jid1, jid2) 66 subscribe(jid1, jid2); 67 subscribe(jid2, jid1); 68end 69 70-- Unsubscribes user from contact (not contact from user, if subscribed). 71function unsubscribe(user_jid, contact_jid) 72 local user_username, user_host = jid.split(user_jid); 73 local contact_username, contact_host = jid.split(contact_jid); 74 if not hosts[user_host] then 75 warn("The host '%s' is not configured for this server.", user_host); 76 return; 77 end 78 if hosts[user_host].users.name == "null" then 79 storagemanager.initialize_host(user_host); 80 usermanager.initialize_host(user_host); 81 end 82 -- Update user's roster to say subscription is cancelled... 83 rostermanager.unsubscribe(user_username, user_host, contact_jid); 84 if hosts[contact_host] then 85 if contact_host ~= user_host and hosts[contact_host].users.name == "null" then 86 storagemanager.initialize_host(contact_host); 87 usermanager.initialize_host(contact_host); 88 end 89 -- Update contact's roster to say subscription is cancelled... 90 rostermanager.unsubscribed(contact_username, contact_host, user_jid); 91 end 92end 93 94-- Cancel any subscription in either direction. 95function unsubscribe_both(jid1, jid2) 96 unsubscribe(jid1, jid2); 97 unsubscribe(jid2, jid1); 98end 99 100-- Set the name shown and group used in the contact list 101function rename(user_jid, contact_jid, contact_nick, contact_group) 102 local user_username, user_host = jid.split(user_jid); 103 if not hosts[user_host] then 104 warn("The host '%s' is not configured for this server.", user_host); 105 return; 106 end 107 if hosts[user_host].users.name == "null" then 108 storagemanager.initialize_host(user_host); 109 usermanager.initialize_host(user_host); 110 end 111 112 -- Load user's roster and find the contact 113 local roster = rostermanager.load_roster(user_username, user_host); 114 local item = roster[contact_jid]; 115 if item then 116 if contact_nick then 117 item.name = contact_nick; 118 end 119 if contact_group then 120 item.groups = {}; -- Remove from all current groups 121 item.groups[contact_group] = true; 122 end 123 rostermanager.save_roster(user_username, user_host, roster); 124 end 125end 126 127function remove(user_jid, contact_jid) 128 unsubscribe_both(user_jid, contact_jid); 129 local user_username, user_host = jid.split(user_jid); 130 local roster = rostermanager.load_roster(user_username, user_host); 131 roster[contact_jid] = nil; 132 rostermanager.save_roster(user_username, user_host, roster); 133end 134 135function module.command(arg) 136 local command = arg[1]; 137 if not command then 138 warn("Valid subcommands: (un)subscribe(_both) | rename"); 139 return 0; 140 end 141 table.remove(arg, 1); 142 if command == "subscribe" then 143 subscribe(arg[1], arg[2]); 144 return 0; 145 elseif command == "subscribe_both" then 146 subscribe_both(arg[1], arg[2]); 147 return 0; 148 elseif command == "unsubscribe" then 149 unsubscribe(arg[1], arg[2]); 150 return 0; 151 elseif command == "unsubscribe_both" then 152 unsubscribe_both(arg[1], arg[2]); 153 return 0; 154 elseif command == "remove" then 155 remove(arg[1], arg[2]); 156 return 0; 157 elseif command == "rename" then 158 rename(arg[1], arg[2], arg[3], arg[4]); 159 return 0; 160 else 161 warn("Unknown command: %s", command); 162 return 1; 163 end 164 return 0; 165end 166