From b489d2017d046c305598a79e31127c26bc9a98fd Mon Sep 17 00:00:00 2001 From: Badlop Date: Fri, 7 Jun 2013 19:00:07 +0200 Subject: [PATCH] New options access_get and access_set in mod_vcard, _ldap and _odbc (EJAB-797) --- doc/guide.tex | 23 +++++++++++++++++++++-- src/mod_vcard.erl | 24 ++++++++++++++++-------- src/mod_vcard_ldap.erl | 45 +++++++++++++++++++++++++++------------------ 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/doc/guide.tex b/doc/guide.tex index 71f88ee..d5bcfbb 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -4616,6 +4616,17 @@ Options: \hostitem{vjud} \iqdiscitem{\ns{vcard-temp}} \dbtype +\titem{access\_get}\ind{options!accessget} Access rule that defines + who is allowed to see vCard of local users. + If a rule returns `deny' on the requester + user name, that user cannot see vCards of local users. + By default anybody can see the vCards of local users. +\titem{access\_set}\ind{options!accessset} Access rule that defines + who is allowed to modify his vCard. + If a rule returns `deny' on the requester + user name, that user cannot modify his vCard. + By default each local account can modify his own local vCard. + Notice that vCard of a user can only be edited by the user himself. \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search functionality is enabled or not If disabled, the option \term{host} will be ignored and the @@ -4651,14 +4662,17 @@ Examples: ]}. \end{verbatim} \item The second situation differs in a way that search results are not limited, - and that all virtual hosts will be searched instead of only the current one: + and that all virtual hosts will be searched instead of only the current one. + Also, vCards of local users can only be seen by Local users. \begin{verbatim} +{access, vcard_get, [{allow, local}]}. {modules, [ ... {mod_vcard, [{search, true}, {matches, infinity}, - {allow_return_all, true}]}, + {allow_return_all, true}, + {access_get, vcard_get}]}, ... ]}. \end{verbatim} @@ -4696,6 +4710,11 @@ consists of the following \modvcardldap{}-specific options: \begin{description} \hostitem{vjud} \iqdiscitem{\ns{vcard-temp}} +\titem{access\_get}\ind{options!accessget} Access rule that defines + who is allowed to see vCard of local users. + If a rule returns `deny' on the requester + user name, that user cannot see vCards of local users. + By default anybody can see the vCards of local users. \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search functionality is enabled (value: \term{true}) or disabled (value: \term{false}). If disabled, the option \term{host} will be ignored and the diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 3b70fe2..0629de6 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -181,7 +181,9 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> #jid{user = User, lserver = LServer} = From, - case lists:member(LServer, ?MYHOSTS) of + Access = gen_mod:get_module_opt(LServer, ?MODULE, access_set, all), + case lists:member(LServer, ?MYHOSTS) andalso + (acl:match_rule(LServer, Access, From) == allow) of true -> set_vcard(User, LServer, SubEl), IQ#iq{type = result, sub_el = []}; @@ -190,13 +192,19 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> end; get -> #jid{luser = LUser, lserver = LServer} = To, - case get_vcard(LUser, LServer) of - error -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; - Els -> - IQ#iq{type = result, sub_el = Els} - end + Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get, all), + case acl:match_rule(LServer, Access, From) of + allow -> + case get_vcard(LUser, LServer) of + error -> + IQ#iq{type = error, + sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; + Els -> + IQ#iq{type = result, sub_el = Els} + end; + deny -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} + end end. get_vcard(LUser, LServer) -> diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index d3e6077..b17b1a3 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -242,38 +242,47 @@ process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ]}]} end. -process_sm_iq(_From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) -> - case catch process_vcard_ldap(To, IQ, LServer) of +process_sm_iq(From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) -> + case catch process_vcard_ldap(From, To, IQ, LServer) of {'EXIT', _} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; Other -> Other end. -process_vcard_ldap(To, IQ, Server) -> +process_vcard_ldap(From, To, IQ, Server) -> {ok, State} = eldap_utils:get_state(Server, ?PROCNAME), #iq{type = Type, sub_el = SubEl} = IQ, case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> - #jid{luser = LUser} = To, - LServer = State#state.serverhost, - case ejabberd_auth:is_user_exists(LUser, LServer) of - true -> - VCardMap = State#state.vcard_map, - case find_ldap_user(LUser, State) of - #eldap_entry{attributes = Attributes} -> - Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}), - IQ#iq{type = result, sub_el = Vcard}; - _ -> - IQ#iq{type = result, sub_el = []} - end; - _ -> - IQ#iq{type = result, sub_el = []} - end + process_vcard_ldap_get_maybe(From, To, IQ, State) end. +process_vcard_ldap_get_maybe(From, To, IQ, State) -> + #jid{luser = LUser} = To, + #jid{lserver = FromLServer} = From, + LServer = State#state.serverhost, + Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get, all), + case ejabberd_auth:is_user_exists(LUser, LServer) andalso + (acl:match_rule(FromLServer, Access, From) == allow) of + true -> + process_vcard_ldap_get(LUser, LServer, IQ, State); + _ -> + IQ#iq{type = result, sub_el = []} + end. + +process_vcard_ldap_get(LUser, LServer, IQ, State) -> + VCardMap = State#state.vcard_map, + case find_ldap_user(LUser, State) of + #eldap_entry{attributes = Attributes} -> + Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}), + IQ#iq{type = result, sub_el = Vcard}; + _ -> + IQ#iq{type = result, sub_el = []} + end. + handle_call(get_state, _From, State) -> {reply, {ok, State}, State}; handle_call(stop, _From, State) -> -- 1.7.10.4