mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
*** empty log message ***
SVN Revision: 27
This commit is contained in:
parent
cdc9b9f38d
commit
5755092b92
43
src/jlib.erl
43
src/jlib.erl
@ -25,7 +25,8 @@
|
||||
get_iq_namespace/1,
|
||||
iq_query_info/1,
|
||||
is_iq_request_type/1,
|
||||
iq_to_xml/1]).
|
||||
iq_to_xml/1,
|
||||
parse_xdata_submit/1]).
|
||||
|
||||
|
||||
%send_iq(From, To, ID, SubTags) ->
|
||||
@ -248,3 +249,43 @@ iq_to_xml({iq, ID, Type, _, SubEl}) ->
|
||||
end.
|
||||
|
||||
|
||||
parse_xdata_submit(El) ->
|
||||
{xmlelement, Name, Attrs, Els} = El,
|
||||
case xml:get_attr_s("type", Attrs) of
|
||||
"submit" ->
|
||||
lists:reverse(parse_xdata_fields(Els, []));
|
||||
_ ->
|
||||
invalid
|
||||
end.
|
||||
|
||||
parse_xdata_fields([], Res) ->
|
||||
Res;
|
||||
parse_xdata_fields([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
|
||||
case Name of
|
||||
"field" ->
|
||||
case xml:get_attr_s("var", Attrs) of
|
||||
"" ->
|
||||
parse_xdata_fields(Els, Res);
|
||||
Var ->
|
||||
Field =
|
||||
{Var, lists:reverse(parse_xdata_values(SubEls, []))},
|
||||
parse_xdata_fields(Els, [Field | Res])
|
||||
end;
|
||||
_ ->
|
||||
parse_xdata_fields(Els, Res)
|
||||
end;
|
||||
parse_xdata_fields([_ | Els], Res) ->
|
||||
parse_xdata_fields(Els, Res).
|
||||
|
||||
parse_xdata_values([], Res) ->
|
||||
Res;
|
||||
parse_xdata_values([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
|
||||
case Name of
|
||||
"value" ->
|
||||
Val = xml:get_cdata(SubEls),
|
||||
parse_xdata_values(Els, [Val | Res]);
|
||||
_ ->
|
||||
parse_xdata_values(Els, Res)
|
||||
end;
|
||||
parse_xdata_values([_ | Els], Res) ->
|
||||
parse_xdata_values(Els, Res).
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
-record(vcard_search, {user, fn, family, given, middle, nickname,
|
||||
bday, ctry, locality, email,
|
||||
bday, ctry="", locality="", email,
|
||||
orgname, orgunit}).
|
||||
-record(vcard, {user, vcard}).
|
||||
|
||||
@ -30,15 +30,17 @@ start() ->
|
||||
mnesia:create_table(vcard_search,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, vcard_search)}]),
|
||||
%mnesia:add_table_index(vcard_search, fn),
|
||||
%mnesia:add_table_index(vcard_search, n),
|
||||
%mnesia:add_table_index(vcard_search, nickname),
|
||||
%mnesia:add_table_index(vcard_search, bday),
|
||||
%mnesia:add_table_index(vcard_search, ctry),
|
||||
%mnesia:add_table_index(vcard_search, locality),
|
||||
%mnesia:add_table_index(vcard_search, email),
|
||||
%mnesia:add_table_index(vcard_search, orgname),
|
||||
%mnesia:add_table_index(vcard_search, orgunit),
|
||||
mnesia:add_table_index(vcard_search, fn),
|
||||
mnesia:add_table_index(vcard_search, family),
|
||||
mnesia:add_table_index(vcard_search, given),
|
||||
mnesia:add_table_index(vcard_search, middle),
|
||||
mnesia:add_table_index(vcard_search, nickname),
|
||||
mnesia:add_table_index(vcard_search, bday),
|
||||
mnesia:add_table_index(vcard_search, ctry),
|
||||
mnesia:add_table_index(vcard_search, locality),
|
||||
mnesia:add_table_index(vcard_search, email),
|
||||
mnesia:add_table_index(vcard_search, orgname),
|
||||
mnesia:add_table_index(vcard_search, orgunit),
|
||||
|
||||
|
||||
ejabberd_local:register_iq_handler(?NS_VCARD,
|
||||
@ -48,7 +50,7 @@ start() ->
|
||||
spawn(?MODULE, init, []).
|
||||
|
||||
init() ->
|
||||
ejabberd_router:register_local_route("ejud." ++ ?MYNAME),
|
||||
ejabberd_router:register_local_route("vjud." ++ ?MYNAME),
|
||||
loop().
|
||||
|
||||
loop() ->
|
||||
@ -131,24 +133,36 @@ set_vcard(LUser, VCARD) ->
|
||||
EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
|
||||
OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
|
||||
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
|
||||
|
||||
LFN = jlib:tolower(FN),
|
||||
LFamily = jlib:tolower(Family),
|
||||
LGiven = jlib:tolower(Given),
|
||||
LMiddle = jlib:tolower(Middle),
|
||||
LNickname = jlib:tolower(Nickname),
|
||||
LBDay = jlib:tolower(BDay),
|
||||
LEMail = jlib:tolower(EMail),
|
||||
LOrgName = jlib:tolower(OrgName),
|
||||
LOrgUnit = jlib:tolower(OrgUnit),
|
||||
|
||||
F = fun() ->
|
||||
mnesia:write(#vcard{user = LUser, vcard = VCARD}),
|
||||
mnesia:write(#vcard_search{user = LUser,
|
||||
fn = FN,
|
||||
family = Family,
|
||||
given = Given,
|
||||
middle = Middle,
|
||||
nickname = Nickname,
|
||||
bday = BDay,
|
||||
%ctry = CTRY,
|
||||
%locality = Locality,
|
||||
email = EMail,
|
||||
orgname = OrgName,
|
||||
orgunit = OrgUnit
|
||||
mnesia:write(#vcard_search{user = LUser,
|
||||
fn = LFN,
|
||||
family = LFamily,
|
||||
given = LGiven,
|
||||
middle = LMiddle,
|
||||
nickname = LNickname,
|
||||
bday = LBDay,
|
||||
%ctry = LCTRY,
|
||||
%locality = LLocality,
|
||||
email = LEMail,
|
||||
orgname = LOrgName,
|
||||
orgunit = LOrgUnit
|
||||
})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
|
||||
-define(FORM,
|
||||
[{xmlelement, "instructions", [],
|
||||
[{xmlcdata, "You need a x:data capable client to search"}]},
|
||||
@ -157,9 +171,42 @@ set_vcard(LUser, VCARD) ->
|
||||
{xmlelement, "instructions", [],
|
||||
[{xmlcdata, "Fill in fields to search "
|
||||
"for any matching Jabber User"}]},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "JID"},
|
||||
{"var", "jid"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Full Name"},
|
||||
{"var", "fn"}], []}
|
||||
{"var", "fn"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Name"},
|
||||
{"var", "given"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Middle Name"},
|
||||
{"var", "middle"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Family Name"},
|
||||
{"var", "family"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Nickname"},
|
||||
{"var", "nickname"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Birthday"},
|
||||
{"var", "bday"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Country"},
|
||||
{"var", "ctry"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "City"},
|
||||
{"var", "locality"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "email"},
|
||||
{"var", "email"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Organization Name"},
|
||||
{"var", "orgname"}], []},
|
||||
{xmlelement, "field", [{"type", "text-single"},
|
||||
{"label", "Organization Unit"},
|
||||
{"var", "orgunit"}], []}
|
||||
]}]).
|
||||
|
||||
|
||||
@ -177,10 +224,36 @@ do_route(From, To, Packet) ->
|
||||
{iq, ID, Type, ?NS_SEARCH, SubEl} ->
|
||||
case Type of
|
||||
set ->
|
||||
% TODO
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "501", "Not Implemented"),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
XDataEl = find_xdata_el(SubEl),
|
||||
case XDataEl of
|
||||
false ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, "400", "Bad Request"),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
XData = jlib:parse_xdata_submit(XDataEl),
|
||||
case XData of
|
||||
invalid ->
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
"400", "Bad Request"),
|
||||
ejabberd_router:route(To, From,
|
||||
Err);
|
||||
_ ->
|
||||
ResIQ =
|
||||
{iq, ID, result, ?NS_SEARCH,
|
||||
[{xmlelement,
|
||||
"query",
|
||||
[{"xmlns", ?NS_SEARCH}],
|
||||
[{xmlelement, "x",
|
||||
[{"xmlns", ?NS_XDATA},
|
||||
{"type", "result"}],
|
||||
search_result(XData)
|
||||
}]}]},
|
||||
ejabberd_router:route(
|
||||
To, From, jlib:iq_to_xml(ResIQ))
|
||||
end
|
||||
end;
|
||||
get ->
|
||||
ResIQ = {iq, ID, result, ?NS_SEARCH,
|
||||
[{xmlelement,
|
||||
@ -206,7 +279,7 @@ do_route(From, To, Packet) ->
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "directory"},
|
||||
{"type", "user"},
|
||||
{"name", "EJUD"}], []},
|
||||
{"name", "vCard User Search"}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_SEARCH}], []}
|
||||
]
|
||||
@ -237,3 +310,113 @@ do_route(From, To, Packet) ->
|
||||
end
|
||||
end.
|
||||
|
||||
find_xdata_el({xmlelement, Name, Attrs, SubEls}) ->
|
||||
find_xdata_el1(SubEls).
|
||||
|
||||
find_xdata_el1([]) ->
|
||||
false;
|
||||
find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
|
||||
case xml:get_attr_s("xmlns", Attrs) of
|
||||
?NS_XDATA ->
|
||||
{xmlelement, Name, Attrs, SubEls};
|
||||
_ ->
|
||||
find_xdata_el1(Els)
|
||||
end;
|
||||
find_xdata_el1([_ | Els]) ->
|
||||
find_xdata_el1(Els).
|
||||
|
||||
search_result(Data) ->
|
||||
[{xmlelement, "title", [], [{xmlcdata, "Users Search Results"}]},
|
||||
{xmlelement, "reported", [],
|
||||
[{xmlelement, "field", [{"label", "JID"}, {"var", "jid"}], []},
|
||||
{xmlelement, "field", [{"label", "Full Name"}, {"var", "fn"}], []},
|
||||
{xmlelement, "field", [{"label", "Name"}, {"var", "given"}], []},
|
||||
{xmlelement, "field", [{"label", "Middle Name"}, {"var", "middle"}], []},
|
||||
{xmlelement, "field", [{"label", "Family Name"}, {"var", "family"}], []},
|
||||
{xmlelement, "field", [{"label", "Nickname"}, {"var", "nickname"}], []},
|
||||
{xmlelement, "field", [{"label", "Birthday"}, {"var", "bday"}], []},
|
||||
{xmlelement, "field", [{"label", "Country"}, {"var", "ctry"}], []},
|
||||
{xmlelement, "field", [{"label", "City"}, {"var", "locality"}], []},
|
||||
{xmlelement, "field", [{"label", "email"}, {"var", "email"}], []},
|
||||
{xmlelement, "field", [{"label", "Organization Name"},
|
||||
{"var", "orgname"}], []},
|
||||
{xmlelement, "field", [{"label", "Organization Unit"},
|
||||
{"var", "orgunit"}], []}
|
||||
]}] ++ lists:map(fun record_to_item/1, search(Data)).
|
||||
|
||||
-define(FIELD(Var, Val),
|
||||
{xmlelement, "field", [{"var", Var}],
|
||||
[{xmlelement, "value", [],
|
||||
[{xmlcdata, Val}]}]}).
|
||||
|
||||
record_to_item(R) ->
|
||||
{xmlelement, "item", [],
|
||||
[
|
||||
?FIELD("jid", R#vcard_search.user ++ "@" ++ ?MYNAME),
|
||||
?FIELD("fn", R#vcard_search.fn),
|
||||
?FIELD("family", R#vcard_search.family),
|
||||
?FIELD("given", R#vcard_search.given),
|
||||
?FIELD("middle", R#vcard_search.middle),
|
||||
?FIELD("nickname", R#vcard_search.nickname),
|
||||
?FIELD("bday", R#vcard_search.bday),
|
||||
?FIELD("ctry", R#vcard_search.ctry),
|
||||
?FIELD("locality", R#vcard_search.locality),
|
||||
?FIELD("email", R#vcard_search.email),
|
||||
?FIELD("orgname", R#vcard_search.orgname),
|
||||
?FIELD("orgunit", R#vcard_search.orgunit)
|
||||
]
|
||||
}.
|
||||
|
||||
|
||||
search(Data) ->
|
||||
MatchSpec = make_matchspec(Data),
|
||||
F = fun() ->
|
||||
mnesia:match_object(MatchSpec)
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, Rs} ->
|
||||
Rs;
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
|
||||
make_matchspec(Data) ->
|
||||
GlobMatch = #vcard_search{user = '_',
|
||||
fn = '_',
|
||||
family = '_',
|
||||
given = '_',
|
||||
middle = '_',
|
||||
nickname = '_',
|
||||
bday = '_',
|
||||
ctry = '_',
|
||||
locality = '_',
|
||||
email = '_',
|
||||
orgname = '_',
|
||||
orgunit = '_'
|
||||
},
|
||||
Match = filter_fields(Data, GlobMatch),
|
||||
Match.
|
||||
|
||||
filter_fields([], Match) ->
|
||||
Match;
|
||||
filter_fields([{SVar, [Val]} | Ds], Match)
|
||||
when is_list(Val) and (Val /= "") ->
|
||||
NewMatch = case SVar of
|
||||
"jid" -> Match;
|
||||
"fn" -> Match#vcard_search{fn = Val};
|
||||
"family" -> Match#vcard_search{family = Val};
|
||||
"given" -> Match#vcard_search{given = Val};
|
||||
"middle" -> Match#vcard_search{middle = Val};
|
||||
"nickname" -> Match#vcard_search{nickname = Val};
|
||||
"bday" -> Match#vcard_search{bday = Val};
|
||||
"ctry" -> Match#vcard_search{ctry = Val};
|
||||
"locality" -> Match#vcard_search{locality = Val};
|
||||
"email" -> Match#vcard_search{email = Val};
|
||||
"orgname" -> Match#vcard_search{orgname = Val};
|
||||
"orgunit" -> Match#vcard_search{orgunit = Val};
|
||||
_ -> Match
|
||||
end,
|
||||
filter_fields(Ds, NewMatch);
|
||||
filter_fields([_ | Ds], Match) ->
|
||||
filter_fields(Ds, Match).
|
||||
|
Loading…
Reference in New Issue
Block a user