mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Improve MUC test cases
This commit is contained in:
parent
1f4e0c8aea
commit
744018425b
@ -177,7 +177,6 @@ db_tests() ->
|
||||
privacy,
|
||||
blocking,
|
||||
vcard,
|
||||
muc_single,
|
||||
pubsub,
|
||||
test_unregister]},
|
||||
{test_roster_subscribe, [parallel],
|
||||
@ -185,6 +184,8 @@ db_tests() ->
|
||||
roster_subscribe_slave]},
|
||||
{test_offline, [sequence],
|
||||
[offline_master, offline_slave]},
|
||||
{test_muc, [parallel],
|
||||
[muc_master, muc_slave]},
|
||||
{test_roster_remove, [parallel],
|
||||
[roster_remove_master,
|
||||
roster_remove_slave]}].
|
||||
@ -202,13 +203,14 @@ db_tests(riak) ->
|
||||
privacy,
|
||||
blocking,
|
||||
vcard,
|
||||
muc_single,
|
||||
test_unregister]},
|
||||
{test_roster_subscribe, [parallel],
|
||||
[roster_subscribe_master,
|
||||
roster_subscribe_slave]},
|
||||
{test_offline, [sequence],
|
||||
[offline_master, offline_slave]},
|
||||
{test_muc, [parallel],
|
||||
[muc_master, muc_slave]},
|
||||
{test_roster_remove, [parallel],
|
||||
[roster_remove_master,
|
||||
roster_remove_slave]}];
|
||||
@ -225,7 +227,6 @@ db_tests(_) ->
|
||||
privacy,
|
||||
blocking,
|
||||
vcard,
|
||||
muc_single,
|
||||
pubsub,
|
||||
test_unregister]},
|
||||
{test_roster_subscribe, [parallel],
|
||||
@ -233,6 +234,8 @@ db_tests(_) ->
|
||||
roster_subscribe_slave]},
|
||||
{test_offline, [sequence],
|
||||
[offline_master, offline_slave]},
|
||||
{test_muc, [parallel],
|
||||
[muc_master, muc_slave]},
|
||||
{test_roster_remove, [parallel],
|
||||
[roster_remove_master,
|
||||
roster_remove_slave]}].
|
||||
@ -916,15 +919,22 @@ proxy65_slave(Config) ->
|
||||
socks5_recv(Socks5, Data),
|
||||
disconnect(Config).
|
||||
|
||||
muc_single(Config) ->
|
||||
muc_master(Config) ->
|
||||
MyJID = my_jid(Config),
|
||||
PeerJID = ?config(slave, Config),
|
||||
PeerBareJID = jlib:jid_remove_resource(PeerJID),
|
||||
PeerJIDStr = jlib:jid_to_string(PeerJID),
|
||||
MUC = muc_jid(Config),
|
||||
Room = muc_room_jid(Config),
|
||||
Nick = ?config(user, Config),
|
||||
NickJID = jlib:jid_replace_resource(Room, Nick),
|
||||
MyNick = ?config(master_nick, Config),
|
||||
MyNickJID = jlib:jid_replace_resource(Room, MyNick),
|
||||
PeerNick = ?config(slave_nick, Config),
|
||||
PeerNickJID = jlib:jid_replace_resource(Room, PeerNick),
|
||||
Subject = ?config(room_subject, Config),
|
||||
Localhost = jlib:make_jid(<<"">>, <<"localhost">>, <<"">>),
|
||||
true = is_feature_advertised(Config, ?NS_MUC, MUC),
|
||||
%% Joining
|
||||
send(Config, #presence{to = NickJID, sub_els = [#muc{}]}),
|
||||
send(Config, #presence{to = MyNickJID, sub_els = [#muc{}]}),
|
||||
%% As per XEP-0045 we MUST receive stanzas in the following order:
|
||||
%% 1. In-room presence from other occupants
|
||||
%% 2. In-room presence from the joining entity itself (so-called "self-presence")
|
||||
@ -933,7 +943,7 @@ muc_single(Config) ->
|
||||
%% 5. Live messages, presence updates, new user joins, etc.
|
||||
%% As this is the newly created room, we receive only the 2nd stanza.
|
||||
#presence{
|
||||
from = NickJID,
|
||||
from = MyNickJID,
|
||||
sub_els = [#muc_user{
|
||||
status_codes = Codes,
|
||||
items = [#muc_item{role = moderator,
|
||||
@ -941,8 +951,7 @@ muc_single(Config) ->
|
||||
affiliation = owner}]}]} = recv(),
|
||||
%% 110 -> Inform user that presence refers to itself
|
||||
%% 201 -> Inform user that a new room has been created
|
||||
true = lists:member(110, Codes),
|
||||
true = lists:member(201, Codes),
|
||||
[110, 201] = lists:sort(Codes),
|
||||
%% Request the configuration
|
||||
#iq{type = result, sub_els = [#muc_owner{config = #xdata{} = RoomCfg}]} =
|
||||
send_recv(Config, #iq{type = get, sub_els = [#muc_owner{}],
|
||||
@ -959,9 +968,13 @@ muc_single(Config) ->
|
||||
[<<"Trying to break the server">>];
|
||||
<<"muc#roomconfig_persistentroom">> ->
|
||||
[<<"1">>];
|
||||
<<"muc#roomconfig_changesubject">> ->
|
||||
<<"members_by_default">> ->
|
||||
[<<"0">>];
|
||||
<<"muc#roomconfig_allowinvites">> ->
|
||||
<<"muc#roomconfig_allowvoicerequests">> ->
|
||||
[<<"1">>];
|
||||
<<"public_list">> ->
|
||||
[<<"1">>];
|
||||
<<"muc#roomconfig_publicroom">> ->
|
||||
[<<"1">>];
|
||||
_ ->
|
||||
[]
|
||||
@ -974,20 +987,230 @@ muc_single(Config) ->
|
||||
end, RoomCfg#xdata.fields),
|
||||
NewRoomCfg = #xdata{type = submit, fields = NewFields},
|
||||
%% BUG: We should not receive any sub_els!
|
||||
%% TODO: fix this crap in ejabberd.
|
||||
#iq{type = result, sub_els = [_|_]} =
|
||||
send_recv(Config, #iq{type = set, to = Room,
|
||||
sub_els = [#muc_owner{config = NewRoomCfg}]}),
|
||||
%% Set subject
|
||||
send(Config, #message{to = Room, type = groupchat,
|
||||
body = [#text{data = <<"Subject">>}]}),
|
||||
#message{from = NickJID, type = groupchat,
|
||||
body = [#text{data = <<"Subject">>}]} = recv(),
|
||||
%% Leaving
|
||||
send(Config, #presence{type = unavailable, to = NickJID}),
|
||||
#presence{from = NickJID, type = unavailable,
|
||||
sub_els = [#muc_user{status_codes = NewCodes}]} = recv(),
|
||||
true = lists:member(110, NewCodes),
|
||||
body = [#text{data = Subject}]}),
|
||||
#message{from = MyNickJID, type = groupchat,
|
||||
body = [#text{data = Subject}]} = recv(),
|
||||
%% Sending messages (and thus, populating history for our peer)
|
||||
lists:foreach(
|
||||
fun(N) ->
|
||||
Text = #text{data = jlib:integer_to_binary(N)},
|
||||
I = send(Config, #message{to = Room, body = [Text],
|
||||
type = groupchat}),
|
||||
#message{from = MyNickJID, id = I,
|
||||
type = groupchat,
|
||||
body = [Text]} = recv()
|
||||
end, lists:seq(1, 5)),
|
||||
%% Inviting the peer
|
||||
send(Config, #message{to = Room, type = normal,
|
||||
sub_els =
|
||||
[#muc_user{
|
||||
invites =
|
||||
[#muc_invite{to = PeerJID}]}]}),
|
||||
%% Peer is joining
|
||||
#presence{from = PeerNickJID,
|
||||
sub_els = [#muc_user{
|
||||
items = [#muc_item{role = visitor,
|
||||
jid = PeerJID,
|
||||
affiliation = none}]}]} = recv(),
|
||||
%% Receiving a voice request
|
||||
#message{from = Room,
|
||||
sub_els = [#xdata{type = form,
|
||||
instructions = [_],
|
||||
fields = VoiceReqFs}]} = recv(),
|
||||
%% Approving the voice request
|
||||
ReplyVoiceReqFs =
|
||||
lists:map(
|
||||
fun(#xdata_field{var = Var, values = OrigVals}) ->
|
||||
Vals = case {Var, OrigVals} of
|
||||
{<<"FORM_TYPE">>,
|
||||
[<<"http://jabber.org/protocol/muc#request">>]} ->
|
||||
OrigVals;
|
||||
{<<"muc#role">>, [<<"participant">>]} ->
|
||||
[<<"participant">>];
|
||||
{<<"muc#jid">>, [PeerJIDStr]} ->
|
||||
[PeerJIDStr];
|
||||
{<<"muc#roomnick">>, [PeerNick]} ->
|
||||
[PeerNick];
|
||||
{<<"muc#request_allow">>, [<<"0">>]} ->
|
||||
[<<"1">>]
|
||||
end,
|
||||
#xdata_field{values = Vals, var = Var}
|
||||
end, VoiceReqFs),
|
||||
send(Config, #message{to = Room,
|
||||
sub_els = [#xdata{type = submit,
|
||||
fields = ReplyVoiceReqFs}]}),
|
||||
%% Peer is becoming a participant
|
||||
#presence{from = PeerNickJID,
|
||||
sub_els = [#muc_user{
|
||||
items = [#muc_item{role = participant,
|
||||
jid = PeerJID,
|
||||
affiliation = none}]}]} = recv(),
|
||||
%% Receive private message from the peer
|
||||
#message{from = PeerNickJID, body = [#text{data = Subject}]} = recv(),
|
||||
%% Granting membership to the peer and localhost server
|
||||
I1 = send(Config,
|
||||
#iq{type = set, to = Room,
|
||||
sub_els =
|
||||
[#muc_admin{
|
||||
items = [#muc_item{jid = Localhost,
|
||||
affiliation = member},
|
||||
#muc_item{nick = PeerNick,
|
||||
jid = PeerBareJID,
|
||||
affiliation = member}]}]}),
|
||||
%% Peer became a member
|
||||
#presence{from = PeerNickJID,
|
||||
sub_els = [#muc_user{
|
||||
items = [#muc_item{affiliation = member,
|
||||
jid = PeerJID,
|
||||
role = participant}]}]} = recv(),
|
||||
%% BUG: We should not receive any sub_els!
|
||||
#iq{type = result, id = I1, sub_els = [_|_]} = recv(),
|
||||
%% Receive groupchat message from the peer
|
||||
#message{type = groupchat, from = PeerNickJID,
|
||||
body = [#text{data = Subject}]} = recv(),
|
||||
%% Kick the peer
|
||||
I2 = send(Config,
|
||||
#iq{type = set, to = Room,
|
||||
sub_els = [#muc_admin{
|
||||
items = [#muc_item{nick = PeerNick,
|
||||
role = none}]}]}),
|
||||
%% Got notification the peer is kicked
|
||||
%% 307 -> Inform user that he or she has been kicked from the room
|
||||
#presence{from = PeerNickJID,
|
||||
sub_els = [#muc_user{
|
||||
status_codes = [307],
|
||||
items = [#muc_item{affiliation = member,
|
||||
jid = PeerJID,
|
||||
role = none}]}]} = recv(),
|
||||
%% BUG: We should not receive any sub_els!
|
||||
#iq{type = result, id = I2, sub_els = [_|_]} = recv(),
|
||||
%% Destroying the room
|
||||
I3 = send(Config,
|
||||
#iq{type = set, to = Room,
|
||||
sub_els = [#muc_owner{
|
||||
destroy = #muc_owner_destroy{
|
||||
reason = Subject}}]}),
|
||||
%% Kicked off
|
||||
#presence{from = MyNickJID, type = unavailable,
|
||||
sub_els = [#muc_user{items = [#muc_item{role = none,
|
||||
affiliation = none}],
|
||||
destroy = #muc_user_destroy{
|
||||
reason = Subject}}]} = recv(),
|
||||
%% BUG: We should not receive any sub_els!
|
||||
#iq{type = result, id = I3, sub_els = [_|_]} = recv(),
|
||||
disconnect(Config).
|
||||
|
||||
muc_slave(Config) ->
|
||||
MyJID = my_jid(Config),
|
||||
MyBareJID = jlib:jid_remove_resource(MyJID),
|
||||
PeerJID = ?config(master, Config),
|
||||
MUC = muc_jid(Config),
|
||||
Room = muc_room_jid(Config),
|
||||
MyNick = ?config(slave_nick, Config),
|
||||
MyNickJID = jlib:jid_replace_resource(Room, MyNick),
|
||||
PeerNick = ?config(master_nick, Config),
|
||||
PeerNickJID = jlib:jid_replace_resource(Room, PeerNick),
|
||||
Subject = ?config(room_subject, Config),
|
||||
Localhost = jlib:make_jid(<<"">>, <<"localhost">>, <<"">>),
|
||||
%% Receive an invite from the peer
|
||||
#message{from = Room, type = normal,
|
||||
sub_els =
|
||||
[#muc_user{invites =
|
||||
[#muc_invite{from = PeerJID}]}]} = recv(),
|
||||
%% But before joining we discover the MUC service first
|
||||
%% to check if the room is in the disco list
|
||||
#iq{type = result,
|
||||
sub_els = [#disco_items{items = [#disco_item{jid = Room}]}]} =
|
||||
send_recv(Config, #iq{type = get, to = MUC,
|
||||
sub_els = [#disco_items{}]}),
|
||||
%% Now check if the peer is in the room. We check this via disco#items
|
||||
#iq{type = result,
|
||||
sub_els = [#disco_items{items = [#disco_item{jid = PeerNickJID,
|
||||
name = PeerNick}]}]} =
|
||||
send_recv(Config, #iq{type = get, to = Room,
|
||||
sub_els = [#disco_items{}]}),
|
||||
%% Now joining
|
||||
send(Config, #presence{to = MyNickJID, sub_els = [#muc{}]}),
|
||||
%% First presence is from the participant, i.e. from the peer
|
||||
#presence{
|
||||
from = PeerNickJID,
|
||||
sub_els = [#muc_user{
|
||||
status_codes = [],
|
||||
items = [#muc_item{role = moderator,
|
||||
affiliation = owner}]}]} = recv(),
|
||||
%% The next is the self-presence (code 110 means it)
|
||||
#presence{
|
||||
from = MyNickJID,
|
||||
sub_els = [#muc_user{
|
||||
status_codes = [110],
|
||||
items = [#muc_item{role = visitor,
|
||||
affiliation = none}]}]} = recv(),
|
||||
%% Receive the room subject
|
||||
#message{from = PeerNickJID, type = groupchat,
|
||||
body = [#text{data = Subject}],
|
||||
sub_els = [#delay{}, #legacy_delay{}]} = recv(),
|
||||
%% Receive MUC history
|
||||
lists:foreach(
|
||||
fun(N) ->
|
||||
Text = #text{data = jlib:integer_to_binary(N)},
|
||||
#message{from = PeerNickJID,
|
||||
type = groupchat,
|
||||
body = [Text],
|
||||
sub_els = [#delay{}, #legacy_delay{}]} = recv()
|
||||
end, lists:seq(1, 5)),
|
||||
%% Sending a voice request
|
||||
VoiceReq = #xdata{
|
||||
type = submit,
|
||||
fields =
|
||||
[#xdata_field{
|
||||
var = <<"FORM_TYPE">>,
|
||||
values = [<<"http://jabber.org/protocol/muc#request">>]},
|
||||
#xdata_field{
|
||||
var = <<"muc#role">>,
|
||||
type = 'text-single',
|
||||
values = [<<"participant">>]}]},
|
||||
send(Config, #message{to = Room, sub_els = [VoiceReq]}),
|
||||
%% Becoming a participant
|
||||
#presence{from = MyNickJID,
|
||||
sub_els = [#muc_user{
|
||||
items = [#muc_item{role = participant,
|
||||
affiliation = none}]}]} = recv(),
|
||||
%% Sending private message to the peer
|
||||
send(Config, #message{to = PeerNickJID,
|
||||
body = [#text{data = Subject}]}),
|
||||
%% Becoming a member
|
||||
#presence{from = MyNickJID,
|
||||
sub_els = [#muc_user{
|
||||
items = [#muc_item{role = participant,
|
||||
affiliation = member}]}]} = recv(),
|
||||
%% Retrieving a member list
|
||||
#iq{type = result, sub_els = [#muc_admin{items = MemberList}]} =
|
||||
send_recv(Config,
|
||||
#iq{type = get, to = Room,
|
||||
sub_els =
|
||||
[#muc_admin{items = [#muc_item{affiliation = member}]}]}),
|
||||
[#muc_item{affiliation = member,
|
||||
jid = Localhost},
|
||||
#muc_item{affiliation = member,
|
||||
jid = MyBareJID}] = lists:keysort(#muc_item.jid, MemberList),
|
||||
%% Sending groupchat message
|
||||
send(Config, #message{to = Room, type = groupchat,
|
||||
body = [#text{data = Subject}]}),
|
||||
%% Receive this message back
|
||||
#message{type = groupchat, from = MyNickJID,
|
||||
body = [#text{data = Subject}]} = recv(),
|
||||
%% We're kicked off
|
||||
%% 307 -> Inform user that he or she has been kicked from the room
|
||||
#presence{from = MyNickJID, type = unavailable,
|
||||
sub_els = [#muc_user{
|
||||
status_codes = [307],
|
||||
items = [#muc_item{affiliation = member,
|
||||
role = none}]}]} = recv(),
|
||||
disconnect(Config).
|
||||
|
||||
offline_master(Config) ->
|
||||
|
@ -39,6 +39,9 @@ init_config(Config) ->
|
||||
{server_host, "localhost"},
|
||||
{server, ?COMMON_VHOST},
|
||||
{user, <<"test_single">>},
|
||||
{master_nick, <<"master_nick">>},
|
||||
{slave_nick, <<"slave_nick">>},
|
||||
{room_subject, <<"hello, world!">>},
|
||||
{certfile, CertFile},
|
||||
{base_dir, BaseDir},
|
||||
{resource, <<"resource">>},
|
||||
|
@ -14,6 +14,21 @@ decode({xmlel, _name, _attrs, _} = _el) ->
|
||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||
{<<"x">>, <<"http://jabber.org/protocol/muc">>} ->
|
||||
decode_muc(_el);
|
||||
{<<"query">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
decode_muc_admin(_el);
|
||||
{<<"reason">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
decode_muc_admin_reason(_el);
|
||||
{<<"continue">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
decode_muc_admin_continue(_el);
|
||||
{<<"actor">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
decode_muc_admin_actor(_el);
|
||||
{<<"item">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
decode_muc_admin_item(_el);
|
||||
{<<"query">>,
|
||||
<<"http://jabber.org/protocol/muc#owner">>} ->
|
||||
decode_muc_owner(_el);
|
||||
@ -691,6 +706,21 @@ decode({xmlel, _name, _attrs, _} = _el) ->
|
||||
is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
||||
case {_name, get_attr(<<"xmlns">>, _attrs)} of
|
||||
{<<"x">>, <<"http://jabber.org/protocol/muc">>} -> true;
|
||||
{<<"query">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
true;
|
||||
{<<"reason">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
true;
|
||||
{<<"continue">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
true;
|
||||
{<<"actor">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
true;
|
||||
{<<"item">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>} ->
|
||||
true;
|
||||
{<<"query">>,
|
||||
<<"http://jabber.org/protocol/muc#owner">>} ->
|
||||
true;
|
||||
@ -1240,6 +1270,10 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) ->
|
||||
encode({muc, _, _} = X) ->
|
||||
encode_muc(X,
|
||||
[{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]);
|
||||
encode({muc_admin, _} = Query) ->
|
||||
encode_muc_admin(Query,
|
||||
[{<<"xmlns">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>}]);
|
||||
encode({muc_owner, _, _} = Query) ->
|
||||
encode_muc_owner(Query,
|
||||
[{<<"xmlns">>,
|
||||
@ -1252,14 +1286,6 @@ encode({muc_user, _, _, _, _, _, _} = X) ->
|
||||
encode_muc_user(X,
|
||||
[{<<"xmlns">>,
|
||||
<<"http://jabber.org/protocol/muc#user">>}]);
|
||||
encode({muc_item, _, _, _, _, _, _, _} = Item) ->
|
||||
encode_muc_user_item(Item,
|
||||
[{<<"xmlns">>,
|
||||
<<"http://jabber.org/protocol/muc#user">>}]);
|
||||
encode({muc_actor, _, _} = Actor) ->
|
||||
encode_muc_user_actor(Actor,
|
||||
[{<<"xmlns">>,
|
||||
<<"http://jabber.org/protocol/muc#user">>}]);
|
||||
encode({muc_invite, _, _, _} = Invite) ->
|
||||
encode_muc_user_invite(Invite,
|
||||
[{<<"xmlns">>,
|
||||
@ -1742,14 +1768,15 @@ pp(muc_history, 4) ->
|
||||
pp(muc_decline, 3) -> [reason, from, to];
|
||||
pp(muc_user_destroy, 2) -> [reason, jid];
|
||||
pp(muc_invite, 3) -> [reason, from, to];
|
||||
pp(muc_actor, 2) -> [jid, nick];
|
||||
pp(muc_item, 7) ->
|
||||
[actor, continue, reason, affiliation, role, jid, nick];
|
||||
pp(muc_user, 6) ->
|
||||
[decline, destroy, invites, items, status_codes,
|
||||
password];
|
||||
pp(muc_owner_destroy, 3) -> [jid, reason, password];
|
||||
pp(muc_owner, 2) -> [destroy, config];
|
||||
pp(muc_item, 7) ->
|
||||
[actor, continue, reason, affiliation, role, jid, nick];
|
||||
pp(muc_actor, 2) -> [jid, nick];
|
||||
pp(muc_admin, 1) -> [items];
|
||||
pp(muc, 2) -> [history, password];
|
||||
pp(_, _) -> no.
|
||||
|
||||
@ -1834,6 +1861,319 @@ encode_muc_attr_password(undefined, _acc) -> _acc;
|
||||
encode_muc_attr_password(_val, _acc) ->
|
||||
[{<<"password">>, _val} | _acc].
|
||||
|
||||
decode_muc_admin({xmlel, <<"query">>, _attrs, _els}) ->
|
||||
Items = decode_muc_admin_els(_els, []),
|
||||
{muc_admin, Items}.
|
||||
|
||||
decode_muc_admin_els([], Items) -> lists:reverse(Items);
|
||||
decode_muc_admin_els([{xmlel, <<"item">>, _attrs, _} =
|
||||
_el
|
||||
| _els],
|
||||
Items) ->
|
||||
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||
if _xmlns == <<>>;
|
||||
_xmlns == <<"http://jabber.org/protocol/muc#admin">> ->
|
||||
decode_muc_admin_els(_els,
|
||||
[decode_muc_admin_item(_el) | Items]);
|
||||
true -> decode_muc_admin_els(_els, Items)
|
||||
end;
|
||||
decode_muc_admin_els([_ | _els], Items) ->
|
||||
decode_muc_admin_els(_els, Items).
|
||||
|
||||
encode_muc_admin({muc_admin, Items}, _xmlns_attrs) ->
|
||||
_els = 'encode_muc_admin_$items'(Items, []),
|
||||
_attrs = _xmlns_attrs,
|
||||
{xmlel, <<"query">>, _attrs, _els}.
|
||||
|
||||
'encode_muc_admin_$items'([], _acc) -> _acc;
|
||||
'encode_muc_admin_$items'([Items | _els], _acc) ->
|
||||
'encode_muc_admin_$items'(_els,
|
||||
[encode_muc_admin_item(Items, []) | _acc]).
|
||||
|
||||
decode_muc_admin_reason({xmlel, <<"reason">>, _attrs,
|
||||
_els}) ->
|
||||
Cdata = decode_muc_admin_reason_els(_els, <<>>), Cdata.
|
||||
|
||||
decode_muc_admin_reason_els([], Cdata) ->
|
||||
decode_muc_admin_reason_cdata(Cdata);
|
||||
decode_muc_admin_reason_els([{xmlcdata, _data} | _els],
|
||||
Cdata) ->
|
||||
decode_muc_admin_reason_els(_els,
|
||||
<<Cdata/binary, _data/binary>>);
|
||||
decode_muc_admin_reason_els([_ | _els], Cdata) ->
|
||||
decode_muc_admin_reason_els(_els, Cdata).
|
||||
|
||||
encode_muc_admin_reason(Cdata, _xmlns_attrs) ->
|
||||
_els = encode_muc_admin_reason_cdata(Cdata, []),
|
||||
_attrs = _xmlns_attrs,
|
||||
{xmlel, <<"reason">>, _attrs, _els}.
|
||||
|
||||
decode_muc_admin_reason_cdata(<<>>) -> undefined;
|
||||
decode_muc_admin_reason_cdata(_val) -> _val.
|
||||
|
||||
encode_muc_admin_reason_cdata(undefined, _acc) -> _acc;
|
||||
encode_muc_admin_reason_cdata(_val, _acc) ->
|
||||
[{xmlcdata, _val} | _acc].
|
||||
|
||||
decode_muc_admin_continue({xmlel, <<"continue">>,
|
||||
_attrs, _els}) ->
|
||||
Thread = decode_muc_admin_continue_attrs(_attrs,
|
||||
undefined),
|
||||
Thread.
|
||||
|
||||
decode_muc_admin_continue_attrs([{<<"thread">>, _val}
|
||||
| _attrs],
|
||||
_Thread) ->
|
||||
decode_muc_admin_continue_attrs(_attrs, _val);
|
||||
decode_muc_admin_continue_attrs([_ | _attrs], Thread) ->
|
||||
decode_muc_admin_continue_attrs(_attrs, Thread);
|
||||
decode_muc_admin_continue_attrs([], Thread) ->
|
||||
decode_muc_admin_continue_attr_thread(Thread).
|
||||
|
||||
encode_muc_admin_continue(Thread, _xmlns_attrs) ->
|
||||
_els = [],
|
||||
_attrs = encode_muc_admin_continue_attr_thread(Thread,
|
||||
_xmlns_attrs),
|
||||
{xmlel, <<"continue">>, _attrs, _els}.
|
||||
|
||||
decode_muc_admin_continue_attr_thread(undefined) ->
|
||||
undefined;
|
||||
decode_muc_admin_continue_attr_thread(_val) -> _val.
|
||||
|
||||
encode_muc_admin_continue_attr_thread(undefined,
|
||||
_acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_continue_attr_thread(_val, _acc) ->
|
||||
[{<<"thread">>, _val} | _acc].
|
||||
|
||||
decode_muc_admin_actor({xmlel, <<"actor">>, _attrs,
|
||||
_els}) ->
|
||||
{Jid, Nick} = decode_muc_admin_actor_attrs(_attrs,
|
||||
undefined, undefined),
|
||||
{muc_actor, Jid, Nick}.
|
||||
|
||||
decode_muc_admin_actor_attrs([{<<"jid">>, _val}
|
||||
| _attrs],
|
||||
_Jid, Nick) ->
|
||||
decode_muc_admin_actor_attrs(_attrs, _val, Nick);
|
||||
decode_muc_admin_actor_attrs([{<<"nick">>, _val}
|
||||
| _attrs],
|
||||
Jid, _Nick) ->
|
||||
decode_muc_admin_actor_attrs(_attrs, Jid, _val);
|
||||
decode_muc_admin_actor_attrs([_ | _attrs], Jid, Nick) ->
|
||||
decode_muc_admin_actor_attrs(_attrs, Jid, Nick);
|
||||
decode_muc_admin_actor_attrs([], Jid, Nick) ->
|
||||
{decode_muc_admin_actor_attr_jid(Jid),
|
||||
decode_muc_admin_actor_attr_nick(Nick)}.
|
||||
|
||||
encode_muc_admin_actor({muc_actor, Jid, Nick},
|
||||
_xmlns_attrs) ->
|
||||
_els = [],
|
||||
_attrs = encode_muc_admin_actor_attr_nick(Nick,
|
||||
encode_muc_admin_actor_attr_jid(Jid,
|
||||
_xmlns_attrs)),
|
||||
{xmlel, <<"actor">>, _attrs, _els}.
|
||||
|
||||
decode_muc_admin_actor_attr_jid(undefined) -> undefined;
|
||||
decode_muc_admin_actor_attr_jid(_val) ->
|
||||
case catch dec_jid(_val) of
|
||||
{'EXIT', _} ->
|
||||
erlang:error({xmpp_codec,
|
||||
{bad_attr_value, <<"jid">>, <<"actor">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>}});
|
||||
_res -> _res
|
||||
end.
|
||||
|
||||
encode_muc_admin_actor_attr_jid(undefined, _acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_actor_attr_jid(_val, _acc) ->
|
||||
[{<<"jid">>, enc_jid(_val)} | _acc].
|
||||
|
||||
decode_muc_admin_actor_attr_nick(undefined) ->
|
||||
undefined;
|
||||
decode_muc_admin_actor_attr_nick(_val) -> _val.
|
||||
|
||||
encode_muc_admin_actor_attr_nick(undefined, _acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_actor_attr_nick(_val, _acc) ->
|
||||
[{<<"nick">>, _val} | _acc].
|
||||
|
||||
decode_muc_admin_item({xmlel, <<"item">>, _attrs,
|
||||
_els}) ->
|
||||
{Actor, Continue, Reason} =
|
||||
decode_muc_admin_item_els(_els, undefined, undefined,
|
||||
undefined),
|
||||
{Affiliation, Role, Jid, Nick} =
|
||||
decode_muc_admin_item_attrs(_attrs, undefined,
|
||||
undefined, undefined, undefined),
|
||||
{muc_item, Actor, Continue, Reason, Affiliation, Role,
|
||||
Jid, Nick}.
|
||||
|
||||
decode_muc_admin_item_els([], Actor, Continue,
|
||||
Reason) ->
|
||||
{Actor, Continue, Reason};
|
||||
decode_muc_admin_item_els([{xmlel, <<"actor">>, _attrs,
|
||||
_} =
|
||||
_el
|
||||
| _els],
|
||||
Actor, Continue, Reason) ->
|
||||
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||
if _xmlns == <<>>;
|
||||
_xmlns == <<"http://jabber.org/protocol/muc#admin">> ->
|
||||
decode_muc_admin_item_els(_els,
|
||||
decode_muc_admin_actor(_el), Continue,
|
||||
Reason);
|
||||
true ->
|
||||
decode_muc_admin_item_els(_els, Actor, Continue, Reason)
|
||||
end;
|
||||
decode_muc_admin_item_els([{xmlel, <<"continue">>,
|
||||
_attrs, _} =
|
||||
_el
|
||||
| _els],
|
||||
Actor, Continue, Reason) ->
|
||||
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||
if _xmlns == <<>>;
|
||||
_xmlns == <<"http://jabber.org/protocol/muc#admin">> ->
|
||||
decode_muc_admin_item_els(_els, Actor,
|
||||
decode_muc_admin_continue(_el), Reason);
|
||||
true ->
|
||||
decode_muc_admin_item_els(_els, Actor, Continue, Reason)
|
||||
end;
|
||||
decode_muc_admin_item_els([{xmlel, <<"reason">>, _attrs,
|
||||
_} =
|
||||
_el
|
||||
| _els],
|
||||
Actor, Continue, Reason) ->
|
||||
_xmlns = get_attr(<<"xmlns">>, _attrs),
|
||||
if _xmlns == <<>>;
|
||||
_xmlns == <<"http://jabber.org/protocol/muc#admin">> ->
|
||||
decode_muc_admin_item_els(_els, Actor, Continue,
|
||||
decode_muc_admin_reason(_el));
|
||||
true ->
|
||||
decode_muc_admin_item_els(_els, Actor, Continue, Reason)
|
||||
end;
|
||||
decode_muc_admin_item_els([_ | _els], Actor, Continue,
|
||||
Reason) ->
|
||||
decode_muc_admin_item_els(_els, Actor, Continue,
|
||||
Reason).
|
||||
|
||||
decode_muc_admin_item_attrs([{<<"affiliation">>, _val}
|
||||
| _attrs],
|
||||
_Affiliation, Role, Jid, Nick) ->
|
||||
decode_muc_admin_item_attrs(_attrs, _val, Role, Jid,
|
||||
Nick);
|
||||
decode_muc_admin_item_attrs([{<<"role">>, _val}
|
||||
| _attrs],
|
||||
Affiliation, _Role, Jid, Nick) ->
|
||||
decode_muc_admin_item_attrs(_attrs, Affiliation, _val,
|
||||
Jid, Nick);
|
||||
decode_muc_admin_item_attrs([{<<"jid">>, _val}
|
||||
| _attrs],
|
||||
Affiliation, Role, _Jid, Nick) ->
|
||||
decode_muc_admin_item_attrs(_attrs, Affiliation, Role,
|
||||
_val, Nick);
|
||||
decode_muc_admin_item_attrs([{<<"nick">>, _val}
|
||||
| _attrs],
|
||||
Affiliation, Role, Jid, _Nick) ->
|
||||
decode_muc_admin_item_attrs(_attrs, Affiliation, Role,
|
||||
Jid, _val);
|
||||
decode_muc_admin_item_attrs([_ | _attrs], Affiliation,
|
||||
Role, Jid, Nick) ->
|
||||
decode_muc_admin_item_attrs(_attrs, Affiliation, Role,
|
||||
Jid, Nick);
|
||||
decode_muc_admin_item_attrs([], Affiliation, Role, Jid,
|
||||
Nick) ->
|
||||
{decode_muc_admin_item_attr_affiliation(Affiliation),
|
||||
decode_muc_admin_item_attr_role(Role),
|
||||
decode_muc_admin_item_attr_jid(Jid),
|
||||
decode_muc_admin_item_attr_nick(Nick)}.
|
||||
|
||||
encode_muc_admin_item({muc_item, Actor, Continue,
|
||||
Reason, Affiliation, Role, Jid, Nick},
|
||||
_xmlns_attrs) ->
|
||||
_els = 'encode_muc_admin_item_$reason'(Reason,
|
||||
'encode_muc_admin_item_$continue'(Continue,
|
||||
'encode_muc_admin_item_$actor'(Actor,
|
||||
[]))),
|
||||
_attrs = encode_muc_admin_item_attr_nick(Nick,
|
||||
encode_muc_admin_item_attr_jid(Jid,
|
||||
encode_muc_admin_item_attr_role(Role,
|
||||
encode_muc_admin_item_attr_affiliation(Affiliation,
|
||||
_xmlns_attrs)))),
|
||||
{xmlel, <<"item">>, _attrs, _els}.
|
||||
|
||||
'encode_muc_admin_item_$actor'(undefined, _acc) -> _acc;
|
||||
'encode_muc_admin_item_$actor'(Actor, _acc) ->
|
||||
[encode_muc_admin_actor(Actor, []) | _acc].
|
||||
|
||||
'encode_muc_admin_item_$continue'(undefined, _acc) ->
|
||||
_acc;
|
||||
'encode_muc_admin_item_$continue'(Continue, _acc) ->
|
||||
[encode_muc_admin_continue(Continue, []) | _acc].
|
||||
|
||||
'encode_muc_admin_item_$reason'(undefined, _acc) ->
|
||||
_acc;
|
||||
'encode_muc_admin_item_$reason'(Reason, _acc) ->
|
||||
[encode_muc_admin_reason(Reason, []) | _acc].
|
||||
|
||||
decode_muc_admin_item_attr_affiliation(undefined) ->
|
||||
undefined;
|
||||
decode_muc_admin_item_attr_affiliation(_val) ->
|
||||
case catch dec_enum(_val,
|
||||
[admin, member, none, outcast, owner])
|
||||
of
|
||||
{'EXIT', _} ->
|
||||
erlang:error({xmpp_codec,
|
||||
{bad_attr_value, <<"affiliation">>, <<"item">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>}});
|
||||
_res -> _res
|
||||
end.
|
||||
|
||||
encode_muc_admin_item_attr_affiliation(undefined,
|
||||
_acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_item_attr_affiliation(_val, _acc) ->
|
||||
[{<<"affiliation">>, enc_enum(_val)} | _acc].
|
||||
|
||||
decode_muc_admin_item_attr_role(undefined) -> undefined;
|
||||
decode_muc_admin_item_attr_role(_val) ->
|
||||
case catch dec_enum(_val,
|
||||
[moderator, none, participant, visitor])
|
||||
of
|
||||
{'EXIT', _} ->
|
||||
erlang:error({xmpp_codec,
|
||||
{bad_attr_value, <<"role">>, <<"item">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>}});
|
||||
_res -> _res
|
||||
end.
|
||||
|
||||
encode_muc_admin_item_attr_role(undefined, _acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_item_attr_role(_val, _acc) ->
|
||||
[{<<"role">>, enc_enum(_val)} | _acc].
|
||||
|
||||
decode_muc_admin_item_attr_jid(undefined) -> undefined;
|
||||
decode_muc_admin_item_attr_jid(_val) ->
|
||||
case catch dec_jid(_val) of
|
||||
{'EXIT', _} ->
|
||||
erlang:error({xmpp_codec,
|
||||
{bad_attr_value, <<"jid">>, <<"item">>,
|
||||
<<"http://jabber.org/protocol/muc#admin">>}});
|
||||
_res -> _res
|
||||
end.
|
||||
|
||||
encode_muc_admin_item_attr_jid(undefined, _acc) -> _acc;
|
||||
encode_muc_admin_item_attr_jid(_val, _acc) ->
|
||||
[{<<"jid">>, enc_jid(_val)} | _acc].
|
||||
|
||||
decode_muc_admin_item_attr_nick(undefined) -> undefined;
|
||||
decode_muc_admin_item_attr_nick(_val) -> _val.
|
||||
|
||||
encode_muc_admin_item_attr_nick(undefined, _acc) ->
|
||||
_acc;
|
||||
encode_muc_admin_item_attr_nick(_val, _acc) ->
|
||||
[{<<"nick">>, _val} | _acc].
|
||||
|
||||
decode_muc_owner({xmlel, <<"query">>, _attrs, _els}) ->
|
||||
{Config, Destroy} = decode_muc_owner_els(_els,
|
||||
undefined, undefined),
|
||||
|
@ -61,9 +61,6 @@
|
||||
node :: binary(),
|
||||
publisher :: binary()}).
|
||||
|
||||
-record(muc_actor, {jid :: any(),
|
||||
nick :: binary()}).
|
||||
|
||||
-record(stat, {name :: binary(),
|
||||
units :: binary(),
|
||||
value :: binary(),
|
||||
@ -126,6 +123,9 @@
|
||||
subid :: binary(),
|
||||
type :: 'none' | 'pending' | 'subscribed' | 'unconfigured'}).
|
||||
|
||||
-record(muc_actor, {jid :: any(),
|
||||
nick :: binary()}).
|
||||
|
||||
-record(shim, {headers = [] :: [{binary(),'undefined' | binary()}]}).
|
||||
|
||||
-record(caps, {hash :: binary(),
|
||||
@ -208,6 +208,8 @@
|
||||
status_codes = [] :: [pos_integer()],
|
||||
password :: binary()}).
|
||||
|
||||
-record(muc_admin, {items = [] :: [#muc_item{}]}).
|
||||
|
||||
-record(bytestreams, {hosts = [] :: [#streamhost{}],
|
||||
used :: any(),
|
||||
activate :: any(),
|
||||
|
@ -1974,6 +1974,56 @@
|
||||
label = '$destroy'},
|
||||
#ref{name = xdata, min = 0, max = 1, label = '$config'}]}).
|
||||
|
||||
-xml(muc_admin_item,
|
||||
#elem{name = <<"item">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc#admin">>,
|
||||
result = {muc_item, '$actor', '$continue', '$reason',
|
||||
'$affiliation', '$role', '$jid', '$nick'},
|
||||
refs = [#ref{name = muc_admin_actor,
|
||||
min = 0, max = 1, label = '$actor'},
|
||||
#ref{name = muc_admin_continue,
|
||||
min = 0, max = 1, label = '$continue'},
|
||||
#ref{name = muc_admin_reason,
|
||||
min = 0, max = 1, label = '$reason'}],
|
||||
attrs = [#attr{name = <<"affiliation">>,
|
||||
dec = {dec_enum, [[admin, member, none,
|
||||
outcast, owner]]},
|
||||
enc = {enc_enum, []}},
|
||||
#attr{name = <<"role">>,
|
||||
dec = {dec_enum, [[moderator, none,
|
||||
participant, visitor]]},
|
||||
enc = {enc_enum, []}},
|
||||
#attr{name = <<"jid">>,
|
||||
dec = {dec_jid, []},
|
||||
enc = {enc_jid, []}},
|
||||
#attr{name = <<"nick">>}]}).
|
||||
|
||||
-xml(muc_admin_actor,
|
||||
#elem{name = <<"actor">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc#admin">>,
|
||||
result = {muc_actor, '$jid', '$nick'},
|
||||
attrs = [#attr{name = <<"jid">>,
|
||||
dec = {dec_jid, []},
|
||||
enc = {enc_jid, []}},
|
||||
#attr{name = <<"nick">>}]}).
|
||||
|
||||
-xml(muc_admin_continue,
|
||||
#elem{name = <<"continue">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc#admin">>,
|
||||
result = '$thread',
|
||||
attrs = [#attr{name = <<"thread">>}]}).
|
||||
|
||||
-xml(muc_admin_reason,
|
||||
#elem{name = <<"reason">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc#admin">>,
|
||||
result = '$cdata'}).
|
||||
|
||||
-xml(muc_admin,
|
||||
#elem{name = <<"query">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc#admin">>,
|
||||
result = {muc_admin, '$items'},
|
||||
refs = [#ref{name = muc_admin_item, label = '$items'}]}).
|
||||
|
||||
-xml(muc,
|
||||
#elem{name = <<"x">>,
|
||||
xmlns = <<"http://jabber.org/protocol/muc">>,
|
||||
|
Loading…
Reference in New Issue
Block a user