/[smecontribs]/rpms/ejabberd/contribs7/mod_shared_roster_ad.erl
ViewVC logotype

Contents of /rpms/ejabberd/contribs7/mod_shared_roster_ad.erl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download)
Tue Nov 25 16:20:11 2008 UTC (16 years ago) by slords
Branch: MAIN
CVS Tags: ejabberd-2_0_5-2_el4_sme, HEAD
Changes since 1.2: +0 -0 lines
Restore

1 %%%----------------------------------------------------------------------
2 %%% File : mod_shared_roster.erl
3 %%% Author : Alexey Shchepin <alexey@sevcom.net>
4 %%% Author : Stanislav Bogatyrev <realloc@realloc.spb.ru>
5 %%% Purpose : Shared roster management
6 %%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@sevcom.net>
7 %%% Id : $Id: mod_shared_roster.erl 24 2005-04-14 01:15:31Z alexey $
8 %%%----------------------------------------------------------------------
9
10 -module(mod_shared_roster_ad).
11 -author('alexey@sevcom.net').
12 -author('realloc@realloc.spb.ru').
13 -vsn('$Revision: 24 $ ').
14
15 -behaviour(gen_mod).
16
17 -export([start/2, stop/1,
18 get_user_roster/2,
19 get_subscription_lists/3,
20 get_jid_info/4,
21 in_subscription/5,
22 out_subscription/4,
23 list_groups/1,
24 create_group/2,
25 create_group/3,
26 delete_group/2,
27 get_group_opts/2,
28 set_group_opts/3,
29 get_group_users/2,
30 get_group_explicit_users/2,
31 add_user_to_group/3,
32 remove_user_from_group/3]).
33
34 -include("ejabberd.hrl").
35 -include("jlib.hrl").
36 -include("mod_roster.hrl").
37 -include("eldap/eldap.hrl").
38
39 -record(sr_group, {group_host, opts}).
40 -record(sr_user, {us, group_host}).
41
42 start(Host, _Opts) ->
43 mnesia:create_table(sr_group,
44 [{disc_copies, [node()]},
45 {attributes, record_info(fields, sr_group)}]),
46 mnesia:create_table(sr_user,
47 [{disc_copies, [node()]},
48 {type, bag},
49 {attributes, record_info(fields, sr_user)}]),
50 mnesia:add_table_index(sr_user, group_host),
51 ejabberd_hooks:add(roster_get, Host,
52 ?MODULE, get_user_roster, 70),
53 ejabberd_hooks:add(roster_in_subscription, Host,
54 ?MODULE, in_subscription, 30),
55 ejabberd_hooks:add(roster_out_subscription, Host,
56 ?MODULE, out_subscription, 30),
57 ejabberd_hooks:add(roster_get_subscription_lists, Host,
58 ?MODULE, get_subscription_lists, 70),
59 ejabberd_hooks:add(roster_get_jid_info, Host,
60 ?MODULE, get_jid_info, 70),
61
62 %ejabberd_hooks:add(remove_user, Host,
63 % ?MODULE, remove_user, 50),
64 LDAPServers = ejabberd_config:get_local_option({ad_servers, Host}),
65 RootDN = ejabberd_config:get_local_option({ad_rootdn, Host}),
66 Password = ejabberd_config:get_local_option({ad_password, Host}),
67 eldap:start_link("mod_shared_roster_ad", LDAPServers, 389, RootDN, Password).
68
69
70
71 stop(Host) ->
72 ejabberd_hooks:delete(roster_get, Host,
73 ?MODULE, get_user_roster, 70),
74 ejabberd_hooks:delete(roster_in_subscription, Host,
75 ?MODULE, in_subscription, 30),
76 ejabberd_hooks:delete(roster_out_subscription, Host,
77 ?MODULE, out_subscription, 30),
78 ejabberd_hooks:delete(roster_get_subscription_lists, Host,
79 ?MODULE, get_subscription_lists, 70),
80 ejabberd_hooks:delete(roster_get_jid_info, Host,
81 ?MODULE, get_jid_info, 70).
82 %ejabberd_hooks:delete(remove_user, Host,
83 % ?MODULE, remove_user, 50),
84
85
86 get_user_roster(Items, US) ->
87 {U, S} = US,
88 DisplayedGroups = get_user_displayed_groups_ad(US),
89 SRUsers =
90 lists:foldl(
91 fun(Group, Acc1) ->
92 lists:foldl(
93 fun(User, Acc2) ->
94 dict:append(User, Group, Acc2)
95 end, Acc1, get_group_users_ad(S, Group))
96 end, dict:new(), DisplayedGroups),
97 {NewItems1, SRUsersRest} =
98 lists:mapfoldl(
99 fun(Item, SRUsers1) ->
100 {_, _, {U1, S1, _}} = Item#roster.usj,
101 US1 = {U1, S1},
102 case dict:find(US1, SRUsers1) of
103 {ok, _GroupNames} ->
104 {Item#roster{subscription = both, ask = none},
105 dict:erase(US1, SRUsers1)};
106 error ->
107 {Item, SRUsers1}
108 end
109 end, SRUsers, Items),
110 SRItems = [#roster{usj = {U, S, {U1, S1, ""}},
111 us = US,
112 jid = {U1, S1, ""},
113 name = get_user_fn(U1,S1),
114 subscription = both,
115 ask = none,
116 groups = GroupNames} ||
117 {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)],
118 SRItems ++ NewItems1.
119
120 get_subscription_lists({F, T}, User, Server) ->
121 LUser = jlib:nodeprep(User),
122 LServer = jlib:nameprep(Server),
123 US = {LUser, LServer},
124 DisplayedGroups = get_user_displayed_groups_ad(US),
125 SRUsers =
126 lists:usort(
127 lists:flatmap(
128 fun(Group) ->
129 get_group_users_ad(LServer, Group)
130 end, DisplayedGroups)),
131 SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers],
132 {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}.
133
134 get_jid_info({Subscription, Groups}, User, Server, JID) ->
135 LUser = jlib:nodeprep(User),
136 LServer = jlib:nameprep(Server),
137 US = {LUser, LServer},
138 {U1, S1, _} = jlib:jid_tolower(JID),
139 US1 = {U1, S1},
140 DisplayedGroups = get_user_displayed_groups_ad(US),
141 SRUsers =
142 lists:foldl(
143 fun(Group, Acc1) ->
144 lists:foldl(
145 fun(User1, Acc2) ->
146 dict:append(
147 User1, Group, Acc2)
148 end, Acc1, get_group_users_ad(LServer, Group))
149 end, dict:new(), DisplayedGroups),
150 case dict:find(US1, SRUsers) of
151 {ok, GroupNames} ->
152 NewGroups = if
153 Groups == [] -> GroupNames;
154 true -> Groups
155 end,
156 {both, NewGroups};
157 error ->
158 {Subscription, Groups}
159 end.
160
161 in_subscription(Acc, User, Server, JID, Type) ->
162 process_subscription(in, User, Server, JID, Type, Acc).
163
164 out_subscription(User, Server, JID, Type) ->
165 process_subscription(out, User, Server, JID, Type, false).
166
167 process_subscription(Direction, User, Server, JID, _Type, Acc) ->
168 LUser = jlib:nodeprep(User),
169 LServer = jlib:nameprep(Server),
170 US = {LUser, LServer},
171 {U1, S1, _} = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
172 US1 = {U1, S1},
173 DisplayedGroups = get_user_displayed_groups_ad(US),
174 SRUsers =
175 lists:usort(
176 lists:flatmap(
177 fun(Group) ->
178 get_group_users_ad(LServer, Group)
179 end, DisplayedGroups)),
180 case lists:member(US1, SRUsers) of
181 true ->
182 case Direction of
183 in ->
184 {stop, false};
185 out ->
186 stop
187 end;
188 false ->
189 Acc
190 end.
191
192 list_groups(Host) ->
193 get_user_displayed_groups_ad({"",Host}).
194
195
196 create_group(Host, Group) ->
197 create_group(Host, Group, []).
198
199 create_group(Host, Group, Opts) ->
200 R = #sr_group{group_host = {Group, Host}, opts = Opts},
201 F = fun() ->
202 mnesia:write(R)
203 end,
204 mnesia:transaction(F).
205
206 delete_group(Host, Group) ->
207 F = fun() ->
208 mnesia:delete({sr_group, {Group, Host}})
209 end,
210 mnesia:transaction(F).
211
212 get_group_opts(Host, Group) ->
213 case catch mnesia:dirty_read(sr_group, {Group, Host}) of
214 [#sr_group{opts = Opts}] ->
215 Opts;
216 _ ->
217 error
218 end.
219
220 set_group_opts(Host, Group, Opts) ->
221 R = #sr_group{group_host = {Group, Host}, opts = Opts},
222 F = fun() ->
223 mnesia:write(R)
224 end,
225 mnesia:transaction(F).
226
227
228
229 get_user_groups(US) ->
230 Host = element(2, US),
231 case catch mnesia:dirty_read(sr_user, US) of
232 Rs when is_list(Rs) ->
233 [Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
234 _ ->
235 []
236 end ++ get_all_users_groups(Host).
237
238 is_group_enabled(Host, Group) ->
239 case catch mnesia:dirty_read(sr_group, {Group, Host}) of
240 [#sr_group{opts = Opts}] ->
241 not lists:member(disabled, Opts);
242 _ ->
243 false
244 end.
245
246 get_group_opt(Host, Group, Opt, Default) ->
247 case catch mnesia:dirty_read(sr_group, {Group, Host}) of
248 [#sr_group{opts = Opts}] ->
249 case lists:keysearch(Opt, 1, Opts) of
250 {value, {_, Val}} ->
251 Val;
252 false ->
253 Default
254 end;
255 _ ->
256 false
257 end.
258
259 get_group_users(Host, Group) ->
260 case get_group_opt(Host, Group, all_users, false) of
261 true ->
262 ejabberd_auth:get_vh_registered_users(Host);
263 false ->
264 []
265 end ++ get_group_explicit_users(Host, Group).
266
267 get_group_explicit_users(Host, Group) ->
268 case catch mnesia:dirty_index_read(
269 sr_user, {Group, Host}, #sr_user.group_host) of
270 Rs when is_list(Rs) ->
271 [R#sr_user.us || R <- Rs];
272 _ ->
273 []
274 end.
275
276 get_group_name(Host, Group) ->
277 get_group_opt(Host, Group, name, Group).
278
279 get_all_users_groups(Host) ->
280 lists:filter(
281 fun(Group) -> get_group_opt(Host, Group, all_users, false) end,
282 list_groups(Host)).
283
284 get_user_displayed_groups(US) ->
285 Host = element(2, US),
286 DisplayedGroups1 =
287 lists:usort(
288 lists:flatmap(
289 fun(Group) ->
290 case is_group_enabled(Host, Group) of
291 true ->
292 get_group_opt(Host, Group, displayed_groups, []);
293 false ->
294 []
295 end
296 end, get_user_groups(US))),
297 [Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)].
298
299
300
301
302 add_user_to_group(Host, US, Group) ->
303 R = #sr_user{us = US, group_host = {Group, Host}},
304 F = fun() ->
305 mnesia:write(R)
306 end,
307 mnesia:transaction(F).
308
309 remove_user_from_group(Host, US, Group) ->
310 R = #sr_user{us = US, group_host = {Group, Host}},
311 F = fun() ->
312 mnesia:delete_object(R)
313 end,
314 mnesia:transaction(F).
315
316
317
318 find_user_attr(User, Host) ->
319 Attr = ejabberd_config:get_local_option({ad_uidattr, Host}),
320 Filter = eldap:equalityMatch(Attr, User),
321 Base = ejabberd_config:get_local_option({ad_base, Host}),
322
323 case eldap:search("mod_shared_roster_ad",
324 [{base, Base},
325 {filter, Filter},
326 {attributes, []}]) of
327 #eldap_search_result{entries = [E | _]} ->
328 E;
329 _ ->
330 false
331 end.
332
333 get_user_displayed_groups_ad(US) ->
334 {_, Host} = US,
335 AdGroup = ejabberd_config:get_local_option({ad_group, Host}),
336 FilterGroup = eldap:equalityMatch("memberOf", AdGroup),
337 Base = ejabberd_config:get_local_option({ad_base, Host}),
338
339 case eldap:search("mod_shared_roster_ad",
340 [{base, Base},
341 {filter, FilterGroup},
342 {attributes, []}]) of
343 #eldap_search_result{entries = E} ->
344 lists:usort(lists:map(
345 fun(X) ->
346 case X of
347 #eldap_entry{attributes = Attributes} ->
348 ldap_get_value(Attributes,"department");
349 false ->
350 ""
351 end
352 end, E
353 ));
354
355 _ ->
356 []
357 end.
358
359 get_eldap_id(Host, Name) ->
360 atom_to_list(gen_mod:get_module_proc(Host, Name)).
361
362
363 get_group_users_ad(Host, Group) ->
364 Attr = ejabberd_config:get_local_option({ad_uidattr, Host}),
365 % AdGroup = ejabberd_config:get_local_option({ad_group, Host}),
366 FilterPerson = eldap:equalityMatch("objectCategory", "person"),
367 FilterComp = eldap:equalityMatch("objectClass", "computer"),
368 FilterHidden = eldap:equalityMatch("description", "hidden"),
369 % FilterGroup = eldap:equalityMatch("memberOf", AdGroup),
370 FilterDep = eldap:equalityMatch("department", Group),
371 FilterLive = eldap:equalityMatch("userAccountControl", "66050"),
372 FilterDef = eldap:present(Attr),
373 Filter = eldap:'and'([
374 FilterDef,
375 FilterPerson,
376 % FilterGroup,
377 FilterDep,
378 eldap:'not'(FilterComp),
379 eldap:'not'(FilterHidden),
380 eldap:'not'(FilterLive)]),
381 Base = ejabberd_config:get_local_option({ad_base, Host}),
382 case eldap:search(get_eldap_id(Host, ejabberd),
383 [{base, Base},
384 {filter, Filter},
385 {attributes, [Attr]}]) of
386 #eldap_search_result{entries = Es} ->
387 lists:flatmap(
388 fun(E) ->
389 case lists:keysearch(Attr, 1, E#eldap_entry.attributes) of
390 {value, {_, [U]}} ->
391 case jlib:nodeprep(U) of
392 error ->
393 [];
394 LU ->
395 [{LU, Host}]
396 end;
397 _ ->
398 []
399 end
400 end, Es);
401 _ ->
402 []
403 end.
404
405
406
407
408
409 ldap_get_value(E,Attribute) ->
410 case lists:filter(fun({A,_}) ->
411 string:equal(A,Attribute)
412 end,E) of
413 [{_,[Value|_]}] ->
414 Value;
415 _ ->
416 none
417 end.
418
419 get_user_fn(User, Host) ->
420 case find_user_attr(User,Host) of
421 #eldap_entry{attributes = Attributes} ->
422 ldap_get_value(Attributes,"cn");
423
424 false ->
425 ""
426 end.
427
428

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed