forked from extern/egroupware
- ACL to allow non-admin users to edit certain (explicitly allowed) fields in their own account contact data
- new hook editaccountcontact to sync other apps with these data - admin ACL "edit users" is now respected by the contact class for account-contact-data too (you can deny admins to edit accounts) - fixed bug in ldap-backend: it was deleting all not set contact fields
This commit is contained in:
parent
df261614f5
commit
b968f9327c
@ -82,6 +82,14 @@ class bocontacts extends socontacts
|
||||
'url',
|
||||
'tz',
|
||||
);
|
||||
|
||||
/**
|
||||
* Which fields is a (non-admin) user allowed to edit in his own account
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $own_account_acl;
|
||||
|
||||
/**
|
||||
* @var double $org_common_factor minimum percentage of the contacts with identical values to construct the "common" (virtual) org-entry
|
||||
*/
|
||||
@ -120,7 +128,7 @@ class bocontacts extends socontacts
|
||||
|
||||
$this->contact_fields = array(
|
||||
'id' => lang('Contact ID'),
|
||||
'tid' => lang('Type'),
|
||||
'tid' => lang('Typ'),
|
||||
'owner' => lang('Addressbook'),
|
||||
'private' => lang('private'),
|
||||
'cat_id' => lang('Category'),
|
||||
@ -213,6 +221,12 @@ class bocontacts extends socontacts
|
||||
'adr_two_countryname' => lang('country').' ('.lang('business').')',
|
||||
);
|
||||
//_debug_array($this->contact_fields);
|
||||
$this->own_account_acl = unserialize($GLOBALS['egw_info']['server']['own_account_acl']);
|
||||
// we have only one acl (n_fn) for the whole name, as not all backends store every part in an own field
|
||||
if ($this->own_account_acl && in_array('n_fn',$this->own_account_acl))
|
||||
{
|
||||
$this->own_account_acl = array_merge($this->own_account_acl,array('n_prefix','n_given','n_middle','n_family','n_suffix'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,8 +461,20 @@ class bocontacts extends socontacts
|
||||
$contact['n_fn'] = $this->fullname($contact);
|
||||
if (isset($contact['org_name'])) $contact['n_fileas'] = $this->fileas($contact);
|
||||
}
|
||||
$to_write = $contact;
|
||||
// (non-admin) user editing his own account, make sure he does not change fields he is not allowed to (eg. via SyncML or xmlrpc)
|
||||
if (!$ignore_acl && !$contact['owner'] && !$this->is_admin($contact))
|
||||
{
|
||||
foreach($contact as $field => $value)
|
||||
{
|
||||
if (!in_array($field,$this->own_account_acl) && !in_array($field,array('id','owner','account_id','modified','modifier')))
|
||||
{
|
||||
unset($to_write[$field]); // user is now allowed to change that
|
||||
}
|
||||
}
|
||||
}
|
||||
// we dont update the content-history, if we run inside setup (admin-account-creation)
|
||||
if(!($this->error = parent::save($contact)) && is_object($GLOBALS['egw']->contenthistory))
|
||||
if(!($this->error = parent::save($to_write)) && is_object($GLOBALS['egw']->contenthistory))
|
||||
{
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'],$isUpdate ? 'modify' : 'add', time());
|
||||
|
||||
@ -456,6 +482,12 @@ class bocontacts extends socontacts
|
||||
{
|
||||
$GLOBALS['egw']->accounts->cache_invalidate($contact['account_id']);
|
||||
}
|
||||
// notify interested apps about changes in the account-contact data
|
||||
if (!$to_write['owner'] && $to_write['account_id'])
|
||||
{
|
||||
$to_write['location'] = 'editaccountcontact';
|
||||
$GLOBALS['egw']->hooks->process($to_write,False,True); // called for every app now, not only enabled ones));
|
||||
}
|
||||
}
|
||||
return $this->error ? false : $contact['id'];
|
||||
}
|
||||
@ -502,7 +534,7 @@ class bocontacts extends socontacts
|
||||
$owner = $contact['owner'];
|
||||
|
||||
// allow the user to edit his own account
|
||||
if (!$owner && $needed == EGW_ACL_EDIT && $contact['account_id'] == $this->user)
|
||||
if (!$owner && $needed == EGW_ACL_EDIT && $contact['account_id'] == $this->user && $this->own_account_acl)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -349,7 +349,6 @@ class so_ldap
|
||||
{
|
||||
return $err;
|
||||
}
|
||||
|
||||
// check the existing objectclasses of an entry, none = array() for new ones
|
||||
$oldObjectclasses = array();
|
||||
$attributes = array('dn','cn','objectClass','uid');
|
||||
@ -399,7 +398,7 @@ class so_ldap
|
||||
$ldapContact[$ldapFieldName] = $ldapFieldName == 'jpegphoto' ? $data[$egwFieldName] :
|
||||
$GLOBALS['egw']->translation->convert(trim($data[$egwFieldName]),$this->charset,'utf-8');
|
||||
}
|
||||
elseif($isUpdate)
|
||||
elseif($isUpdate && isset($data[$egwFieldName]))
|
||||
{
|
||||
$ldapContact[$ldapFieldName] = array();
|
||||
}
|
||||
@ -411,7 +410,6 @@ class so_ldap
|
||||
$this->$egw2objectclass($ldapContact,$data,$isUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
if($isUpdate)
|
||||
{
|
||||
// update entry
|
||||
|
@ -240,7 +240,7 @@ class socontacts
|
||||
$this->grants[0] = EGW_ACL_READ;
|
||||
}
|
||||
// add account grants for admins
|
||||
if (isset($GLOBALS['egw_info']['user']['apps']['admin'])) // admin rights can be limited by ACL!
|
||||
if ($this->is_admin()) // admin rights can be limited by ACL!
|
||||
{
|
||||
$this->grants[0] = EGW_ACL_READ; // admins always have read-access
|
||||
if (!$GLOBALS['egw']->acl->check('account_access',16,'admin')) $this->grants[0] |= EGW_ACL_EDIT;
|
||||
@ -268,6 +268,19 @@ class socontacts
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is an admin (can unconditionally edit accounts)
|
||||
*
|
||||
* We check now the admin ACL for edit users, as the admin app does it for editing accounts.
|
||||
*
|
||||
* @param array $contact=null for future use, where admins might not be admins for all accounts
|
||||
* @return boolean
|
||||
*/
|
||||
function is_admin($contact=null)
|
||||
{
|
||||
return isset($GLOBALS['egw_info']['user']['apps']['admin']) && !$GLOBALS['egw']->acl->check('account_access',16,'admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all customfields of the given id's
|
||||
*
|
||||
|
@ -932,6 +932,14 @@ class uicontacts extends bocontacts
|
||||
{
|
||||
$readonlys[$field] = true;
|
||||
}
|
||||
// for editing the own account (by a non-admin), enable only the fields allowed via the "onw_account_acl"
|
||||
if (!$content['owner'] && !$this->is_admin($content))
|
||||
{
|
||||
foreach($this->get_fields('supported',$content['id'],$content['owner']) as $field)
|
||||
{
|
||||
if (!$this->own_account_acl || !in_array($field,$this->own_account_acl)) $readonlys[$field] = true;
|
||||
}
|
||||
}
|
||||
for($i = -23; $i<=23; $i++) $tz[$i] = ($i > 0 ? '+' : '').$i;
|
||||
$sel_options['tz'] = $tz;
|
||||
$content['tz'] = $content['tz'] ? $content['tz'] : 0;
|
||||
@ -1360,7 +1368,7 @@ $readonlys['button[vcard]'] = true;
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
parse_navbar();
|
||||
|
||||
if (!$GLOBALS['egw_info']['user']['apps']['admin'])
|
||||
if (!$this->is_admin())
|
||||
{
|
||||
echo '<h1>'.lang('Permission denied !!!')."</h1>\n";
|
||||
}
|
||||
|
@ -26,3 +26,32 @@ function contact_repositories($config)
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
function own_account_acl($config)
|
||||
{
|
||||
$bocontacts =& CreateObject('addressbook.bocontacts');
|
||||
$supported_fields = $bocontacts->get_fields('supported',null,0); // fields supported by the backend (ldap schemas!)
|
||||
// get the list of account fields
|
||||
$fields = array();
|
||||
foreach($bocontacts->contact_fields as $field => $label)
|
||||
{
|
||||
// some fields the user should never be allowed to edit or are covert by an other attribute (n_fn for all n_*)
|
||||
if (!in_array($field,array('id','tid','owner','created','creator','modified','modifier','private','n_prefix','n_given','n_middle','n_family','n_suffix')))
|
||||
{
|
||||
$fields[$field] = $label;
|
||||
}
|
||||
}
|
||||
if ($config['account_repository'] != 'ldap') // no custom-fields in ldap
|
||||
{
|
||||
$custom =& CreateObject('admin.customfields',$contact_app);
|
||||
foreach($custom->get_customfields() as $name => $data)
|
||||
{
|
||||
$fields['#'.$name] = $data['label'];
|
||||
}
|
||||
}
|
||||
if (!is_object($GLOBALS['egw']->html))
|
||||
{
|
||||
$GLOBALS['egw']->html =& CreateObject('phpgwapi.html');
|
||||
}
|
||||
return $GLOBALS['egw']->html->checkbox_multiselect('newsettings[own_account_acl]',$config['own_account_acl'],$fields,true,'',8);
|
||||
}
|
||||
|
@ -21,6 +21,17 @@
|
||||
<td> {lang_Size_of_popup_(WxH,_eg.400x300,_if_a_popup_should_be_used)}:</td>
|
||||
<td><input name="newsettings[call_popup]" value="{value_call_popup}" size="10"></td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2">
|
||||
<b>{lang_Allow_users_to_maintain_their_own_account-data}</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td> {lang_Fields_the_user_is_allowed_to_edit_himself}</td>
|
||||
<td>
|
||||
{hook_own_account_acl}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="th">
|
||||
<td colspan="2"> <b>{lang_Contact_repository}</b></td>
|
||||
</tr>
|
||||
|
Loading…
Reference in New Issue
Block a user