1<?php 2/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org> 4 * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net> 5 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> 6 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com> 7 * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> 8 * Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <https://www.gnu.org/licenses/>. 22 */ 23 24/** 25 * \file htdocs/user/perms.php 26 * \brief Page to set permission of a user record 27 */ 28 29if (!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET 30 31require '../main.inc.php'; 32require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; 33require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; 34require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; 35 36// Load translation files required by page 37$langs->loadLangs(array('users', 'admin')); 38 39$id = GETPOST('id', 'int'); 40$action = GETPOST('action', 'aZ09'); 41$confirm = GETPOST('confirm', 'alpha'); 42$module = GETPOST('module', 'alpha'); 43$rights = GETPOST('rights', 'int'); 44$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'userperms'; // To manage different context of search 45 46if (!isset($id) || empty($id)) accessforbidden(); 47 48// Define if user can read permissions 49$canreaduser = ($user->admin || $user->rights->user->user->lire); 50// Define if user can modify other users and permissions 51$caneditperms = ($user->admin || $user->rights->user->user->creer); 52// Advanced permissions 53if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) 54{ 55 $canreaduser = ($user->admin || ($user->rights->user->user->lire && $user->rights->user->user_advance->readperms)); 56 $caneditselfperms = ($user->id == $id && $user->rights->user->self_advance->writeperms); 57 $caneditperms = (($caneditperms || $caneditselfperms) ? 1 : 0); 58} 59 60// Security check 61$socid = 0; 62if (isset($user->socid) && $user->socid > 0) $socid = $user->socid; 63$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); 64// A user can always read its own card if not advanced perms enabled, or if he has advanced perms, except for admin 65if ($user->id == $id && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->user->self_advance->readperms) && empty($user->admin))) 66{ 67 accessforbidden(); 68} 69 70$result = restrictedArea($user, 'user', $id, 'user&user', $feature2); 71if ($user->id <> $id && !$canreaduser) accessforbidden(); 72 73$object = new User($db); 74$object->fetch($id, '', '', 1); 75$object->getrights(); 76 77$entity = $conf->entity; 78 79// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context 80$hookmanager->initHooks(array('usercard', 'userperms', 'globalcard')); 81 82 83/* 84 * Actions 85 */ 86 87$parameters = array('id'=>$socid); 88$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 89if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 90 91if (empty($reshook)) { 92 if ($action == 'addrights' && $caneditperms && $confirm == 'yes') { 93 $edituser = new User($db); 94 $edituser->fetch($object->id); 95 $result = $edituser->addrights($rights, $module, '', $entity); 96 if ($result < 0) 97 { 98 setEventMessages($edituser->error, $edituser->errors, 'errors'); 99 } 100 101 // If we are changing our own permissions, we reload 102 if ($object->id == $user->id) { 103 $user->clearrights(); 104 $user->getrights(); 105 $menumanager->loadMenu(); 106 } 107 108 $object->clearrights(); 109 $object->getrights(); 110 } 111 112 if ($action == 'delrights' && $caneditperms && $confirm == 'yes') { 113 $edituser = new User($db); 114 $edituser->fetch($object->id); 115 $result = $edituser->delrights($rights, $module, '', $entity); 116 if ($result < 0) 117 { 118 setEventMessages($edituser->error, $edituser->errors, 'errors'); 119 } 120 121 // If we are changing our own permissions, we reload 122 if ($object->id == $user->id) { 123 $user->clearrights(); 124 $user->getrights(); 125 $menumanager->loadMenu(); 126 } 127 128 $object->clearrights(); 129 $object->getrights(); 130 } 131} 132 133 134/* 135 * View 136 */ 137 138$form = new Form($db); 139 140llxHeader('', $langs->trans("Permissions")); 141 142$head = user_prepare_head($object); 143 144$title = $langs->trans("User"); 145print dol_get_fiche_head($head, 'rights', $title, -1, 'user'); 146 147 148$db->begin(); 149 150// Search all modules with permission and reload permissions def. 151$modules = array(); 152$modulesdir = dolGetModulesDirs(); 153 154foreach ($modulesdir as $dir) 155{ 156 $handle = @opendir(dol_osencode($dir)); 157 if (is_resource($handle)) 158 { 159 while (($file = readdir($handle)) !== false) 160 { 161 if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') 162 { 163 $modName = substr($file, 0, dol_strlen($file) - 10); 164 165 if ($modName) 166 { 167 include_once $dir.$file; 168 $objMod = new $modName($db); 169 170 // Load all lang files of module 171 if (isset($objMod->langfiles) && is_array($objMod->langfiles)) 172 { 173 foreach ($objMod->langfiles as $domain) 174 { 175 $langs->load($domain); 176 } 177 } 178 // Load all permissions 179 if ($objMod->rights_class) 180 { 181 $ret = $objMod->insert_permissions(0, $entity); 182 $modules[$objMod->rights_class] = $objMod; 183 //print "modules[".$objMod->rights_class."]=$objMod;"; 184 } 185 } 186 } 187 } 188 } 189} 190 191$db->commit(); 192 193// Read permissions of user 194$permsuser = array(); 195 196$sql = "SELECT DISTINCT ur.fk_id"; 197$sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur"; 198$sql .= " WHERE ur.entity = ".$entity; 199$sql .= " AND ur.fk_user = ".$object->id; 200 201dol_syslog("get user perms", LOG_DEBUG); 202$result = $db->query($sql); 203if ($result) 204{ 205 $num = $db->num_rows($result); 206 $i = 0; 207 while ($i < $num) 208 { 209 $obj = $db->fetch_object($result); 210 array_push($permsuser, $obj->fk_id); 211 $i++; 212 } 213 $db->free($result); 214} else { 215 dol_print_error($db); 216} 217 218// Lecture des droits groupes 219$permsgroupbyentity = array(); 220 221$sql = "SELECT DISTINCT gr.fk_id, gu.entity"; 222$sql .= " FROM ".MAIN_DB_PREFIX."usergroup_rights as gr,"; 223$sql .= " ".MAIN_DB_PREFIX."usergroup_user as gu"; 224$sql .= " WHERE gr.entity = ".$entity; 225$sql .= " AND gr.fk_usergroup = gu.fk_usergroup"; 226$sql .= " AND gu.fk_user = ".$object->id; 227 228dol_syslog("get user perms", LOG_DEBUG); 229$result = $db->query($sql); 230if ($result) 231{ 232 $num = $db->num_rows($result); 233 $i = 0; 234 while ($i < $num) 235 { 236 $obj = $db->fetch_object($result); 237 if (!isset($permsgroupbyentity[$obj->entity])) 238 $permsgroupbyentity[$obj->entity] = array(); 239 array_push($permsgroupbyentity[$obj->entity], $obj->fk_id); 240 $i++; 241 } 242 $db->free($result); 243} else { 244 dol_print_error($db); 245} 246 247 248/* 249 * Part to add/remove permissions 250 */ 251 252$linkback = ''; 253 254if ($user->rights->user->user->lire || $user->admin) { 255 $linkback = '<a href="'.DOL_URL_ROOT.'/user/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; 256} 257 258dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); 259 260 261print '<div class="underbanner clearboth"></div>'; 262 263if ($user->admin) print info_admin($langs->trans("WarningOnlyPermissionOfActivatedModules")); 264// Show warning about external users 265if (empty($user->socid)) print info_admin(showModulesExludedForExternal($modules))."\n"; 266 267$parameters = array('permsgroupbyentity'=>$permsgroupbyentity); 268$reshook = $hookmanager->executeHooks('insertExtraHeader', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 269if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 270 271 272print "\n"; 273print '<div class="div-table-responsive-no-min">'; 274print '<table class="noborder centpercent">'; 275 276print '<tr class="liste_titre">'; 277print '<td>'.$langs->trans("Module").'</td>'; 278if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->admin)) 279{ 280 if ($caneditperms) 281 { 282 print '<td class="center nowrap">'; 283 print '<a class="reposition commonlink" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&module=allmodules&confirm=yes&token='.newToken().'">'.$langs->trans("All")."</a>"; 284 print ' / '; 285 print '<a class="reposition commonlink" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&entity='.$entity.'&module=allmodules&confirm=yes&token='.newToken().'">'.$langs->trans("None")."</a>"; 286 print '</td>'; 287 } 288 print '<td class="center" width="24"> </td>'; 289} 290print '<td>'.$langs->trans("Permissions").'</td>'; 291if ($user->admin) print '<td class="right">'.$langs->trans("ID").'</td>'; 292print '</tr>'."\n"; 293 294//print "xx".$conf->global->MAIN_USE_ADVANCED_PERMS; 295$sql = "SELECT r.id, r.libelle as label, r.module, r.perms, r.subperms, r.module_position"; 296$sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r"; 297$sql .= " WHERE r.libelle NOT LIKE 'tou%'"; // On ignore droits "tous" 298$sql .= " AND r.entity = ".$entity; 299if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) $sql .= " AND r.perms NOT LIKE '%_advance'"; // Hide advanced perms if option is not enabled 300$sql .= " ORDER BY r.family_position, r.module_position, r.module, r.id"; 301 302$result = $db->query($sql); 303if ($result) 304{ 305 $num = $db->num_rows($result); 306 $i = 0; 307 $oldmod = ''; 308 309 while ($i < $num) 310 { 311 $obj = $db->fetch_object($result); 312 313 // If line is for a module that doe snot existe anymore (absent of includes/module), we ignore it 314 if (empty($modules[$obj->module])) 315 { 316 $i++; 317 continue; 318 } 319 320 // Save field module_position in database if value is still zero 321 if (empty($obj->module_position)) 322 { 323 if (is_object($modules[$obj->module]) && ($modules[$obj->module]->module_position > 0)) 324 { 325 // TODO Define familyposition 326 $family = $modules[$obj->module]->family_position; 327 $familyposition = 0; 328 $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX."rights_def SET module_position = ".((int) $modules[$obj->module]->module_position).","; 329 $sqlupdate .= " family_position = ".((int) $familyposition); 330 $sqlupdate .= " WHERE module_position = 0 AND module = '".$db->escape($obj->module)."'"; 331 $db->query($sqlupdate); 332 } 333 } 334 335 if (isset($obj->module) && ($oldmod <> $obj->module)) 336 { 337 $oldmod = $obj->module; 338 339 // Break detected, we get objMod 340 $objMod = $modules[$obj->module]; 341 $picto = ($objMod->picto ? $objMod->picto : 'generic'); 342 343 // Show break line 344 print '<tr class="oddeven trforbreak">'; 345 print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">'; 346 print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName(); 347 print '<a name="'.$objMod->getName().'"></a>'; 348 print '</td>'; 349 if (($caneditperms && empty($objMod->rights_admin_allowed)) || empty($object->admin)) 350 { 351 if ($caneditperms) 352 { 353 print '<td class="center nowrap">'; 354 print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&module='.$obj->module.'&confirm=yes&token='.newToken().'">'.$langs->trans("All")."</a>"; 355 print ' / '; 356 print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&entity='.$entity.'&module='.$obj->module.'&confirm=yes&token='.newToken().'">'.$langs->trans("None")."</a>"; 357 print '</td>'; 358 } 359 print '<td> </td>'; 360 } else { 361 if ($caneditperms) 362 { 363 print '<td> </td>'; 364 } 365 print '<td> </td>'; 366 } 367 print '<td> </td>'; 368 369 // Permission id 370 if ($user->admin) print '<td class="right"></td>'; 371 372 print '</tr>'."\n"; 373 } 374 375 print '<!-- '.$obj->module.'->'.$obj->perms.($obj->subperms ? '->'.$obj->subperms : '').' -->'."\n"; 376 print '<tr class="oddeven">'; 377 378 // Picto and label of module 379 print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">'; 380 //print img_object('', $picto, 'class="pictoobjectwidth"').' '.$objMod->getName(); 381 print '</td>'; 382 383 // Permission and tick 384 if (!empty($object->admin) && !empty($objMod->rights_admin_allowed)) // Permission granted because admin 385 { 386 if ($caneditperms) 387 { 388 print '<td class="center">'.img_picto($langs->trans("Administrator"), 'star').'</td>'; 389 } 390 print '<td class="center nowrap">'; 391 print img_picto($langs->trans("Active"), 'tick'); 392 print '</td>'; 393 } elseif (in_array($obj->id, $permsuser)) // Permission granted by user 394 { 395 if ($caneditperms) 396 { 397 print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'">'; 398 //print img_edit_remove($langs->trans("Remove")); 399 print img_picto($langs->trans("Remove"), 'switch_on'); 400 print '</a></td>'; 401 } 402 print '<td class="center nowrap">'; 403 print img_picto($langs->trans("Active"), 'tick'); 404 print '</td>'; 405 } elseif (is_array($permsgroupbyentity[$entity])) 406 { 407 if (in_array($obj->id, $permsgroupbyentity[$entity])) // Permission granted by group 408 { 409 if ($caneditperms) 410 { 411 print '<td class="center">'; 412 print $form->textwithtooltip($langs->trans("Inherited"), $langs->trans("PermissionInheritedFromAGroup")); 413 print '</td>'; 414 } 415 print '<td class="center nowrap">'; 416 print img_picto($langs->trans("Active"), 'tick'); 417 print '</td>'; 418 } else { 419 // Do not own permission 420 if ($caneditperms) 421 { 422 print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'">'; 423 //print img_edit_add($langs->trans("Add")); 424 print img_picto($langs->trans("Add"), 'switch_off'); 425 print '</a></td>'; 426 } 427 print '<td> </td>'; 428 } 429 } else { 430 // Do not own permission 431 if ($caneditperms) 432 { 433 print '<td class="center"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addrights&entity='.$entity.'&rights='.$obj->id.'&confirm=yes&token='.newToken().'">'; 434 //print img_edit_add($langs->trans("Add")); 435 print img_picto($langs->trans("Add"), 'switch_off'); 436 print '</a></td>'; 437 } 438 print '<td> </td>'; 439 } 440 441 // Label of permission 442 $permlabel = (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ($langs->trans("PermissionAdvanced".$obj->id) != ("PermissionAdvanced".$obj->id)) ? $langs->trans("PermissionAdvanced".$obj->id) : (($langs->trans("Permission".$obj->id) != ("Permission".$obj->id)) ? $langs->trans("Permission".$obj->id) : $langs->trans($obj->label))); 443 print '<td class="maxwidthonsmartphone">'; 444 print $permlabel; 445 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { 446 if (preg_match('/_advance$/', $obj->perms)) { 447 print ' <span class="opacitymedium">('.$langs->trans("AdvancedModeOnly").')</span>'; 448 } 449 } 450 print '</td>'; 451 452 // Permission id 453 if ($user->admin) print '<td class="right"><span class="opacitymedium">'.$obj->id.'</span></td>'; 454 455 print '</tr>'."\n"; 456 457 $i++; 458 } 459} else dol_print_error($db); 460print '</table>'; 461print '</div>'; 462 463$parameters = array(); 464$reshook = $hookmanager->executeHooks('insertExtraFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 465if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 466 467 468print dol_get_fiche_end(); 469 470// End of page 471llxFooter(); 472$db->close(); 473