core/rostermanager.lua
changeset 7158 4a0825984e42
parent 7157 b3b92204802f
child 7170 7ae430fecf12
equal deleted inserted replaced
7157:b3b92204802f 7158:4a0825984e42
    27 
    27 
    28 local function add_to_roster(session, jid, item)
    28 local function add_to_roster(session, jid, item)
    29 	if session.roster then
    29 	if session.roster then
    30 		local old_item = session.roster[jid];
    30 		local old_item = session.roster[jid];
    31 		session.roster[jid] = item;
    31 		session.roster[jid] = item;
    32 		if save_roster(session.username, session.host) then
    32 		if save_roster(session.username, session.host, nil, jid) then
    33 			return true;
    33 			return true;
    34 		else
    34 		else
    35 			session.roster[jid] = old_item;
    35 			session.roster[jid] = old_item;
    36 			return nil, "wait", "internal-server-error", "Unable to save roster";
    36 			return nil, "wait", "internal-server-error", "Unable to save roster";
    37 		end
    37 		end
    42 
    42 
    43 local function remove_from_roster(session, jid)
    43 local function remove_from_roster(session, jid)
    44 	if session.roster then
    44 	if session.roster then
    45 		local old_item = session.roster[jid];
    45 		local old_item = session.roster[jid];
    46 		session.roster[jid] = nil;
    46 		session.roster[jid] = nil;
    47 		if save_roster(session.username, session.host) then
    47 		if save_roster(session.username, session.host, nil, jid) then
    48 			return true;
    48 			return true;
    49 		else
    49 		else
    50 			session.roster[jid] = old_item;
    50 			session.roster[jid] = old_item;
    51 			return nil, "wait", "internal-server-error", "Unable to save roster";
    51 			return nil, "wait", "internal-server-error", "Unable to save roster";
    52 		end
    52 		end
   121 		hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster });
   121 		hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster });
   122 	end
   122 	end
   123 	return roster, err;
   123 	return roster, err;
   124 end
   124 end
   125 
   125 
   126 function save_roster(username, host, roster)
   126 function save_roster(username, host, roster, jid)
   127 	if not um_user_exists(username, host) then
   127 	if not um_user_exists(username, host) then
   128 		log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host);
   128 		log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host);
   129 		return nil;
   129 		return nil;
   130 	end
   130 	end
   131 
   131 
   132 	log("debug", "save_roster: saving roster for %s@%s", username, host);
   132 	log("debug", "save_roster: saving roster for %s@%s, (%s)", username, host, jid or "all contacts");
   133 	if not roster then
   133 	if not roster then
   134 		roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster;
   134 		roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster;
   135 		--if not roster then
   135 		--if not roster then
   136 		--	--roster = load_roster(username, host);
   136 		--	--roster = load_roster(username, host);
   137 		--	return true; -- roster unchanged, no reason to save
   137 		--	return true; -- roster unchanged, no reason to save
   141 		local metadata = roster_metadata(roster);
   141 		local metadata = roster_metadata(roster);
   142 		if metadata.version ~= true then
   142 		if metadata.version ~= true then
   143 			metadata.version = (metadata.version or 0) + 1;
   143 			metadata.version = (metadata.version or 0) + 1;
   144 		end
   144 		end
   145 		if metadata.broken then return nil, "Not saving broken roster" end
   145 		if metadata.broken then return nil, "Not saving broken roster" end
   146 		local roster_store = require "core.storagemanager".open(host, "roster", "keyval");
   146 		if jid == nil then
   147 		return roster_store:set(username, roster);
   147 			local roster_store = require "core.storagemanager".open(host, "roster", "keyval");
       
   148 			return roster_store:set(username, roster);
       
   149 		else
       
   150 			local roster_store = require "core.storagemanager".open(host, "roster", "map");
       
   151 			return roster_store:set_keys(username, { [false] = metadata, [jid] = roster[jid] or roster_store.remove });
       
   152 		end
   148 	end
   153 	end
   149 	log("warn", "save_roster: user had no roster to save");
   154 	log("warn", "save_roster: user had no roster to save");
   150 	return nil;
   155 	return nil;
   151 end
   156 end
   152 
   157 
   158 			item.subscription = "to";
   163 			item.subscription = "to";
   159 		else -- subscription == from
   164 		else -- subscription == from
   160 			item.subscription = "both";
   165 			item.subscription = "both";
   161 		end
   166 		end
   162 		item.ask = nil;
   167 		item.ask = nil;
   163 		return save_roster(username, host, roster);
   168 		return save_roster(username, host, roster, jid);
   164 	end
   169 	end
   165 end
   170 end
   166 
   171 
   167 local is_contact_pending_out -- forward declaration
   172 local is_contact_pending_out -- forward declaration
   168 
   173 
   182 			item.subscription = "from";
   187 			item.subscription = "from";
   183 			changed = true;
   188 			changed = true;
   184 		end
   189 		end
   185 	end
   190 	end
   186 	if changed then
   191 	if changed then
   187 		return save_roster(username, host, roster);
   192 		return save_roster(username, host, roster, jid);
   188 	end
   193 	end
   189 end
   194 end
   190 
   195 
   191 local is_contact_pending_in -- forward declaration
   196 local is_contact_pending_in -- forward declaration
   192 
   197 
   206 			item.subscription = "to";
   211 			item.subscription = "to";
   207 			changed = true;
   212 			changed = true;
   208 		end
   213 		end
   209 	end
   214 	end
   210 	if changed then
   215 	if changed then
   211 		return save_roster(username, host, roster);
   216 		return save_roster(username, host, roster, jid);
   212 	end
   217 	end
   213 end
   218 end
   214 
   219 
   215 local function _get_online_roster_subscription(jidA, jidB)
   220 local function _get_online_roster_subscription(jidA, jidB)
   216 	local user = bare_sessions[jidA];
   221 	local user = bare_sessions[jidA];
   239 	local item = roster[jid];
   244 	local item = roster[jid];
   240 	if item and (item.subscription == "from" or item.subscription == "both") then
   245 	if item and (item.subscription == "from" or item.subscription == "both") then
   241 		return; -- false
   246 		return; -- false
   242 	end
   247 	end
   243 	roster[false].pending[jid] = true;
   248 	roster[false].pending[jid] = true;
   244 	return save_roster(username, host, roster);
   249 	return save_roster(username, host, roster, jid);
   245 end
   250 end
   246 function is_contact_pending_out(username, host, jid)
   251 function is_contact_pending_out(username, host, jid)
   247 	local roster = load_roster(username, host);
   252 	local roster = load_roster(username, host);
   248 	local item = roster[jid];
   253 	local item = roster[jid];
   249 	return item and item.ask;
   254 	return item and item.ask;
   258 		item = {subscription = "none", groups = {}};
   263 		item = {subscription = "none", groups = {}};
   259 		roster[jid] = item;
   264 		roster[jid] = item;
   260 	end
   265 	end
   261 	item.ask = "subscribe";
   266 	item.ask = "subscribe";
   262 	log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid);
   267 	log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid);
   263 	return save_roster(username, host, roster);
   268 	return save_roster(username, host, roster, jid);
   264 end
   269 end
   265 local function unsubscribe(username, host, jid)
   270 local function unsubscribe(username, host, jid)
   266 	local roster = load_roster(username, host);
   271 	local roster = load_roster(username, host);
   267 	local item = roster[jid];
   272 	local item = roster[jid];
   268 	if not item then return false; end
   273 	if not item then return false; end
   273 	if item.subscription == "both" then
   278 	if item.subscription == "both" then
   274 		item.subscription = "from";
   279 		item.subscription = "from";
   275 	elseif item.subscription == "to" then
   280 	elseif item.subscription == "to" then
   276 		item.subscription = "none";
   281 		item.subscription = "none";
   277 	end
   282 	end
   278 	return save_roster(username, host, roster);
   283 	return save_roster(username, host, roster, jid);
   279 end
   284 end
   280 local function subscribed(username, host, jid)
   285 local function subscribed(username, host, jid)
   281 	if is_contact_pending_in(username, host, jid) then
   286 	if is_contact_pending_in(username, host, jid) then
   282 		local roster = load_roster(username, host);
   287 		local roster = load_roster(username, host);
   283 		local item = roster[jid];
   288 		local item = roster[jid];
   289 			item.subscription = "from";
   294 			item.subscription = "from";
   290 		else -- subscription == to
   295 		else -- subscription == to
   291 			item.subscription = "both";
   296 			item.subscription = "both";
   292 		end
   297 		end
   293 		roster[false].pending[jid] = nil;
   298 		roster[false].pending[jid] = nil;
   294 		return save_roster(username, host, roster);
   299 		return save_roster(username, host, roster, jid);
   295 	end -- TODO else implement optional feature pre-approval (ask = subscribed)
   300 	end -- TODO else implement optional feature pre-approval (ask = subscribed)
   296 end
   301 end
   297 local function unsubscribed(username, host, jid)
   302 local function unsubscribed(username, host, jid)
   298 	local roster = load_roster(username, host);
   303 	local roster = load_roster(username, host);
   299 	local item = roster[jid];
   304 	local item = roster[jid];
   309 		elseif item.subscription == "both" then
   314 		elseif item.subscription == "both" then
   310 			item.subscription = "to";
   315 			item.subscription = "to";
   311 			is_subscribed = true;
   316 			is_subscribed = true;
   312 		end
   317 		end
   313 	end
   318 	end
   314 	local success = (pending or is_subscribed) and save_roster(username, host, roster);
   319 	local success = (pending or is_subscribed) and save_roster(username, host, roster, jid);
   315 	return success, pending, subscribed;
   320 	return success, pending, subscribed;
   316 end
   321 end
   317 
   322 
   318 local function process_outbound_subscription_request(username, host, jid)
   323 local function process_outbound_subscription_request(username, host, jid)
   319 	local roster = load_roster(username, host);
   324 	local roster = load_roster(username, host);
   320 	local item = roster[jid];
   325 	local item = roster[jid];
   321 	if item and (item.subscription == "none" or item.subscription == "from") then
   326 	if item and (item.subscription == "none" or item.subscription == "from") then
   322 		item.ask = "subscribe";
   327 		item.ask = "subscribe";
   323 		return save_roster(username, host, roster);
   328 		return save_roster(username, host, roster, jid);
   324 	end
   329 	end
   325 end
   330 end
   326 
   331 
   327 --[[function process_outbound_subscription_approval(username, host, jid)
   332 --[[function process_outbound_subscription_approval(username, host, jid)
   328 	local roster = load_roster(username, host);
   333 	local roster = load_roster(username, host);