<?php
/**
 * @version $Id$
 * @author Thomas Crespin <thomas.crespin@sesamath.net>
 * @copyright Thomas Crespin 2009-2022
 * 
 * ****************************************************************************************************
 * SACoche <https://sacoche.sesamath.net> - Suivi d’Acquisitions de Compétences
 * © Thomas Crespin pour Sésamath <https://www.sesamath.net> - Tous droits réservés.
 * Logiciel placé sous la licence libre Affero GPL 3 <https://www.gnu.org/licenses/agpl-3.0.html>.
 * ****************************************************************************************************
 * 
 * Ce fichier est une partie de SACoche.
 * 
 * SACoche est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes 
 * de la “GNU Affero General Public License” telle que publiée par la Free Software Foundation :
 * soit la version 3 de cette licence, soit (à votre gré) toute version ultérieure.
 * 
 * SACoche est distribué dans l’espoir qu’il vous sera utile, mais SANS AUCUNE GARANTIE :
 * sans même la garantie implicite de COMMERCIALISABILITÉ ni d’ADÉQUATION À UN OBJECTIF PARTICULIER.
 * Consultez la Licence Publique Générale GNU Affero pour plus de détails.
 * 
 * Vous devriez avoir reçu une copie de la Licence Publique Générale GNU Affero avec SACoche ;
 * si ce n’est pas le cas, consultez : <http://www.gnu.org/licenses/>.
 * 
 */

// Fichier d’API.
// Développement initié pour un interfaçage avec Papillon <https://getpapillon.xyz>.

// Passage en POST des paramètres par sécurité (éviter d’avoir le jeton dans l’URL).
// Cela a nécessité de faire renvoyer à chaque appel un élément qui permette de retrouver le session.
// En effet, autant en GET ça fonctionnait très bien, autant en POST le cookie de session n’était pas retrouvé lors de l’appel suivant.
// Probablement à cause de l’attribut samesite à "Lax", mais on ne va pas le passer à "None" (et je ne sais pas pourquoi ça passe en GET quand même)
// Afin d’éviter de multiplier / confondre les paramètres, j’ai choisi d’utiliser le même jeton que pour l’authentification.
// Cela a induit de ne pas toujours prendre un identifiant de session aléatoire : pour l’API il est imposé afin de pouvoir être retrouvé.

// Constantes / Configuration serveur / Autoload classes / Fonction de sortie
require('./_inc/_loader.php');

// Service appelé
$SERVICE = Clean::post('service', 'id');
$PAGE = 'api_'.$SERVICE;
if(!$SERVICE)
{
  Json::api_end( 400 /* Bad Request */ , 'Service manquant (paramètre "service" non transmis en POST ou invalide).' );
}

// Jeton d’authentification
$JETON = Clean::post('jeton', 'lettres_chiffres');
if( !$JETON || !preg_match('/^[A-Za-z0-9]{65,75}$/',$JETON) )
{
  Json::api_end( 400 /* Bad Request */ , 'Jeton d’authentification manquant (paramètre "jeton" non transmis en POST ou invalide).' );
}

// Fichier d’informations sur l’hébergement (requis avant la gestion de la session).
if(is_file(CHEMIN_FICHIER_CONFIG_INSTALL))
{
  require(CHEMIN_FICHIER_CONFIG_INSTALL);
}
else
{
  Json::api_end( 456 /* Unrecoverable Error */ , 'Les informations relatives à l’hébergement n’ont pas été trouvées.' );
}

// Le fait de lister les droits d’accès de chaque page empêche de surcroit l’exploitation d’une vulnérabilité "include PHP" (https://www.cert.ssi.gouv.fr/alerte/CERTA-2003-ALE-003/).
if(!Session::recuperer_droit_acces($PAGE))
{
  Json::api_end( 400 /* Bad Request */ , 'Service demandé inexistant ou droit du service API "'.$SERVICE.'" manquant.' );
}

// Ouverture de la session et gestion des droits d’accès
Session::execute($JETON);

  // Json::api_end( 0 , '', $_SESSION );

// Vérification du service
$filename_php = CHEMIN_DOSSIER_API.$PAGE.'.php';
if(!is_file($filename_php))
{
  Json::api_end( 400 /* Bad Request */ , 'Service demandé inexistant.' );
}

// Interface de connexion à la base, chargement et config (test sur CHEMIN_FICHIER_CONFIG_INSTALL car à éviter si procédure d’installation non terminée).
if(is_file(CHEMIN_FICHIER_CONFIG_INSTALL))
{
  // Choix des paramètres de connexion à la base de données adaptée...
  // ...multi-structures ; base sacoche_structure_*** (si connecté sur un établissement)
  if( (HEBERGEUR_INSTALLATION=='multi-structures') && ($_SESSION['BASE']>0) )
  {
    $fichier_sql_param    = 'serveur_sacoche_structure_'.$_SESSION['BASE'];
    $fichier_class_config = 'class.DB.config.sacoche_structure';
  }
  // ...multi-structures ; base sacoche_webmestre (si non connecté ou connecté comme webmestre)
  elseif(HEBERGEUR_INSTALLATION=='multi-structures')
  {
    $fichier_sql_param    = 'serveur_sacoche_webmestre';
    $fichier_class_config = 'class.DB.config.sacoche_webmestre';
  }
  // ...mono-structure ; base sacoche_structure
  elseif(HEBERGEUR_INSTALLATION=='mono-structure')
  {
    $fichier_sql_param    = 'serveur_sacoche_structure';
    $fichier_class_config = 'class.DB.config.sacoche_structure';
  }
  else
  {
    Json::api_end( 456 /* Unrecoverable Error */ , 'Une anomalie dans les données d’hébergement empêche le service de se poursuivre.' );
  }
  // Chargement du fichier de connexion à la BDD
  define('CHEMIN_FICHIER_CONFIG_SQL',CHEMIN_DOSSIER_PRIVATE_SQL.$fichier_sql_param.'.php');
  if(is_file(CHEMIN_FICHIER_CONFIG_SQL))
  {
    require(CHEMIN_FICHIER_CONFIG_SQL);
    require(CHEMIN_DOSSIER_INCLUDE.$fichier_class_config.'.php');
  }
  else
  {
    Json::api_end( 456 /* Unrecoverable Error */ , 'Les paramètres de connexion à la base de données n’ont pas été trouvés.' );
  }
}

// Connexion
if( ($SERVICE!='login') && ($SERVICE!='logout') )
{
  // Fermeture de session (mais pas destruction, juste écriture et libération des données pour éviter un verrouillage en écriture)
  Session::write_close('api');
  // Traductions
  if($_SESSION['USER_PROFIL_TYPE']!='public')
  {
    Lang::setlocale( LC_MESSAGES, Lang::get_locale_used() );
    Lang::bindtextdomain( LOCALE_DOMAINE, LOCALE_DIR );
    Lang::bind_textdomain_codeset( LOCALE_DOMAINE, LOCALE_CHARSET );
    Lang::textdomain( LOCALE_DOMAINE );
  }
  // Blocage éventuel par le webmestre ou un administrateur ou l’automate (on ne peut pas le tester avant car il faut avoir récupéré les données de session)
  LockAcces::stopper_si_blocage( $_SESSION['BASE'] , FALSE /*demande_connexion_profil*/ );
}

// Autres fonctions à charger
require(CHEMIN_DOSSIER_INCLUDE.'fonction_divers.php');

// Chargement de la page concernée
require($filename_php);

?>
