plugins/muc/muc.lib.lua
changeset 6135 6b061f8c6e11
parent 6134 48b6ef993888
child 6136 2068242028ff
equal deleted inserted replaced
6134:48b6ef993888 6135:6b061f8c6e11
   467 		self:broadcast_presence(pr, from);
   467 		self:broadcast_presence(pr, from);
   468 		return true;
   468 		return true;
   469 	end
   469 	end
   470 end
   470 end
   471 
   471 
   472 function room_mt:handle_join(origin, stanza)
   472 module:hook("muc-occupant-pre-join", function(event)
       
   473 	return module:fire_event("muc-occupant-pre-join/affiliation", event)
       
   474 		or module:fire_event("muc-occupant-pre-join/password", event)
       
   475 		or module:fire_event("muc-occupant-pre-join/locked", event)
       
   476 		or module:fire_event("muc-occupant-pre-join/nick-conflict", event)
       
   477 end, -1)
       
   478 
       
   479 module:hook("muc-occupant-pre-join/password", function(event)
       
   480 	local room, stanza = event.room, event.stanza;
   473 	local from, to = stanza.attr.from, stanza.attr.to;
   481 	local from, to = stanza.attr.from, stanza.attr.to;
   474 	log("debug", "%s joining as %s", from, to);
       
   475 	local password = stanza:get_child("x", "http://jabber.org/protocol/muc");
   482 	local password = stanza:get_child("x", "http://jabber.org/protocol/muc");
   476 	password = password and password:get_child("password", "http://jabber.org/protocol/muc");
   483 	password = password and password:get_child("password", "http://jabber.org/protocol/muc");
   477 	password = password and password[1] ~= "" and password[1];
   484 	password = password and password[1] ~= "" and password[1];
   478 	if self:get_password() and self:get_password() ~= password then
   485 	if room:get_password() and room:get_password() ~= password then
       
   486 		local from, to = stanza.attr.from, stanza.attr.to;
   479 		log("debug", "%s couldn't join due to invalid password: %s", from, to);
   487 		log("debug", "%s couldn't join due to invalid password: %s", from, to);
   480 		local reply = st.error_reply(stanza, "auth", "not-authorized"):up();
   488 		local reply = st.error_reply(stanza, "auth", "not-authorized"):up();
   481 		reply.tags[1].attr.code = "401";
   489 		reply.tags[1].attr.code = "401";
   482 		origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   490 		event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   483 		return true;
   491 		return true;
   484 	elseif self._occupants[to] -- occupant already exists
   492 	end
   485 		and jid_bare(from) ~= jid_bare(self._occupants[to].jid) then -- and has different bare real jid
   493 end, -1)
       
   494 
       
   495 module:hook("muc-occupant-pre-join/nick-conflict", function(event)
       
   496 	local room, stanza = event.room, event.stanza;
       
   497 	local from, to = stanza.attr.from, stanza.attr.to;
       
   498 	local occupant = room._occupants[to]
       
   499 	if occupant -- occupant already exists
       
   500 		and jid_bare(from) ~= jid_bare(occupant.jid) then -- and has different bare real jid
   486 		log("debug", "%s couldn't join due to nick conflict: %s", from, to);
   501 		log("debug", "%s couldn't join due to nick conflict: %s", from, to);
   487 		local reply = st.error_reply(stanza, "cancel", "conflict"):up();
   502 		local reply = st.error_reply(stanza, "cancel", "conflict"):up();
   488 		reply.tags[1].attr.code = "409";
   503 		reply.tags[1].attr.code = "409";
   489 		origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   504 		event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   490 		return true;
   505 		return true;
   491 	end
   506 	end
   492 	if not next(self._affiliations) then -- new room, no owners
   507 end, -1)
   493 		self._affiliations[jid_bare(from)] = "owner";
   508 
       
   509 module:hook("muc-occupant-pre-join/locked", function(event)
       
   510 	if event.room:is_locked() then -- Deny entry
       
   511 		event.origin.send(st.error_reply(event.stanza, "cancel", "item-not-found"));
       
   512 		return true;
       
   513 	end
       
   514 end, -1)
       
   515 
       
   516 function room_mt:handle_join(origin, stanza)
       
   517 	local from, to = stanza.attr.from, stanza.attr.to;
       
   518 	local affiliation = self:get_affiliation(from);
       
   519 	if affiliation == nil and next(self._affiliations) == nil then -- new room, no owners
       
   520 		affiliation = "owner";
       
   521 		self._affiliations[jid_bare(from)] = affiliation;
   494 		if self:is_locked() and not stanza:get_child("x", "http://jabber.org/protocol/muc") then
   522 		if self:is_locked() and not stanza:get_child("x", "http://jabber.org/protocol/muc") then
   495 			self:unlock(); -- Older groupchat protocol doesn't lock
   523 			self:unlock(); -- Older groupchat protocol doesn't lock
   496 		end
   524 		end
   497 	elseif self:is_locked() then -- Deny entry
   525 	end
   498 		origin.send(st.error_reply(stanza, "cancel", "item-not-found"));
   526 	if module:fire_event("muc-occupant-pre-join", {
   499 		return true;
   527 		room = self;
   500 	end
   528 		origin = origin;
   501 	local affiliation = self:get_affiliation(from);
   529 		stanza = stanza;
       
   530 		affiliation = affiliation;
       
   531 	}) then return true; end
       
   532 	log("debug", "%s joining as %s", from, to);
       
   533 
   502 	local role = self:get_default_role(affiliation)
   534 	local role = self:get_default_role(affiliation)
   503 	if role then -- new occupant
   535 	if role then -- new occupant
   504 		local is_merge = not not self._occupants[to]
   536 		local is_merge = not not self._occupants[to]
   505 		if not is_merge then
   537 		if not is_merge then
   506 			self._occupants[to] = {affiliation=affiliation, role=role, jid=from, sessions={[from]=get_filtered_presence(stanza)}};
   538 			self._occupants[to] = {affiliation=affiliation, role=role, jid=from, sessions={[from]=get_filtered_presence(stanza)}};
   526 		pr.attr.to = from;
   558 		pr.attr.to = from;
   527 		self:_route_stanza(pr);
   559 		self:_route_stanza(pr);
   528 		self:send_history(from, stanza);
   560 		self:send_history(from, stanza);
   529 		self:send_subject(from);
   561 		self:send_subject(from);
   530 		return true;
   562 		return true;
   531 	elseif not affiliation then -- registration required for entering members-only room
   563 	end
   532 		local reply = st.error_reply(stanza, "auth", "registration-required"):up();
   564 end
       
   565 
       
   566 -- registration required for entering members-only room
       
   567 module:hook("muc-occupant-pre-join/affiliation", function(event)
       
   568 	if event.affiliation == nil and event.room:get_members_only() then
       
   569 		local reply = st.error_reply(event.stanza, "auth", "registration-required"):up();
   533 		reply.tags[1].attr.code = "407";
   570 		reply.tags[1].attr.code = "407";
   534 		origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   571 		event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   535 		return true;
   572 		return true;
   536 	else -- banned
   573 	end
   537 		local reply = st.error_reply(stanza, "auth", "forbidden"):up();
   574 end, -1)
       
   575 
       
   576 -- banned
       
   577 module:hook("muc-occupant-pre-join/affiliation", function(event)
       
   578 	if event.affiliation == "outcast" then
       
   579 		local reply = st.error_reply(event.stanza, "auth", "forbidden"):up();
   538 		reply.tags[1].attr.code = "403";
   580 		reply.tags[1].attr.code = "403";
   539 		origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   581 		event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
   540 		return true;
   582 		return true;
   541 	end
   583 	end
   542 end
   584 end, -1)
   543 
   585 
   544 function room_mt:handle_available_to_occupant(origin, stanza)
   586 function room_mt:handle_available_to_occupant(origin, stanza)
   545 	local from, to = stanza.attr.from, stanza.attr.to;
   587 	local from, to = stanza.attr.from, stanza.attr.to;
   546 	local current_nick = self:get_occupant_jid(from);
   588 	local current_nick = self:get_occupant_jid(from);
   547 	if current_nick then
   589 	if current_nick then