mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Add roster checks
This commit is contained in:
parent
0baf4e6088
commit
3f8a10c092
@ -26,8 +26,46 @@
|
|||||||
|
|
||||||
-define(PUBSUB(Node), <<(?NS_PUBSUB)/binary, "#", Node>>).
|
-define(PUBSUB(Node), <<(?NS_PUBSUB)/binary, "#", Node>>).
|
||||||
|
|
||||||
|
-define(recv2(P1, P2),
|
||||||
|
(fun() ->
|
||||||
|
case {R1 = recv(), R2 = recv()} of
|
||||||
|
{P1, P2} -> {R1, R2};
|
||||||
|
{P2, P1} -> {R2, R1}
|
||||||
|
end
|
||||||
|
end)()).
|
||||||
|
|
||||||
|
-define(recv3(P1, P2, P3),
|
||||||
|
(fun() ->
|
||||||
|
case R3 = recv() of
|
||||||
|
P1 -> insert(R3, 1, ?recv2(P2, P3));
|
||||||
|
P2 -> insert(R3, 2, ?recv2(P1, P3));
|
||||||
|
P3 -> insert(R3, 3, ?recv2(P1, P2))
|
||||||
|
end
|
||||||
|
end)()).
|
||||||
|
|
||||||
|
-define(recv4(P1, P2, P3, P4),
|
||||||
|
(fun() ->
|
||||||
|
case R4 = recv() of
|
||||||
|
P1 -> insert(R4, 1, ?recv3(P2, P3, P4));
|
||||||
|
P2 -> insert(R4, 2, ?recv3(P1, P3, P4));
|
||||||
|
P3 -> insert(R4, 3, ?recv3(P1, P2, P4));
|
||||||
|
P4 -> insert(R4, 4, ?recv3(P1, P2, P3))
|
||||||
|
end
|
||||||
|
end)()).
|
||||||
|
|
||||||
|
-define(recv5(P1, P2, P3, P4, P5),
|
||||||
|
(fun() ->
|
||||||
|
case R5 = recv() of
|
||||||
|
P1 -> insert(R5, 1, ?recv4(P2, P3, P4, P5));
|
||||||
|
P2 -> insert(R5, 2, ?recv4(P1, P3, P4, P5));
|
||||||
|
P3 -> insert(R5, 3, ?recv4(P1, P2, P4, P5));
|
||||||
|
P4 -> insert(R5, 4, ?recv4(P1, P2, P3, P5));
|
||||||
|
P5 -> insert(R5, 5, ?recv4(P1, P2, P3, P4))
|
||||||
|
end
|
||||||
|
end)()).
|
||||||
|
|
||||||
suite() ->
|
suite() ->
|
||||||
[{timetrap,{seconds,30}}].
|
[{timetrap, {seconds,10}}].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
DataDir = proplists:get_value(data_dir, Config),
|
DataDir = proplists:get_value(data_dir, Config),
|
||||||
@ -53,16 +91,36 @@ init_per_suite(Config) ->
|
|||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_group(GroupName, Config) ->
|
init_per_group(_GroupName, Config) ->
|
||||||
User = list_to_binary(atom_to_list(GroupName)),
|
Pid = start_event_relay(),
|
||||||
set_opt(user, User, Config).
|
set_opt(event_relay, Pid, Config).
|
||||||
|
|
||||||
end_per_group(_GroupName, _Config) ->
|
end_per_group(_GroupName, Config) ->
|
||||||
|
stop_event_relay(Config),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
init_per_testcase(stop_ejabberd = TestCase, OrigConfig) ->
|
||||||
|
Test = atom_to_list(TestCase),
|
||||||
|
Resource = list_to_binary(Test),
|
||||||
|
User = <<"test_stop">>,
|
||||||
|
Config = set_opt(resource, Resource,
|
||||||
|
set_opt(user, User, OrigConfig)),
|
||||||
|
ejabberd_auth:try_register(User,
|
||||||
|
?config(server, Config),
|
||||||
|
?config(password, Config)),
|
||||||
|
open_session(bind(auth(connect(Config))));
|
||||||
init_per_testcase(TestCase, OrigConfig) ->
|
init_per_testcase(TestCase, OrigConfig) ->
|
||||||
Resource = list_to_binary(atom_to_list(TestCase)),
|
subscribe_to_events(OrigConfig),
|
||||||
Config = set_opt(resource, Resource, OrigConfig),
|
Test = atom_to_list(TestCase),
|
||||||
|
Resource = list_to_binary(Test),
|
||||||
|
IsMaster = lists:suffix("_master", Test),
|
||||||
|
IsSlave = lists:suffix("_slave", Test),
|
||||||
|
User = if IsMaster -> <<"test_master">>;
|
||||||
|
IsSlave -> <<"test_slave">>;
|
||||||
|
true -> <<"test_single">>
|
||||||
|
end,
|
||||||
|
Config = set_opt(resource, Resource,
|
||||||
|
set_opt(user, User, OrigConfig)),
|
||||||
case TestCase of
|
case TestCase of
|
||||||
test_connect ->
|
test_connect ->
|
||||||
Config;
|
Config;
|
||||||
@ -82,9 +140,11 @@ init_per_testcase(TestCase, OrigConfig) ->
|
|||||||
auth(connect(Config));
|
auth(connect(Config));
|
||||||
test_open_session ->
|
test_open_session ->
|
||||||
bind(auth(connect(Config)));
|
bind(auth(connect(Config)));
|
||||||
stop_ejabberd ->
|
_ when IsMaster or IsSlave ->
|
||||||
Config1 = set_opt(user, <<"stop_ejabberd">>, Config),
|
Server = ?config(server, Config),
|
||||||
open_session(bind(auth(register(connect(Config1)))));
|
Password = ?config(password, Config),
|
||||||
|
ejabberd_auth:try_register(User, Server, Password),
|
||||||
|
open_session(bind(auth(connect(Config))));
|
||||||
_ ->
|
_ ->
|
||||||
open_session(bind(auth(connect(Config))))
|
open_session(bind(auth(connect(Config))))
|
||||||
end.
|
end.
|
||||||
@ -116,10 +176,11 @@ groups() ->
|
|||||||
blocking,
|
blocking,
|
||||||
vcard,
|
vcard,
|
||||||
pubsub,
|
pubsub,
|
||||||
test_unregister]}].
|
test_unregister]},
|
||||||
|
{test_roster, [parallel], [roster_master, roster_slave]}].
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[{group, single_user}, stop_ejabberd].
|
[{group, single_user}, {group, test_roster}, stop_ejabberd].
|
||||||
|
|
||||||
stop_ejabberd(Config) ->
|
stop_ejabberd(Config) ->
|
||||||
ok = application:stop(ejabberd),
|
ok = application:stop(ejabberd),
|
||||||
@ -177,7 +238,7 @@ test_starttls(Config) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
starttls(Config) ->
|
starttls(Config) ->
|
||||||
_ = send(Config, #starttls{}),
|
send(Config, #starttls{}),
|
||||||
#starttls_proceed{} = recv(),
|
#starttls_proceed{} = recv(),
|
||||||
TLSSocket = ejabberd_socket:starttls(
|
TLSSocket = ejabberd_socket:starttls(
|
||||||
?config(socket, Config),
|
?config(socket, Config),
|
||||||
@ -199,7 +260,7 @@ test_zlib(Config) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
zlib(Config) ->
|
zlib(Config) ->
|
||||||
_ = send(Config, #compress{methods = [<<"zlib">>]}),
|
send(Config, #compress{methods = [<<"zlib">>]}),
|
||||||
#compressed{} = recv(),
|
#compressed{} = recv(),
|
||||||
ZlibSocket = ejabberd_socket:compress(?config(socket, Config)),
|
ZlibSocket = ejabberd_socket:compress(?config(socket, Config)),
|
||||||
init_stream(set_opt(socket, ZlibSocket, Config)).
|
init_stream(set_opt(socket, ZlibSocket, Config)).
|
||||||
@ -279,7 +340,7 @@ open_session(Config) ->
|
|||||||
roster_get(Config) ->
|
roster_get(Config) ->
|
||||||
ID = send(Config, #iq{type = get, sub_els = [#roster{}]}),
|
ID = send(Config, #iq{type = get, sub_els = [#roster{}]}),
|
||||||
#iq{type = result, id = ID,
|
#iq{type = result, id = ID,
|
||||||
sub_els = [#roster{item = []}]} = recv(),
|
sub_els = [#roster{items = []}]} = recv(),
|
||||||
disconnect(Config).
|
disconnect(Config).
|
||||||
|
|
||||||
presence_broadcast(Config) ->
|
presence_broadcast(Config) ->
|
||||||
@ -373,13 +434,11 @@ privacy(Config) ->
|
|||||||
stanza = 'presence-in',
|
stanza = 'presence-in',
|
||||||
value = JID}]}]}]}),
|
value = JID}]}]}]}),
|
||||||
#iq{type = result, id = I2, sub_els = []} = recv(),
|
#iq{type = result, id = I2, sub_els = []} = recv(),
|
||||||
_Push1 = #iq{type = set, id = PushI1,
|
Push1 = #iq{type = set,
|
||||||
sub_els = [#privacy{
|
sub_els = [#privacy{
|
||||||
lists = [#privacy_list{
|
lists = [#privacy_list{
|
||||||
name = <<"public">>}]}]} = recv(),
|
name = <<"public">>}]}]} = recv(),
|
||||||
%% BUG: ejabberd replies on this result
|
send(Config, make_iq_result(Push1)),
|
||||||
%% TODO: this should be fixed in ejabberd
|
|
||||||
%% _ = send(Config, Push1#iq{type = result, sub_els = []}),
|
|
||||||
I3 = send(Config, #iq{type = set,
|
I3 = send(Config, #iq{type = set,
|
||||||
sub_els = [#privacy{active = <<"public">>}]}),
|
sub_els = [#privacy{active = <<"public">>}]}),
|
||||||
#iq{type = result, id = I3, sub_els = []} = recv(),
|
#iq{type = result, id = I3, sub_els = []} = recv(),
|
||||||
@ -405,10 +464,11 @@ privacy(Config) ->
|
|||||||
%% BUG: We should receive this:
|
%% BUG: We should receive this:
|
||||||
%% _Push2 = #iq{type = set, id = PushI2, sub_els = []} = recv(),
|
%% _Push2 = #iq{type = set, id = PushI2, sub_els = []} = recv(),
|
||||||
%% TODO: this should be fixed in ejabberd
|
%% TODO: this should be fixed in ejabberd
|
||||||
_Push2 = #iq{type = set, id = PushI2,
|
Push2 = #iq{type = set,
|
||||||
sub_els = [#privacy{
|
sub_els = [#privacy{
|
||||||
lists = [#privacy_list{
|
lists = [#privacy_list{
|
||||||
name = <<"public">>}]}]} = recv(),
|
name = <<"public">>}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push2)),
|
||||||
disconnect(Config).
|
disconnect(Config).
|
||||||
|
|
||||||
blocking(Config) ->
|
blocking(Config) ->
|
||||||
@ -472,12 +532,11 @@ vcard(Config) ->
|
|||||||
disconnect(Config).
|
disconnect(Config).
|
||||||
|
|
||||||
stats(Config) ->
|
stats(Config) ->
|
||||||
ServerJID = server_jid(Config),
|
|
||||||
ID = send(Config, #iq{type = get, sub_els = [#stats{}],
|
ID = send(Config, #iq{type = get, sub_els = [#stats{}],
|
||||||
to = server_jid(Config)}),
|
to = server_jid(Config)}),
|
||||||
#iq{type = result, id = ID, sub_els = [#stats{stat = Stats}]} = recv(),
|
#iq{type = result, id = ID, sub_els = [#stats{stat = Stats}]} = recv(),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(#stat{name = Name} = Stat) ->
|
fun(#stat{} = Stat) ->
|
||||||
I = send(Config, #iq{type = get,
|
I = send(Config, #iq{type = get,
|
||||||
sub_els = [#stats{stat = [Stat]}],
|
sub_els = [#stats{stat = [Stat]}],
|
||||||
to = server_jid(Config)}),
|
to = server_jid(Config)}),
|
||||||
@ -542,6 +601,123 @@ auth_plain(Config) ->
|
|||||||
{skipped, 'PLAIN_not_available'}
|
{skipped, 'PLAIN_not_available'}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
roster_master(Config) ->
|
||||||
|
send(Config, #presence{}),
|
||||||
|
#presence{} = recv(),
|
||||||
|
wait_for_slave(Config),
|
||||||
|
Peer = jlib:make_jid(<<"test_slave">>, ?config(server, Config),
|
||||||
|
<<"roster_slave">>),
|
||||||
|
LPeer = jlib:jid_remove_resource(Peer),
|
||||||
|
send(Config, #presence{type = subscribe, to = LPeer}),
|
||||||
|
Push1 = #iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
ask = subscribe,
|
||||||
|
subscription = none,
|
||||||
|
jid = LPeer}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push1)),
|
||||||
|
{Push2, _} = ?recv2(
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
subscription = to,
|
||||||
|
jid = LPeer}]}]},
|
||||||
|
#presence{type = subscribed, from = LPeer}),
|
||||||
|
send(Config, make_iq_result(Push2)),
|
||||||
|
#presence{type = undefined, from = Peer} = recv(),
|
||||||
|
%% BUG: ejabberd sends previous push again. Is it ok?
|
||||||
|
Push3 = #iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
subscription = to,
|
||||||
|
jid = LPeer}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push3)),
|
||||||
|
#presence{type = subscribe, from = LPeer} = recv(),
|
||||||
|
send(Config, #presence{type = subscribed, to = LPeer}),
|
||||||
|
Push4 = #iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
subscription = both,
|
||||||
|
jid = LPeer}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push4)),
|
||||||
|
%% Move into a group
|
||||||
|
Groups = [<<"A">>, <<"B">>],
|
||||||
|
Item = #roster_item{jid = LPeer, groups = Groups},
|
||||||
|
I1 = send(Config, #iq{type = set, sub_els = [#roster{items = [Item]}]}),
|
||||||
|
{Push5, _} = ?recv2(
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els =
|
||||||
|
[#roster{items = [#roster_item{
|
||||||
|
jid = LPeer,
|
||||||
|
groups = Groups,
|
||||||
|
subscription = both}]}]},
|
||||||
|
#iq{type = result, id = I1, sub_els = []}),
|
||||||
|
send(Config, make_iq_result(Push5)),
|
||||||
|
wait_for_slave(Config),
|
||||||
|
%% The peer removed us from.
|
||||||
|
{Push6, Push7, _, _, _} =
|
||||||
|
?recv5(
|
||||||
|
%% TODO: I guess this can be optimized, we don't need
|
||||||
|
%% to send transient roster push with subscription = 'to'.
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els =
|
||||||
|
[#roster{items = [#roster_item{
|
||||||
|
jid = LPeer,
|
||||||
|
groups = Groups,
|
||||||
|
subscription = to}]}]},
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els =
|
||||||
|
[#roster{items = [#roster_item{
|
||||||
|
jid = LPeer,
|
||||||
|
groups = Groups,
|
||||||
|
subscription = none}]}]},
|
||||||
|
#presence{type = unsubscribe, from = LPeer},
|
||||||
|
#presence{type = unsubscribed, from = LPeer},
|
||||||
|
#presence{type = unavailable, from = Peer}),
|
||||||
|
send(Config, make_iq_result(Push6)),
|
||||||
|
send(Config, make_iq_result(Push7)),
|
||||||
|
disconnect(Config).
|
||||||
|
|
||||||
|
roster_slave(Config) ->
|
||||||
|
send(Config, #presence{}),
|
||||||
|
#presence{} = recv(),
|
||||||
|
wait_for_master(Config),
|
||||||
|
Peer = jlib:make_jid(<<"test_master">>, ?config(server, Config),
|
||||||
|
<<"roster_master">>),
|
||||||
|
LPeer = jlib:jid_remove_resource(Peer),
|
||||||
|
#presence{type = subscribe, from = LPeer} = recv(),
|
||||||
|
send(Config, #presence{type = subscribed, to = LPeer}),
|
||||||
|
Push1 = #iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
subscription = from,
|
||||||
|
jid = LPeer}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push1)),
|
||||||
|
send(Config, #presence{type = subscribe, to = LPeer}),
|
||||||
|
Push2 = #iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
ask = subscribe,
|
||||||
|
subscription = from,
|
||||||
|
jid = LPeer}]}]} = recv(),
|
||||||
|
send(Config, make_iq_result(Push2)),
|
||||||
|
{Push3, _} = ?recv2(
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els = [#roster{items = [#roster_item{
|
||||||
|
subscription = both,
|
||||||
|
jid = LPeer}]}]},
|
||||||
|
#presence{type = subscribed, from = LPeer}),
|
||||||
|
send(Config, make_iq_result(Push3)),
|
||||||
|
#presence{type = undefined, from = Peer} = recv(),
|
||||||
|
wait_for_master(Config),
|
||||||
|
%% Remove the peer from roster.
|
||||||
|
Item = #roster_item{jid = LPeer, subscription = remove},
|
||||||
|
I1 = send(Config, #iq{type = set, sub_els = [#roster{items = [Item]}]}),
|
||||||
|
{Push4, _} = ?recv2(
|
||||||
|
#iq{type = set,
|
||||||
|
sub_els =
|
||||||
|
[#roster{items = [#roster_item{
|
||||||
|
jid = LPeer,
|
||||||
|
subscription = remove}]}]},
|
||||||
|
#iq{type = result, id = I1, sub_els = []}),
|
||||||
|
send(Config, make_iq_result(Push4)),
|
||||||
|
#presence{type = unavailable, from = Peer} = recv(),
|
||||||
|
disconnect(Config).
|
||||||
|
|
||||||
auth_SASL(Mech, Config) ->
|
auth_SASL(Mech, Config) ->
|
||||||
{Response, SASL} = sasl_new(Mech,
|
{Response, SASL} = sasl_new(Mech,
|
||||||
?config(user, Config),
|
?config(user, Config),
|
||||||
@ -738,3 +914,74 @@ bookmark_conference() ->
|
|||||||
|
|
||||||
set_opt(Opt, Val, Config) ->
|
set_opt(Opt, Val, Config) ->
|
||||||
[{Opt, Val}|lists:keydelete(Opt, 1, Config)].
|
[{Opt, Val}|lists:keydelete(Opt, 1, Config)].
|
||||||
|
|
||||||
|
wait_for_master(Config) ->
|
||||||
|
put_event(Config, slave_ready),
|
||||||
|
master_ready = get_event(Config).
|
||||||
|
|
||||||
|
wait_for_slave(Config) ->
|
||||||
|
put_event(Config, master_ready),
|
||||||
|
slave_ready = get_event(Config).
|
||||||
|
|
||||||
|
make_iq_result(#iq{from = From} = IQ) ->
|
||||||
|
IQ#iq{type = result, to = From, from = undefined, sub_els = []}.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Clients puts and gets events via this relay.
|
||||||
|
%%%===================================================================
|
||||||
|
start_event_relay() ->
|
||||||
|
spawn(fun event_relay/0).
|
||||||
|
|
||||||
|
stop_event_relay(Config) ->
|
||||||
|
Pid = ?config(event_relay, Config),
|
||||||
|
exit(Pid, normal).
|
||||||
|
|
||||||
|
event_relay() ->
|
||||||
|
event_relay([], []).
|
||||||
|
|
||||||
|
event_relay(Events, Subscribers) ->
|
||||||
|
receive
|
||||||
|
{subscribe, From} ->
|
||||||
|
From ! {ok, self()},
|
||||||
|
lists:foreach(
|
||||||
|
fun(Event) -> From ! {event, Event, self()}
|
||||||
|
end, Events),
|
||||||
|
event_relay(Events, [From|Subscribers]);
|
||||||
|
{put, Event, From} ->
|
||||||
|
From ! {ok, self()},
|
||||||
|
lists:foreach(
|
||||||
|
fun(Pid) when Pid /= From ->
|
||||||
|
Pid ! {event, Event, self()};
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end, Subscribers),
|
||||||
|
event_relay([Event|Events], Subscribers)
|
||||||
|
end.
|
||||||
|
|
||||||
|
subscribe_to_events(Config) ->
|
||||||
|
Relay = ?config(event_relay, Config),
|
||||||
|
Relay ! {subscribe, self()},
|
||||||
|
receive
|
||||||
|
{ok, Relay} ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
put_event(Config, Event) ->
|
||||||
|
Relay = ?config(event_relay, Config),
|
||||||
|
Relay ! {put, Event, self()},
|
||||||
|
receive
|
||||||
|
{ok, Relay} ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_event(Config) ->
|
||||||
|
Relay = ?config(event_relay, Config),
|
||||||
|
receive
|
||||||
|
{event, Event, Relay} ->
|
||||||
|
Event
|
||||||
|
end.
|
||||||
|
|
||||||
|
insert(Val, N, Tuple) ->
|
||||||
|
L = tuple_to_list(Tuple),
|
||||||
|
{H, T} = lists:split(N-1, L),
|
||||||
|
list_to_tuple(H ++ [Val|T]).
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
%% Created automatically by XML generator (xml_gen.erl)
|
%% Created automatically by XML generator (xml_gen.erl)
|
||||||
%% Source: xmpp_codec.spec
|
%% Source: xmpp_codec.spec
|
||||||
%% Date: Fri, 14 Jun 2013 16:48:12 GMT
|
%% Date: Sat, 15 Jun 2013 09:36:14 GMT
|
||||||
|
|
||||||
-module(xmpp_codec).
|
-module(xmpp_codec).
|
||||||
|
|
||||||
@ -1265,22 +1265,22 @@ encode_roster_item_attr_ask(_val, _acc) ->
|
|||||||
[{<<"ask">>, xml_gen:enc_enum(_val)} | _acc].
|
[{<<"ask">>, xml_gen:enc_enum(_val)} | _acc].
|
||||||
|
|
||||||
decode_roster({xmlel, <<"query">>, _attrs, _els}) ->
|
decode_roster({xmlel, <<"query">>, _attrs, _els}) ->
|
||||||
Item = decode_roster_els(_els, []),
|
Items = decode_roster_els(_els, []),
|
||||||
Ver = decode_roster_attrs(_attrs, undefined),
|
Ver = decode_roster_attrs(_attrs, undefined),
|
||||||
{roster, Item, Ver}.
|
{roster, Items, Ver}.
|
||||||
|
|
||||||
decode_roster_els([], Item) -> lists:reverse(Item);
|
decode_roster_els([], Items) -> lists:reverse(Items);
|
||||||
decode_roster_els([{xmlel, <<"item">>, _attrs, _} = _el
|
decode_roster_els([{xmlel, <<"item">>, _attrs, _} = _el
|
||||||
| _els],
|
| _els],
|
||||||
Item) ->
|
Items) ->
|
||||||
_xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
|
_xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
|
||||||
if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
|
if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
|
||||||
decode_roster_els(_els,
|
decode_roster_els(_els,
|
||||||
[decode_roster_item(_el) | Item]);
|
[decode_roster_item(_el) | Items]);
|
||||||
true -> decode_roster_els(_els, Item)
|
true -> decode_roster_els(_els, Items)
|
||||||
end;
|
end;
|
||||||
decode_roster_els([_ | _els], Item) ->
|
decode_roster_els([_ | _els], Items) ->
|
||||||
decode_roster_els(_els, Item).
|
decode_roster_els(_els, Items).
|
||||||
|
|
||||||
decode_roster_attrs([{<<"ver">>, _val} | _attrs],
|
decode_roster_attrs([{<<"ver">>, _val} | _attrs],
|
||||||
_Ver) ->
|
_Ver) ->
|
||||||
@ -1290,15 +1290,15 @@ decode_roster_attrs([_ | _attrs], Ver) ->
|
|||||||
decode_roster_attrs([], Ver) ->
|
decode_roster_attrs([], Ver) ->
|
||||||
decode_roster_attr_ver(Ver).
|
decode_roster_attr_ver(Ver).
|
||||||
|
|
||||||
encode_roster({roster, Item, Ver}, _xmlns_attrs) ->
|
encode_roster({roster, Items, Ver}, _xmlns_attrs) ->
|
||||||
_els = 'encode_roster_$item'(Item, []),
|
_els = 'encode_roster_$items'(Items, []),
|
||||||
_attrs = encode_roster_attr_ver(Ver, _xmlns_attrs),
|
_attrs = encode_roster_attr_ver(Ver, _xmlns_attrs),
|
||||||
{xmlel, <<"query">>, _attrs, _els}.
|
{xmlel, <<"query">>, _attrs, _els}.
|
||||||
|
|
||||||
'encode_roster_$item'([], _acc) -> _acc;
|
'encode_roster_$items'([], _acc) -> _acc;
|
||||||
'encode_roster_$item'([Item | _els], _acc) ->
|
'encode_roster_$items'([Items | _els], _acc) ->
|
||||||
'encode_roster_$item'(_els,
|
'encode_roster_$items'(_els,
|
||||||
[encode_roster_item(Item, []) | _acc]).
|
[encode_roster_item(Items, []) | _acc]).
|
||||||
|
|
||||||
decode_roster_attr_ver(undefined) -> undefined;
|
decode_roster_attr_ver(undefined) -> undefined;
|
||||||
decode_roster_attr_ver(_val) -> _val.
|
decode_roster_attr_ver(_val) -> _val.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
%% Created automatically by XML generator (xml_gen.erl)
|
%% Created automatically by XML generator (xml_gen.erl)
|
||||||
%% Source: xmpp_codec.spec
|
%% Source: xmpp_codec.spec
|
||||||
%% Date: Fri, 14 Jun 2013 16:48:12 GMT
|
%% Date: Sat, 15 Jun 2013 09:36:14 GMT
|
||||||
|
|
||||||
-record(last, {seconds, text}).
|
-record(last, {seconds, text}).
|
||||||
|
|
||||||
@ -10,7 +10,7 @@
|
|||||||
-record(roster_item,
|
-record(roster_item,
|
||||||
{jid, name, groups = [], subscription = none, ask}).
|
{jid, name, groups = [], subscription = none, ask}).
|
||||||
|
|
||||||
-record(roster, {item = [], ver}).
|
-record(roster, {items = [], ver}).
|
||||||
|
|
||||||
-record(privacy_item,
|
-record(privacy_item,
|
||||||
{order, action, type, value, stanza}).
|
{order, action, type, value, stanza}).
|
||||||
|
@ -66,9 +66,9 @@
|
|||||||
{roster,
|
{roster,
|
||||||
#elem{name = <<"query">>,
|
#elem{name = <<"query">>,
|
||||||
xmlns = <<"jabber:iq:roster">>,
|
xmlns = <<"jabber:iq:roster">>,
|
||||||
result = {roster, '$item', '$ver'},
|
result = {roster, '$items', '$ver'},
|
||||||
attrs = [#attr{name = <<"ver">>}],
|
attrs = [#attr{name = <<"ver">>}],
|
||||||
refs = [#ref{name = roster_item, label = '$item'}]}}.
|
refs = [#ref{name = roster_item, label = '$items'}]}}.
|
||||||
|
|
||||||
{privacy_message, #elem{name = <<"message">>, xmlns = <<"jabber:iq:privacy">>,
|
{privacy_message, #elem{name = <<"message">>, xmlns = <<"jabber:iq:privacy">>,
|
||||||
result = message}}.
|
result = message}}.
|
||||||
|
Loading…
Reference in New Issue
Block a user