]> git.pld-linux.org Git - packages/ejabberd.git/blob - ejabberd-vcard-access-get.patch
- up to 2.1.12; vcard-access-get.patch needs update
[packages/ejabberd.git] / ejabberd-vcard-access-get.patch
1 diff --git a/doc/guide.tex b/doc/guide.tex
2 index 5de409d..ac3dba8 100644
3 --- a/doc/guide.tex
4 +++ b/doc/guide.tex
5 @@ -4052,6 +4052,17 @@ Options:
6  \begin{description}
7  \hostitem{vjud}
8  \iqdiscitem{\ns{vcard-temp}}
9 +\titem{access\_get}\ind{options!accessget} Access rule that defines
10 +  who is allowed to see vCard of local users.
11 +  If a rule returns `deny' on the requester
12 +  user name, that user cannot see vCards of local users.
13 +  By default anybody can see the vCards of local users.
14 +\titem{access\_set}\ind{options!accessset} Access rule that defines
15 +  who is allowed to modify his vCard.
16 +  If a rule returns `deny' on the requester
17 +  user name, that user cannot modify his vCard.
18 +  By default each local account can modify his own local vCard.
19 +  Notice that vCard of a user can only be edited by the user himself.
20  \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search
21    functionality is enabled or not
22    If disabled, the option \term{host} will be ignored and the
23 @@ -4128,6 +4142,11 @@ consists of the following \modvcardldap{}-specific options:
24  \begin{description}
25  \hostitem{vjud}
26  \iqdiscitem{\ns{vcard-temp}}
27 +\titem{access\_get}\ind{options!accessget} Access rule that defines
28 +  who is allowed to see vCard of local users.
29 +  If a rule returns `deny' on the requester
30 +  user name, that user cannot see vCards of local users.
31 +  By default anybody can see the vCards of local users.
32  \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search
33    functionality is enabled (value: \term{true}) or disabled (value:
34    \term{false}). If disabled, the option \term{host} will be ignored and the
35 @@ -4651,14 +4651,17 @@ Examples:
36   ]}.
37  \end{verbatim}
38  \item The second situation differs in a way that search results are not limited,
39 -  and that all virtual hosts will be searched instead of only the current one:
40 +  and that all virtual hosts will be searched instead of only the current one.
41 +  Also, vCards of local users can only be seen by Local users.
42  \begin{verbatim}
43 +{access, vcard_get, [{allow, local}]}.
44  {modules,
45   [
46    ...
47    {mod_vcard, [{search, true},
48                 {matches, infinity},
49 -               {allow_return_all, true}]},
50 +               {allow_return_all, true},
51 +               {access_get, vcard_get}]},
52    ...
53   ]}.
54  \end{verbatim}
55 diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
56 index 4384087..c54e8ea 100644
57 --- a/src/mod_vcard.erl
58 +++ b/src/mod_vcard.erl
59 @@ -174,7 +174,9 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
60      case Type of
61         set ->
62             #jid{user = User, lserver = LServer} = From,
63 -           case lists:member(LServer, ?MYHOSTS) of
64 +           Access = gen_mod:get_module_opt(LServer, ?MODULE, access_set, all),
65 +           case lists:member(LServer, ?MYHOSTS) andalso
66 +            (acl:match_rule(LServer, Access, From) == allow) of
67                 true ->
68                     set_vcard(User, LServer, SubEl),
69                     IQ#iq{type = result, sub_el = []};
70 @@ -183,19 +185,28 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
71             end;
72         get ->
73             #jid{luser = LUser, lserver = LServer} = To,
74 -           US = {LUser, LServer},
75 -           F = fun() ->
76 -                       mnesia:read({vcard, US})
77 -               end,
78 -           Els = case mnesia:transaction(F) of
79 -                     {atomic, Rs} ->
80 -                         lists:map(fun(R) ->
81 -                                           R#vcard.vcard
82 -                                   end, Rs);
83 -                     {aborted, _Reason} ->
84 -                         []
85 -                 end,
86 -           IQ#iq{type = result, sub_el = Els}
87 +           Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get, all),
88 +           case acl:match_rule(LServer, Access, From) of
89 +               allow ->
90 +                   Els = get_vcard(LUser, LServer),
91 +                   IQ#iq{type = result, sub_el = Els};
92 +               deny ->
93 +                   IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
94 +           end
95 +    end.
96 +
97 +get_vcard(LUser, LServer) ->
98 +    US = {LUser, LServer},
99 +    F = fun() ->
100 +               mnesia:read({vcard, US})
101 +       end,
102 +    case mnesia:transaction(F) of
103 +       {atomic, Rs} ->
104 +           lists:map(fun(R) ->
105 +                             R#vcard.vcard
106 +                     end, Rs);
107 +       {aborted, _Reason} ->
108 +           []
109      end.
110  
111  set_vcard(User, LServer, VCARD) ->
112 diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
113 index f4078df..074bdf7 100644
114 --- a/src/mod_vcard_ldap.erl
115 +++ b/src/mod_vcard_ldap.erl
116 @@ -241,38 +241,47 @@ process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ)
117                              ]}]}
118      end.
119  
120 -process_sm_iq(_From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) ->
121 -    case catch process_vcard_ldap(To, IQ, LServer) of
122 +process_sm_iq(From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) ->
123 +    case catch process_vcard_ldap(From, To, IQ, LServer) of
124         {'EXIT', _} ->
125             IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
126         Other ->
127             Other
128      end.
129  
130 -process_vcard_ldap(To, IQ, Server) ->
131 +process_vcard_ldap(From, To, IQ, Server) ->
132      {ok, State} = eldap_utils:get_state(Server, ?PROCNAME),
133      #iq{type = Type, sub_el = SubEl} = IQ,
134      case Type of
135         set ->
136             IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
137         get ->
138 -           #jid{luser = LUser} = To,
139 -           LServer = State#state.serverhost,
140 -           case ejabberd_auth:is_user_exists(LUser, LServer) of
141 -               true ->
142 -                   VCardMap = State#state.vcard_map,
143 -                   case find_ldap_user(LUser, State) of
144 -                       #eldap_entry{attributes = Attributes} ->
145 -                           Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}),
146 -                           IQ#iq{type = result, sub_el = Vcard};
147 -                       _ ->
148 -                           IQ#iq{type = result, sub_el = []}
149 -                   end;
150 -               _ ->
151 -                   IQ#iq{type = result, sub_el = []}
152 -           end
153 +           process_vcard_ldap_get_maybe(From, To, IQ, State)
154         end.
155  
156 +process_vcard_ldap_get_maybe(From, To, IQ, State) ->
157 +    #jid{luser = LUser} = To,
158 +    #jid{lserver = FromLServer} = From,
159 +    LServer = State#state.serverhost,
160 +    Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get, all),
161 +    case ejabberd_auth:is_user_exists(LUser, LServer) andalso
162 +       (acl:match_rule(FromLServer, Access, From) == allow) of
163 +       true ->
164 +           process_vcard_ldap_get(LUser, LServer, IQ, State);
165 +       _ ->
166 +           IQ#iq{type = result, sub_el = []}
167 +    end.
168 +
169 +process_vcard_ldap_get(LUser, LServer, IQ, State) ->
170 +    VCardMap = State#state.vcard_map,
171 +    case find_ldap_user(LUser, State) of
172 +       #eldap_entry{attributes = Attributes} ->
173 +           Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}),
174 +           IQ#iq{type = result, sub_el = Vcard};
175 +       _ ->
176 +           IQ#iq{type = result, sub_el = []}
177 +    end.
178 +
179  handle_call(get_state, _From, State) ->
180      {reply, {ok, State}, State};
181  handle_call(stop, _From, State) ->
182 diff --git a/src/mod_vcard_odbc.erl b/src/mod_vcard_odbc.erl
183 index 30c2888..d239823 100644
184 --- a/src/mod_vcard_odbc.erl
185 +++ b/src/mod_vcard_odbc.erl
186 @@ -138,7 +138,9 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
187      case Type of
188         set ->
189             #jid{user = User, lserver = LServer} = From,
190 -           case lists:member(LServer, ?MYHOSTS) of
191 +           Access = gen_mod:get_module_opt(LServer, ?MODULE, access_set, all),
192 +           case lists:member(LServer, ?MYHOSTS) andalso
193 +               (acl:match_rule(LServer, Access, From) == allow) of
194                 true ->
195                     set_vcard(User, LServer, SubEl),
196                     IQ#iq{type = result, sub_el = []};
197 @@ -147,24 +149,34 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
198             end;
199         get ->
200             #jid{luser = LUser, lserver = LServer} = To,
201 -           Username = ejabberd_odbc:escape(LUser),
202 -           case catch odbc_queries:get_vcard(LServer, Username) of
203 -               {selected, ["vcard"], [{SVCARD}]} ->
204 -                   case xml_stream:parse_element(SVCARD) of
205 -                       {error, _Reason} ->
206 -                           IQ#iq{type = error,
207 -                                 sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
208 -                       VCARD ->
209 -                           IQ#iq{type = result, sub_el = [VCARD]}
210 -                   end;
211 -               {selected, ["vcard"], []} ->
212 -                   IQ#iq{type = result, sub_el = []};
213 -               _ ->
214 -                   IQ#iq{type = error,
215 -                         sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
216 +           Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get, all),
217 +           case acl:match_rule(LServer, Access, From) of
218 +               allow ->
219 +                   get_vcard(LUser, LServer, SubEl, IQ);
220 +               deny ->
221 +                   IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
222             end
223      end.
224  
225 +get_vcard(LUser, LServer, SubEl, IQ) ->
226 +    Username = ejabberd_odbc:escape(LUser),
227 +    case catch odbc_queries:get_vcard(LServer, Username) of
228 +       {selected, ["vcard"], [{SVCARD}]} ->
229 +           case xml_stream:parse_element(SVCARD) of
230 +               {error, _Reason} ->
231 +                   IQ#iq{type = error,
232 +                         sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
233 +               VCARD ->
234 +                   IQ#iq{type = result, sub_el = [VCARD]}
235 +           end;
236 +       {selected, ["vcard"], []} ->
237 +           IQ#iq{type = result, sub_el = []};
238 +       _ ->
239 +           IQ#iq{type = error,
240 +                 sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
241 +    end.
242 +
243 +
244  set_vcard(User, LServer, VCARD) ->
245      FN       = xml:get_path_s(VCARD, [{elem, "FN"},                     cdata]),
246      Family   = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"},    cdata]),
This page took 0.076879 seconds and 4 git commands to generate.