mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* src/mod_muc/mod_muc_room.erl: Support for members-only
conferences, invitations. Bugfix in affiliation change processing
* src/jlib.hrl: Added jabber❌conference namespace definition
SVN Revision: 98
This commit is contained in:
parent
71d4115a08
commit
ae6669c9af
@ -1,3 +1,10 @@
|
|||||||
|
2003-04-13 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_muc/mod_muc_room.erl: Support for members-only
|
||||||
|
conferences, invitations. Bugfix in affiliation change processing
|
||||||
|
|
||||||
|
* src/jlib.hrl: Added jabber:x:conference namespace definition
|
||||||
|
|
||||||
2003-04-07 Alexey Shchepin <alexey@sevcom.net>
|
2003-04-07 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/jlib.hrl: Added jaber:iq:auth:error namespace and
|
* src/jlib.hrl: Added jaber:iq:auth:error namespace and
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
-define(NS_IQDATA, "jabber:iq:data").
|
-define(NS_IQDATA, "jabber:iq:data").
|
||||||
-define(NS_DELAY, "jabber:x:delay").
|
-define(NS_DELAY, "jabber:x:delay").
|
||||||
-define(NS_EVENT, "jabber:x:event").
|
-define(NS_EVENT, "jabber:x:event").
|
||||||
|
-define(NS_XCONFERENCE, "jabber:x:conference").
|
||||||
-define(NS_STATS, "http://jabber.org/protocol/stats").
|
-define(NS_STATS, "http://jabber.org/protocol/stats").
|
||||||
-define(NS_MUC, "http://jabber.org/protocol/muc").
|
-define(NS_MUC, "http://jabber.org/protocol/muc").
|
||||||
-define(NS_MUC_USER, "http://jabber.org/protocol/muc#user").
|
-define(NS_MUC_USER, "http://jabber.org/protocol/muc#user").
|
||||||
|
@ -43,8 +43,8 @@
|
|||||||
persistent = false,
|
persistent = false,
|
||||||
moderated = false, % TODO
|
moderated = false, % TODO
|
||||||
members_by_default = true,
|
members_by_default = true,
|
||||||
members_only = false, % TODO
|
members_only = false,
|
||||||
allow_user_invites = false, % TODO
|
allow_user_invites = false,
|
||||||
password_protected = false, % TODO
|
password_protected = false, % TODO
|
||||||
anonymous = true,
|
anonymous = true,
|
||||||
logging = false % TODO
|
logging = false % TODO
|
||||||
@ -76,6 +76,8 @@
|
|||||||
?OLD_ERROR("409", "Nickname already in use.")).
|
?OLD_ERROR("409", "Nickname already in use.")).
|
||||||
-define(ERR_MUC_BANNED,
|
-define(ERR_MUC_BANNED,
|
||||||
?OLD_ERROR("403", "You have been banned from this room.")).
|
?OLD_ERROR("403", "You have been banned from this room.")).
|
||||||
|
-define(ERR_MUC_NOT_MEMBER,
|
||||||
|
?OLD_ERROR("407", "Membership required to enter this room.")).
|
||||||
|
|
||||||
|
|
||||||
-define(DBGFSM, true).
|
-define(DBGFSM, true).
|
||||||
@ -188,6 +190,34 @@ normal_state({route, From, "",
|
|||||||
end;
|
end;
|
||||||
"error" ->
|
"error" ->
|
||||||
{next_state, normal_state, StateData};
|
{next_state, normal_state, StateData};
|
||||||
|
Type when (Type == "") or (Type == "normal") ->
|
||||||
|
case check_invitation(From, Els, StateData) of
|
||||||
|
error ->
|
||||||
|
Err = jlib:make_error_reply(
|
||||||
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
|
ejabberd_router:route(
|
||||||
|
{StateData#state.room, StateData#state.host, ""},
|
||||||
|
From, Err),
|
||||||
|
{next_state, normal_state, StateData};
|
||||||
|
IJID ->
|
||||||
|
Config = StateData#state.config,
|
||||||
|
case Config#config.members_only of
|
||||||
|
true ->
|
||||||
|
case get_affiliation(IJID, StateData) of
|
||||||
|
none ->
|
||||||
|
NSD = set_affiliation(
|
||||||
|
IJID,
|
||||||
|
member,
|
||||||
|
StateData),
|
||||||
|
{next_state, normal_state, NSD};
|
||||||
|
_ ->
|
||||||
|
{next_state, normal_state,
|
||||||
|
StateData}
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
{next_state, normal_state, StateData}
|
||||||
|
end
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_NOT_ALLOWED),
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
@ -311,7 +341,13 @@ normal_state({route, From, Nick,
|
|||||||
case Role of
|
case Role of
|
||||||
none ->
|
none ->
|
||||||
Err = jlib:make_error_reply(
|
Err = jlib:make_error_reply(
|
||||||
Packet, ?ERR_MUC_BANNED),
|
Packet,
|
||||||
|
case Affiliation of
|
||||||
|
outcast ->
|
||||||
|
?ERR_MUC_BANNED;
|
||||||
|
_ ->
|
||||||
|
?ERR_MUC_NOT_MEMBER
|
||||||
|
end),
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
{StateData#state.room,
|
{StateData#state.room,
|
||||||
StateData#state.host,
|
StateData#state.host,
|
||||||
@ -544,15 +580,38 @@ get_affiliation(JID, StateData) ->
|
|||||||
|
|
||||||
set_role(JID, Role, StateData) ->
|
set_role(JID, Role, StateData) ->
|
||||||
LJID = jlib:jid_tolower(JID),
|
LJID = jlib:jid_tolower(JID),
|
||||||
|
LJIDs = case LJID of
|
||||||
|
{U, S, ""} ->
|
||||||
|
?DICT:fold(
|
||||||
|
fun(J, _, Js) ->
|
||||||
|
case J of
|
||||||
|
{U, S, _} ->
|
||||||
|
[J | Js];
|
||||||
|
_ ->
|
||||||
|
Js
|
||||||
|
end
|
||||||
|
end, [], StateData#state.users);
|
||||||
|
_ ->
|
||||||
|
case ?DICT:is_key(LJID, StateData#state.users) of
|
||||||
|
true ->
|
||||||
|
[LJID];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end,
|
||||||
Users = case Role of
|
Users = case Role of
|
||||||
none ->
|
none ->
|
||||||
?DICT:erase(LJID,
|
lists:foldl(fun(J, Us) ->
|
||||||
StateData#state.users);
|
?DICT:erase(J,
|
||||||
|
Us)
|
||||||
|
end, StateData#state.users, LJIDs);
|
||||||
_ ->
|
_ ->
|
||||||
{ok, User} = ?DICT:find(LJID, StateData#state.users),
|
lists:foldl(fun(J, Us) ->
|
||||||
?DICT:store(LJID,
|
{ok, User} = ?DICT:find(J, Us),
|
||||||
|
?DICT:store(J,
|
||||||
User#user{role = Role},
|
User#user{role = Role},
|
||||||
StateData#state.users)
|
Us)
|
||||||
|
end, StateData#state.users, LJIDs)
|
||||||
end,
|
end,
|
||||||
StateData#state{users = Users}.
|
StateData#state{users = Users}.
|
||||||
|
|
||||||
@ -572,12 +631,17 @@ get_default_role(Affiliation, StateData) ->
|
|||||||
member -> participant;
|
member -> participant;
|
||||||
outcast -> none;
|
outcast -> none;
|
||||||
none ->
|
none ->
|
||||||
|
case (StateData#state.config)#config.members_only of
|
||||||
|
true ->
|
||||||
|
none;
|
||||||
|
_ ->
|
||||||
case (StateData#state.config)#config.members_by_default of
|
case (StateData#state.config)#config.members_by_default of
|
||||||
true ->
|
true ->
|
||||||
participant;
|
participant;
|
||||||
_ ->
|
_ ->
|
||||||
visitor
|
visitor
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -665,6 +729,30 @@ is_nick_change(JID, Nick, StateData) ->
|
|||||||
Nick /= OldNick
|
Nick /= OldNick
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
send_update_presence(JID, StateData) ->
|
||||||
|
LJID = jlib:jid_tolower(JID),
|
||||||
|
LJIDs = case LJID of
|
||||||
|
{U, S, ""} ->
|
||||||
|
?DICT:fold(
|
||||||
|
fun(J, _, Js) ->
|
||||||
|
case J of
|
||||||
|
{U, S, _} ->
|
||||||
|
[J | Js];
|
||||||
|
_ ->
|
||||||
|
Js
|
||||||
|
end
|
||||||
|
end, [], StateData#state.users);
|
||||||
|
_ ->
|
||||||
|
case ?DICT:is_key(LJID, StateData#state.users) of
|
||||||
|
true ->
|
||||||
|
[LJID];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
lists:foreach(fun(J) ->
|
||||||
|
send_new_presence(J, StateData)
|
||||||
|
end, LJIDs).
|
||||||
|
|
||||||
send_new_presence(NJID, StateData) ->
|
send_new_presence(NJID, StateData) ->
|
||||||
{ok, #user{jid = RealJID,
|
{ok, #user{jid = RealJID,
|
||||||
@ -1022,13 +1110,13 @@ process_admin_items_set(UJID, Items, StateData) ->
|
|||||||
(A == admin) or (A == owner)->
|
(A == admin) or (A == owner)->
|
||||||
SD1 = set_affiliation(JID, A, SD),
|
SD1 = set_affiliation(JID, A, SD),
|
||||||
SD2 = set_role(JID, moderator, SD1),
|
SD2 = set_role(JID, moderator, SD1),
|
||||||
catch send_new_presence(JID, SD2),
|
send_update_presence(JID, SD2),
|
||||||
SD2;
|
SD2;
|
||||||
{JID, affiliation, member, Reason} ->
|
{JID, affiliation, member, Reason} ->
|
||||||
SD1 = set_affiliation(
|
SD1 = set_affiliation(
|
||||||
JID, member, SD),
|
JID, member, SD),
|
||||||
SD2 = set_role(JID, participant, SD1),
|
SD2 = set_role(JID, participant, SD1),
|
||||||
catch send_new_presence(JID, SD2),
|
send_update_presence(JID, SD2),
|
||||||
SD2;
|
SD2;
|
||||||
{JID, role, R, Reason} ->
|
{JID, role, R, Reason} ->
|
||||||
SD1 = set_role(JID, R, SD),
|
SD1 = set_role(JID, R, SD),
|
||||||
@ -1036,7 +1124,7 @@ process_admin_items_set(UJID, Items, StateData) ->
|
|||||||
SD1;
|
SD1;
|
||||||
{JID, affiliation, A, Reason} ->
|
{JID, affiliation, A, Reason} ->
|
||||||
SD1 = set_affiliation(JID, A, SD),
|
SD1 = set_affiliation(JID, A, SD),
|
||||||
catch send_new_presence(JID, SD1),
|
send_update_presence(JID, SD1),
|
||||||
SD1
|
SD1
|
||||||
end
|
end
|
||||||
) of
|
) of
|
||||||
@ -1119,7 +1207,7 @@ find_changed_items(UJID, UAffiliation, URole,
|
|||||||
UJID,
|
UJID,
|
||||||
UAffiliation, URole,
|
UAffiliation, URole,
|
||||||
Items, StateData,
|
Items, StateData,
|
||||||
[{JID,
|
[{jlib:jid_remove_resource(JID),
|
||||||
affiliation,
|
affiliation,
|
||||||
SAffiliation,
|
SAffiliation,
|
||||||
xml:get_path_s(
|
xml:get_path_s(
|
||||||
@ -1274,7 +1362,32 @@ can_change_ra(FAffiliation, FRole,
|
|||||||
false.
|
false.
|
||||||
|
|
||||||
|
|
||||||
send_kickban_presence(UJID, Reason, Code, StateData) ->
|
send_kickban_presence(JID, Reason, Code, StateData) ->
|
||||||
|
LJID = jlib:jid_tolower(JID),
|
||||||
|
LJIDs = case LJID of
|
||||||
|
{U, S, ""} ->
|
||||||
|
?DICT:fold(
|
||||||
|
fun(J, _, Js) ->
|
||||||
|
case J of
|
||||||
|
{U, S, _} ->
|
||||||
|
[J | Js];
|
||||||
|
_ ->
|
||||||
|
Js
|
||||||
|
end
|
||||||
|
end, [], StateData#state.users);
|
||||||
|
_ ->
|
||||||
|
case ?DICT:is_key(LJID, StateData#state.users) of
|
||||||
|
true ->
|
||||||
|
[LJID];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
lists:foreach(fun(J) ->
|
||||||
|
send_kickban_presence1(J, Reason, Code, StateData)
|
||||||
|
end, LJIDs).
|
||||||
|
|
||||||
|
send_kickban_presence1(UJID, Reason, Code, StateData) ->
|
||||||
{ok, #user{jid = RealJID,
|
{ok, #user{jid = RealJID,
|
||||||
nick = Nick}} =
|
nick = Nick}} =
|
||||||
?DICT:find(jlib:jid_tolower(UJID), StateData#state.users),
|
?DICT:find(jlib:jid_tolower(UJID), StateData#state.users),
|
||||||
@ -1317,7 +1430,6 @@ process_iq_owner(From, set, SubEl, StateData) ->
|
|||||||
case {xml:get_tag_attr_s("xmlns", XEl),
|
case {xml:get_tag_attr_s("xmlns", XEl),
|
||||||
xml:get_tag_attr_s("type", XEl)} of
|
xml:get_tag_attr_s("type", XEl)} of
|
||||||
{?NS_XDATA, "cancel"} ->
|
{?NS_XDATA, "cancel"} ->
|
||||||
%{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
|
|
||||||
{result, [], StateData};
|
{result, [], StateData};
|
||||||
{?NS_XDATA, "submit"} ->
|
{?NS_XDATA, "submit"} ->
|
||||||
set_config(XEl, StateData);
|
set_config(XEl, StateData);
|
||||||
@ -1367,48 +1479,6 @@ process_iq_owner(From, get, SubEl, StateData) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
% case xml:get_subtag(SubEl, "item") of
|
|
||||||
% false ->
|
|
||||||
% {error, ?ERR_BAD_REQUEST};
|
|
||||||
% Item ->
|
|
||||||
% FAffiliation = get_affiliation(From, StateData),
|
|
||||||
% FRole = get_role(From, StateData),
|
|
||||||
% case xml:get_tag_attr("role", Item) of
|
|
||||||
% false ->
|
|
||||||
% case xml:get_tag_attr("affiliation", Item) of
|
|
||||||
% false ->
|
|
||||||
% {error, ?ERR_BAD_REQUEST};
|
|
||||||
% {value, StrAffiliation} ->
|
|
||||||
% case catch list_to_affiliation(StrAffiliation) of
|
|
||||||
% {'EXIT', _} ->
|
|
||||||
% {error, ?ERR_BAD_REQUEST};
|
|
||||||
% SAffiliation ->
|
|
||||||
% if
|
|
||||||
% FAffiliation == owner ->
|
|
||||||
% Items = items_with_affiliation(
|
|
||||||
% SAffiliation, StateData),
|
|
||||||
% {result, Items, StateData};
|
|
||||||
% true ->
|
|
||||||
% {error, ?ERR_NOT_ALLOWED}
|
|
||||||
% end
|
|
||||||
% end
|
|
||||||
% end;
|
|
||||||
% {value, StrRole} ->
|
|
||||||
% case catch list_to_role(StrRole) of
|
|
||||||
% {'EXIT', _} ->
|
|
||||||
% {error, ?ERR_BAD_REQUEST};
|
|
||||||
% SRole ->
|
|
||||||
% if
|
|
||||||
% FAffiliation == owner ->
|
|
||||||
% Items = items_with_role(SRole, StateData),
|
|
||||||
% {result, Items, StateData};
|
|
||||||
% true ->
|
|
||||||
% {error, ?ERR_NOT_ALLOWED}
|
|
||||||
% end
|
|
||||||
% end
|
|
||||||
% end
|
|
||||||
% end.
|
|
||||||
|
|
||||||
|
|
||||||
-define(XFIELD(Type, Label, Var, Val),
|
-define(XFIELD(Type, Label, Var, Val),
|
||||||
{xmlelement, "field", [{"type", Type},
|
{xmlelement, "field", [{"type", Type},
|
||||||
@ -1677,3 +1747,73 @@ get_title(StateData) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% Invitation support
|
||||||
|
|
||||||
|
check_invitation(From, Els, StateData) ->
|
||||||
|
FAffiliation = get_affiliation(From, StateData),
|
||||||
|
CanInvite = (StateData#state.config)#config.allow_user_invites
|
||||||
|
orelse (FAffiliation == admin) orelse (FAffiliation == owner),
|
||||||
|
case xml:remove_cdata(Els) of
|
||||||
|
[{xmlelement, "x", Attrs1, Els1} = XEl] ->
|
||||||
|
case xml:get_tag_attr_s("xmlns", XEl) of
|
||||||
|
?NS_MUC_USER ->
|
||||||
|
case xml:remove_cdata(Els1) of
|
||||||
|
[{xmlelement, "invite", Attrs2, Els2} = InviteEl] ->
|
||||||
|
case jlib:string_to_jid(
|
||||||
|
xml:get_attr_s("to", Attrs2)) of
|
||||||
|
error ->
|
||||||
|
error;
|
||||||
|
JID ->
|
||||||
|
case CanInvite of
|
||||||
|
true ->
|
||||||
|
Reason =
|
||||||
|
xml:get_path_s(
|
||||||
|
InviteEl,
|
||||||
|
[{elem, "reason"}, cdata]),
|
||||||
|
IEl =
|
||||||
|
[{xmlelement, "invite",
|
||||||
|
[{"from",
|
||||||
|
jlib:jid_to_string(From)}],
|
||||||
|
[{xmlelement, "reason", [],
|
||||||
|
[{xmlcdata, Reason}]}]}],
|
||||||
|
PasswdEl = [],
|
||||||
|
Msg =
|
||||||
|
{xmlelement, "message",
|
||||||
|
[{"type", "normal"}],
|
||||||
|
[{xmlelement, "x",
|
||||||
|
[{"xmlns", ?NS_MUC_USER}],
|
||||||
|
IEl ++ PasswdEl},
|
||||||
|
{xmlelement, "x",
|
||||||
|
[{"xmlns",
|
||||||
|
?NS_XCONFERENCE},
|
||||||
|
{"jid",
|
||||||
|
jlib:jid_to_string(
|
||||||
|
{StateData#state.room,
|
||||||
|
StateData#state.host,
|
||||||
|
""})}],
|
||||||
|
[{xmlcdata, Reason}]}]},
|
||||||
|
ejabberd_router:route(
|
||||||
|
{StateData#state.room,
|
||||||
|
StateData#state.host,
|
||||||
|
""},
|
||||||
|
JID,
|
||||||
|
Msg),
|
||||||
|
JID;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user