Readonly VCard

Hi. I'd like to configure ejabberd such that only an admin can update anyones VCard profile but a user themselves cannot. However, anyone should be able to search and read the profiles - the profiles will be populated from another source. I can do everything except disable updates.

I am using Psi to try and achieve this and played around with vcard_set and so on but to no success. Here is an example - don't really know what this does tbh but i was still able to update via Psi.

acl:
  adminextraresource:
    resource: "modadminextraf8x,31ad"
access:
  vcard_set:
    adminextraresource: allow
    all: deny
modules:
  mod_admin_extra:
    module_resource: "modadminextraf8x,31ad"
  mod_vcard:
    access_set: vcard_set

Does anyone know if this is possible and what i'd need to do?

thanks,
steven

I think such thing is not

I think such thing is not possible. Where did you read about that "access_set" option? I can't find it in the ejabberd source code.

Hi - it's in the ejabberd

Hi - it's in the ejabberd configuration documentation:

https://docs.ejabberd.im/admin/configuration/#mod-admin-extra

Oh, I guess that

Oh, I guess that documentation refers to a feature implemented only in this patch:
https://support.process-one.net/browse/EJAB-797

And this patch was not included in ejabberd. In case you are interested, I've updated the patch to work with ejabberd git master. I don't know if it will work with ejabberd 17.04:

From 9a63873c2b31540fe30c80e3fe28f2488a0fad7e Mon Sep 17 00:00:00 2001
From: Badlop 
Date: Mon, 15 May 2017 17:42:29 +0200
Subject: [PATCH] New options access_get and access_set in mod_vcard, _ldap and
 _odbc (EJAB-797)

# Conflicts:
#	src/mod_vcard.erl
#	src/mod_vcard_ldap.erl
---
 src/mod_vcard.erl      | 28 +++++++++++++++++++---------
 src/mod_vcard_ldap.erl | 12 ++++++++++++
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 00fd4bb..d813b55 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -203,7 +203,10 @@ process_local_iq(#iq{type = get, lang = Lang} = IQ) ->
 process_sm_iq(#iq{type = set, lang = Lang, from = From,
 		  sub_els = [SubEl]} = IQ) ->
     #jid{user = User, lserver = LServer} = From,
-    case lists:member(LServer, ?MYHOSTS) of
+    Access = gen_mod:get_module_opt(LServer, ?MODULE, access_set,
+	    fun(A) when is_atom(A) -> A end, all),
+    case lists:member(LServer, ?MYHOSTS) andalso
+	(acl:match_rule(LServer, Access, From) == allow) of
 	true ->
 	    set_vcard(User, LServer, SubEl),
 	    xmpp:make_iq_result(IQ);
@@ -213,14 +216,21 @@ process_sm_iq(#iq{type = set, lang = Lang, from = From,
     end;
 process_sm_iq(#iq{type = get, from = From, to = To, lang = Lang} = IQ) ->
     #jid{luser = LUser, lserver = LServer} = To,
-    case get_vcard(LUser, LServer) of
-	error ->
-	    Txt = <<"Database failure">>,
-	    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
-	[] ->
-	    xmpp:make_iq_result(IQ, #vcard_temp{});
-	Els ->
-	    IQ#iq{type = result, to = From, from = To, sub_els = Els}
+    Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get,
+	     fun(A) when is_atom(A) -> A end, all),
+    case acl:match_rule(LServer, Access, From) of
+	allow ->
+	    case get_vcard(LUser, LServer) of
+		error ->
+		    Txt = <<"Database failure">>,
+		    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
+		[] ->
+		    xmpp:make_iq_result(IQ, #vcard_temp{});
+		Els ->
+		    IQ#iq{type = result, to = From, from = To, sub_els = Els}
+	    end;
+	deny ->
+	    xmpp:make_error(IQ, xmpp:err_not_allowed())
     end.
 
 -spec process_vcard(iq()) -> iq().
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index fe11d09..4e54652 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -91,6 +91,18 @@ is_search_supported(_LServer) ->
     true.
 
 get_vcard(LUser, LServer) ->
+    Access = gen_mod:get_module_opt(LServer, ?MODULE, access_get,
+	fun(A) when is_atom(A) -> A end, all),
+    From = jid:make(LUser, LServer),
+    case ejabberd_auth:is_user_exists(LUser, LServer) andalso
+	(acl:match_rule(LServer, Access, From) == allow) of
+	true ->
+	    get_vcard2(LUser, LServer);
+	_ ->
+	    xmpp:make_error(#iq{}, xmpp:err_not_allowed())
+    end.
+
+get_vcard2(LUser, LServer) ->
     {ok, State} = eldap_utils:get_state(LServer, ?PROCNAME),
     VCardMap = State#state.vcard_map,
     case find_ldap_user(LUser, State) of
-- 
2.7.4


Wow - thank you :-) I didn't

Wow - thank you :-) I didn't realise it was only in the patch.

I will give it a try. If it doesn't work i will figure it out and put the code somewhere.

thanks again,
steven

Syndicate content