dolibarr  13.0.2
api_users.class.php
1 <?php
2 /* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 /* Copyright (C) 2020 Thibault FOUCART <support@ptibogxiv.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 use Luracast\Restler\RestException;
20 
21 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
22 require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
23 
30 class Users extends DolibarrApi
31 {
36  static $FIELDS = array(
37  'login',
38  );
39 
43  public $useraccount;
44 
48  public function __construct()
49  {
50  global $db, $conf;
51  $this->db = $db;
52  $this->useraccount = new User($this->db);
53  }
54 
55 
70  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $category = 0, $sqlfilters = '')
71  {
72  global $db, $conf;
73 
74  $obj_ret = array();
75 
76  if (!DolibarrApiAccess::$user->rights->user->user->lire) {
77  throw new RestException(401, "You are not allowed to read list of users");
78  }
79 
80  // case of external user, $societe param is ignored and replaced by user's socid
81  //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe;
82 
83  $sql = "SELECT t.rowid";
84  $sql .= " FROM ".MAIN_DB_PREFIX."user as t";
85  if ($category > 0) {
86  $sql .= ", ".MAIN_DB_PREFIX."categorie_user as c";
87  }
88  $sql .= ' WHERE t.entity IN ('.getEntity('user').')';
89  if ($user_ids) {
90  $sql .= " AND t.rowid IN (".$user_ids.")";
91  }
92 
93  // Select products of given category
94  if ($category > 0) {
95  $sql .= " AND c.fk_categorie = ".$this->db->escape($category);
96  $sql .= " AND c.fk_user = t.rowid ";
97  }
98 
99  // Add sql filters
100  if ($sqlfilters) {
101  if (!DolibarrApi::_checkFilters($sqlfilters)) {
102  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
103  }
104  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
105  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
106  }
107 
108  $sql .= $this->db->order($sortfield, $sortorder);
109  if ($limit) {
110  if ($page < 0) {
111  $page = 0;
112  }
113  $offset = $limit * $page;
114 
115  $sql .= $this->db->plimit($limit + 1, $offset);
116  }
117 
118  $result = $this->db->query($sql);
119 
120  if ($result) {
121  $i = 0;
122  $num = $this->db->num_rows($result);
123  $min = min($num, ($limit <= 0 ? $num : $limit));
124  while ($i < $min) {
125  $obj = $this->db->fetch_object($result);
126  $user_static = new User($this->db);
127  if ($user_static->fetch($obj->rowid)) {
128  $obj_ret[] = $this->_cleanObjectDatas($user_static);
129  }
130  $i++;
131  }
132  } else {
133  throw new RestException(503, 'Error when retrieve User list : '.$this->db->lasterror());
134  }
135  if (!count($obj_ret)) {
136  throw new RestException(404, 'No User found');
137  }
138  return $obj_ret;
139  }
140 
151  public function get($id, $includepermissions = 0)
152  {
153  //if (!DolibarrApiAccess::$user->rights->user->user->lire) {
154  //throw new RestException(401);
155  //}
156  if ($id == 0) {
157  $result = $this->useraccount->initAsSpecimen();
158  } else {
159  $result = $this->useraccount->fetch($id);
160  }
161  if (!$result) {
162  throw new RestException(404, 'User not found');
163  }
164 
165  if ($id > 0 && !DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
166  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
167  }
168 
169  if ($includepermissions) {
170  $this->useraccount->getRights();
171  }
172 
173  return $this->_cleanObjectDatas($this->useraccount);
174  }
175 
188  public function getByLogin($login, $includepermissions = 0)
189  {
190  //if (!DolibarrApiAccess::$user->rights->user->user->lire) {
191  //throw new RestException(401);
192  //}
193 
194  $result = $this->useraccount->fetch('', $login);
195  if (!$result) {
196  throw new RestException(404, 'User not found');
197  }
198 
199  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
200  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
201  }
202 
203  if ($includepermissions) {
204  $this->useraccount->getRights();
205  }
206 
207  return $this->_cleanObjectDatas($this->useraccount);
208  }
209 
222  public function getByEmail($email, $includepermissions = 0)
223  {
224  //if (!DolibarrApiAccess::$user->rights->user->user->lire) {
225  //throw new RestException(401);
226  //}
227 
228  $result = $this->useraccount->fetch('', '', '', 0, -1, $email);
229  if (!$result) {
230  throw new RestException(404, 'User not found');
231  }
232 
233  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
234  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
235  }
236 
237  if ($includepermissions) {
238  $this->useraccount->getRights();
239  }
240 
241  return $this->_cleanObjectDatas($this->useraccount);
242  }
243 
255  public function getInfo($includepermissions = 0)
256  {
257  $apiUser = DolibarrApiAccess::$user;
258 
259  $result = $this->useraccount->fetch($apiUser->id);
260  if (!$result) {
261  throw new RestException(404, 'User not found');
262  }
263 
264  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
265  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
266  }
267 
268  if ($includepermissions) {
269  $this->useraccount->getRights();
270  }
271 
272  $usergroup = new UserGroup($this->db);
273  $userGroupList = $usergroup->listGroupsForUser($apiUser->id, false);
274  if (!is_array($userGroupList)) {
275  throw new RestException(404, 'User group not found');
276  }
277 
278  $this->useraccount->user_group_list = $this->_cleanUserGroupListDatas($userGroupList);
279 
280  return $this->_cleanObjectDatas($this->useraccount);
281  }
282 
289  public function post($request_data = null)
290  {
291  // check user authorization
292  //if(! DolibarrApiAccess::$user->rights->user->creer) {
293  // throw new RestException(401, "User creation not allowed");
294  //}
295  // check mandatory fields
296  /*if (!isset($request_data["login"]))
297  throw new RestException(400, "login field missing");
298  if (!isset($request_data["password"]))
299  throw new RestException(400, "password field missing");
300  if (!isset($request_data["lastname"]))
301  throw new RestException(400, "lastname field missing");*/
302  //assign field values
303  foreach ($request_data as $field => $value) {
304  $this->useraccount->$field = $value;
305  }
306 
307  if ($this->useraccount->create(DolibarrApiAccess::$user) < 0) {
308  throw new RestException(500, 'Error creating', array_merge(array($this->useraccount->error), $this->useraccount->errors));
309  }
310  return $this->useraccount->id;
311  }
312 
313 
325  public function put($id, $request_data = null)
326  {
327  //if (!DolibarrApiAccess::$user->rights->user->user->creer) {
328  //throw new RestException(401);
329  //}
330 
331  $result = $this->useraccount->fetch($id);
332  if (!$result) {
333  throw new RestException(404, 'Account not found');
334  }
335 
336  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
337  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
338  }
339 
340  foreach ($request_data as $field => $value) {
341  if ($field == 'id') {
342  continue;
343  }
344  // The status must be updated using setstatus() because it
345  // is not handled by the update() method.
346  if ($field == 'statut') {
347  $result = $this->useraccount->setstatus($value);
348  if ($result < 0) {
349  throw new RestException(500, 'Error when updating status of user: '.$this->useraccount->error);
350  }
351  } else {
352  $this->useraccount->$field = $value;
353  }
354  }
355 
356  // If there is no error, update() returns the number of affected
357  // rows so if the update is a no op, the return value is zezo.
358  if ($this->useraccount->update(DolibarrApiAccess::$user) >= 0) {
359  return $this->get($id);
360  } else {
361  throw new RestException(500, $this->useraccount->error);
362  }
363  }
364 
365 
377  public function getGroups($id)
378  {
379  $obj_ret = array();
380 
381  if (!DolibarrApiAccess::$user->rights->user->user->lire) {
382  throw new RestException(403);
383  }
384 
385  $user = new User($this->db);
386  $result = $user->fetch($id);
387  if (!$result) {
388  throw new RestException(404, 'user not found');
389  }
390 
391  $usergroup = new UserGroup($this->db);
392  $groups = $usergroup->listGroupsForUser($id, false);
393  $obj_ret = array();
394  foreach ($groups as $group) {
395  $obj_ret[] = $this->_cleanObjectDatas($group);
396  }
397  return $obj_ret;
398  }
399 
400 
411  public function setGroup($id, $group, $entity = 1)
412  {
413 
414  global $conf;
415 
416  //if (!DolibarrApiAccess::$user->rights->user->user->supprimer) {
417  //throw new RestException(401);
418  //}
419  $result = $this->useraccount->fetch($id);
420  if (!$result) {
421  throw new RestException(404, 'User not found');
422  }
423 
424  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
425  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
426  }
427 
428  if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && !empty(DolibarrApiAccess::$user->admin) && empty(DolibarrApiAccess::$user->entity)) {
429  $entity = (!empty($entity) ? $entity : $conf->entity);
430  } else {
431  // When using API, action is done on entity of logged user because a user of entity X with permission to create user should not be able to
432  // hack the security by giving himself permissions on another entity.
433  $entity = (DolibarrApiAccess::$user->entity > 0 ? DolibarrApiAccess::$user->entity : $conf->entity);
434  }
435 
436  $result = $this->useraccount->SetInGroup($group, $entity);
437  if (!($result > 0)) {
438  throw new RestException(500, $this->useraccount->error);
439  }
440 
441  return 1;
442  }
443 
459  public function listGroups($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $group_ids = 0, $sqlfilters = '')
460  {
461  global $db, $conf;
462 
463  $obj_ret = array();
464 
465  if (!DolibarrApiAccess::$user->rights->user->group_advance->read) {
466  throw new RestException(401, "You are not allowed to read list of groups");
467  }
468 
469  // case of external user, $societe param is ignored and replaced by user's socid
470  //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe;
471 
472  $sql = "SELECT t.rowid";
473  $sql .= " FROM ".MAIN_DB_PREFIX."usergroup as t";
474  $sql .= ' WHERE t.entity IN ('.getEntity('user').')';
475  if ($group_ids) {
476  $sql .= " AND t.rowid IN (".$group_ids.")";
477  }
478  // Add sql filters
479  if ($sqlfilters) {
480  if (!DolibarrApi::_checkFilters($sqlfilters)) {
481  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
482  }
483  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
484  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
485  }
486 
487  $sql .= $this->db->order($sortfield, $sortorder);
488  if ($limit) {
489  if ($page < 0) {
490  $page = 0;
491  }
492  $offset = $limit * $page;
493 
494  $sql .= $this->db->plimit($limit + 1, $offset);
495  }
496 
497  $result = $this->db->query($sql);
498 
499  if ($result) {
500  $i = 0;
501  $num = $this->db->num_rows($result);
502  $min = min($num, ($limit <= 0 ? $num : $limit));
503  while ($i < $min) {
504  $obj = $this->db->fetch_object($result);
505  $group_static = new UserGroup($this->db);
506  if ($group_static->fetch($obj->rowid)) {
507  $obj_ret[] = $this->_cleanObjectDatas($group_static);
508  }
509  $i++;
510  }
511  } else {
512  throw new RestException(503, 'Error when retrieve Group list : '.$this->db->lasterror());
513  }
514  if (!count($obj_ret)) {
515  throw new RestException(404, 'No Group found');
516  }
517  return $obj_ret;
518  }
519 
531  public function infoGroups($group, $load_members = 0)
532  {
533  global $db, $conf;
534 
535  if (!DolibarrApiAccess::$user->rights->user->group_advance->read) {
536  throw new RestException(401, "You are not allowed to read groups");
537  }
538 
539  $group_static = new UserGroup($this->db);
540  $result = $group_static->fetch($group, '', $load_members);
541 
542  if (!$result) {
543  throw new RestException(404, 'Group not found');
544  }
545 
546  return $this->_cleanObjectDatas($group_static);
547  }
548 
555  public function delete($id)
556  {
557  //if (!DolibarrApiAccess::$user->rights->user->user->supprimer) {
558  //throw new RestException(401);
559  //}
560  $result = $this->useraccount->fetch($id);
561  if (!$result) {
562  throw new RestException(404, 'User not found');
563  }
564 
565  if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) {
566  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
567  }
568  $this->useraccount->oldcopy = clone $this->useraccount;
569  return $this->useraccount->delete(DolibarrApiAccess::$user);
570  }
571 
572  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
579  protected function _cleanObjectDatas($object)
580  {
581  // phpcs:enable
582  global $conf;
583 
584  $object = parent::_cleanObjectDatas($object);
585 
586  unset($object->default_values);
587  unset($object->lastsearch_values);
588  unset($object->lastsearch_values_tmp);
589 
590  unset($object->total_ht);
591  unset($object->total_tva);
592  unset($object->total_localtax1);
593  unset($object->total_localtax2);
594  unset($object->total_ttc);
595 
596  unset($object->label_incoterms);
597  unset($object->location_incoterms);
598 
599  unset($object->fk_delivery_address);
600  unset($object->fk_incoterms);
601  unset($object->all_permissions_are_loaded);
602  unset($object->shipping_method_id);
603  unset($object->nb_rights);
604  unset($object->search_sid);
605  unset($object->ldap_sid);
606  unset($object->clicktodial_loaded);
607 
608  // List of properties never returned by API, whatever are permissions
609  unset($object->pass);
610  unset($object->pass_indatabase);
611  unset($object->pass_indatabase_crypted);
612  unset($object->pass_temp);
613  unset($object->api_key);
614  unset($object->clicktodial_password);
615  unset($object->openid);
616 
617  unset($object->lines);
618  unset($object->model_pdf);
619  unset($object->skype);
620  unset($object->twitter);
621  unset($object->facebook);
622  unset($object->linkedin);
623 
624  $canreadsalary = ((!empty($conf->salaries->enabled) && !empty(DolibarrApiAccess::$user->rights->salaries->read))
625  || (!empty($conf->hrm->enabled) && !empty(DolibarrApiAccess::$user->rights->hrm->employee->read)));
626 
627  if (!$canreadsalary) {
628  unset($object->salary);
629  unset($object->salaryextra);
630  unset($object->thm);
631  unset($object->tjm);
632  }
633 
634  return $object;
635  }
636 
643  private function _cleanUserGroupListDatas($objectList)
644  {
645  $cleanObjectList = array();
646 
647  foreach ($objectList as $object) {
648  $cleanObject = parent::_cleanObjectDatas($object);
649 
650  unset($cleanObject->default_values);
651  unset($cleanObject->lastsearch_values);
652  unset($cleanObject->lastsearch_values_tmp);
653 
654  unset($cleanObject->total_ht);
655  unset($cleanObject->total_tva);
656  unset($cleanObject->total_localtax1);
657  unset($cleanObject->total_localtax2);
658  unset($cleanObject->total_ttc);
659 
660  unset($cleanObject->libelle_incoterms);
661  unset($cleanObject->location_incoterms);
662 
663  unset($cleanObject->fk_delivery_address);
664  unset($cleanObject->fk_incoterms);
665  unset($cleanObject->all_permissions_are_loaded);
666  unset($cleanObject->shipping_method_id);
667  unset($cleanObject->nb_rights);
668  unset($cleanObject->search_sid);
669  unset($cleanObject->ldap_sid);
670  unset($cleanObject->clicktodial_loaded);
671 
672  unset($cleanObject->datec);
673  unset($cleanObject->datem);
674  unset($cleanObject->members);
675  unset($cleanObject->note);
676  unset($cleanObject->note_private);
677 
678  $cleanObjectList[] = $cleanObject;
679  }
680 
681  return $cleanObjectList;
682  }
683 
691  private function _validate($data)
692  {
693  $account = array();
694  foreach (Users::$FIELDS as $field) {
695  if (!isset($data[$field])) {
696  throw new RestException(400, "$field field missing");
697  }
698  $account[$field] = $data[$field];
699  }
700  return $account;
701  }
702 }
index($sortfield="t.rowid", $sortorder= 'ASC', $limit=100, $page=0, $user_ids=0, $category=0, $sqlfilters= '')
List Users.
_cleanObjectDatas($object)
Clean sensible object datas.
__construct()
Constructor.
setGroup($id, $group, $entity=1)
Add a user into a group.
Class to manage Dolibarr users.
Definition: user.class.php:44
_validate($data)
Validate fields before create or update object.
infoGroups($group, $load_members=0)
Get properties of an group object.
_cleanUserGroupListDatas($objectList)
Clean sensible user group list datas.
Class to manage user groups.
listGroups($sortfield="t.rowid", $sortorder= 'ASC', $limit=100, $page=0, $group_ids=0, $sqlfilters= '')
List Groups.
$conf db
API class for accounts.
Definition: inc.php:54
_checkFilters($sqlfilters)
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:278
Class for API REST v1.
Definition: api.class.php:30
getByLogin($login, $includepermissions=0)
Get properties of an user object by login.
getInfo($includepermissions=0)
Get properties of user connected.
getByEmail($email, $includepermissions=0)
Get properties of an user object by Email.
put($id, $request_data=null)
Update account.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid')
Check user access to a resource.
Definition: api.class.php:252
post($request_data=null)
Create user account.
getGroups($id)
List the groups of a user.