<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2007                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined("_ECRIRE_INC_VERSION")) return;    #securite

include_spip('inc/headers');
include_spip('inc/session');
include_spip('inc/cookie');
include_spip('inc/texte');

/* Loading simplesamlphp */
include_spip('inc/simplesamlphp/lib/_autoload');

// http://doc.spip.org/@balise_URL_LOGOUT
function balise_LOGIN_SAML ($p) {
    spip_log("[auth_saml] balise_LOGIN_SAML");
    return calculer_balise_dynamique($p,'LOGIN_SAML', array());
}

// $args[0] = url destination apres logout [(#URL_LOGOUT{url})]
// http://doc.spip.org/@balise_URL_LOGOUT_stat
function balise_LOGIN_SAML_stat ($args, $filtres) {
        return array($args[0]);
}

// http://doc.spip.org/@balise_URL_LOGOUT_dyn
function balise_LOGIN_SAML_dyn() 
{
    $simplesaml = new SimpleSAML_Auth_Simple('default-sp');

    spip_log("[auth_saml] balise_LOGIN_SAML_dyn");

    if (!$simplesaml->isAuthenticated()) {
        spip_log("[auth_saml] required auth");
        $simplesaml->requireAuth();
    }
    else return login_saml_successfull();
}

function generate_password($length = 15) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*\_-~#/!+={[]}()&$%';
    $count = mb_strlen($chars);

    for ($i = 0, $result = ''; $i < $length; $i++) {
        $index = rand(0, $count - 1);
        $result .= mb_substr($chars, $index, 1);
    }

    return $result;
}

function update_numeros($titre, $type, $numero, $id_auteur) {
    /* $type: cell, home, fax */
    if ($numero) {
        $id_numero = null;
        spip_log("[auth_saml] sync numero $titre $type $numero $id_auteur");
        $result = spip_query("SELECT id_numero, type FROM spip_numeros_liens WHERE id_objet=$id_auteur and objet='auteur'");
        while ($row = spip_fetch_array($result)) {
            if ($row['type'] == $type) {
                $id_numero = $row['id_numero'];
            }
        }
        if ($id_numero) {
            spip_log("[auth_saml] mise a jour du mobile $id_numero");
            spip_query("UPDATE spip_numeros SET numero='$numero' WHERE id_numero='$id_numero'");
        }
        else {
            spip_log("[auth_saml] ajout d'un numero $type");
            $champs = pipeline('pre_insertion', array(
                        'args' => array(
                            'table' => 'spip_numeros',
                            ),
                        'data' => array(
                        'numero' => $numero,
                        'titre' => $titre
                        )
                        ));
            $id_numero = sql_insertq("spip_numeros", $champs);
            $c = array('objet' => 'auteur',
                    'id_objet' => $id_auteur,
                    'type' => $type,
                    'id_numero' => $id_numero
                    );
            sql_insertq("spip_numeros_liens", $c);
        }
    }
}

function login_saml_successfull()
{
    $simplesaml = new SimpleSAML_Auth_Simple('default-sp');

    spip_log("[auth_saml] Traitement login SAML");

    $attributes = $simplesaml->getAttributes();
    $login = $attributes['uid'][0];
    $first_name = $attributes['gn'][0];
    $last_name = $attributes['sn'][0];
    $email = $attributes['email'][0];
    $nameid = $attributes['NameID'][0];
    $display_name = $first_name . ' ' . $last_name;
    $street = $attributes['street'][0];
    $zipcode = $attributes['postalCode'][0];
    $city = $attributes['l'][0];
    $mobile = $attributes['mobile'][0];
    $phone = $attributes['telephoneNumber'][0];
    $fax = $attributes['fax'][0];

    if (!$nameid) {
        spip_log("[auth_saml] no NameID found in SAML attributes, cancel login", _LOG_ERREUR);
        redirige_par_entete('/');
    }

    spip_log("[auth_saml] authentification reussi pour l'utilisateur =".$email);

    // Si l'utilisateur figure deja dans la base, y recuperer les infos
    $result = spip_query("SELECT * FROM spip_auteurs WHERE nameid=". _q($nameid) ." AND statut<>'6form'");
    $row_auteur = spip_fetch_array($result);

    if (!$row_auteur) {
        $result = spip_query("SELECT * FROM spip_auteurs WHERE email=". _q($email) ." AND statut<>'6form'" );
        $row_auteur = spip_fetch_array($result);
    }

    spip_log("[auth_saml] attribus utilisateur =".$row_auteur['login']);

    if ($row_auteur) {
        spip_log("[auth_saml] updating user [" . $email . "]");
        spip_log("[auth_saml] display name : $display_name and login : $login");
        if (! $row_auteur['nameid'])
            spip_query("UPDATE spip_auteurs SET nameid=" . _q($nameid) . " WHERE email="._q($email));
        spip_query("UPDATE spip_auteurs SET nom=". _q($display_name) .", login=". _q($login) .", email="._q($email)." WHERE nameid="._q($nameid));

    }
    else
    {
        spip_log("[auth_saml] creating user [" . $login . "]");
        spip_log("[auth_saml] display name : $display_name and email : $email");
        $pass = hash('sha256', generate_password());
        spip_query("INSERT INTO spip_auteurs (nameid, nom, login, email, pass, statut, webmestre) VALUES
            ('$nameid', '$display_name', '$login', '$email', '$pass', '6forum', 'non')");
        // On recupere l('utilisateur
        $result = spip_query("SELECT * FROM spip_auteurs WHERE nameid=" ._q($nameid). " AND statut<>'6forum'" );
        $row_auteur = spip_fetch_array($result);
    }
    if ($street || $zipcode || $city) {
        $adresse_id = null;
        spip_log("[auth_saml] sync address {$row_auteur['id_auteur']}");
        $result = spip_query("SELECT id_adresse, type FROM spip_adresses_liens WHERE id_objet={$row_auteur['id_auteur']} and objet='auteur'");
        while ($row = spip_fetch_array($result)) {
            if ($row['type'] == 'pref') {
                $adresse_id = $row['id_adresse'];
            }
        }
        if ($adresse_id) {
            spip_log("[auth_saml] mise a jour de l'adresse $adresse_id");
            spip_query("UPDATE spip_adresses SET voie=". _q($street) .", code_postal=". _q($zipcode) .", ville="._q($city)." WHERE id_adresse="._q($adresse_id));
        }
        else {
            spip_log("[auth_saml] ajout d'une nouvelle adresse");
            $champs = pipeline('pre_insertion', array(
                        'args' => array(
                            'table' => 'spip_adresses',
                            ),
                        'data' => array('voie' => $street,
                            'code_postal' => $zipcode,
                            'ville' => $city)
                        ));
            $id_adresse = sql_insertq("spip_adresses", $champs);
            $c = array('objet' => 'auteur',
                    'id_objet' => $row_auteur['id_auteur'],
                    'type' => 'pref',
                    'id_adresse' => $id_adresse
                    );
            sql_insertq("spip_adresses_liens", $c);
        }
    }
    update_numeros('Téléphone mobile', 'cell', $mobile, $row_auteur['id_auteur']);
    update_numeros('Téléphone fixe', 'home', $phone, $row_auteur['id_auteur']);
    update_numeros('Fax', 'fax', $fax, $row_auteur['id_auteur']);

    // Debug
    spip_log('[auth_saml] nameid :' . $row_auteur['nameid'] . ' status : ' . $row_auteur['statut'] . ' email : ' . $row_auteur['email']);
    // chargement de l'utilisateur en session
    $GLOBALS['auteur_session'] =  $row_auteur;
    $session = charger_fonction('session', 'inc');
    $cookie_session = $session($row_auteur);
    spip_setcookie('spip_session', $cookie_session);
    $next_url = $_GET['url'];
    spip_log('[auth_saml] redirect ' . $next_url);
    redirige_par_entete($next_url);
}

?>
