* 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>
* src/jlib.hrl: Added jaber:iq:auth:error namespace and

View File

@ -20,6 +20,7 @@
-define(NS_IQDATA, "jabber:iq:data").
-define(NS_DELAY, "jabber:x:delay").
-define(NS_EVENT, "jabber:x:event").
-define(NS_XCONFERENCE, "jabber:x:conference").
-define(NS_STATS, "http://jabber.org/protocol/stats").
-define(NS_MUC, "http://jabber.org/protocol/muc").
-define(NS_MUC_USER, "http://jabber.org/protocol/muc#user").

View File

@ -43,8 +43,8 @@
persistent = false,
moderated = false, % TODO
members_by_default = true,
members_only = false, % TODO
allow_user_invites = false, % TODO
members_only = false,
allow_user_invites = false,
password_protected = false, % TODO
anonymous = true,
logging = false % TODO
@ -76,6 +76,8 @@
?OLD_ERROR("409", "Nickname already in use.")).
-define(ERR_MUC_BANNED,
?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).
@ -188,6 +190,34 @@ normal_state({route, From, "",
end;
"error" ->
{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(
Packet, ?ERR_NOT_ALLOWED),
@ -311,7 +341,13 @@ normal_state({route, From, Nick,
case Role of
none ->
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(
{StateData#state.room,
StateData#state.host,
@ -544,15 +580,38 @@ get_affiliation(JID, StateData) ->
set_role(JID, Role, 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,
Users = case Role of
none ->
?DICT:erase(LJID,
StateData#state.users);
lists:foldl(fun(J, Us) ->
?DICT:erase(J,
Us)
end, StateData#state.users, LJIDs);
_ ->
{ok, User} = ?DICT:find(LJID, StateData#state.users),
?DICT:store(LJID,
User#user{role = Role},
StateData#state.users)
lists:foldl(fun(J, Us) ->
{ok, User} = ?DICT:find(J, Us),
?DICT:store(J,
User#user{role = Role},
Us)
end, StateData#state.users, LJIDs)
end,
StateData#state{users = Users}.
@ -572,11 +631,16 @@ get_default_role(Affiliation, StateData) ->
member -> participant;
outcast -> none;
none ->
case (StateData#state.config)#config.members_by_default of
case (StateData#state.config)#config.members_only of
true ->
participant;
none;
_ ->
visitor
case (StateData#state.config)#config.members_by_default of
true ->
participant;
_ ->
visitor
end
end
end.
@ -665,6 +729,30 @@ is_nick_change(JID, Nick, StateData) ->
Nick /= OldNick
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) ->
{ok, #user{jid = RealJID,
@ -1022,13 +1110,13 @@ process_admin_items_set(UJID, Items, StateData) ->
(A == admin) or (A == owner)->
SD1 = set_affiliation(JID, A, SD),
SD2 = set_role(JID, moderator, SD1),
catch send_new_presence(JID, SD2),
send_update_presence(JID, SD2),
SD2;
{JID, affiliation, member, Reason} ->
SD1 = set_affiliation(
JID, member, SD),
SD2 = set_role(JID, participant, SD1),
catch send_new_presence(JID, SD2),
send_update_presence(JID, SD2),
SD2;
{JID, role, R, Reason} ->
SD1 = set_role(JID, R, SD),
@ -1036,7 +1124,7 @@ process_admin_items_set(UJID, Items, StateData) ->
SD1;
{JID, affiliation, A, Reason} ->
SD1 = set_affiliation(JID, A, SD),
catch send_new_presence(JID, SD1),
send_update_presence(JID, SD1),
SD1
end
) of
@ -1119,7 +1207,7 @@ find_changed_items(UJID, UAffiliation, URole,
UJID,
UAffiliation, URole,
Items, StateData,
[{JID,
[{jlib:jid_remove_resource(JID),
affiliation,
SAffiliation,
xml:get_path_s(
@ -1274,7 +1362,32 @@ can_change_ra(FAffiliation, FRole,
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,
nick = Nick}} =
?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),
xml:get_tag_attr_s("type", XEl)} of
{?NS_XDATA, "cancel"} ->
%{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
{result, [], StateData};
{?NS_XDATA, "submit"} ->
set_config(XEl, StateData);
@ -1367,48 +1479,6 @@ process_iq_owner(From, get, SubEl, StateData) ->
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),
{xmlelement, "field", [{"type", Type},
@ -1677,3 +1747,73 @@ get_title(StateData) ->
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.