Permalink
Browse files

jabber plugin refactoring, first step: use dyndata instead of process…

… dictionary
  • Loading branch information...
1 parent 583ea5e commit ebe284ce0783e0e089179d82cc4c67ad00594a63 @nniclausse nniclausse committed Aug 23, 2012
View
@@ -24,7 +24,14 @@
-vc('$Id$ ').
-author('nicolas.niclausse@niclux.org').
--record(jabber_dyndata, {id, regexp}).
+-record(jabber_session, { }).
+
+-record(jabber_dyndata, {id,
+ regexp,
+ user_server,
+ username,
+ passwd,
+ domain}).
-record(jabber, {dest,
size,
@@ -52,7 +59,8 @@
resource,
node_type,
subid,
- version %% 1.0 or "legacy", used by type=connect
+ version, %% 1.0 or "legacy", used by type=connect
+ prefix %% username prefix
}).
-define(setroster_intensity, 1/(ts_utils:get_val(setroster)*1000)).
@@ -73,63 +73,46 @@ auth_sasl_test()->
Res = << "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' >AGp1bGlldAByMG0zMG15cjBtMzA=</auth>" >>,
?assertMatch(Res, ts_jabber_common:auth_sasl("juliet","r0m30myr0m30","PLAIN")).
-choose_id_user_test()->
- ?assertEqual({user_defined,"user","pwd"}, ts_jabber:choose_or_cache_user_id(user_defined,"user","pwd")).
-choose_id_user1_test()->
- ts_jabber:choose_or_cache_user_id(user_defined,"user","pwd"),
- ?assertEqual({user_defined,"user","pwd"}, ts_jabber:choose_or_cache_user_id(0,"user","pwd")).
-choose_id2_test()->
- erase(xmpp_user_id),
+add_dynparams_test()->
ts_user_server:start(),
ts_user_server:reset(100),
- ?assertEqual({1,"user","pwd"}, ts_jabber:choose_or_cache_user_id(0,"user","pwd")).
-choose_id3_test()->
- erase(xmpp_user_id),
- ts_jabber:choose_or_cache_user_id(0,"user","pwd"),
- ?assertEqual({2,"user","pwd"}, ts_jabber:choose_or_cache_user_id(0,"user","pwd")).
-
-add_dynparams_test()->
- erase(xmpp_user_id),
- Session = #jabber{id=0,username="foo",passwd="bar",domain={domain,"localdomain"}},
- ?assertEqual(Session#jabber{id=3,user_server=default,domain="localdomain"}, ts_jabber:add_dynparams(true,[],Session,"localhost")).
+ Session = #jabber{id=0,prefix="foo",username="foo",passwd="bar",domain={domain,"localdomain"}},
+ JDD=#jabber_dyndata{},
+ ?assertEqual(Session#jabber{id=1,username="foo1",passwd="bar1",user_server=default,domain="localdomain"}, ts_jabber:add_dynparams(true,#dyndata{proto=JDD},Session,"localhost")).
add_dynparams2_test()->
- Session = #jabber{id=0,username="foo",passwd="bar",domain={domain,"localdomain"}},
- ?assertEqual(Session#jabber{id=3,user_server=default,domain="localdomain"}, ts_jabber:add_dynparams(true,[],Session,"localhost")).
+ Session = #jabber{id=0,prefix="foo",username="foo",passwd="bar",domain={domain,"localdomain"}},
+ ?assertEqual(Session#jabber{id=2,username="foo2",passwd="bar2",user_server=default,domain="localdomain"}, ts_jabber:add_dynparams(true,#dyndata{proto=#jabber_dyndata{}},Session,"localhost")).
get_message_test()->
- erase(xmpp_user_id),
ts_msg_server:start(),
- Session = #jabber{id=0,username="foo",type='auth_set_plain',passwd="bar",domain={domain,"localdomain"},resource="tsung"},
- Req=ts_jabber:add_dynparams(false,[],Session,"localhost"),
- RepOK={<<"<iq id='1' type='set' ><query xmlns='jabber:iq:auth'><username>foo4</username><resource>tsung</resource><password>bar4</password></query></iq>" >>,undefined},
+ Session = #jabber{id=0,prefix="foo",username="foo",type='auth_set_plain',passwd="bar",domain={domain,"localdomain"},resource="tsung"},
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
+ RepOK={<<"<iq id='1' type='set' ><query xmlns='jabber:iq:auth'><username>foo3</username><resource>tsung</resource><password>bar3</password></query></iq>" >>,undefined},
Rep=ts_jabber:get_message(Req,#state_rcv{}),
?assertEqual(RepOK,Rep ).
get_message2_test()->
- erase(xmpp_user_id),
Session = #jabber{id=user_defined,username="foo",type='auth_set_plain',passwd="bar",domain={domain,"localdomain"},resource="tsung"},
- Req=ts_jabber:add_dynparams(false,[],Session,"localhost"),
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
RepOK={<<"<iq id='2' type='set' ><query xmlns='jabber:iq:auth'><username>foo</username><resource>tsung</resource><password>bar</password></query></iq>" >>,undefined},
Rep=ts_jabber:get_message(Req,#state_rcv{}),
?assertEqual(RepOK,Rep ).
pubsub_unsubscribe_test()->
- erase(xmpp_user_id),
ts_msg_server:start(),
ts_user_server:reset(1),
- Session = #jabber{id=0,username="foo",type='pubsub:unsubscribe',passwd="bar",domain={domain,"localdomain"},dest=random, node="node", pubsub_service="mypubsub", subid="myid",resource="tsung"},
- Req=ts_jabber:add_dynparams(false,[],Session,"localhost"),
- RepOK= << "<iq to='mypubsub' type='set' id='3'><pubsub xmlns='http://jabber.org/protocol/pubsub'><unsubscribe node='/home/localdomain/2/node' jid='foo1@localdomain' subid='myid'/></pubsub></iq>" >>,
+ Session = #jabber{id=0,prefix="foo",username="foo",type='pubsub:unsubscribe',passwd="bar",domain={domain,"localdomain"},dest=random, node="node", pubsub_service="mypubsub", subid="myid",resource="tsung"},
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
+ RepOK= << "<iq to='mypubsub' type='set' id='3'><pubsub xmlns='http://jabber.org/protocol/pubsub'><unsubscribe node='/home/localdomain/foo2/node' jid='foo1@localdomain' subid='myid'/></pubsub></iq>" >>,
{Rep,_}=ts_jabber:get_message(Req,#state_rcv{}),
?assertEqual(RepOK,Rep ).
connect_legacy_test()->
- erase(xmpp_user_id),
ts_msg_server:start(),
ts_user_server:reset(1),
- Session = #jabber{id=0,username="foo",type='connect',passwd="bar",domain={domain,"localdomain"},resource="tsung", version="legacy"},
- Req=ts_jabber:add_dynparams(false,[],Session,"localhost"),
+ Session = #jabber{id=0,prefix="foo",username="foo",type='connect',passwd="bar",domain={domain,"localdomain"},resource="tsung", version="legacy"},
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
RepOK= <<"<?xml version='1.0'?><stream:stream id='4' to='localdomain' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>" >>,
{Rep,_} = ts_jabber:get_message(Req,#state_rcv{}),
?assertEqual(RepOK,Rep).
@@ -138,22 +121,20 @@ connect_xmpp_test()->
erase(xmpp_user_id),
ts_msg_server:start(),
ts_user_server:reset(1),
- Session = #jabber{id=0,username="foo",type='connect',passwd="bar",domain={domain,"localdomain"},resource="tsung", version="1.0"},
- Req=ts_jabber:add_dynparams(false,[],Session,"localhost"),
+ Session = #jabber{id=0,prefix="foo",username="foo",type='connect',passwd="bar",domain={domain,"localdomain"},resource="tsung", version="1.0"},
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
RepOK= <<"<?xml version='1.0'?><stream:stream id='5' to='localdomain' xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams'>" >>,
{Rep,_} = ts_jabber:get_message(Req,#state_rcv{}),
?assertEqual(RepOK,Rep).
-choose_id_limit_test()->
- ts_user_server:reset(3),
- erase(xmpp_user_id),
- ts_jabber:choose_or_cache_user_id(0,"user","pwd"),
- erase(xmpp_user_id),
- ts_jabber:choose_or_cache_user_id(0,"user","pwd"),
- erase(xmpp_user_id),
- ts_jabber:choose_or_cache_user_id(0,"user","pwd"),
- erase(xmpp_user_id),
- ?assertExit(no_free_userid, ts_jabber:choose_or_cache_user_id(0,"user","pwd")).
+
+pubsub_subscribe_test()->
+ ts_user_server:reset(1),
+ Session = #jabber{id=0,prefix="foo",dest="foo2",username="foo",type='pubsub:subscribe',passwd="bar",domain={domain,"localdomain"},node="node", pubsub_service="mypubsub", resource="tsung"},
+ Req=ts_jabber:add_dynparams(false,#dyndata{proto=#jabber_dyndata{}},Session,"localhost"),
+ RepOK= << "<iq to='mypubsub' type='set' id='6'><pubsub xmlns='http://jabber.org/protocol/pubsub'><subscribe node='/home/localdomain/foo2/node' jid='foo1@localdomain'/></pubsub></iq>" >>,
+ {Rep,_}=ts_jabber:get_message(Req,#state_rcv{}),
+ ?assertEqual(RepOK,Rep ).
myset_env()->
myset_env(0).
@@ -10,7 +10,7 @@
-compile(export_all).
-include("ts_http.hrl").
--include("ts_profile.hrl").
+-include("ts_macros.hrl").
-include_lib("eunit/include/eunit.hrl").
-import(ts_http_common,[parse_req/1, parse_req/2]).
View
@@ -60,7 +60,7 @@ session_defaults() ->
%% @doc We need to decode buffer (remove chunks, decompress ...) for
%% matching or dyn_variables
%% @end
-decode_buffer(Buffer,#jabber{}) ->
+decode_buffer(Buffer,#jabber_session{}) ->
Buffer. % nothing to do for jabber
%%----------------------------------------------------------------------
@@ -69,7 +69,7 @@ decode_buffer(Buffer,#jabber{}) ->
%% Returns: record or []
%%----------------------------------------------------------------------
new_session() ->
- #jabber{}. %FIXME: we should use another record (#jabber_session for ex.)
+ #jabber_session{}.
%%----------------------------------------------------------------------
%% Function: get_message/1
%% Purpose: Build a message/request
@@ -182,44 +182,59 @@ parse_config(Element, Conf) ->
%% if we are testing a single domain (the default case), we change from {domain,D}.
%% to the specified domain (D). If {vhost,FileId}, we choose a domain from that file
%% and set it.
-add_dynparams(Subst,DynData, Param =#jabber{id=OldId,username=OldUser,passwd=OldPasswd, domain={domain,Domain}}, Host) ->
- {Id,User,Pwd} = choose_or_cache_user_id(OldId,OldUser,OldPasswd),
- add_dynparams(Subst,DynData, Param#jabber{id=Id,username=User,passwd=Pwd,domain=Domain, user_server=default},Host);
+%% handle domain (first request in session)
+add_dynparams(Subst,DynData=#dyndata{proto=JDynData}, Param=#jabber{domain={domain,Domain}}, Host) when JDynData#jabber_dyndata.domain == undefined ->
+ NewJDynData = JDynData#jabber_dyndata{domain=Domain, user_server=default},
+ add_dynparams(Subst,DynData#dyndata{proto=NewJDynData}, Param,Host);
-add_dynparams(Subst,DynData,Param =#jabber{id=OldId, username=OldUser,passwd=OldPasswd, domain={vhost,FileId}}, Host) ->
- {Id,User,Pwd} = choose_or_cache_user_id(OldId,OldUser,OldPasswd),
+add_dynparams(Subst,DynData=#dyndata{proto=JDynData}, Param =#jabber{domain={vhost,FileId}}, Host) when JDynData#jabber_dyndata.domain == undefined->
{Domain,UserServer} = choose_domain(FileId),
- add_dynparams(Subst,DynData, Param#jabber{id=Id,username=User, passwd=Pwd,
- domain=Domain,
- user_server=UserServer},Host);
-add_dynparams(_Subst,[], Param, _Host) ->
- Param;
-add_dynparams(false,#dyndata{proto=_DynData}, Param, _Host) ->
+ NewJDynData = JDynData#jabber_dyndata{domain=Domain,user_server=UserServer},
+ add_dynparams(Subst,DynData#dyndata{proto=NewJDynData}, Param, Host);
+
+%% handle username/passwd (first request in session)
+add_dynparams(Subst,DynData=#dyndata{proto=JDynData}, Param=#jabber{id=user_defined,username=User,passwd=Passwd}, Host) when JDynData#jabber_dyndata.id == undefined->
+ NewJDynData = JDynData#jabber_dyndata{id=user_defined,username=User,passwd=Passwd},
+ add_dynparams(Subst,DynData#dyndata{proto=NewJDynData}, Param, Host);
+add_dynparams(Subst,DynData=#dyndata{proto=JDynData}, Param=#jabber{prefix=Prefix,passwd=Passwd}, Host) when JDynData#jabber_dyndata.id == undefined->
+ Id = case ts_user_server:get_idle(JDynData#jabber_dyndata.user_server) of
+ {error, no_free_userid} ->
+ ts_mon:add({ count, error_no_free_userid }),
+ exit(no_free_userid);
+ Val->
+ Val
+ end,
+ {NewUser,NewPasswd} = {username(Prefix,Id), password(Passwd,Id)},
+ NewJDynData = JDynData#jabber_dyndata{id=Id,username=NewUser,passwd=NewPasswd},
+ add_dynparams(Subst,DynData#dyndata{proto=NewJDynData}, Param,Host);
+
+
+%% regular case
+add_dynparams(Subst,DynData=#dyndata{proto=JDynData}, Param =#jabber{}, Host) ->
+ ?LOG("glop0~n",?DEB),
+ add_dynparams2(Subst,DynData, Param#jabber{id=JDynData#jabber_dyndata.id,
+ username=JDynData#jabber_dyndata.username,
+ passwd=JDynData#jabber_dyndata.passwd,
+ domain=JDynData#jabber_dyndata.domain,
+ user_server=JDynData#jabber_dyndata.user_server},Host).
+
+add_dynparams2(false,#dyndata{}, Param, _Host) ->
Param; %%ID substitution already done
-add_dynparams(true,#dyndata{proto=_JabDynData, dynvars=DynVars}, Param, _Host) ->
+add_dynparams2(true,#dyndata{proto=_JabDynData, dynvars=DynVars}, Param, _Host) ->
?DebugF("Subst in jabber msg (~p) with dyn vars ~p~n",[Param,DynVars]),
+ ?LOG("glop1~n",?DEB),
NewParam = subst(Param, DynVars),
+ ?LOG("glop2~n",?DEB),
updatejab(DynVars, NewParam).
%% This isn't ideal.. but currently there is no other way
%% than use side effects, as get_message/1 andn add_dynparams/4 aren't allowed
%% to return a new DynData, and so they can't modify the session state.
choose_domain(VHostFileId) ->
- case get(xmpp_vhost_domain) of
- undefined ->
- Domain = do_choose_domain(VHostFileId),
- UserServer = global:whereis_name(list_to_atom("us_"++Domain)),
- put(xmpp_vhost_domain,{Domain,UserServer}),
- {Domain,UserServer};
- X ->
- X
- end.
-
-do_choose_domain(VHostFileId) ->
- {ok,D} = ts_file_server:get_random_line(VHostFileId),
- D.
-
+ {ok,Domain} = ts_file_server:get_random_line(VHostFileId),
+ UserServer = global:whereis_name(list_to_atom("us_"++Domain)),
+ {Domain,UserServer}.
init_dynparams() ->
#dyndata{proto=#jabber_dyndata{}}.
@@ -231,60 +246,32 @@ init_dynparams() ->
%% ( add_dynparams/4 gets a copy of the request, from
%% the request we can check the file name, etc)
-
-
-choose_user_id(UserServer) ->
- case ts_user_server:get_idle(UserServer) of
- {error, no_free_userid} ->
- ts_mon:add({ count, error_no_free_userid }),
- exit(no_free_userid);
- Id->
- Id
- end.
-
-choose_or_cache_user_id(user_defined,User,Pwd) ->
- put(xmpp_user_id,{User,Pwd}),
- {user_defined, User,Pwd};
-
-choose_or_cache_user_id(_OldId,User,Pwd) ->
- case get(xmpp_user_id) of
- undefined ->
- Id = choose_user_id(default),
- put(xmpp_user_id,Id),
- {Id,User,Pwd};
- {DefinedUser,DefinedPwd} ->
- {user_defined, DefinedUser,DefinedPwd} ;
- Id ->
- {Id,User,Pwd}
- end.
-
-
%%----------------------------------------------------------------------
%% Function: subst/2
%% Purpose: Replace on the fly dynamic element
%%----------------------------------------------------------------------
-subst(Req=#jabber{type = Type}, DynData) when Type == 'muc:chat' ; Type == 'muc:join'; Type == 'muc:nick' ; Type == 'muc:exit' ->
- Req#jabber{nick = ts_search:subst(Req#jabber.nick, DynData),
- room = ts_search:subst(Req#jabber.room, DynData)};
-subst(Req=#jabber{type = Type}, DynData) when Type == 'pubsub:create' ; Type == 'pubsub:subscribe'; Type == 'pubsub:publish'; Type == 'pubsub:delete' ->
- Req#jabber{node = ts_search:subst(Req#jabber.node, DynData)};
-subst(Req=#jabber{type = Type}, DynData) when Type == 'pubsub:unsubscribe' ->
- NewNode=ts_search:subst(Req#jabber.node,DynData),
- NewSubId=ts_search:subst(Req#jabber.subid,DynData),
- put(xmpp_user_id,{NewNode,NewSubId}),% we need to keep the substitution for futures requests
- Req#jabber{node=NewNode,subid=NewSubId};
-
-subst(Req=#jabber{id=user_defined, username=Name,passwd=Pwd, data=Data}, DynData) ->
+subst(Req=#jabber{id=user_defined, username=Name,passwd=Pwd, data=Data, resource=Resource}, DynData) ->
NewUser = ts_search:subst(Name,DynData),
NewPwd = ts_search:subst(Pwd,DynData),
NewData = ts_search:subst(Data,DynData),
- put(xmpp_user_id,{NewUser,NewPwd}),% we need to keep the substitution for futures requests
- Req#jabber{username=NewUser,passwd=NewPwd,data=NewData};
+ subst2(Req#jabber{username=NewUser,passwd=NewPwd,data=NewData,resource=ts_search:subst(Resource,DynData)}, DynData);
subst(Req=#jabber{data=Data,resource=Resource}, DynData) ->
- Req#jabber{data=ts_search:subst(Data,DynData),resource=ts_search:subst(Resource,DynData)}.
+ subst2(Req#jabber{data=ts_search:subst(Data,DynData),resource=ts_search:subst(Resource,DynData)},DynData).
+subst2(Req=#jabber{type = Type}, DynData) when Type == 'muc:chat' ; Type == 'muc:join'; Type == 'muc:nick' ; Type == 'muc:exit' ->
+ Req#jabber{nick = ts_search:subst(Req#jabber.nick, DynData),
+ room = ts_search:subst(Req#jabber.room, DynData)};
+subst2(Req=#jabber{type = Type}, DynData) when Type == 'pubsub:create' ; Type == 'pubsub:subscribe'; Type == 'pubsub:publish'; Type == 'pubsub:delete' ->
+ Req#jabber{node = ts_search:subst(Req#jabber.node, DynData)};
+subst2(Req=#jabber{type = Type}, DynData) when Type == 'pubsub:unsubscribe' ->
+ NewNode=ts_search:subst(Req#jabber.node,DynData),
+ NewSubId=ts_search:subst(Req#jabber.subid,DynData),
+ Req#jabber{node=NewNode,subid=NewSubId};
+subst2(Req, DynData) ->
+ Req.
+
%%----------------------------------------------------------------------
%% Func: updatejab/2
%% takes dyn vars and adds them to jabber record
@@ -300,3 +287,22 @@ updatejab([{sid, Val}|Rest], Param)->
updatejab([_|Rest], Param)->
updatejab(Rest, Param).
+
+
+%%%----------------------------------------------------------------------
+%%% Func: username/2
+%%% Generate the username given a prefix and id
+%%%----------------------------------------------------------------------
+username(Prefix, DestId) when is_integer(DestId)->
+ Prefix ++ integer_to_list(DestId);
+username(Prefix, DestId) ->
+ Prefix ++ DestId.
+
+%%%----------------------------------------------------------------------
+%%% Func: password/1
+%%% Generate password for a given username
+%%%----------------------------------------------------------------------
+password(Prefix,Id) ->
+ username(Prefix,Id).
+
+
Oops, something went wrong.

0 comments on commit ebe284c

Please sign in to comment.