From cfd5d6cd5cd413b5056c760fcc7c65b119b458da Mon Sep 17 00:00:00 2001 From: mose Date: Fri, 30 Sep 2022 05:45:50 +0800 Subject: [PATCH] initial --- README.md | 49 +++++++ actions/login.php | 177 +++++++++++++++++++++++ actions/usersettings.php | 3 + templates/login/discourse-login.tpl.html | 13 ++ 4 files changed, 242 insertions(+) create mode 100644 README.md create mode 100644 actions/login.php create mode 100644 actions/usersettings.php create mode 100644 templates/login/discourse-login.tpl.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..1111336 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +Discourse <-> YesWiki +========================= + +Ceci est un repo temporaire pour garder traces de ce qu'on doit mettre au propre + +Discourse comme provider d'auth pour yeswiki +--------------------------------------------- + +- copier le code de ce repo dans `custom/` (en attendant que ca soit mis au propre dans une extension) +- dans discourse admin > settings > login + - activer `enable discourse connect provider` + - dans `discourse connect provider secrets` mettre le nom de domaine du yeswiki et une clé secrete arbitraire +- dans `wakka.config.php` ajouter: +``` +'discourse_connect_url' => 'https:///session/sso_provider', + 'discourse_connect_secret' => '0123456789', +``` + + +Discourse comme systeme de commentaire pour les pages bazar +------------------------------------------------------- + +voir: https://meta.discourse.org/t/embed-discourse-comments-on-another-website-via-javascript/31963 + + +- dans discourse ajouter un host dans `/admin/customize/embedding` +- ajouter un champs bazar custom avec dedans: +``` +
+ +``` +(si dans customhtml, il faut tout mettre sur une seule ligne) + +--- + +mrflos, mose & 12b \ No newline at end of file diff --git a/actions/login.php b/actions/login.php new file mode 100644 index 0000000..d9bec4b --- /dev/null +++ b/actions/login.php @@ -0,0 +1,177 @@ +config['discourse_connect_url']) or empty($this->config['discourse_connect_url'])) { + echo '
'._t('action {{login}} for discourse : valeur de discourse_connect_url manquante dans wakka.config.php.').'
'; + return; +} +if (!isset($this->config['discourse_connect_secret']) or empty($this->config['discourse_connect_secret'])) { + echo '
'._t('action {{login}} for discourse : valeur de discourse_connect_secret manquante dans wakka.config.php.').'
'; + return; +} + +// Lecture des parametres de l'action + +// url d'inscription +$signupurl = 'http'.((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; + +// url du profil +$profileurl = $this->GetParameter('profileurl'); + +// sauvegarde de l'url d'ou on vient +$incomingurl = $this->GetParameter('incomingurl'); +if (empty($incomingurl)) { + $incomingurl = 'http'.((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; +} + +$userpage = $this->GetParameter("userpage"); +// si pas d'url de page de sortie renseignée, on retourne sur la page courante +if (empty($userpage)) { + $userpage = $incomingurl; + // si l'url de sortie contient le passage de parametres de déconnexion, on l'efface + if (isset($_REQUEST["action"]) && $_REQUEST["action"] == "logout") { + $userpage = str_replace('&action=logout', '', $userpage); + } +} else { + if ($this->IsWikiName($userpage)) { + $userpage = $this->href('', $userpage); + } +} + +// classe css pour l'action +$class = $this->GetParameter("class"); + +// classe css pour les boutons +$btnclass = $this->GetParameter("btnclass"); +if (empty($btnclass)) { + $btnclass = 'btn-default'; +} +$nobtn = $this->GetParameter("nobtn"); + +// template par défaut +$template = "discourse-login.tpl.html"; + +$error = ''; +$PageMenuUser = ''; + +// on initialise la valeur vide si elle n'existe pas +if (!isset($_REQUEST["action"])) { + $_REQUEST["action"] = ''; +} + +// cas de la déconnexion +if ($_REQUEST["action"] == "logout") { + $this->LogoutUser(); + $this->SetMessage(_t('LOGIN_YOU_ARE_NOW_DISCONNECTED')); + $this->Redirect(str_replace('&action=logout', '', $incomingurl)); + exit; +} + +// cas de l'identification +if (!empty($_GET["sso"])) { + $sso = $_GET['sso']; + $sig = $_GET['sig']; + + // validate sso + if(hash_hmac('sha256', urldecode($sso), $GLOBALS['wiki']->config['discourse_connect_secret']) !== $sig){ + header("HTTP/1.1 404 Not Found"); + die(); + } + + $sso = urldecode($sso); + $query = array(); + parse_str(base64_decode($sso), $query); + dump($query); + // verify nonce with generated nonce + if($_SESSION['nonce'] != $query['nonce']){ + header("HTTP/1.1 404 Not Found"); + die(); + } + $user = $this->LoadUser($query['username']); + if ($user) { + $this->SetUser($user, 1); + } else { + $this->Query("insert into ".$this->config["table_prefix"]."users set ". + "signuptime = now(), ". + "motto = '', ". + "name = '".mysqli_real_escape_string($this->dblink, $query['username'])."', ". + "email = '".mysqli_real_escape_string($this->dblink, $query['email'])."', ". + "password = md5('generated_by_discourse')"); + + // log in + $this->SetUser($this->LoadUser($query['username'])); + } +} + +// cas d'une personne connectée déjà +if ($user = $this->GetUser()) { + $connected = true; + if ($this->LoadPage("PageMenuUser")) { + $PageMenuUser.= $this->Format("{{include page=\"PageMenuUser\"}}"); + } + + // si pas de pas d'url de profil renseignée, on utilise ParametresUtilisateur + if (empty($profileurl)) { + //TODO : clean up your cochoneries + $profileurl = str_replace('/session/sso_provider', '/u/'.$user['name'].'/preferences/account', $GLOBALS['wiki']->config['discourse_connect_url']); + } elseif ($profileurl == 'WikiName') { + $profileurl = $this->href("edit", $user['name'], ""); + } else { + if ($this->IsWikiName($profileurl)) { + $profileurl = $this->href('', $profileurl); + } + } +} else { + // cas d'une personne non connectée + $connected = false; + + // si l'authentification passe mais la session n'est pas créée, on a un problème de cookie + if ($_REQUEST['action'] == 'checklogged') { + $error = 'Vous devez accepter les cookies pour pouvoir vous connecter.'; + } +} + + +$nonce = hash('sha512', mt_rand()); +$_SESSION['nonce'] = $nonce; + +$payload = base64_encode( http_build_query( array ( + 'nonce' => $nonce, + 'return_sso_url' => $incomingurl + ) +) ); + +$request = array( + 'sso' => $payload, + 'sig' => hash_hmac('sha256', $payload, $GLOBALS['wiki']->config['discourse_connect_secret'] ) + ); + +$query = http_build_query($request); + +$discourse_url = $GLOBALS['wiki']->config['discourse_connect_url'].'?'.$query; + + +// +// on affiche le template +// +$html = $this->render('@login/'.$template, [ + "connected" => $connected, + "user" => ((isset($user["name"])) ? $user["name"] : ((isset($_POST["name"])) ? $_POST["name"] : '')), + "email" => ((isset($user["email"])) ? $user["email"] : ((isset($_POST["email"])) ? $_POST["email"] : '')), + "incomingurl" => $incomingurl, + "discourseurl" => $discourse_url, + "signupurl" => $signupurl, + "profileurl" => $profileurl, + "userpage" => $userpage, + "PageMenuUser" => $PageMenuUser, + "btnclass" => $btnclass, + "nobtn" => $nobtn, + "error" => $error +]); + +$output = (!empty($class)) ? '
'."\n".$html."\n".'
'."\n" : $html; + +echo $output; diff --git a/actions/usersettings.php b/actions/usersettings.php new file mode 100644 index 0000000..c1df733 --- /dev/null +++ b/actions/usersettings.php @@ -0,0 +1,3 @@ + diff --git a/templates/login/discourse-login.tpl.html b/templates/login/discourse-login.tpl.html new file mode 100644 index 0000000..9136d0b --- /dev/null +++ b/templates/login/discourse-login.tpl.html @@ -0,0 +1,13 @@ + +
 
+ + + +
+ + class="btn btn-secondary-1 btn-lg">Log in with discourse +