X-Git-Url: http://git.cyclocoop.org/?p=velocampus%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Finc%2Fauth.php;fp=www%2Fecrire%2Finc%2Fauth.php;h=31cb420b427194d348e4d8270e00fea7cf7d8ede;hp=0000000000000000000000000000000000000000;hb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed;hpb=aaf970bf4cdaf76689ecc10609048e18d073820c diff --git a/www/ecrire/inc/auth.php b/www/ecrire/inc/auth.php new file mode 100644 index 0000000..31cb420 --- /dev/null +++ b/www/ecrire/inc/auth.php @@ -0,0 +1,673 @@ + $s)); + include_spip('inc/modifier'); + revision_auteur($id_auteur, array('bio'=>'')); + include_spip('inc/session'); + session_set('statut',$s); + return $s; +} + +// Fonction d'authentification. Retourne: +// - URL de connexion si on ne sait rien (pas de cookie, pas Auth_user); +// - un tableau si visiteur sans droit (tableau = sa ligne SQL) +// - code numerique d'erreur SQL +// - une chaine vide si autorisation a penetrer dans l'espace prive. + +// http://doc.spip.org/@inc_auth_dist +function inc_auth_dist() { + + global $connect_login ; + + $row = auth_mode(); + + if ($row) return auth_init_droits($row); + + if (!$connect_login) return auth_a_loger(); + + // Cas ou l'auteur a ete identifie mais on n'a pas d'info sur lui + // C'est soit parce que la base est inutilisable, + // soit parce que la table des auteurs a changee (restauration etc) + // Pas la peine d'insister. + // Renvoyer le nom fautif et une URL de remise a zero + + if (spip_connect()) + return array('login' => $connect_login, + 'site' => generer_url_public('', "action=logout&logout=prive")); + + $n = intval(sql_errno()); + spip_log("Erreur base de donnees $n " . sql_error()); + return $n ? $n : 1; +} + +// fonction appliquee par ecrire/index sur le resultat de la precedente +// en cas de refus de connexion. +// Retourne un message a afficher ou redirige illico. + +function auth_echec($raison) +{ + include_spip('inc/minipres'); + include_spip('inc/headers'); + // pas authentifie. Pourquoi ? + if (is_string($raison)) { + // redirection vers une page d'authentification + // on ne revient pas de cette fonction + // sauf si pb de header + $raison = redirige_formulaire($raison); + } elseif (is_int($raison)) { + // erreur SQL a afficher + $raison = minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'). "
".sql_errno()." ".sql_error()."
"); + } elseif (@$raison['statut']) { + // un simple visiteur n'a pas acces a l'espace prive + spip_log("connexion refusee a " . @$raison['id_auteur']); + $raison = minipres(_T('avis_erreur_connexion'),_T('avis_erreur_visiteur')); + } else { + // auteur en fin de droits ... + $h = $raison['site']; + $raison = minipres(_T('avis_erreur_connexion'), + ""
+ . _T('texte_inc_auth_1',
+ array('auth_login' => $raison['login']))
+ . " "
+ . _T('texte_inc_auth_2')
+ . ""
+ . _T('texte_inc_auth_3'));
+ }
+ return $raison;
+}
+
+// Retourne la description d'un authentifie par cookie ou http_auth
+// Et affecte la globale $connect_login
+
+function auth_mode()
+{
+ global $auth_can_disconnect, $ignore_auth_http, $ignore_remote_user;
+ global $connect_login ;
+
+ //
+ // Initialiser variables (eviter hacks par URL)
+ //
+
+ $connect_login = '';
+ $id_auteur = NULL;
+ $auth_can_disconnect = false;
+
+ //
+ // Recuperer les donnees d'identification
+ //
+
+ // Session valide en cours ?
+ if (isset($_COOKIE['spip_session'])) {
+ $session = charger_fonction('session', 'inc');
+ if ($id_auteur = $session()
+ OR $id_auteur===0 // reprise sur restauration
+ ) {
+ $auth_can_disconnect = true;
+ $connect_login = $GLOBALS['visiteur_session']['login'];
+ } else unset($_COOKIE['spip_session']);
+ }
+
+ // Essayer auth http si significatif
+ // (ignorer les login d'intranet independants de spip)
+ if (!$ignore_auth_http) {
+ if (
+ (isset($_SERVER['PHP_AUTH_USER']) AND isset($_SERVER['PHP_AUTH_PW'])
+ AND $r = lire_php_auth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))
+ OR
+ // Si auth http differtente de basic, PHP_AUTH_PW
+ // est indisponible mais tentons quand meme pour
+ // autocreation via LDAP
+ (isset($_SERVER['REMOTE_USER'])
+ AND $r = lire_php_auth($_SERVER['PHP_AUTH_USER'] = $_SERVER['REMOTE_USER'], ''))
+ ) {
+ if (!$id_auteur) {
+ $_SERVER['PHP_AUTH_PW'] = '';
+ $auth_can_disconnect = true;
+ $GLOBALS['visiteur_session'] = $r;
+ $connect_login = $GLOBALS['visiteur_session']['login'];
+ } else {
+ // cas de la session en plus de PHP_AUTH
+ /* if ($id_auteur != $r['id_auteur']){
+ spip_log("vol de session $id_auteur" . join(', ', $r));
+ unset($_COOKIE['spip_session']);
+ $id_auteur = '';
+ } */
+ }
+ }
+ // Authentification .htaccess old style, car .htaccess semble
+ // souvent definir *aussi* PHP_AUTH_USER et PHP_AUTH_PW
+ else if (isset($_SERVER['REMOTE_USER']))
+ $connect_login = $_SERVER['REMOTE_USER'];
+ }
+
+ $where = (is_numeric($id_auteur)
+ /*AND $id_auteur>0*/ // reprise lors des restaurations
+ ) ?
+ "id_auteur=$id_auteur" :
+ (!strlen($connect_login) ? '' : "login=" . sql_quote($connect_login));
+
+ if (!$where) return '';
+
+ // Trouver les autres infos dans la table auteurs.
+ // le champ 'quand' est utilise par l'agenda
+
+ return sql_fetsel("*, en_ligne AS quand", "spip_auteurs", "$where AND statut!='5poubelle'");
+}
+
+//
+// Init des globales pour tout l'espace prive si visiteur connu
+// Le tableau global visiteur_session contient toutes les infos pertinentes et
+// a jour (tandis que $visiteur_session peut avoir des valeurs un peu datees
+// s'il est pris dans le fichier de session)
+// Les plus utiles sont aussi dans les variables simples ci-dessus
+// si la globale est vide ce n'est pas un tableau, on la force pour empecher un warning
+
+function auth_init_droits($row)
+{
+ global $connect_statut, $connect_toutes_rubriques, $connect_id_rubrique, $connect_login, $connect_id_auteur;
+
+ $connect_id_auteur = $row['id_auteur'];
+ $connect_login = $row['login'];
+ $connect_statut = acces_statut($connect_id_auteur, $row['statut'], $row['bio']);
+
+
+ $GLOBALS['visiteur_session'] = array_merge((array)$GLOBALS['visiteur_session'], $row);
+ $r = @unserialize($row['prefs']);
+ $GLOBALS['visiteur_session']['prefs'] =
+ (@isset($r['couleur'])) ? $r : array('couleur' =>1, 'display'=>0);
+
+ // au cas ou : ne pas memoriser les champs sensibles
+ unset($GLOBALS['visiteur_session']['pass']);
+ unset($GLOBALS['visiteur_session']['htpass']);
+ unset($GLOBALS['visiteur_session']['alea_actuel']);
+ unset($GLOBALS['visiteur_session']['alea_futur']);
+
+ // rajouter les sessions meme en mode auth_http
+ // pour permettre les connexions multiples et identifier les visiteurs
+ if (!isset($_COOKIE['spip_session'])) {
+ $session = charger_fonction('session', 'inc');
+ if ($spip_session = $session($row)) {
+ include_spip('inc/cookie');
+ spip_setcookie(
+ 'spip_session',
+ $_COOKIE['spip_session'] = $spip_session,
+ time() + 3600 * 24 * 14
+ );
+ }
+ }
+
+ // Etablir les droits selon le codage attendu
+ // dans ecrire/index.php ecrire/prive.php
+
+ // Pas autorise a acceder a ecrire ? renvoyer le tableau
+ // A noter : le premier appel a autoriser() a le bon gout
+ // d'initialiser $GLOBALS['visiteur_session']['restreint'],
+ // qui ne figure pas dans le fichier de session
+ include_spip('inc/autoriser');
+
+ if (!autoriser('ecrire'))
+ return $row;
+
+ // autoriser('ecrire') ne laisse passer que les Admin et les Redac
+
+ auth_trace($row);
+
+ // Administrateurs
+ if ($connect_statut == '0minirezo') {
+ if (is_array($GLOBALS['visiteur_session']['restreint']))
+ $connect_id_rubrique = $GLOBALS['visiteur_session']['restreint'];
+ $connect_toutes_rubriques = !$connect_id_rubrique;
+ }
+ // Pour les redacteurs, inc_version a fait l'initialisation minimale
+
+ return ''; // i.e. pas de pb.
+}
+
+function auth_a_loger()
+{
+ $redirect = generer_url_public('login',
+ "url=" . rawurlencode(self('&',true)), '&');
+
+ // un echec au "bonjour" (login initial) quand le statut est
+ // inconnu signale sans doute un probleme de cookies
+ if (isset($_GET['bonjour']))
+ $redirect = parametre_url($redirect,
+ 'var_erreur',
+ (!isset($GLOBALS['visiteur_session']['statut'])
+ ? 'cookie'
+ : 'statut'
+ ),
+ '&'
+ );
+ return $redirect;
+}
+
+// http://doc.spip.org/@auth_trace
+function auth_trace($row, $date=null)
+{
+ // Indiquer la connexion. A la minute pres ca suffit.
+ if (!is_numeric($connect_quand = $row['quand']))
+ $connect_quand = strtotime($connect_quand);
+
+ if (is_null($date))
+ $date = date('Y-m-d H:i:s');
+
+ if (abs(strtotime($date) - $connect_quand) >= 60) {
+ sql_updateq("spip_auteurs", array("en_ligne" => $date), "id_auteur=" .$row['id_auteur']);
+ }
+}
+
+
+/** ----------------------------------------------------------------------------
+ * API Authentification, gestion des identites centralisees
+ */
+
+/**
+ * Fonction aiguillage, privee
+ * @param string $fonction
+ * @param array $args
+ * @param mixed $defaut
+ * @return mixed
+ */
+function auth_administrer($fonction,$args,$defaut=false){
+ $auth_methode = array_shift($args);
+ $auth_methode = $auth_methode ? $auth_methode : 'spip'; // valeur par defaut au cas ou
+ if ($auth = charger_fonction($auth_methode,'auth',true)
+ AND function_exists($f="auth_{$auth_methode}_$fonction")
+ )
+ return call_user_func_array($f, $args);
+ else
+ return $defaut;
+}
+
+/**
+ * Pipeline pour inserer du contenu dans le formulaire de login
+ *
+ * @param array $flux
+ * @return array
+ */
+function auth_formulaire_login($flux){
+ foreach ($GLOBALS['liste_des_authentifications'] as $methode)
+ $flux = auth_administrer('formulaire_login',array($methode,$flux),$flux);
+ return $flux;
+}
+
+
+
+/**
+ * Retrouver le login interne lie a une info login saisie
+ * la saisie peut correspondre a un login delegue
+ * qui sera alors converti en login interne apres verification
+ *
+ * @param string $login
+ * @param string $serveur
+ * @return string/bool
+ */
+function auth_retrouver_login($login, $serveur=''){
+ if (!spip_connect($serveur)) {
+ include_spip('inc/minipres');
+ echo minipres(_T('info_travaux_titre'),
+ _T('titre_probleme_technique'));
+ exit;
+ }
+
+ foreach ($GLOBALS['liste_des_authentifications'] as $methode) {
+ if ($auteur = auth_administrer('retrouver_login',array($methode, $login, $serveur))) {
+ return $auteur;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * informer sur un login
+ * Ce dernier transmet le tableau ci-dessous a la fonction JS informer_auteur
+ * Il est invoque par la fonction JS actualise_auteur via la globale JS
+ * page_auteur=#URL_PAGE{informer_auteur} dans le squelette login
+ * N'y aurait-il pas plus simple ?
+ *
+ * @param string $login
+ * @param string $serveur
+ * @return array
+ */
+function auth_informer_login($login, $serveur=''){
+ if (!$login
+ OR !$login = auth_retrouver_login($login, $serveur)
+ OR !$row = sql_fetsel('*','spip_auteurs','login='.sql_quote($login),'','','','',$serveur)
+ )
+ return array();
+
+ $prefs = unserialize($row['prefs']);
+ $infos = array(
+ 'id_auteur'=>$row['id_auteur'],
+ 'login'=>$row['login'],
+ 'cnx' => ($prefs['cnx'] == 'perma') ? '1' : '0',
+ 'logo' => recuperer_fond('formulaires/inc-logo_auteur', $row),
+ );
+
+ // desactiver le hash md5 si pas auteur spip ?
+ if ($row['source']!=='spip'){
+ $row['alea_actuel']= '';
+ $row['alea_futur']= '';
+ }
+ verifier_visiteur();
+
+ return auth_administrer('informer_login',array($row['source'],$infos, $row, $serveur),$infos);
+}
+
+
+/**
+ * Essayer les differentes sources d'authenfication dans l'ordre specifie.
+ * S'en souvenir dans visiteur_session['auth']
+ *
+ * @param string $login
+ * @param string $password
+ * @param string $serveur
+ * @return mixed
+ */
+function auth_identifier_login($login, $password, $serveur=''){
+ $erreur = "";
+ foreach ($GLOBALS['liste_des_authentifications'] as $methode) {
+ if ($auth = charger_fonction($methode, 'auth',true)){
+ $auteur = $auth($login, $password, $serveur);
+ if (is_array($auteur) AND count($auteur)) {
+ spip_log("connexion de $login par methode $methode");
+ $auteur['auth'] = $methode;
+ return $auteur;
+ }
+ elseif (is_string($auteur))
+ $erreur .= "$auteur ";
+ }
+ }
+ return $erreur;
+}
+
+/**
+ * Fournir une url de retour apres login par un SSO
+ * pour finir l'authentification
+ *
+ * @param string $auth_methode
+ * @param string $login
+ * @param string $serveur
+ * @return string
+ */
+function auth_url_retour_login($auth_methode, $login, $redirect='', $serveur=''){
+ $securiser_action = charger_fonction('securiser_action','inc');
+ return $securiser_action('auth', "$auth_methode/$login", $redirect, true);
+}
+
+function auth_terminer_identifier_login($auth_methode, $login, $serveur=''){
+ $args = func_get_args();
+ $auteur = auth_administrer('terminer_identifier_login',$args);
+ return $auteur;
+}
+
+ /**
+ * Loger un auteur suite a son identification
+ *
+ * @param array $auteur
+ */
+ function auth_loger($auteur, $refuse_cookie_admin=false){
+ if (!is_array($auteur) OR !count($auteur))
+ return false;
+
+ $session = charger_fonction('session', 'inc');
+ $session($auteur);
+ $p = ($auteur['prefs']) ? unserialize($auteur['prefs']) : array();
+ $p['cnx'] = ($auteur['cookie'] == 'oui') ? 'perma' : '';
+ $p = array('prefs' => serialize($p));
+ sql_updateq('spip_auteurs', $p, "id_auteur=" . $auteur['id_auteur']);
+
+ if ($auteur['statut'] == 'nouveau') {
+ $session(); // charger la session car on va la modifier
+ $auteur['statut'] = acces_statut($auteur['id_auteur'], $auteur['statut'], $auteur['bio']);
+ }
+
+ // Si on est admin, poser le cookie de correspondance
+ include_spip('inc/cookie');
+ if (!$refuse_cookie_admin AND $auteur['statut'] == '0minirezo') {
+ spip_setcookie('spip_admin', '@'.$auteur['login'],
+ time() + 7 * 24 * 3600);
+ }
+ // sinon le supprimer ...
+ else {
+ spip_setcookie('spip_admin', '',1);
+ }
+
+ // bloquer ici le visiteur qui tente d'abuser de ses droits
+ verifier_visiteur();
+ return true;
+}
+
+
+function auth_deloger(){
+ $logout = charger_fonction('logout','action');
+ $logout();
+}
+
+/**
+ * Tester la possibilite de modifier le login d'authentification
+ * pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $serveur
+ * @return bool
+ */
+function auth_autoriser_modifier_login($auth_methode, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('autoriser_modifier_login',$args);
+}
+
+/**
+ * Verifier la validite d'un nouveau login pour modification
+ * pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $new_login
+ * @param int $id_auteur
+ * @param string $serveur
+ * @return string
+ * message d'erreur ou chaine vide si pas d'erreur
+ */
+function auth_verifier_login($auth_methode, $new_login, $id_auteur=0, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('verifier_login',$args,'');
+}
+
+/**
+ * Modifier le login d'un auteur pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $new_login
+ * @param int $id_auteur
+ * @param string $serveur
+ * @return bool
+ */
+function auth_modifier_login($auth_methode, $new_login, $id_auteur, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('modifier_login',$args);
+}
+
+/**
+ * Tester la possibilite de modifier le pass
+ * pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $serveur
+ * @return bool
+ * succes ou echec
+ */
+function auth_autoriser_modifier_pass($auth_methode, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('autoriser_modifier_pass',$args);
+}
+
+/**
+ * Verifier la validite d'un pass propose pour modification
+ * pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $login
+ * @param string $new_pass
+ * @param int $id_auteur
+ * @param string $serveur
+ * @return string
+ * message d'erreur ou chaine vide si pas d'erreur
+ */
+function auth_verifier_pass($auth_methode, $login, $new_pass, $id_auteur=0, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('verifier_pass',$args,'');
+}
+
+/**
+ * Modifier le mot de passe d'un auteur
+ * pour la methode donnee
+ *
+ * @param string $auth_methode
+ * @param string $login
+ * @param string $new_pass
+ * @param int $id_auteur
+ * @param string $serveur
+ * @return bool
+ * succes ou echec
+ */
+function auth_modifier_pass($auth_methode, $login, $new_pass, $id_auteur, $serveur=''){
+ $args = func_get_args();
+ return auth_administrer('modifier_pass',$args);
+}
+
+/**
+ * Synchroniser un compte sur une base distante pour la methode
+ * donnee lorsque des modifications sont faites dans la base auteur
+ *
+ * @param string $auth_methode
+ * ici true permet de forcer la synchronisation de tous les acces pour toutes les methodes
+ * @param int $id_auteur
+ * @param array $champs
+ * @param array $options
+ * @param string $serveur
+ * @return void
+ */
+function auth_synchroniser_distant($auth_methode=true, $id_auteur=0, $champs=array(), $options = array(), $serveur=''){
+ $args = func_get_args();
+ if ($auth_methode===true OR (isset($options['all']) AND $options['all']==true)){
+ $options['all'] = true; // ajouter une option all=>true pour chaque auth
+ $args = array(true, $id_auteur, $champs, $options, $serveur);
+ foreach ($GLOBALS['liste_des_authentifications'] as $methode) {
+ array_shift($args);
+ array_unshift($args,$methode);
+ auth_administrer('synchroniser_distant',$args);
+ }
+ }
+ else
+ auth_administrer('synchroniser_distant',$args);
+}
+
+
+/**
+ *
+ * @param string $login
+ * @param string $pw
+ * @param string $serveur
+ * @return array
+ */
+function lire_php_auth($login, $pw, $serveur=''){
+
+ $row = sql_fetsel('*', 'spip_auteurs', 'login=' . sql_quote($login),'','','','',$serveur);
+
+ if (!$row) {
+ if (spip_connect_ldap($serveur)
+ AND $auth_ldap = charger_fonction('ldap', 'auth', true))
+ return $auth_ldap($login, $pw, $serveur);
+ return false;
+ }
+ // su pas de source definie
+ // ou auth/xxx introuvable, utiliser 'spip'
+ if (!$auth_methode = $row['source']
+ OR !$auth = charger_fonction($auth_methode, 'auth', true))
+ $auth = charger_fonction('spip', 'auth', true);
+
+ $auteur='';
+ if ($auth)
+ $auteur = $auth($login, $pw, $serveur);
+ // verifier que ce n'est pas un message d'erreur
+ if (is_array($auteur) AND count($auteur))
+ return $auteur;
+ return false;
+}
+
+/**
+ * entete php_auth (est-encore utilise ?)
+ *
+ * @param $raison