Files
ms1inscription-v5/php/chronotrack_api/fx_chronotrack_oauth.php
stephan 121186a0b9 Update version code and integrate MSIN API ChronoTrack functionality
This commit updates the version code to 4.72.725 and introduces the `fxSettingsApplyChronotrackApi` function to manage ChronoTrack API credentials based on the environment. It also adds relevant UI elements in the sidebar and form sections for ChronoTrack configuration, enhancing the integration of ChronoTrack features within the application.
2026-07-02 18:10:51 -04:00

134 lines
4.8 KiB
PHP

<?php
/**
* MSIN API ChronoTrack — OAuth2 Password Flow + cache token.
*/
function fxChronotrackApiOAuthGetTokenRow() {
global $objDatabase;
$sql = "SELECT * FROM api_chronotrack_token WHERE token_key = '"
. $objDatabase->fxEscape(MSIN_API_CHRONOTRACK_TOKEN_KEY) . "' LIMIT 1";
return $objDatabase->fxGetRow($sql);
}
function fxChronotrackApiOAuthSaveToken($strAccessToken, $strRefreshToken, $intExpiresEpoch) {
global $objDatabase;
$strExpires = '';
if ($intExpiresEpoch > 0) {
$strExpires = date('Y-m-d H:i:s', $intExpiresEpoch);
}
$sqlExists = "SELECT token_key FROM api_chronotrack_token WHERE token_key = '"
. $objDatabase->fxEscape(MSIN_API_CHRONOTRACK_TOKEN_KEY) . "' LIMIT 1";
if ($objDatabase->fxGetRow($sqlExists) !== null) {
$sql = "UPDATE api_chronotrack_token SET access_token = '"
. $objDatabase->fxEscape($strAccessToken) . "', refresh_token = '"
. $objDatabase->fxEscape($strRefreshToken) . "', expires_at = "
. ($strExpires !== '' ? "'" . $objDatabase->fxEscape($strExpires) . "'" : 'NULL')
. ", updated_at = '" . fxGetDateTime() . "' WHERE token_key = '"
. $objDatabase->fxEscape(MSIN_API_CHRONOTRACK_TOKEN_KEY) . "'";
} else {
$sql = "INSERT INTO api_chronotrack_token SET token_key = '"
. $objDatabase->fxEscape(MSIN_API_CHRONOTRACK_TOKEN_KEY) . "', access_token = '"
. $objDatabase->fxEscape($strAccessToken) . "', refresh_token = '"
. $objDatabase->fxEscape($strRefreshToken) . "', expires_at = "
. ($strExpires !== '' ? "'" . $objDatabase->fxEscape($strExpires) . "'" : 'NULL')
. ", updated_at = '" . fxGetDateTime() . "'";
}
$objDatabase->fxQuery($sql);
}
function fxChronotrackApiOAuthTokenValid($arrRow) {
if ($arrRow === null || trim((string)($arrRow['access_token'] ?? '')) === '') {
return false;
}
if (empty($arrRow['expires_at'])) {
return true;
}
$intExpires = strtotime($arrRow['expires_at']);
if ($intExpires === false) {
return true;
}
return ($intExpires > (time() + 120));
}
function fxChronotrackApiOAuthFetchToken($blnForceRefresh = false) {
if (!fxChronotrackApiSettingsConfigured()) {
return array('state' => 'error', 'message' => fxChronotrackApiSettingsErrorMessage());
}
if (!$blnForceRefresh) {
$arrCached = fxChronotrackApiOAuthGetTokenRow();
if (fxChronotrackApiOAuthTokenValid($arrCached)) {
return array(
'state' => 'ok',
'access_token' => $arrCached['access_token'],
'from_cache' => true,
);
}
}
$strBase = fxChronotrackApiGetBaseUrl();
$strQuery = http_build_query(array(
'grant_type' => 'password',
'username' => fxChronotrackApiGetServiceUser(),
'password' => fxChronotrackApiGetServicePass(),
));
$strUrl = $strBase . '/oauth2/token?' . $strQuery;
$arrHttp = fxChronotrackApiHttpRequest('GET', $strUrl, array(
'basic_user' => fxChronotrackApiGetClientId(),
'basic_pass' => fxChronotrackApiGetClientSecret(),
));
if ($arrHttp['state'] !== 'ok' || !is_array($arrHttp['json'])) {
return array(
'state' => 'error',
'message' => fxChronotrackApiHttpGetJsonErrorMessage($arrHttp),
);
}
$strToken = trim((string)($arrHttp['json']['access_token'] ?? ''));
if ($strToken === '') {
return array('state' => 'error', 'message' => 'access_token absent dans la réponse OAuth');
}
$strRefresh = trim((string)($arrHttp['json']['refresh_token'] ?? ''));
$intExpires = intval($arrHttp['json']['expires'] ?? 0);
fxChronotrackApiOAuthSaveToken($strToken, $strRefresh, $intExpires);
return array(
'state' => 'ok',
'access_token' => $strToken,
'from_cache' => false,
);
}
function fxChronotrackApiOAuthApiGet($strPath, $arrQuery = array()) {
$arrToken = fxChronotrackApiOAuthFetchToken(false);
if ($arrToken['state'] !== 'ok') {
return $arrToken;
}
$arrQuery['client_id'] = fxChronotrackApiGetClientId();
$strUrl = fxChronotrackApiGetApiBaseUrl() . '/' . ltrim($strPath, '/');
if (!empty($arrQuery)) {
$strUrl .= '?' . http_build_query($arrQuery);
}
$arrHttp = fxChronotrackApiHttpRequest('GET', $strUrl, array(
'headers' => array('Authorization: Bearer ' . $arrToken['access_token']),
));
if ($arrHttp['state'] === 'ok') {
return array('state' => 'ok', 'json' => $arrHttp['json'], 'http' => $arrHttp);
}
return array(
'state' => 'error',
'message' => fxChronotrackApiHttpGetJsonErrorMessage($arrHttp),
'http' => $arrHttp,
);
}