dolibarr 25.0.0-alpha
card.php
1<?php
2/* Copyright (C) 2005-2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2010-2015 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro.com>
5 * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
6 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
28// Load Dolibarr environment
29require '../../main.inc.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
39
40// Load translation files required by page
41$langs->loadLangs(array('admin', 'users', 'errors'));
42$error = 0;
43
44// Security check
45$id = GETPOSTINT('id');
46$action = GETPOST('action', 'aZ09');
47
48if (empty($id) && $action != 'add' && $action != 'create') {
50}
51
52$socid = 0;
53if ($user->socid > 0) {
54 $socid = $user->socid;
55}
56$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user');
57
58// Retrieve needed GETPOSTS for this file
59$toselect = GETPOST('toselect', 'array');
60$tokenid = GETPOST('tokenid', 'aZ09');
61$confirm = GETPOST('confirm', 'alpha');
62$module = GETPOST('module', 'alpha');
63$rights = GETPOSTINT('rights');
64$cancel = GETPOST('cancel', 'alpha');
65$backtopage = GETPOST('backtopage', 'alpha');
66
67// SQL query to retrieve the selected token
68$sql = "SELECT oat.rowid as token_id, oat.token, oat.entity, oat.state as rights, oat.datec as date_creation, oat.tms as date_modification";
69if (isModEnabled('multicompany')) {
70 $sql .= ", e.label";
71}
72$sql .= " FROM ".MAIN_DB_PREFIX."oauth_token as oat";
73if (isModEnabled('multicompany')) {
74 $sql .= " JOIN ".$db->prefix()."entity as e ON oat.entity = e.rowid";
75}
76$sql .= " WHERE oat.rowid = ".((int) $tokenid);
77$sql .= " AND oat.fk_user = ".((int) $id);
78$sql .= " AND oat.service = 'dolibarr_rest_api'";
79
80$resql = $db->query($sql);
81
82$object = new User($db);
83$object->fetch($id, '', '', 1);
84$object->loadRights();
85
86// Deny access if user not using api
87if (empty($object->api_key)) {
89}
90
91$form = new Form($db);
92$token = $db->fetch_object($resql);
93if (!empty($tokenid) && empty($token)) {
95}
96
97$entity = $conf->entity;
98
99$result = restrictedArea($user, 'user', $id, 'user&user', $feature2);
100
101// $user is current user, $id is id of edited user
102$canreaduser = ($user->admin || ($user->id == $id));
103$canedittoken = ($user->admin || (($user->id == $id) && $user->hasRight("user", "self", "write")));
104
105if (!$canreaduser) {
107}
108
109
110/*
111 * Actions
112 */
113
114$parameters = array('id' => $socid);
115$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
116if ($reshook < 0) {
117 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
118}
119
120if (empty($reshook)) {
121 if (empty($backtopage)) {
122 $backtopage = 'list.php?id='.$object->id;
123 }
124
125 if ($cancel) {
126 if (!empty($backtopage)) {
127 header("Location: ".$backtopage);
128 exit;
129 }
130 $action = '';
131 }
132
133 if ($action == 'add' && $canedittoken) {
134 $tokenstring = GETPOST('api_key', 'alphanohtml');
135 $userid = GETPOSTINT('user');
136 // Only an admin can create a token for another user
137 $useridtoadd = ($user->admin && $userid > 0) ? $userid : $id;
138
139 if (empty($tokenstring)) {
140 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Token")), null, 'errors');
141 $action = 'create';
142 $error++;
143 }
144
145 if (empty($useridtoadd)) {
146 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("User")), null, 'errors');
147 $action = 'create';
148 $error++;
149 }
150
151 // Check if a token already exists for the dolibarr api service duplicates
152 $nbtotalofrecords = '';
153 $sqlforcount = 'SELECT COUNT(*) as nbtotalofrecords';
154 $sqlforcount .= " FROM ".MAIN_DB_PREFIX."oauth_token as oat";
155 $sqlforcount .= " WHERE token = '".$db->escape(dolEncrypt($tokenstring, '', '', 'dolibarr'))."'";
156 $sqlforcount .= " AND service = 'dolibarr_rest_api'";
157 $resql = $db->query($sqlforcount);
158 if ($resql) {
159 $objforcount = $db->fetch_object($resql);
160 $nbtotalofrecords = $objforcount->nbtotalofrecords;
161 } else {
162 dol_print_error($db);
163 $error++;
164 }
165
166 if (isset($nbtotalofrecords) && $nbtotalofrecords > 0) {
167 setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentitiesnoconv("Token")), null, 'errors');
168 $action = 'create';
169 $error++;
170 }
171
172 $db->begin();
173
174 if (!$error) {
175 $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, state, fk_user, entity, datec)";
176 $sql .= " VALUES ('dolibarr_rest_api', '".$db->escape(dolEncrypt($tokenstring, '', '', 'dolibarr'))."', 0, ".((int) $useridtoadd).", ".((int) $entity).", '".$db->idate(dol_now())."')";
177 $resql = $db->query($sql);
178 if (!$resql) {
179 $error++;
180 }
181
182 // TODO Manage also ACL permission per token
183
184
185 // TODO Manage also IP permission per token
186 }
187
188 if ($error) {
189 dol_print_error($db);
190 $db->rollback();
191 } else {
192 $insertedtokenid = $db->last_insert_id(MAIN_DB_PREFIX."oauth_token");
193 $db->commit();
194
195 header("Location: " . dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $useridtoadd, 'tokenid' => $insertedtokenid]));
196 exit;
197 }
198 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $canedittoken) {
199 // Remove token
200 $sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token";
201 $sql .= " WHERE rowid = ".((int) $tokenid);
202 $sql .= " AND fk_user = ".((int) $object->id);
203 $sql .= " AND service = 'dolibarr_rest_api'";
204
205 $resql = $db->query($sql);
206
207 if ($resql) {
208 header('Location: list.php?id='.((int) $object->id));
209 exit;
210 } else {
211 dol_print_error($db);
212 }
213 }
214}
215
216
217/*
218 * View
219 */
220
221if ($object->id > 0) {
222 $person_name = !empty($object->firstname) ? $object->lastname.", ".$object->firstname : $object->lastname;
223 $title = $person_name." - ".$langs->trans('ApiTokens');
224} else {
225 $title = $langs->trans("NewToken");
226}
227$help_url = '';
228
229llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-user page-card_param_ihm');
230
231$formconfirm = '';
232
233if ($action == 'delete') {
234 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&tokenid='.$token->token_id, $langs->trans('DeleteToken'), $langs->trans('ConfirmDeleteToken'), 'confirm_delete', '', 0, 1);
235}
236
237print $formconfirm;
238
239if ($action == 'create') {
240 print load_fiche_titre($title, '', 'user');
241 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
242 print '<input type="hidden" name="token" value="'.newToken().'">';
243 print '<input type="hidden" name="action" value="add">';
244 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
245
246 print dol_get_fiche_head();
247
248 print '<table class="border centpercent tableforfieldcreate">';
249
250 if ($user->admin && empty($id)) {
251 print '<tr class="field_ref"><td class="titlefieldcreate fieldrequired">'.$langs->trans('User').'</td>';
252 print '<td class="valuefieldcreate">';
253 print $form->select_dolusers('', 'user', 1, null, 0, '', '', (string) $object->entity, 0, 0, '', 0, '', 'minwidth200 maxwidth500');
254 print '</td></tr>';
255 } else {
256 print '<tr class="field_ref"><td class="titlefieldcreate fieldrequired">'.$langs->trans('User').'</td><td class="valuefieldcreate">'.($person_name ?? '').'</td></tr>';
257 }
258
259 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Token").'</td>';
260 print '<td>';
261 print '<input class="minwidth300 maxwidth400 widthcentpercentminusx" minlength="12" maxlength="128" type="text" id="api_key" name="api_key" value="'.GETPOST('api_key', 'alphanohtml').'" autocomplete="off">';
262 if (!empty($conf->use_javascript_ajax)) {
263 print img_picto($langs->transnoentities('Generate'), 'refresh', 'id="generate_api_key" class="linkobject paddingleft"');
264 }
265 print '</td></tr>';
266 print "</table>\n";
267
268 print dol_get_fiche_end();
269
270 print '<div class="center">';
271 print '<input class="button" name="add" value="'.$langs->trans("Create").'" type="submit">';
272 print '<input class="button button-cancel" value="'.$langs->trans("Cancel").'" name="cancel" type="submit">';
273 print '</div>';
274
275 print "</form>";
276} elseif ($id > 0 && !empty($token)) {
277 $arrayofselected = is_array($toselect) ? $toselect : array();
278
279 $head = user_prepare_head($object);
280
281 $title = $langs->trans("User");
282
283 print dol_get_fiche_head($head, 'apitoken', $title, -1, 'user');
284
285 $tokenvalue = dolDecrypt($token->token);
286
287 $linkback = '<a href="'.DOL_URL_ROOT.'/user/api_token/list.php?id='.$id.'">'.$langs->trans("BackToTokenList").'</a>';
288 $linkback .= '<a href="'.DOL_URL_ROOT.'/user/list.php">'.$langs->trans("BackToList").'</a>';
289
290 $morehtmlref = '<a href="'.DOL_URL_ROOT.'/user/vcard.php?id='.$object->id.'&output=file&file='.urlencode(dol_sanitizeFileName($object->getFullName($langs).'.vcf')).'" class="refid" rel="noopener">';
291 $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"');
292 $morehtmlref .= '</a>';
293
294 $urltovirtualcard = '/user/virtualcard.php?id='.((int) $object->id);
295 $morehtmlref .= dolButtonToOpenUrlInDialogPopup('publicvirtualcard', $langs->transnoentitiesnoconv("PublicVirtualCardUrl").' - '.$object->getFullName($langs), img_picto($langs->trans("PublicVirtualCardUrl"), 'card', 'class="valignmiddle marginleftonly paddingrightonly"'), $urltovirtualcard, '', 'nohover');
296
297 dol_banner_tab($object, 'api_token_card', $linkback, $user->admin, 'rowid', 'ref', $morehtmlref);
298
299 // Tokens info
300 print '<div class="fichecenter">';
301 print '<div class="underbanner clearboth"></div>';
302 print '<table class="border centpercent tableforfield">';
303
304 // Login
305 print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>';
306 if (!empty($object->ldap_sid) && $object->status == 0) {
307 print '<td class="error">';
308 print $langs->trans("LoginAccountDisableInDolibarr");
309 print '</td>';
310 } else {
311 print '<td>';
312 $addadmin = '';
313 if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
314 $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "superadmin", 'class="paddingleft valignmiddle"');
315 } elseif (!empty($object->admin)) {
316 $addadmin .= img_picto($langs->trans("AdministratorDesc"), "admin", 'class="paddingleft valignmiddle"');
317 }
318 print showValueWithClipboardCPButton($object->login).$addadmin;
319 print '</td>';
320 }
321 print '</tr>'."\n";
322
323 // Token
324 print '<tr><td class="titlefield">'.$langs->trans("Token").'</td>';
325 print '<td>';
326 print showValueWithClipboardCPButton($tokenvalue, 1, $tokenvalue);
327 print '</td>';
328 print '</tr>'."\n";
329
330 // Creation date
331 print '<tr><td class="titlefield">'.$langs->trans("DateCreation").'</td>';
332 print '<td>';
333 print dol_print_date($db->jdate($token->date_creation), 'dayhour');
334 print '</td>';
335 print '</tr>'."\n";
336
337 // Modification date
338 print '<tr><td class="titlefield">'.$langs->trans("DateModification").'</td>';
339 print '<td>';
340 print dol_print_date($db->jdate($token->date_modification), 'dayhour');
341 print '</td>';
342 print '</tr>'."\n";
343
344 print '</table>';
345 print '<div class="tabsAction">';
346 print dolGetButtonAction($langs->trans('Delete'), $langs->trans('Delete'), 'delete', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'tokenid' => $token->token_id, 'action' => 'delete'], true), '', $canedittoken, array('attr' => array('class' => 'reposition')))."\n";
347 print '</div>';
348 print '</div>';
349
350 print dol_get_fiche_end();
351
352
353 print load_fiche_titre($langs->trans("ListOfRightsForToken"), '', 'fa-at');
354
355 print '<!-- Rights section -->'."\n";
356
357 if ($user->admin) {
358 print info_admin($langs->trans("WarningOnlyPermissionOfActivatedModules"));
359 }
360
361 print 'TODO If no ACL given, show message to say permissions are the one of user. If ACL set, show ACL active (common to user permission)and ACL no more active (not own by user)';
362}
363
364if (isModEnabled('api') && $action == 'create') {
365 include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
366 print dolJSToSetRandomPassword('api_key', 'generate_api_key', 1);
367}
368
369// End of page
370llxFooter();
371$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage generation of HTML components Only common components must be here.
Class to manage Dolibarr users.
if(! $sortfield) if(! $sortorder) $module
Definition list.php:193
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
isModEnabled($module)
Is Dolibarr module enabled.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $jsonclose='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
Definition html.lib.php:435
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
dolJSToSetRandomPassword($htmlname, $htmlnameofbutton='generate_token', $generic=1)
Output javascript to autoset a generated password using default module into a HTML element.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.
dolEncrypt($chain, $key='', $ciphering='', $forceseed='', $obfuscationmode='dolcrypt')
Encode a string with a symmetric encryption.
user_prepare_head(User $object)
Prepare array with list of tabs.