From e467b48fea69b0e8a594020cbc69b9606804bc44 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Mon, 26 Sep 2016 11:40:02 +0200 Subject: [PATCH] allow to import without acl-check and setting modifier --- api/src/Contacts.php | 14 +++++++++----- api/src/Contacts/Sql.php | 3 ++- infolog/inc/class.infolog_bo.inc.php | 18 ++++++++++-------- infolog/inc/class.infolog_so.inc.php | 5 +++-- timesheet/inc/class.timesheet_bo.inc.php | 6 ++++++ 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/api/src/Contacts.php b/api/src/Contacts.php index 3198431d9b..6fcce4bcd4 100755 --- a/api/src/Contacts.php +++ b/api/src/Contacts.php @@ -848,9 +848,10 @@ class Contacts extends Contacts\Storage * * @param array &$contact contact array from etemplate::exec * @param boolean $ignore_acl =false should the acl be checked or not + * @param boolean $touch_modified =true should modified/r be updated * @return int/string/boolean id on success, false on failure, the error-message is in $this->error */ - function save(&$contact,$ignore_acl=false) + function save(&$contact, $ignore_acl=false, $touch_modified=true) { // remember if we add or update a entry if (($isUpdate = $contact['id'])) @@ -885,8 +886,8 @@ class Contacts extends Contacts\Storage $contact['owner'] = $this->default_addressbook ? $this->default_addressbook : $this->user; } // allow admins to import contacts with creator / created date set - if (!$contact['creator'] || !$this->is_admin($contact)) $contact['creator'] = $this->user; - if (!$contact['created'] || !$this->is_admin($contact)) $contact['created'] = $this->now_su; + if (!$contact['creator'] || !$ignore_acl && !$this->is_admin($contact)) $contact['creator'] = $this->user; + if (!$contact['created'] || !$ignore_acl && !$this->is_admin($contact)) $contact['created'] = $this->now_su; if (!$contact['tid']) $contact['tid'] = 'n'; } @@ -932,8 +933,11 @@ class Contacts extends Contacts\Storage } // last modified - $contact['modifier'] = $this->user; - $contact['modified'] = $this->now_su; + if ($touch_modified) + { + $contact['modifier'] = $this->user; + $contact['modified'] = $this->now_su; + } // set full name and fileas from the content if (!isset($contact['n_fn'])) { diff --git a/api/src/Contacts/Sql.php b/api/src/Contacts/Sql.php index be5b92cdac..e64397bb8f 100644 --- a/api/src/Contacts/Sql.php +++ b/api/src/Contacts/Sql.php @@ -344,7 +344,8 @@ class Sql extends Api\Storage } if (isset($filter['list'])) { - $join .= " JOIN $this->ab2list_table ON $this->table_name.contact_id=$this->ab2list_table.contact_id AND list_id=".(int)$filter['list']; + $join .= " JOIN $this->ab2list_table ON $this->table_name.contact_id=$this->ab2list_table.contact_id AND ". + $this->db->expression($this->ab2list_table, array('list_id' => $filter['list'])); unset($filter['list']); } // add join to show only active accounts (only if accounts are shown and in sql and we not already join the accounts table, eg. used by admin) diff --git a/infolog/inc/class.infolog_bo.inc.php b/infolog/inc/class.infolog_bo.inc.php index 1871c386ce..b301b54d78 100644 --- a/infolog/inc/class.infolog_bo.inc.php +++ b/infolog/inc/class.infolog_bo.inc.php @@ -712,16 +712,17 @@ class infolog_bo * @param boolean $skip_notification = false true = do NOT send notification, false (default) = send notifications * @param boolean $throw_exception = false Throw an exception (if required fields are not set) * @param string $purge_cfs = null null=dont, 'ical'=only iCal X-properties (cfs name starting with "#"), 'all'=all cfs + * @param boolean $ignore_acl =true * * @return int|boolean info_id on a successfull write or false */ function write(&$values_in, $check_defaults=true, $touch_modified=true, $user2server=true, - $skip_notification=false, $throw_exception=false, $purge_cfs=null) + $skip_notification=false, $throw_exception=false, $purge_cfs=null, $ignore_acl=false) { $values = $values_in; //echo "boinfolog::write()values="; _debug_array($values); - if (!$values['info_id'] && !$this->check_access(0,Acl::EDIT,$values['info_owner']) && - !$this->check_access(0,Acl::ADD,$values['info_owner'])) + if (!$ignore_acl && (!$values['info_id'] && !$this->check_access(0,Acl::EDIT,$values['info_owner']) && + !$this->check_access(0,Acl::ADD,$values['info_owner']))) { return false; } @@ -750,8 +751,8 @@ class infolog_bo $status_only = $undelete = $this->check_access($values['info_id'],self::ACL_UNDELETE); } } - if ($values['info_id'] && !$this->check_access($values['info_id'],Acl::EDIT) && !$status_only || - !$values['info_id'] && $values['info_id_parent'] && !$this->check_access($values['info_id_parent'],Acl::ADD)) + if (!$ignore_acl && ($values['info_id'] && !$this->check_access($values['info_id'],Acl::EDIT) && !$status_only || + !$values['info_id'] && $values['info_id_parent'] && !$this->check_access($values['info_id_parent'],Acl::ADD))) { return false; } @@ -1031,9 +1032,10 @@ class infolog_bo * @param $query[action] / $query[action_id] if only entries linked to a specified app/entry show be used * @param &$query[start], &$query[total] nextmatch-parameters will be used and set if query returns less entries * @param $query[col_filter] array with column-name - data pairs, data == '' means no filter (!) + * @param boolean $no_acl =false true: ignore all acl * @return array with id's as key of the matching log-entries */ - function &search(&$query) + function &search(&$query, $no_acl=false) { //error_log(__METHOD__.'('.array2string($query).')'); @@ -1065,14 +1067,14 @@ class infolog_bo } } - $ret = $this->so->search($query); + $ret = $this->so->search($query, $no_acl); $this->total = $query['total']; if (is_array($ret)) { foreach ($ret as $id => &$data) { - if (!$this->check_access($data,Acl::READ)) + if (!$no_acl && !$this->check_access($data,Acl::READ)) { unset($ret[$id]); continue; diff --git a/infolog/inc/class.infolog_so.inc.php b/infolog/inc/class.infolog_so.inc.php index 5ead9ab34c..db620d2ed9 100644 --- a/infolog/inc/class.infolog_so.inc.php +++ b/infolog/inc/class.infolog_so.inc.php @@ -747,9 +747,10 @@ class infolog_so * @param string|array $query[cols]=null what to query, if set the recordset / iterator get's returned * @param string $query[append]=null get's appended to sql query, eg. for GROUP BY * @param boolean $query['custom_fields']=false query custom-fields too, default not + * @param boolean $no_acl =false true: ignore all acl * @return array|iterator with id's as key of the matching log-entries or recordset/iterator if cols is set */ - function search(&$query) + function search(&$query, $no_acl=false) { //error_log(__METHOD__.'('.array2string($query).')'); $action2app = array( @@ -806,7 +807,7 @@ class infolog_so { $ordermethod = 'ORDER BY info_datemodified DESC'; // newest first } - $filtermethod = $this->aclFilter($query['filter']); + $filtermethod = $no_acl ? '1=1' : $this->aclFilter($query['filter']); if (!$query['col_filter']['info_status']) $filtermethod .= $this->statusFilter($query['filter']); $filtermethod .= $this->dateFilter($query['filter']); $cfcolfilter=0; diff --git a/timesheet/inc/class.timesheet_bo.inc.php b/timesheet/inc/class.timesheet_bo.inc.php index bb3f01ecae..2ab360c9d9 100644 --- a/timesheet/inc/class.timesheet_bo.inc.php +++ b/timesheet/inc/class.timesheet_bo.inc.php @@ -396,6 +396,7 @@ class timesheet_bo extends Api\Storage * search the timesheet * * reimplemented to limit result to users we have grants from + * Use $filter['ts_owner'] === false for no ACL check. * * @param array|string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!) * @param boolean|string $only_keys =true True returns only keys, False returns all cols. comma seperated list of keys to return @@ -431,6 +432,11 @@ class timesheet_bo extends Api\Storage { $filter['ts_owner'] = array_keys($this->grants); } + // $filter['ts_owner'] === false --> no ACL checks + elseif ($filter['ts_owner'] === false) + { + $filter['ts_owner'] = ''; + } else { if (!is_array($filter['ts_owner'])) $filter['ts_owner'] = array($filter['ts_owner']);