Fichier FrameBeurk
Fmbk/Module/Uzers/fonctionsUzers.php
<?php //FrameBeurk V0.65 Copyright ToolOscope 2016. Licence CeCILL-C.
// ---------------------------- Gestion de la session ----------------------------
function Uzers_verifieSession(&$TRANSAC, &$DIALOG) {
global $CONFIG;
//$TRANSAC['StatutLogin'] = 9; // par défaut, User non logué
// si le IdUser a un dialogue identifié
if (isset($DIALOG['IdUser']) && isset($DIALOG['TempsDebSession'])) {
$result = db_QUERY("SELECT IdEtat, AdresseIP FROM Uzers_UserSession WHERE IdUser = '" . $DIALOG['IdUser'] . "' and TsDeb = '" . $DIALOG['TempsDebSession'] . "'");
if (list($IdEtat, $AdresseIP) = db_FETCH_ROW($result)) {
// adresse IP ne correspond pas avec celle de la session
//if ($AdresseIP != " $_SERVER['REMOTE_ADDR']) {
// $TRANSAC['StatutLogin'] = 2;
// session fermée
if (Beurk_terminal($IdEtat) != 'V')
$TRANSAC['StatutLogin'] = 3;
// session OK
else
$TRANSAC['StatutLogin'] = -1;
// session non trouvee en table
} else
$TRANSAC['StatutLogin'] = 4;
db_FREE($result);
if ($TRANSAC['StatutLogin'] != -1) { //suppression de la session en mémoire si erreur
$CONFIG['Module']['Beurk']['Fonctions']['InitDialogue']();
$TRANSAC['Message']['Connexion'] = Uzers_libelleStatutLogin($TRANSAC['StatutLogin']);
} else //OK, on compte cette transaction
db_QUERY("UPDATE Uzers_UserSession SET NbTransac = NbTransac + 1, TsFin=" . $TRANSAC['Stat']['TsBeurkIni'] . ", IdStyle='" . Beurk_id($DIALOG['Style'])
. "' WHERE IdUser='" . $DIALOG['IdUser'] . "' and TsDeb='" . $DIALOG['TempsDebSession'] . "'");
}
}
// initialisation (ou re-) du dialogue
function Uzers_initDialogue() {
global $CONFIG, $DIALOG;
if (isset($DIALOG['Style'])) //stockage temporaire de l'existant à conserver
$myStyle = $DIALOG['Style'];
if (isset($DIALOG['Langue']))
$myLangue = $DIALOG['Langue'];
if (isset($DIALOG['Pagination']))
$myPagination = $DIALOG['Pagination'];
if (isset($DIALOG['ClefVuePage']))
$vueCourante = $DIALOG['ClefVuePage'];
if (isset($DIALOG['Historique']))
$histo = $DIALOG['Historique'];
$DIALOG = array();
if (isset($_SESSION['DIALOG']))
unset($_SESSION['DIALOG']); // pour être sûr
Beurk_initDialogue($DIALOG);
$DIALOG['IdUser'] = $CONFIG['Defaut']['User']['IdUser'];
$DIALOG['User'] = $CONFIG['Defaut']['User']['User'];
$DIALOG['Groupes'] = array($CONFIG['Controle']['Groupes']['ALL']); //init des groupes ( = groupe commun ALL)
$DIALOG['IdEtatsAutorises'] = Uzers_listeEtats();
if (isset($myStyle)) //reprise de l'existant à conserver
$DIALOG['Style'] = $myStyle;
if (isset($myLangue))
$DIALOG['Langue'] = $myLangue;
if (isset($myPagination))
$DIALOG['Pagination'] = $myPagination;
if (isset($vueCourante))
$DIALOG['ClefVuePage'] = $vueCourante;
if (isset($histo))
$DIALOG['Historique'] = $histo;
// feuille de style par défaut
if (! isset($DIALOG['Style']))
$DIALOG['Style'] = $CONFIG['Defaut']['Style'];
}
// renvoie le message associé au statut du Login
function Uzers_libelleStatutLogin($statut) {
switch ($statut) {
case -1:
return ''; // utilisateur logué
case 1:
return '<p Class="bravo">' . Beurk_traduit('Déconnecté', 'Uzers') . '</p>';
case 2:
return '<p Class="erreur">' . Beurk_traduit('Adresse IP modifiée', 'Uzers') . '</p>';
case 3:
return '<p Class="erreur">' . Beurk_traduit('Session fermée', 'Uzers') . '</p>';
case 4:
return '<p Class="erreur">' . Beurk_traduit('Session inconnue', 'Uzers') . '</p>';
case 5:
return '<p Class="erreur">' . Beurk_traduit('Mot de passe erroné', 'Uzers') . '</p>';
case 6:
return '<p Class="erreur">' . Beurk_traduit('Utilisateur inconnu', 'Uzers') . '</p>';
case 7:
return '<p Class="erreur">' . Beurk_traduit('Utilisateur fermé', 'Uzers') . '</p>';
case 8:
return '<p Class="erreur">' . Beurk_traduit('Session en double', 'Uzers') . '</p>';
case 9:
return ''; //pas de login - navigation libre
}
}
// renvoie la liste des états autorisés en consultation selon le user
function Uzers_listeEtats() {
return (Uzers_estAdmin()) ? "'" . Beurk_id('V') . "', '" . Beurk_id('F') . "', '" . Beurk_id('R') . "', '" . Beurk_id('C') . "', '" . Beurk_id('T') . "'"
: "'" . Beurk_id('V') . "', '" . Beurk_id('F') . "', '" . Beurk_id('R') . "'"; //liste des états consultables (bricolage)
}
// fonction renvoie True si le User fait parti du Groupe ADMIN
function Uzers_estAdmin() {
global $CONFIG, $DIALOG;
return (Uzers_estLogue() ? in_array($CONFIG['Controle']['Groupes']['ADMIN'] , $DIALOG['Groupes']) : false);
}
// fonction renvoie True si le User est logué
function Uzers_estLogue() {
global $TRANSAC;
return ($TRANSAC['StatutLogin'] === -1);
}
// fonction renvoie True si le User logué est celui en paramètre
function Uzers_estUserLogue($IdUser) {
global $DIALOG;
return (Uzers_estLogue() ? ($DIALOG['IdUser'] == $IdUser) : 0);
}
function Uzers_verifiePassword($IdUser, $MotDePasse) {
$result = db_QUERY("SELECT MotDePasse, IdEtat FROM Uzers_User WHERE IdUser = '" . Beurk_Request2DB($IdUser) . "'");
if (list($VraiMotDePasse, $IdEtatUser) = db_FETCH_ROW($result)) {
if (md5($MotDePasse) != $VraiMotDePasse)
return 5; // mot de passe faux
elseif (Beurk_terminal($IdEtatUser) != 'V')
return 7; // User inactive
else
return 0; // OK
} else // user non trouvé en table
return 6; // user invalide
db_FREE($result);
}
//--------------------------------- Gestion des autorisations ---------------------------------
//recherche le createur d'une entité
function Uzers_CreateurEntite($IdNoeud) {
global $CONFIG, $DIALOG;
//recherche si créateur déjà lu
if (isset($DIALOG['Createurs'][$IdNoeud]))
return $DIALOG['Createurs'][$IdNoeud];
//constitution de la requete (recherche du noeud lié par 'aPourCreateur')
$result = db_QUERY("SELECT R.IdLie FROM Beurk_Lien R WHERE R.IdNoeud = '" . $IdNoeud . "' AND R.IdRelation = '" . $CONFIG['Relation']['aPourCreateur']['Id']. "'");
if (! (list($IdCreateur) = db_FETCH_ROW($result)))
$IdCreateur = -1; // IdUser inexistant
db_FREE($result);
$DIALOG['Createurs'][$IdNoeud] = $IdCreateur; //stockage du résultat
return $IdCreateur;
}
// vérifie si le user est logué
function Uzers_autoLogue(&$paramAuto) {
if (! Uzers_estLogue())
return Beurk_message('Login obligatoire', 'Uzers');
}
// vérifie si le user logué est celui en paramètre
function Uzers_autoUser(&$paramAuto) {
global $CONFIG;
if (! Uzers_estLogue()) {
if ($paramAuto['IdMaj'] != $CONFIG['Defaut']['User']['IdUser']) //si le user en paramètre est anonymous
return Beurk_message('Login obligatoire', 'Uzers');
} elseif (! Uzers_estUserLogue($paramAuto['IdMaj']))
return Beurk_message("Vous n'êtes pas cet utilisateur", 'Uzers');
}
// vérifie si le user connecté est admin
function Uzers_autoAdmin(&$paramAuto) {
if (! Uzers_estAdmin())
return Beurk_message("Vous n'êtes pas admin", 'Uzers');
}
// vérifie si le user est logué ou si la somme de contrôle est correcte
function Uzers_autoLogueOuSomme(&$paramAuto) {
if (! Uzers_estLogue())
return Beurk_autoSomme($paramAuto);
}
// vérifie si le user a la permission requise
function Uzers_autoPermission(&$paramAuto) {
global $TRANSAC;
if (! Uzers_estAdmin()) {
$auto = Uzers_recherchePermissions($paramAuto);
if ($auto < 0)
return Beurk_message('Permission refusée', 'Uzers');
elseif ($auto == 1) { // la permission dépend du périmètre
$auto = Uzers_verifiePerimetrePermissions($paramAuto); // examen du périmètre (IdRef)
if ($auto < 0)
return Beurk_message('Permission refusée', 'Uzers');
elseif ($auto == 1) {
if ((! isset($paramAuto['preAuto'])) || $paramAuto['preAuto'] == false) { // controle inhibé dans le cas de l'affichage d'un lien vers la recherche
var_dump($paramAuto);
return Beurk_message('Permission indéterminée', 'Uzers');
}
}
}
}
}
// vérifie que le user est admin ET que la somme de contrôle est correcte
function Uzers_autoAdminEtSomme(&$paramAuto) {
if (! Uzers_estAdmin())
return Beurk_message("Vous n'êtes pas admin", 'Uzers');
return Beurk_autoSomme($paramAuto);
}
// vérifie si le user connecté est le créateur de l'entité (la fonction est tissée pour pouvoir être surchargée)
function Uzers_autoCreateurOuAdmin(&$paramAuto) {
global $CONFIG;
if (! Uzers_estLogue())
return Beurk_message('Login obligatoire', 'Uzers');
if (! Uzers_estAdmin()) {
if (! Uzers_estUserLogue($CONFIG['Module']['Uzers']['Fonctions']['CreateurEntite']($paramAuto['IdMaj'])))
return Beurk_message("Vous n'êtes pas le créateur", 'Uzers');
}
}
// vérifie si le user connecté est le créateur de l'entité (la fonction est tissée pour pouvoir être surchargée)
function Uzers_autoUserOuCreateurOuAdmin(&$paramAuto) {
global $CONFIG;
if (Uzers_autoUser($paramAuto) && Uzers_autoCreateurOuAdmin($paramAuto))
return Beurk_message("Vous n'êtes ni ce User ni son créateur", 'Uzers');
}
// ------------------------------------------------- Permissions --------------------------------------------------------------
//rem charge toutes les contraintes de périmètre et détermine si l'action (ou vue) est autorisée (ou peut l'être en fonction du périmètre)
// renvoie (-1=action interdite; 0=permission non paramétrée; 1=autorisation dépendant du périmètre;
// 2=autorisé par défaut pour ce type d'entité; 3=action autorisée)
function Uzers_recherchePermissions(&$paramAuto) {
global $DIALOG, $CONFIG;
//recherche en session si demande déjà historisée
$ClefPermission = ($ActMaj = $paramAuto['ActMaj']) . '.' . ($IdMaj = $paramAuto['IdMaj']);
// if (isset($DIALOG['Permissions'][$ClefPermission]))
// return $DIALOG['Permissions'][$ClefPermission]['auto'];
$clausePermission = array();
$entitesPermission = array();
$Groupes = implode(',', $DIALOG['Groupes']); //constitue une liste à partir des groupes du User connecté (ou anonymous)
$EntMaj = Beurk_terminal($IdMaj);
$IdMaj = Beurk_id($IdMaj);
$IdV = Beurk_id('V');
// cette requête renvoie tout les périmètres paramétrés pour l'action demandée
$requete = 'SELECT DISTINCT PP.IdEntite, PP.PermisOuInterdit
FROM Uzers_GroupePermission AS GP
JOIN Uzers_Permission AS P ON P.IdPermission = GP.IdPermission
JOIN Uzers_PermissionAction AS PAV ON PAV.IdPermission = P.IdPermission
JOIN Uzers_PermissionPerimetre AS PP ON PP.IdPermission = P.IdPermission
WHERE GP.IdGroupe IN (' . $Groupes . ') AND GP.IdEtat = "' . $IdV . '" AND P.IdEtat = "' . $IdV . '"
AND PAV.IdAction = "' . $CONFIG['Action'][$ActMaj]['Id'] . '" AND PAV.IdEntite IN ("' . $IdMaj . '", "' . $CONFIG['Entite'][$EntMaj]['Id'] . '")';
// ORDER BY PP.IdEntite, PP.PermisOuInterdit';
//echo "\n<!-- $requete --> \n";
$result = db_QUERY($requete);
if (db_NB_SELECTED($result) == 0) { //aucune autorisation sur cette combinaison
$auto = -1;
$clausePermission['0'] = ' = 1';
} else {
$auto = 0; //init résultat de la recherche
// init variable de calcul de la clause de sélection du périmètre
$tabIdPerimetre = array();
while (list($IdEntPerimetre, $PermisOuInterdit) = db_FETCH_ROW($result)) {
$EntPerimetre = Beurk_terminal($IdEntPerimetre);
// 1ère fonction : recherche si permission accordée
//echo " Uzers_calculeAutoPermission($auto, $EntMaj, $IdMaj, $EntPerimetre, $IdEntPerimetre, $PermisOuInterdit) = ";
$auto = Uzers_calculeAutoPermission($auto, $EntMaj, $IdMaj, $EntPerimetre, $IdEntPerimetre, $PermisOuInterdit);
//echo " $auto; ";
// stockage des Id par entité pour la 2ème fonction
if (! isset($tabIdPerimetre[$EntPerimetre])) {
$tabIdPerimetre[$EntPerimetre][0] = array(); //permis
$tabIdPerimetre[$EntPerimetre][1] = array(); //interdit
}
$tabIdPerimetre[$EntPerimetre][$PermisOuInterdit][] = $IdEntPerimetre;
}
// 2ème fonction : constitution des clauses de filtrage par Id
Uzers_constitueClausePermission($clausePermission, $entitesPermission, $tabIdPerimetre); // variables passées par référence
}
db_FREE($result);
// stockage en session
$DIALOG['Permissions'][$ClefPermission] = array('auto' => $auto,
'clauses' => $clausePermission, // utilisé pour compléter les tabQueries
'Entite' => $entitesPermission); // utilisé pour vérifier une action sur un périmètre
return $auto;
}
// recalcule l'autorisation en fonction de l'entité lue / entité de la permission
function Uzers_calculeAutoPermission($auto, $EntMaj, $IdMaj, $EntPerm, $IdPerm, $PermisOuInterdit) {
global $CONFIG;
// cas 1 : même entité exactement
if ($IdMaj == $IdPerm) {
if ($PermisOuInterdit == 0) //autorisé
return 3;
elseif ($auto <= 2) //interdit, sauf si explicitement autorisé ($auto = 3)
return -1;
// cas 2 : entité de types différents
} elseif ($EntMaj != $EntPerm) {
if ($PermisOuInterdit == 0) {
if ($auto == 0) // pourrait être autorisé
return 1;
} elseif ($auto <= 2) // pourrait être interdit
return 1;
// cas 3 : même type, et le périmètre porte sur toutes les entités du type EntMaj
} elseif ($IdPerm == $CONFIG['Entite'][$EntPerm]['Id']) {
if ($PermisOuInterdit == 0) {
if ($auto > -1) //autorisé, sauf si Id explicitement interdite
return 2;
} elseif ($auto <= 2) //interdit, sauf si Id explicitement autorisé ($auto = 3)
return -1;
// cas 4 : même type, mais autre Id...
}
return $auto; // pas de changement
}
// fonction appelée par la fonction ci-dessus à rupture EntPerm, pour compléter la clause de filtrage
function Uzers_constitueClausePermission(&$clausePermission, &$entitesPermission, &$tabIdPerimetre) {
global $CONFIG;
$autoParDefaut = 0; // par défaut
$clause = '';
// boucle sur les entités
foreach($tabIdPerimetre as $EntPerm => &$tabParEnt) {
$IdEntPerm = $CONFIG['Entite'][$EntPerm]['Id'];
// recherche si un id interdit est aussi présent dans les permis
foreach($tabParEnt[1] as $indice => $idInterdit) {
if (in_array($idInterdit, $tabParEnt[0])) // en cas de conflit, c'est le permis qui l'emporte
unset($tabParEnt[1][$indice]); //suppression de l'item interdit
}
// si toutes ces entités sont permises par défaut
if (($indice = array_search($IdEntPerm, $tabParEnt[0])) !== false) {
$autoParDefaut = 1;
unset($tabParEnt[0][$indice]); //on le retire du tableau
}
// si toutes ces entités sont interdites par défaut
if (($indice = array_search($IdEntPerm, $tabParEnt[1])) !== false) {
$autoParDefaut = -1;
unset($tabParEnt[1][$indice]); //on le retire du tableau
}
// si pas de défaut : on prend la condition inverse des cas particuliers rencontrés
if ($autoParDefaut == 0) {
if (count($tabParEnt[0]) > 0) // il y a des id particulières permises
$autoParDefaut = -1; // => par défaut : interdit
else
$autoParDefaut = 1; // le contraire
}
// selon la combinaison de cas
if ($autoParDefaut == 1) { //par défaut autorisé : on ne garde que les id interdites (et sous-entendu 1=1 si aucune)
if (count($tabParEnt[1]) > 0) {
$clausePermission['Id' . $EntPerm] = 'NOT IN (' . implode(',', $tabParEnt[1]) . ')';
$entitesPermission[$EntPerm] = array('permis' => false, 'liste' => $tabParEnt[1]);
} else {
$entitesPermission[$EntPerm] = array('permis' => false, 'liste' => array());
}
} elseif ($autoParDefaut == -1) { // par défaut interdit : on ne garde que les id permises, et 0=1 si aucune
if (count($tabParEnt[0]) > 0) {
$clausePermission['Id' . $EntPerm] = 'IN (' . implode(',', $tabParEnt[0]) . ')';
$entitesPermission[$EntPerm] = array('permis' => true, 'liste' => $tabParEnt[0]);
} else {
$clausePermission['Id' . $EntPerm] = '= -1'; //aucune Id permise
$entitesPermission[$EntPerm] = array('permis' => true, 'liste' => array());
}
}
}
unset ($tabParEnt); //passé par référence dans le foreach : à réinitialiser par sécurité
return true;
}
// cette fontion complète la clause WHERE des requêtes (tableau) soumises à Permissions, ou à filtre sur le code IdEtat
// selon la clef de permission stockée dans $TRANSAC[Etape]['ClefPermission']
function Uzers_ajoutePermissionQUERY(&$tabRequete) {
global $TRANSAC, $DIALOG;
if (! isset($tabRequete['SELECT']) || ! is_array($select = $tabRequete['SELECT']))
die('la clause SELECT envoyée à Uzers_ajoutePermissionQUERY() doit être un array.');
$ajoutWhere = '';
if (isset($DIALOG['Permissions'][$TRANSAC[ $TRANSAC['Etape'] ]['ClefPermission']])) // si pas renseigné, c'est que cette action n'est pas soumise à Permission (même si la requête SQL le prévoit)
$tabClauses =& $DIALOG['Permissions'][$TRANSAC[ $TRANSAC['Etape'] ]['ClefPermission']]['clauses'];
else
$tabClauses = array();
foreach($select as $surnom => $colonnePrefixee) { // boucle sur toutes les colonnes du SELECT
$tabCol = explode('.', $colonnePrefixee);
$colonne = (isset($tabCol[1])) ? $tabCol[1] : $colonnePrefixee;
// 1) ajout dans la clause WHERE des filtres sur le code IdEtat des entités lues
if ($surnom === 'IdEtat' || $colonnePrefixee === 'IdEtat') // le nom de la colonne ou de la colonne renommée (avec AS) matche
$ajoutWhere = db_AND($ajoutWhere, 'IdEtat IN (' . $DIALOG['IdEtatsAutorises'] . ')');
elseif ($colonne === 'IdEtat')
$ajoutWhere = db_AND($ajoutWhere, $colonnePrefixee . ' IN (' . $DIALOG['IdEtatsAutorises'] . ')');
// 2) ajout dans la clause WHERE des clauses de permission
foreach($tabClauses as $EntPerm => $condition) {
if ($surnom === $EntPerm || $colonnePrefixee === $EntPerm) // le nom de la colonne ou de la colonne renommée (avec AS) matche
$ajoutWhere = db_AND($ajoutWhere, $EntPerm . ' ' . $condition);
elseif ($colonne === $EntPerm)
$ajoutWhere = db_AND($ajoutWhere, $colonnePrefixee . ' ' . $condition);
}
}
// 3) concaténation des clauses WHERE
if ($ajoutWhere != '') {
if (! isset($tabRequete['WHERE']))
$tabRequete['WHERE'] = $ajoutWhere;
else
$tabRequete['WHERE'] = db_AND('(' . $tabRequete['WHERE'] . ')', $ajoutWhere);
}
return $tabRequete;
}
// cette fontion vérifie si l'action est autorisée par les permissions, compte-tenu du périmètre.
// ne peut être appelée qu'après appel à la fonction Uzers_recherchePermissions, et si celle-ci a renvoyé 1 = autorisation dépendant du périmètre
function Uzers_verifiePerimetrePermissions(&$paramAuto) {
global $TRANSAC, $DIALOG;
// la permission est en session
$clefPermission = $paramAuto['ActMaj'] . '.' . $paramAuto['IdMaj'];
$permission =& $DIALOG['Permissions'][$clefPermission]['Entite'];
// chemin complet de l'entité
$chemin[0] = $paramAuto['IdMaj']; // 1er noeud
$profondeur = 0;
if (isset($paramAuto['IdRef'])) {
$chemin[1] = $paramAuto['IdRef']; // 2ème noeud (les controleurs Vue et Maj alimentent IdRef à partir des données retournées par l'utilisateur ou des relations)
$profondeur = 1;
}
$fin = false;
while (! $fin) {
$idSup = Beurk_estElementDe($chemin[$profondeur]); // nème noeud
if ($idSup == null || in_array($idSup, $chemin)) // si on arrive au bout ou si on retombe sur un noeud déjà dans le chemin
$fin = true;
else {
$profondeur +=1;
$chemin[$profondeur] = $idSup;
}
}
//var_dump($chemin);
// parcours du chemin ascendant et contrôle des périmètres
$autoDefaut = 1; //autorisation par défaut
foreach($chemin as $idNoeud) {
$entNoeud = Beurk_terminal($idNoeud);
if (isset($permission[$entNoeud])) { // la permission a des contraintes sur ce type d'entité
$tabEntite =& $permission[$entNoeud];
if ($tabEntite['permis'] == true) {
if (in_array($idNoeud, $tabEntite['liste'])) // idNoeud fait partie du périmètre explicitement permis
return 3;
if (empty($tabEntite['liste'])) // la liste des permis est vide : par défaut, tout est interdit
$autoDefaut = -1;
} else {
if (in_array($idNoeud, $tabEntite['liste'])) // idNoeud fait partie du périmètre explicitement interdit
return -1;
if (empty($tabEntite['liste'])) // la liste des interdits est vide : par défaut, tout est permis
$autoDefaut = 2;
}
}
}
//echo '...defaut=', $autoDefaut;
return $autoDefaut; // périmètre non trouvé précisément : la permission par défaut s'applique
}
// -------------------------------------------- Mises à jour ------------------------------------------------------------
// enregistre la nouvelle feuille de style en préférence du User
function Uzers_stockePreferenceStyle($newStyle) {
global $DIALOG;
db_QUERY("UPDATE Uzers_User SET IdStyle='$newStyle' WHERE IdUser='" . $DIALOG['IdUser'] . "'");
}