WIP Login with Google

This commit is contained in:
Laurent Destailleur 2022-01-19 20:33:20 +01:00
parent ff1037634b
commit d38784f45a
5 changed files with 78 additions and 23 deletions

View File

@ -122,7 +122,7 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai
$form = new Form($db);
llxHeader('', $langs->trans("PrintingSetup"));
llxHeader('', $langs->trans("TokenManager"));
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup');
@ -163,13 +163,24 @@ if ($mode == 'setup' && $user->admin) {
$urltocheckperms = 'https://github.com/settings/applications/';
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
// We pass this param list in to 'state' because we need it before and after the redirect.
$shortscope = 'userinfo_email,userinfo_profile,cloud_print';
if (!empty($conf->global->OAUTH_GSUITE)) {
// List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
// We pass this key list into the param 'state' because we need it before and after the redirect.
$shortscope = 'userinfo_email,userinfo_profile';
$shortscope .= ',openid,email,profile'; // For openid connect
if (!empty($conf->printing->enabled)) {
$shortscope .= ',cloud_print';
}
if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) {
$shortscope .= ',admin_directory_user';
}
//$scope.=',gmail_full';
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) {
$shortscope.=',gmail_full';
}
$oauthstateanticsrf = bin2hex(random_bytes(128/8));
$_SESSION['oauthstateanticsrf'] = $shortscope.'-'.$oauthstateanticsrf;
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
} elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') {

View File

@ -34,7 +34,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
*/
class modPrinting extends DolibarrModules
{
/**
* Constructor
*

View File

@ -16,6 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// This page should make the process to login and get token as described here:
// https://developers.google.com/identity/protocols/oauth2/openid-connect#server-flow
/**
* \file htdocs/core/modules/oauth/google_oauthcallback.php
* \ingroup oauth
@ -70,9 +73,13 @@ $credentials = new Credentials(
$currentUri->getAbsoluteUri()
);
$state = GETPOST('state');
$requestedpermissionsarray = array();
if (GETPOST('state')) {
$requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back
if ($state) {
// 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back
$statewithscopeonly = preg_replace('/\-.*$/', '', $state);
$requestedpermissionsarray = explode(',', $statewithscopeonly); // Example: 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print'.
}
if ($action != 'delete' && empty($requestedpermissionsarray)) {
print 'Error, parameter state is not defined';
@ -80,6 +87,8 @@ if ($action != 'delete' && empty($requestedpermissionsarray)) {
}
//var_dump($requestedpermissionsarray);exit;
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
// $requestedpermissionsarray contains list of scopes.
// Conversion into URL is done by Reflection on constant with name SCOPE_scope_in_uppercase
@ -91,6 +100,8 @@ $apiService->setAccessType('offline');
$apiService->setApprouvalPrompt('force');
//$apiService->setLoginHint(email); // If we know the email of Google account, we can set it to have it correctly selected on login prompt on multiaccount
$langs->load("oauth");
@ -108,17 +119,12 @@ if ($action == 'delete') {
exit();
}
if (!empty($_GET['code'])) { // We are coming from oauth provider page
if (GETPOST('code')) { // We are coming from oauth provider page.
dol_syslog("We are coming from the oauth provider page");
//llxHeader('',$langs->trans("OAuthSetup"));
//$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
//print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
// TODO
// We should validate that the $sate is same than the one into $_SESSION['oauthstateanticsrf'], return error if not.
//print dol_get_fiche_head();
// retrieve the CSRF state parameter
$state = isset($_GET['state']) ? $_GET['state'] : null;
//print '<table>';
// This was a callback request from service, get the token
try {
@ -126,9 +132,13 @@ if (!empty($_GET['code'])) { // We are coming from oauth provider page
//var_dump($state);
//var_dump($apiService); // OAuth\OAuth2\Service\Google
$token = $apiService->requestAccessToken($_GET['code'], $state);
// This request the token
// Result is stored into object managed by class DoliStorage into includes/OAuth/Common/Storage/DoliStorage.php, so into table llx_oauth_token
$token = $apiService->requestAccessToken(GETPOST('code'), $state);
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
// Note: The token contains a lot of information about the user.
setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs');
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
@ -138,8 +148,9 @@ if (!empty($_GET['code'])) { // We are coming from oauth provider page
} catch (Exception $e) {
print $e->getMessage();
}
} else // If entry on page with no parameter, we arrive here
{
} else {
// If we enter this page without 'code' parameter, we arrive here. this is the case when we want to get the redirect
// to the OAuth provider login page
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
// This may create record into oauth_state before the header redirect.
@ -160,6 +171,6 @@ if (!empty($_GET['code'])) { // We are coming from oauth provider page
* View
*/
// No view at all, just actions
// No view at all, just actions, so we never reach this line, except on error.
$db->close();

View File

@ -33,6 +33,8 @@ if (empty($conf) || !is_object($conf)) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
header('Cache-Control: Public, must-revalidate');
header("Content-type: text/html; charset=".$conf->file->character_set_client);
@ -316,6 +318,37 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->fil
echo '</div>';
}
if (isset($conf->file->main_authentication) && preg_match('/google/', $conf->file->main_authentication)) {
$langs->load("users");
global $dolibarr_main_url_root;
// Define $urlwithroot
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
echo '<br>';
echo '<div class="center" style="margin-top: 4px;">';
$shortscope = 'userinfo_email,userinfo_profile';
$shortscope .= ',openid,email,profile'; // For openid connect
$oauthstateanticsrf = bin2hex(random_bytes(128/8));
$_SESSION['oauthstateanticsrf'] = $shortscope.'-'.$oauthstateanticsrf;
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$url = $urltorenew;
//if (!empty($url)) {
print img_picto('', 'google', 'class="pictofixedwidth"').'<a class="alogin" href="'.$url.'">'.$langs->trans("LoginWith", "Google").'</a>';
/*} else {
$langs->load("errors");
print '<span class="warning">'.$langs->trans("ErrorOpenIDSetupNotComplete", 'MAIN_AUTHENTICATION_OPENID_URL').'</span>';
}*/
echo '</div>';
}
?>

View File

@ -272,7 +272,8 @@ ProjectCreatedByEmailCollector=Project created by email collector from email MSG
TicketCreatedByEmailCollector=Ticket created by email collector from email MSGID %s
OpeningHoursFormatDesc=Use a - to separate opening and closing hours.<br>Use a space to enter different ranges.<br>Example: 8-12 14-18
SuffixSessionName=Suffix for session name
LoginWith=Login with %s
##### Export #####
ExportsArea=Exports area
AvailableFormats=Available formats