24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-14 22:00:16 +02:00

* src/mod_muc/mod_muc_room.erl: Support for members-only

conferences, invitations.  Bugfix in affiliation change processing

* src/jlib.hrl: Added jabberconference namespace definition

SVN Revision: 98
This commit is contained in:
Alexey Shchepin 2003-04-13 19:22:46 +00:00
parent 71d4115a08
commit ae6669c9af
3 changed files with 208 additions and 60 deletions

View File

@ -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

View File

@ -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").

View File

@ -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.