dolibarr 20.0.0
api_login.class.php
1<?php
2/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20use Luracast\Restler\RestException;
21
22require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
23require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
24
28class Login
29{
33 public $db;
34
38 public function __construct()
39 {
40 global $db;
41 $this->db = $db;
42
43 //$conf->global->API_DISABLE_LOGIN_API = 1;
44 if (getDolGlobalString('API_DISABLE_LOGIN_API')) {
45 throw new RestException(403, "Error login APIs are disabled. You must get the token from backoffice to be able to use APIs");
46 }
47 }
48
68 public function loginUnsecured($login, $password, $entity = '', $reset = 0)
69 {
70 return $this->index($login, $password, $entity, $reset);
71 }
72
92 public function index($login, $password, $entity = '', $reset = 0)
93 {
94 global $conf, $dolibarr_main_authentication, $dolibarr_auto_user;
95
96 // Is the login API disabled ? The token must be generated from backoffice only.
97 if (getDolGlobalString('API_DISABLE_LOGIN_API')) {
98 dol_syslog("Warning: A try to use the login API has been done while the login API is disabled. You must generate or get the token from the backoffice.", LOG_WARNING);
99 throw new RestException(403, "Error, the login API has been disabled for security purpose. You must generate or get the token from the backoffice.");
100 }
101
102 // Authentication mode
103 if (empty($dolibarr_main_authentication)) {
104 $dolibarr_main_authentication = 'dolibarr';
105 }
106
107 // Authentication mode: forceuser
108 if ($dolibarr_main_authentication == 'forceuser') {
109 if (empty($dolibarr_auto_user)) {
110 $dolibarr_auto_user = 'auto';
111 }
112 if ($dolibarr_auto_user != $login) {
113 dol_syslog("Warning: your instance is set to use the automatic forced login '".$dolibarr_auto_user."' that is not the requested login. API usage is forbidden in this mode.");
114 throw new RestException(403, "Your instance is set to use the automatic login '".$dolibarr_auto_user."' that is not the requested login. API usage is forbidden in this mode.");
115 }
116 }
117
118 // Set authmode
119 $authmode = explode(',', $dolibarr_main_authentication);
120
121 if ($entity != '' && !is_numeric($entity)) {
122 throw new RestException(403, "Bad value for entity, must be the numeric ID of company.");
123 }
124 if ($entity == '') {
125 $entity = 1;
126 }
127
128 include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
129 $login = checkLoginPassEntity($login, $password, $entity, $authmode, 'api'); // Check credentials.
130 if ($login === '--bad-login-validity--') {
131 $login = '';
132 }
133 if (empty($login)) {
134 throw new RestException(403, 'Access denied');
135 }
136
137 $token = 'failedtogenerateorgettoken';
138
139 $tmpuser = new User($this->db);
140 $tmpuser->fetch(0, $login, 0, 0, $entity);
141 if (empty($tmpuser->id)) {
142 throw new RestException(500, 'Failed to load user');
143 }
144
145 // Renew the hash
146 if (empty($tmpuser->api_key) || $reset) {
147 $tmpuser->getrights();
148 if (!$tmpuser->hasRight('user', 'self', 'creer')) {
149 if (empty($tmpuser->api_key)) {
150 throw new RestException(403, 'No API token set for this user and user need write permission on itself to reset its API token');
151 } else {
152 throw new RestException(403, 'User need write permission on itself to reset its API token');
153 }
154 }
155
156 // Generate token for user
157 $token = dol_hash($login.uniqid().(!getDolGlobalString('MAIN_API_KEY') ? '' : $conf->global->MAIN_API_KEY), 1);
158
159 // We store API token into database
160 $sql = "UPDATE ".MAIN_DB_PREFIX."user";
161 $sql .= " SET api_key = '".$this->db->escape(dolEncrypt($token, '', '', 'dolibarr'))."'";
162 $sql .= " WHERE login = '".$this->db->escape($login)."'";
163
164 dol_syslog(get_class($this)."::login", LOG_DEBUG); // No log
165 $result = $this->db->query($sql);
166 if (!$result) {
167 throw new RestException(500, 'Error when updating api_key for user :'.$this->db->lasterror());
168 }
169 } else {
170 $token = $tmpuser->api_key;
171 if (!utf8_check($token)) {
172 throw new RestException(500, 'Error, the API token of this user has a non valid value. Try to update it with a valid value.');
173 }
174 }
175
176 if (!ascii_check($token)) {
177 throw new RestException(500, 'Error the token for this user has not an hexa format. Try first to reset it.');
178 }
179
180 //return token
181 return array(
182 'success' => array(
183 'code' => 200,
184 'token' => $token,
185 'entity' => $tmpuser->entity,
186 'message' => 'Welcome '.$login.($reset ? ' - Token is new' : ' - This is your token (recorded for your user). You can use it to make any REST API call, or enter it into the DOLAPIKEY field to use the Dolibarr API explorer.')
187 )
188 );
189 }
190}
API that allows to log in with an user account.
__construct()
Constructor of the class.
index($login, $password, $entity='', $reset=0)
Login.
loginUnsecured($login, $password, $entity='', $reset=0)
Login.
Class to manage Dolibarr users.
ascii_check($str)
Check if a string is in ASCII.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
utf8_check($str)
Check if a string is in UTF8.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $authmode, $context='')
Return a login if login/pass was successful.
dolEncrypt($chain, $key='', $ciphering='AES-256-CTR', $forceseed='')
Encode a string with a symmetric encryption.
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.