Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW Module to setup OpenID Connect module #30317

Merged
merged 22 commits into from
Jul 21, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
00fdf39
import openid connect custom module phase 1
MaximilienR-easya Jun 20, 2024
395efe7
Merge branch 'dev_Add_openid_connect_mod' into dev_final_openid_connect
MaximilienR-easya Jul 1, 2024
e9ecf07
Merge pull request #7 from MaximilienR-easya/dev_final_openid_connect
MaximilienR-easya Jul 1, 2024
6735c77
indent fix
MaximilienR-easya Jul 1, 2024
606ed12
fix ci
MaximilienR-easya Jul 1, 2024
604990d
Fix ci
MaximilienR-easya Jul 1, 2024
dd7f1c2
Fix
MaximilienR-easya Jul 1, 2024
0f9b0a6
add missing lang file
MaximilienR-easya Jul 1, 2024
3be8628
lang file
MaximilienR-easya Jul 2, 2024
9d2b49f
Multiple fix: callback url overwriten by a js.php from a module, admi…
MaximilienR-easya Jul 3, 2024
420c79b
windows-ci friendly modification
MaximilienR-easya Jul 3, 2024
089a08c
windows-ci friendly modification
MaximilienR-easya Jul 3, 2024
2897bff
Merge branch 'Dolibarr:develop' into dev_Add_openid_connect_mod
MaximilienR-easya Jul 8, 2024
b8c770a
comment
MaximilienR-easya Jul 8, 2024
8ab3312
Fix precommit
MaximilienR-easya Jul 8, 2024
18aa793
Merge branch 'Dolibarr:develop' into dev_Add_openid_connect_mod
MaximilienR-easya Jul 10, 2024
273a3fa
Fix precommit
MaximilienR-easya Jul 10, 2024
5dbc128
Fix precommit
MaximilienR-easya Jul 10, 2024
384ce06
Fix precommit
MaximilienR-easya Jul 10, 2024
20246ec
Update lang file and conditions
MaximilienR-easya Jul 11, 2024
f4b6343
Merge branch 'develop' into dev_Add_openid_connect_mod
eldy Jul 16, 2024
c198fee
Update functions_openid_connect.php
eldy Jul 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions htdocs/admin/openid_connect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?php
/* Copyright (C) 2023 Maximilien Rozniecki <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* \file htdocs/admin/openid_connect.php
* \ingroup openid_connect
* \brief Page to setup openid_connect module
*/

// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/openid_connect.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
dol_include_once('/core/lib/openid_connect.lib.php');

$langs->load("admin");
$langs->load("openidconnect");

if (!$user->admin) accessforbidden();

$action = GETPOST('action', 'alpha');


/*
* Actions
*/

$errors = [];
$error = 0;

if ($action == 'set') {
$client_id = GETPOST('MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM', $client_id, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$client_id = GETPOST('MAIN_AUTHENTICATION_OIDC_CLIENT_ID', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_CLIENT_ID', $client_id, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$client_secret = GETPOST('MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET', $client_secret, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$scopes = GETPOST('MAIN_AUTHENTICATION_OIDC_SCOPES', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_SCOPES', $scopes, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$authorize_url = GETPOST('MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL', $authorize_url, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$value = GETPOST('MAIN_AUTHENTICATION_OIDC_TOKEN_URL', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_TOKEN_URL', $value, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$value = GETPOST('MAIN_AUTHENTICATION_OIDC_USERINFO_URL', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_USERINFO_URL', $value, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}

$logout_url = GETPOST('MAIN_AUTHENTICATION_OIDC_LOGOUT_URL', 'alpha');
$res = dolibarr_set_const($db, 'MAIN_AUTHENTICATION_OIDC_LOGOUT_URL', $logout_url, 'chaine', 0, '', 0);
if (!$res > 0) {
$errors[] = $db->lasterror();
$error++;
}
}

if ($action != '') {
if (!$error) {
setEventMessage($langs->trans("SetupSaved"));
header("Location: " . $_SERVER["PHP_SELF"]);
exit;
} else {
setEventMessages('', $errors, 'errors');
}
}


/*
* View
*/

$form = new Form($db);

llxHeader();

$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("OpenIDconnectSetup"), $linkback, 'title_setup');
print "<br>\n";

$head = openid_connect_prepare_head();

print dol_get_fiche_head($head, 'settings', $langs->trans("Parameters"), 0, 'action');


print '<br>';
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="set">';

$var=true;

print '<table class="noborder" width="100%">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameters").'</td>'."\n";
print '<td align="center">&nbsp;</td>'."\n";
print '<td align="right">'.$langs->trans("Value").'</td>'."\n";
print "</tr>\n";

// MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLoginClaimName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLoginClaimDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM" id="MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM') ? GETPOST('MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_LOGIN_CLAIM") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_CLIENT_ID
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcClientIdName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcClientIdDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_CLIENT_ID" id="MAIN_AUTHENTICATION_OIDC_CLIENT_ID" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_CLIENT_ID') ? GETPOST('MAIN_AUTHENTICATION_OIDC_CLIENT_ID', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_CLIENT_ID) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_CLIENT_ID") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcClientSecretName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcClientSecretDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input type="password" name="MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET" id="MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET') ? GETPOST('MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_SCOPES
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcScopesName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcScopesDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_SCOPES" id="MAIN_AUTHENTICATION_OIDC_SCOPES" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_SCOPES') ? GETPOST('MAIN_AUTHENTICATION_OIDC_SCOPES', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_SCOPES) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_SCOPES") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcAuthorizeUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcAuthorizeUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL" id="MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL') ? GETPOST('MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_TOKEN_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcTokenUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcTokenUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_TOKEN_URL" id="MAIN_AUTHENTICATION_OIDC_TOKEN_URL" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_TOKEN_URL') ? GETPOST('MAIN_AUTHENTICATION_OIDC_TOKEN_URL', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_TOKEN_URL) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_TOKEN_URL") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_USERINFO_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcUserinfoUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcUserinfoUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_USERINFO_URL" id="MAIN_AUTHENTICATION_OIDC_USERINFO_URL" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_USERINFO_URL') ? GETPOST('MAIN_AUTHENTICATION_OIDC_USERINFO_URL', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_USERINFO_URL) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_USERINFO_URL") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// MAIN_AUTHENTICATION_OIDC_LOGOUT_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLogoutUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLogoutUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input name="MAIN_AUTHENTICATION_OIDC_LOGOUT_URL" id="MAIN_AUTHENTICATION_OIDC_LOGOUT_URL" class="minwidth300" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_AUTHENTICATION_OIDC_LOGOUT_URL') ? GETPOST('MAIN_AUTHENTICATION_OIDC_LOGOUT_URL', 'nohtml') : (!empty($conf->global->MAIN_AUTHENTICATION_OIDC_LOGOUT_URL) ? getDolGlobalString("MAIN_AUTHENTICATION_OIDC_LOGOUT_URL") : ''))).'"></td></tr>';
print '</td></tr>' . "\n";

// REDIRECT_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcRedirectUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcRedirectUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input class="minwidth300" value="'.dol_escape_htmltag(openid_connect_get_redirect_url()).'" disabled></td></tr>';
print '</td></tr>' . "\n";

// LOGOUT_URL
$var = !$var;
print '<tr ' . $bc[$var] . '>' . "\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLogoutRedirectUrlName").'</td>'."\n";
print '<td>'.$langs->trans("MainAuthenticationOidcLogoutRedirectUrlDesc").'</td>'."\n";
print '<td align="right">' . "\n";
print '<input class="minwidth300" value="'.dol_escape_htmltag(getDolGlobalString('MAIN_LOGOUT_GOTO_URL', DOL_MAIN_URL_ROOT . "/index.php")).'" disabled></td></tr>';
print '</td></tr>' . "\n";

print '</table>'."\n";

print '<br>';
print '<div align="center">';
print '<input type="submit" class="button" value="'.$langs->trans("Save").'">';
print '</div>';

print '</form>';

print '<br>';

print dol_get_fiche_end();

llxFooter();
76 changes: 76 additions & 0 deletions htdocs/core/lib/openid_connect.lib.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/* Copyright (C) 2017 Open-DSI <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* \file htdocs/admin/openid_connect.php
* \ingroup openid_connect
* \brief Functions for the module openid_connect
*/

/**
* Prepare array with list of tabs
*
* @return array Array of tabs to show
*/
function openid_connect_prepare_head()
{
global $langs, $conf, $user;
$h = 0;
$head = array();

$head[$h][0] = dol_buildpath("/admin/openid_connect.php", 1);
$head[$h][1] = $langs->trans("Parameters");
$head[$h][2] = 'settings';
$h++;

complete_head_from_modules($conf, $langs, null, $head, $h, 'openid_connect_admin');

return $head;
}


/**
* return the current state
*
* @return string String containing the state
*/
function openid_connect_get_state()
{
return hash('sha256', session_id());
}


/**
* return the redirect url
*
* @return string Redirect url
*/
function openid_connect_get_redirect_url()
{
return DOL_MAIN_URL_ROOT . '/core/modules/openid_connect/callback.php';
}


/**
* Return authentication url
*
* @return string Authentication url
*/
function openid_connect_get_url()
{
return getDolGlobalString('MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL') . '?client_id=' . getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_ID') . '&redirect_uri=' . openid_connect_get_redirect_url() . '&scope=' . getDolGlobalString('MAIN_AUTHENTICATION_OIDC_SCOPES') . '&response_type=code&state=' . openid_connect_get_state();
}
11 changes: 9 additions & 2 deletions htdocs/core/login/functions_openid_connect.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/

include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
dol_include_once('/core/lib/openid_connect.lib.php');

/**
* Check validity of user/password/entity
Expand All @@ -41,6 +42,12 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
{
global $db;

if (getDolGlobalInt('MAIN_MODULE_OPENIDCONNECT', 0) <= 0) {
$_SESSION["dol_loginmesg"] = "OpenID Connect is disabled";
dol_syslog("functions_openid_connect::check_user_password_openid_connect Module disabled");
return false;
}

// Force master entity in transversal mode
$entity = $entitytotest;
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
Expand Down Expand Up @@ -72,7 +79,7 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
$state = GETPOST('state', 'aZ09');
dol_syslog('functions_openid_connect::check_user_password_openid_connect code='.$auth_code.' state='.$state);

if ($state !== hash('sha256', session_id())) {
if ($state !== openid_connect_get_state()) {
// State does not match
$_SESSION["dol_loginmesg"] = "Error in OAuth 2.0 flow (state does not match)";
dol_syslog("functions_openid_connect::check_user_password_openid_connect::state does not match", LOG_ERR);
Expand All @@ -85,7 +92,7 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
'client_id' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_ID'),
'client_secret' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET'),
'code' => $auth_code,
'redirect_uri' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_REDIRECT_URL')
'redirect_uri' => openid_connect_get_redirect_url()
];

$token_response = getURLContent(getDolGlobalString('MAIN_AUTHENTICATION_OIDC_TOKEN_URL'), 'POST', http_build_query($auth_param), 1, array(), array('https'), 2);
Expand Down
Loading
Loading