dolibarr 24.0.0-beta
webportal.main.inc.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2023-2024 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2023-2024 Lionel Vessiller <lvessiller@easya.solutions>
4 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27if (!defined('WEBPORTAL')) {
28 define('WEBPORTAL', 1);
29}
30if (!defined('NOLOGIN')) {
31 define('NOLOGIN', 1);
32}
33if (!defined('NOREQUIREUSER')) {
34 define('NOREQUIREUSER', 1);
35}
36if (!defined('NOREQUIREMENU')) {
37 define('NOREQUIREMENU', 1);
38}
39if (!defined('NOREQUIRESOC')) {
40 define('NOREQUIRESOC', 1);
41}
42if (!defined('EVEN_IF_ONLY_LOGIN_ALLOWED')) {
43 define('EVEN_IF_ONLY_LOGIN_ALLOWED', 1);
44}
45if (!defined('NOIPCHECK')) {
46 define('NOIPCHECK', 1);
47}
48
49
50if (!function_exists('dol_getprefix')) {
60 function dol_getprefix($mode = '') // @phan-suppress-current-line PhanRedefineFunction
61 {
62 global $dolibarr_main_instance_unique_id,
63 $dolibarr_main_cookie_cryptkey; // This is loaded by filefunc.inc.php
64
65 $tmp_instance_unique_id = empty($dolibarr_main_instance_unique_id) ?
66 (empty($dolibarr_main_cookie_cryptkey) ? '' :
67 $dolibarr_main_cookie_cryptkey) : $dolibarr_main_instance_unique_id;
68 // Unique id of instance
69
70 // The recommended value (may be not defined for old versions)
71 if (!empty($tmp_instance_unique_id)) {
72 return sha1('webportal' . $tmp_instance_unique_id);
73 } else {
74 return sha1('webportal' . $_SERVER['SERVER_NAME'].$_SERVER['DOCUMENT_ROOT'].DOL_DOCUMENT_ROOT);
75 }
76 }
77}
78
79include __DIR__.'/../../main.inc.php';
80require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
81require_once DOL_DOCUMENT_ROOT . '/societe/class/societeaccount.class.php';
82require_once DOL_DOCUMENT_ROOT . '/public/webportal/lib/webportal.lib.php';
83require_once DOL_DOCUMENT_ROOT . '/webportal/class/context.class.php';
84require_once DOL_DOCUMENT_ROOT . '/webportal/class/webportalmember.class.php';
85require_once DOL_DOCUMENT_ROOT . '/webportal/class/webportalpartnership.class.php';
95'
96@phan-var-force string $sessionname
97@phan-var-force string $sessiontimeout
98';
99// Init session. Name of session is specific to WEBPORTAL instance.
100// Must be done after the include of filefunc.inc.php so global variables of conf file are defined (like $dolibarr_main_instance_unique_id or $dolibarr_main_force_https).
101// Note: the function dol_getprefix is defined into functions.lib.php but may have been defined to return a different key to manage another area to protect.
102//$prefix = dol_getprefix('');
103//$sessionname = 'WEBPORTAL_SESSID_' . $prefix;
104//$sessiontimeout = 'WEBPORTAL_SESSTIMEOUT_' . $prefix;
105//if (!empty($_COOKIE[$sessiontimeout]) && session_status() === PHP_SESSION_NONE) {
106// ini_set('session.gc_maxlifetime', $_COOKIE[$sessiontimeout]);
107//}
108
110$context->initController();
111
112$hookmanager->initHooks(array('main', 'webportal'));
113
114$logged_user = new User($db);
115$anti_spam_session_key = 'dol_antispam_value';
116
117if (!defined('NOREQUIREDB') && empty($conf->webportal->enabled)) {
118 accessforbidden('Module not activated');
119}
120
121if (!defined('WEBPORTAL_NOREQUIRETRAN') || (!defined('WEBPORTAL_NOLOGIN') && !empty($context->controllerInstance->accessNeedLoggedUser))) {
122 if (!is_object($langs)) { // This can occurs when calling page with NOREQUIRETRAN defined, however we need langs for error messages.
123 include_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php';
124 $langs = new Translate("", $conf);
125 $langcode = (GETPOST('lang', 'aZ09', 1) ? GETPOST('lang', 'aZ09', 1) : (empty($logged_user->conf->MAIN_LANG_DEFAULT) ? getDolGlobalString('MAIN_LANG_DEFAULT', 'auto') : $logged_user->conf->MAIN_LANG_DEFAULT));
126 if (defined('MAIN_LANG_DEFAULT')) {
127 $langcode = constant('MAIN_LANG_DEFAULT');
128 }
129 $langs->setDefaultLang($langcode);
130 }
131 $langs->loadLangs(array('website', 'main'));
132}
133
134/*
135 * Phase authentication / login
136 */
137if (getDolGlobalInt('WEBPORTAL_LOGIN_BY_MODULE') && !empty($conf->modules_parts['webportallogin']) && is_array($conf->modules_parts['webportallogin'])) {
138 foreach ($conf->modules_parts['webportallogin'] as $module => $file) {
139 $path=dol_buildpath("/$module/$file");
140 include_once $path;
141 break;
142 }
143} elseif (!defined('WEBPORTAL_NOLOGIN') && !empty($context->controllerInstance->accessNeedLoggedUser)) {
144 $error = 0;
145
146 // Hooks for security access
147 $hookmanager->initHooks(array('login'));
148 $parameters = array(
149 "webportal_sessionname" => $sessionname,
150 "webportal_anti_spam_session_key" => $anti_spam_session_key,
151 );
152 $reshook = $hookmanager->executeHooks('beforeLoginAuthentication', $parameters, $context);
153 if ($reshook < 0) {
154 $error++;
155 } elseif (empty($reshook)) {
156 $admin_error_messages = array();
157 $webportal_logged_thirdparty_account_id = isset($_SESSION["webportal_logged_thirdparty_account_id"]) && $_SESSION["webportal_logged_thirdparty_account_id"] > 0 ? $_SESSION["webportal_logged_thirdparty_account_id"] : 0;
158 $webportal_logged_member_account_id = isset($_SESSION["webportal_logged_member_account_id"]) && $_SESSION["webportal_logged_member_account_id"] > 0 ? $_SESSION["webportal_logged_member_account_id"] : 0;
159
160 if (!$context->userIsLog()) {
161 // It is not already authenticated and it requests the login / password
162 $langs->loadLangs(array("other", "help", "admin"));
163
164 $action = GETPOST('action_login', 'alphanohtml');
165
166 if ($action == 'login') {
167 $login = GETPOST('login', 'alphanohtml');
168 $password = GETPOST('password', 'password');
169 $security_code = GETPOST('security_code', 'alphanohtml');
170
171 if (empty($login)) {
172 $context->setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")), 'errors');
173 $focus_element = 'login';
174 $error++;
175 }
176 if (empty($password)) {
177 $context->setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Password")), 'errors');
178 if (empty($focus_element)) {
179 $focus_element = 'password';
180 }
181 $error++;
182 }
183 // check security graphic code
184 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_WEBPORTAL')) {
185 $ok = (array_key_exists($anti_spam_session_key, $_SESSION) && (strtolower($_SESSION[$anti_spam_session_key]) == strtolower($security_code)));
186 if (!$ok) {
187 $error++;
188 $context->setEventMessage($langs->trans("ErrorBadValueForCode"), 'errors');
189 if (empty($focus_element)) {
190 $focus_element = 'security_code';
191 }
192 }
193 }
194
195 if (!$error && (isModEnabled('societe') && !getDolGlobalInt('WEBPORTAL_LOGIN_BY_MEMBER_ACCOUNT'))) {
196 // fetch third-party account from login and account type
197 $thirdparty_account_id = $context->getThirdPartyAccountFromLogin($login, $password);
198 if ($thirdparty_account_id <= 0) {
199 $error++;
200 dol_syslog($langs->transnoentitiesnoconv('WebPortalErrorFetchThirdPartyAccountFromLogin', $login), LOG_WARNING);
201 } else {
202 $_SESSION["webportal_logged_thirdparty_account_id"] = $thirdparty_account_id;
203 $webportal_logged_thirdparty_account_id = $thirdparty_account_id;
204 $context->controller = 'default';
205 $context->initController();
206 }
207 } elseif (!$error && isModEnabled('member') && getDolGlobalInt('WEBPORTAL_LOGIN_BY_MEMBER_ACCOUNT') && !getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
208 // fetch member account from login
209 $member_account_id = $context->getMemberAccountFromLogin($login, $password);
210 if ($member_account_id <= 0) {
211 $error++;
212 dol_syslog($langs->transnoentitiesnoconv('WebPortalErrorFetchMemberAccountFromLogin', $login), LOG_WARNING);
213 } else {
214 $_SESSION["webportal_logged_member_account_id"] = $member_account_id;
215 $webportal_logged_member_account_id = $member_account_id;
216 $context->controller = 'default';
217 $context->initController();
218 }
219 } else {
220 $error++;
221 dol_syslog($langs->transnoentitiesnoconv('WebPortalErrorNoFetchMethod'), LOG_WARNING);
222 }
223
224 if ($error) {
225 $context->setEventMessage($langs->transnoentitiesnoconv('WebPortalErrorAuthentication'), 'errors');
226 }
227 }
228
229 if (empty($webportal_logged_thirdparty_account_id) && empty($webportal_logged_member_account_id)) {
230 // Set cookie for timeout management
231 if (getDolGlobalString('MAIN_SESSION_TIMEOUT')) {
232 dolSetCookie($sessiontimeout, getDolGlobalString('MAIN_SESSION_TIMEOUT'), 0);
233 }
234
235 $context->controller = 'login';
236 $context->initController();
237 }
238 }
239
240 if (!$error && $context->userIsLog()) {
241 $logged_member = null;
242 $websiteaccount = null;
243 // We are already into an authenticated session
244 if (isModEnabled('member') && getDolGlobalInt('WEBPORTAL_LOGIN_BY_MEMBER_ACCOUNT') && !getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
245 // get member
246 $logged_member = new WebPortalMember($db);
247 $result = $logged_member->fetch($webportal_logged_member_account_id);
248 if ($result <= 0) {
249 $error++;
250
251 // Account has been removed after login
252 dol_syslog("Can't load member account (ID: $webportal_logged_member_account_id) even if session logged.", LOG_WARNING);
253 session_destroy();
254 session_set_cookie_params(0, '/', null, !empty($dolibarr_main_force_https), true); // Add tag secure and httponly on session cookie
255 session_name($sessionname);
256 session_start();
257
258 $error_msg = $langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedMember', (string) $webportal_logged_member_account_id);
259 dol_syslog($error_msg, LOG_ERR);
260 $context->setEventMessage($error_msg, 'errors');
261 }
262 } else {
263 $websiteaccount = new SocieteAccount($db);
264 $result = $websiteaccount->fetch($webportal_logged_thirdparty_account_id);
265
266 if ($result <= 0) {
267 $error++;
268
269 // Account has been removed after login
270 dol_syslog("Can't load third-party account (ID: $webportal_logged_thirdparty_account_id) even if session logged.", LOG_WARNING);
271 session_destroy();
272 session_set_cookie_params(0, '/', null, !empty($dolibarr_main_force_https), true); // Add tag secure and httponly on session cookie
273 session_name($sessionname);
274 session_start();
275
276 $context->setEventMessage($langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedThirdPartyAccount', $webportal_logged_thirdparty_account_id), 'errors');
277 }
278 }
279
280 if (!$error) {
281 $user_id = getDolGlobalInt('WEBPORTAL_USER_LOGGED');
282
283 if ($user_id <= 0) {
284 $error++;
285 $error_msg = $langs->transnoentitiesnoconv('WebPortalSetupNotComplete');
286 dol_syslog($error_msg, LOG_WARNING);
287 $context->setEventMessages($error_msg, null, 'errors');
288 }
289
290 if (!$error) {
291 $result = $logged_user->fetch($user_id);
292 if ($result <= 0) {
293 $error++;
294 $error_msg = $langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedUser', (string) $user_id);
295 dol_syslog($error_msg, LOG_ERR);
296 $context->setEventMessages($error_msg, null, 'errors');
297 }
298 }
299
300 if (!getDolGlobalInt('WEBPORTAL_LOGIN_BY_MEMBER_ACCOUNT')) {
301 if (!$error) {
302 // get third-party
303 $logged_thirdparty = $websiteaccount->thirdparty;
304 if (!$logged_thirdparty || !($logged_thirdparty->id > 0)) {
305 $result = $websiteaccount->fetch_thirdparty();
306
307 if ($result < 0) {
308 $error_msg = $langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedThirdParty', (string) $websiteaccount->fk_soc);
309 //dol_syslog("Can't load third-party (ID: ".$websiteaccount->fk_soc.") even if session logged.", LOG_ERR);
310 dol_syslog($error_msg, LOG_ERR);
311 $context->setEventMessage($error_msg, 'errors');
312 $error++;
313 }
314 }
315
316 if (!$error) {
317 $logged_thirdparty = $websiteaccount->thirdparty;
318
319 // get member
320 $logged_member = new WebPortalMember($db);
321 $result = $logged_member->fetch(0, '', $websiteaccount->thirdparty->id);
322 if ($result < 0) {
323 $error++;
324 $error_msg = $langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedMember', (string) $websiteaccount->thirdparty->id);
325 dol_syslog($error_msg, LOG_ERR);
326 $context->setEventMessage($error_msg, 'errors');
327 }
328
329 if (isModEnabled('partnership') && !$error && $logged_member->id > 0) {
330 // get partnership
331 $logged_partnership = new WebPortalPartnership($db);
332 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
333 $result = $logged_partnership->fetch(0, '', $logged_member->id, $websiteaccount->thirdparty->id);
334 if ($result < 0) {
335 $error++;
336 $error_msg = $langs->transnoentitiesnoconv('WebPortalErrorFetchLoggedPartnership', (string) $websiteaccount->thirdparty->id, (string) $logged_member->id);
337 dol_syslog($error_msg, LOG_ERR);
338 $context->setEventMessage($error_msg, 'errors');
339 }
340 }
341
342 if (!$error) {
343 if ($logged_thirdparty->default_lang != $langs->defaultlang && !defined('WEBPORTAL_NOREQUIRETRAN')) {
344 if (!is_object($langs)) { // This can occurs when calling page with NOREQUIRETRAN defined, however we need langs for error messages.
345 include_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php';
346 $langs = new Translate("", $conf);
347 $langs->setDefaultLang($logged_thirdparty->default_lang);
348 }
349 $langs->loadLangs(array('website', 'main'));
350 }
351
352 $context->logged_thirdparty = $logged_thirdparty;
353 if (!empty($logged_partnership)) {
354 $context->logged_partnership = $logged_partnership;
355 }
356 }
357 }
358 }
359 }
360
361 if (!$error) {
362 $context->logged_user = $logged_user;
363 if (!empty($logged_member)) {
364 $context->logged_member = $logged_member;
365 }
366
367 global $user; // set global user as logged user (used for hooks in external modules)
368 $user = $context->logged_user;
369 }
370 }
371 }
372 }
373
374 if ($error) {
375 // Hooks on failed login
376 $parameters = array(
377 "webportal_sessionname" => $sessionname,
378 "webportal_anti_spam_session_key" => $anti_spam_session_key,
379 );
380 $reshook = $hookmanager->executeHooks('afterLoginFailed', $parameters, $context);
381 if ($reshook < 0) {
382 $error++;
383 }
384 } else {
385 // Hooks on after login
386 $parameters = array(
387 "webportal_sessionname" => $sessionname,
388 "webportal_anti_spam_session_key" => $anti_spam_session_key,
389 );
390 $reshook = $hookmanager->executeHooks('afterLogin', $parameters, $context);
391 if ($reshook < 0) {
392 $error++;
393 }
394 }
395}
static getInstance()
Singleton method to create one instance of this object.
Class for SocieteAccount.
Class to manage translations.
Class to manage Dolibarr users.
Class for WebPortalMember.
Class for WebPortalPartnership.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dolSetCookie(string $cookiename, string $cookievalue, int $expire=-1)
Set a cookie.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition inc.php:426
$context
@method int call_trigger(string $triggerName, ?User $user)
Definition logout.php:42
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.