]> granicus.if.org Git - ejabberd/commitdiff
*** empty log message ***
authorAlexey Shchepin <alexey@process-one.net>
Wed, 1 Jan 2003 19:54:44 +0000 (19:54 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Wed, 1 Jan 2003 19:54:44 +0000 (19:54 +0000)
SVN Revision: 24

src/ejabberd_auth.erl
src/ejabberd_local.erl
src/ejabberd_sm.erl
src/mod_disco.erl [new file with mode: 0644]
src/xml.erl

index 86b6d3b49d94aebc8d2f4ec9c9a3a90d9f2f08c5..63d136a2f711b6cd8dbdb154d590f4edc1330824 100644 (file)
@@ -23,7 +23,8 @@
         try_register/2]).
 
 %% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
+       dirty_get_registered_users/0]).
 
 -record(state, {}).
 
@@ -158,3 +159,6 @@ try_register(User, Password) ->
         end,
     mnesia:transaction(F).
 
+dirty_get_registered_users() ->
+    mnesia:dirty_all_keys(passwd).
+
index b75ffe08c12cce4586a356133e429aa139626d24..c42a8a019f181cf96d5b3f949e91ac31dacbf7d7 100644 (file)
@@ -22,13 +22,14 @@ start() ->
     register(ejabberd_local, spawn(ejabberd_local, init, [])),
     mod_register:start(),
     mod_roster:start(),
+    mod_disco:start(),
     ok.
 
 init() ->
     MyDomain = ?MYNAME,
     ejabberd_router:register_local_route(MyDomain),
     loop(#state{mydomain = MyDomain,
-               iqtable = ets:new(iqtable, [])}).
+               iqtable = ets:new(local_iqtable, [named_table])}).
 
 loop(State) ->
     receive
@@ -37,6 +38,7 @@ loop(State) ->
            loop(State);
        {register_iq_handler, XMLNS, Module, Function} ->
            ets:insert(State#state.iqtable, {XMLNS, Module, Function}),
+           mod_disco:register_feature(XMLNS),
            loop(State)
     end.
 
index 9ca4168016dcd7d25bb40813da17476515f7e686..8c092eb39bf3ec3ce8abb31630334af0e7466e59 100644 (file)
@@ -13,7 +13,9 @@
 -export([start/0, init/0, open_session/2, close_session/2,
         get_user_resources/1,
         set_presence/3,
-        unset_presence/2]).
+        unset_presence/2,
+        dirty_get_sessions_list/0,
+        register_iq_handler/3]).
 
 -include_lib("mnemosyne/include/mnemosyne.hrl").
 -include("ejabberd.hrl").
@@ -41,6 +43,7 @@ init() ->
                         {attributes, record_info(fields, presence)}]),
     mnesia:add_table_index(presence, user),
     mnesia:subscribe(system),
+    ets:new(sm_iqtable, [named_table]),
     loop().
 
 loop() ->
@@ -61,6 +64,9 @@ loop() ->
        {route, From, To, Packet} ->
            do_route(From, To, Packet),
            loop();
+       {register_iq_handler, XMLNS, Module, Function} ->
+           ets:insert(sm_iqtable, {XMLNS, Module, Function}),
+           loop();
        _ ->
            loop()
     end.
@@ -231,6 +237,7 @@ do_route(From, To, Packet) ->
                                           Packet}
                    end;
                "iq" ->
+                   process_iq(From, To, Packet),
                    % TODO
                    ok;
                "broadcast" ->
@@ -313,3 +320,41 @@ get_user_present_resources(User) ->
            []
     end.
 
+dirty_get_sessions_list() ->
+    mnesia:dirty_all_keys(session).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+process_iq(From, To, Packet) ->
+    IQ = jlib:iq_query_info(Packet),
+    case IQ of
+       {iq, ID, Type, XMLNS, SubEl} ->
+           case ets:lookup(sm_iqtable, XMLNS) of
+               [{_, Module, Function}] ->
+                   ResIQ = apply(Module, Function, [From, To, IQ]),
+                   if
+                       ResIQ /= ignore ->
+                           ejabberd_router ! {route,
+                                              To,
+                                              From,
+                                              jlib:iq_to_xml(ResIQ)};
+                       true ->
+                           ok
+                   end;
+               [] ->
+                   Err = jlib:make_error_reply(
+                           Packet, "501", "Not Implemented"),
+                   ejabberd_router ! {route, To, From, Err}
+           end;
+       reply ->
+           ok;
+       _ ->
+           Err = jlib:make_error_reply(Packet, "400", "Bad Request"),
+           ejabberd_router ! {route, To, From, Err},
+           ok
+    end.
+
+register_iq_handler(XMLNS, Module, Fun) ->
+    ejabberd_sm ! {register_iq_handler, XMLNS, Module, Fun}.
+
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
new file mode 100644 (file)
index 0000000..16512dd
--- /dev/null
@@ -0,0 +1,202 @@
+%%%----------------------------------------------------------------------
+%%% File    : mod_disco.erl
+%%% Author  : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : 
+%%% Created :  1 Jan 2003 by Alexey Shchepin <alex@alex.sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_disco).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start/0, init/0,
+        process_local_iq_items/3,
+        process_local_iq_info/3,
+        process_sm_iq_items/3,
+        process_sm_iq_info/3,
+        register_feature/1]).
+
+-include("ejabberd.hrl").
+
+-define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items").
+-define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info").
+
+-define(EMPTY_INFO_RESULT,
+       {iq, ID, result, XMLNS, [{xmlelement, "query",
+                                 [{"xmlns", ?NS_DISCO_INFO}], []}]}).
+
+start() ->
+    ejabberd_local:register_iq_handler(?NS_DISCO_ITEMS,
+                                      ?MODULE, process_local_iq_items),
+    ejabberd_local:register_iq_handler(?NS_DISCO_INFO,
+                                      ?MODULE, process_local_iq_info),
+    ejabberd_sm:register_iq_handler(?NS_DISCO_ITEMS,
+                                   ?MODULE, process_sm_iq_items),
+    ejabberd_sm:register_iq_handler(?NS_DISCO_INFO,
+                                   ?MODULE, process_sm_iq_info),
+    register_feature("iq"),
+    register_feature("presence"),
+    register_feature("presence-invisible"),
+    ok.
+
+init() ->
+    ok.
+
+register_feature(Feature) ->
+    catch ets:new(disco_features, [named_table, ordered_set, public]),
+    ets:insert(disco_features, {Feature}).
+
+process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
+                                           [{"code", "405"}],
+                                           [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           case xml:get_tag_attr_s("node", SubEl) of
+               "" ->
+                   Domains = [],
+                   {iq, ID, result, XMLNS,
+                    [{xmlelement,
+                      "query",
+                      [{"xmlns", ?NS_DISCO_ITEMS}],
+                      Domains ++
+                      [{xmlelement, "item",
+                        [{"jid", jlib:jid_to_string(To)},
+                         {"name", "Online Users"},
+                         {"node", "online users"}], []},
+                       {xmlelement, "item",
+                        [{"jid", jlib:jid_to_string(To)},
+                         {"name", "All Users"},
+                         {"node", "all users"}], []}]
+                     }]};
+               "online users" ->
+                   {iq, ID, result, XMLNS,
+                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
+                      get_online_users()
+                     }]};
+               "all users" ->
+                   {iq, ID, result, XMLNS,
+                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
+                      get_all_users()
+                     }]};
+               _ ->
+                   {iq, ID, error, XMLNS,
+                    [SubEl, {xmlelement, "error",
+                             [{"code", "501"}],
+                             [{xmlcdata, "Not Implemented"}]}]}
+           end
+    end.
+
+
+process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
+                                           [{"code", "405"}],
+                                           [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           case xml:get_tag_attr_s("node", SubEl) of
+               "" ->
+                   Features = lists:map(fun feature_to_xml/1,
+                                        ets:tab2list(disco_features)),
+                   {iq, ID, result, XMLNS, [{xmlelement,
+                                             "query",
+                                             [{"xmlns", ?NS_DISCO_INFO}],
+                                             [{xmlelement, "identity",
+                                               [{"category", "service"},
+                                                {"type", "jabber"},
+                                                {"name", "ejabberd"}], []}] ++
+                                             Features
+                                            }]};
+               "online users" -> ?EMPTY_INFO_RESULT;
+               "all users" -> ?EMPTY_INFO_RESULT;
+               _ ->
+                   {iq, ID, error, XMLNS,
+                    [SubEl, {xmlelement, "error",
+                             [{"code", "501"}],
+                             [{xmlcdata, "Not Implemented"}]}]}
+           end
+    end.
+
+
+feature_to_xml({Feature}) ->
+    {xmlelement, "feature", [{"var", Feature}], []}.
+
+
+get_online_users() ->
+    case catch ejabberd_sm:dirty_get_sessions_list() of
+       {'EXIT', Reason} ->
+           [];
+       URs ->
+           lists:map(fun({U, R}) ->
+                             {xmlelement, "item",
+                              [{"jid", U ++ "@" ++ ?MYNAME ++ "/" ++ R},
+                               {"name", U}], []}
+                     end, lists:sort(URs))
+    end.
+
+get_all_users() ->
+    case catch ejabberd_auth:dirty_get_registered_users() of
+       {'EXIT', Reason} ->
+           [];
+       Users ->
+           lists:map(fun(U) ->
+                             {xmlelement, "item",
+                              [{"jid", U ++ "@" ++ ?MYNAME},
+                               {"name", U}], []}
+                     end, lists:sort(Users))
+    end.
+
+
+process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    {User, _, _} = To,
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
+                                           [{"code", "405"}],
+                                           [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           case xml:get_tag_attr_s("node", SubEl) of
+               "" ->
+                   {iq, ID, result, XMLNS,
+                    [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}],
+                      get_user_resources(User)
+                     }]};
+               _ ->
+                   {iq, ID, error, XMLNS,
+                    [SubEl, {xmlelement, "error",
+                             [{"code", "501"}],
+                             [{xmlcdata, "Not Implemented"}]}]}
+           end
+    end.
+
+
+process_sm_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
+                                           [{"code", "405"}],
+                                           [{xmlcdata, "Not Allowed"}]}]};
+       get ->
+           case xml:get_tag_attr_s("node", SubEl) of
+               "" -> ?EMPTY_INFO_RESULT;
+               _ ->
+                   {iq, ID, error, XMLNS,
+                    [SubEl, {xmlelement, "error",
+                             [{"code", "501"}],
+                             [{xmlcdata, "Not Implemented"}]}]}
+           end
+    end.
+
+
+
+get_user_resources(User) ->
+    Rs = ejabberd_sm:get_user_resources(User),
+    lists:map(fun(R) ->
+                     {xmlelement, "item",
+                      [{"jid", User ++ "@" ++ ?MYNAME ++ "/" ++ R},
+                       {"name", User}], []}
+             end, lists:sort(Rs)).
+
index 3bdcb62f7563d5355265b9ac4bf843fab4c22a36..171607361c9e9d00a860f12124a65a74c4890469 100644 (file)
@@ -12,7 +12,8 @@
 
 -export([element_to_string/1, crypt/1, remove_cdata/1,
         get_cdata/1, get_tag_cdata/1,
-        get_attr/2, get_attr_s/2]).
+        get_attr/2, get_attr_s/2,
+        get_tag_attr/2, get_tag_attr_s/2]).
 
 element_to_string(El) ->
     case El of
@@ -93,4 +94,9 @@ get_attr_s(AttrName, Attrs) ->
            ""
     end.
 
+get_tag_attr(AttrName, {xmlelement, Name, Attrs, Els}) ->
+    get_attr(AttrName, Attrs).
+
+get_tag_attr_s(AttrName, {xmlelement, Name, Attrs, Els}) ->
+    get_attr_s(AttrName, Attrs).