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 |