209 lines
6.5 KiB
PHP
209 lines
6.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Piwik - free/libre analytics platform
|
|
*
|
|
* @link http://piwik.org
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*/
|
|
|
|
namespace Piwik\Plugins\LoginOIDC;
|
|
|
|
use Exception;
|
|
use Piwik\Common;
|
|
use Piwik\Config;
|
|
use Piwik\Db;
|
|
use Piwik\DbHelper;
|
|
use Piwik\FrontController;
|
|
use Piwik\Plugins\LoginOIDC\SystemSettings;
|
|
use Piwik\Plugins\LoginOIDC\Url;
|
|
use Piwik\Session;
|
|
|
|
class LoginOIDC extends \Piwik\Plugin
|
|
{
|
|
/**
|
|
* Subscribe to Matomo events and assign handlers.
|
|
* https://developer.matomo.org/api-reference/Piwik/Plugin#registerevents
|
|
*
|
|
* @return array
|
|
*/
|
|
public function registerEvents() : array
|
|
{
|
|
return array(
|
|
"Session.beforeSessionStart" => "beforeSessionStart",
|
|
"AssetManager.getStylesheetFiles" => "getStylesheetFiles",
|
|
"Template.userSecurity.afterPassword" => "renderLoginOIDCUserSettings",
|
|
"Template.loginNav" => "renderLoginOIDCMod",
|
|
"Template.confirmPasswordContent" => "renderConfirmPasswordMod",
|
|
"Login.logout" => "logoutMod",
|
|
"Login.userRequiresPasswordConfirmation" => "userRequiresPasswordConfirmation"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create RememberMe cookie.
|
|
* @see \Piwik\Plugins\Login::beforeSessionStart
|
|
*
|
|
* @return void
|
|
*/
|
|
public function beforeSessionStart() : void
|
|
{
|
|
if (!$this->shouldHandleRememberMe()) {
|
|
return;
|
|
}
|
|
Session::rememberMe(Config::getInstance()->General["login_cookie_expire"]);
|
|
}
|
|
|
|
/**
|
|
* Decide if RememberMe cookie should be handled by the plugin.
|
|
* @see \Piwik\Plugins\Login::shouldHandleRememberMe
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function shouldHandleRememberMe() : bool
|
|
{
|
|
$module = Common::getRequestVar("module", false);
|
|
$action = Common::getRequestVar("action", false);
|
|
return ($module == "LoginOIDC") && ($action == "callback");
|
|
}
|
|
|
|
/**
|
|
* Append additional stylesheets.
|
|
*
|
|
* @param array $files
|
|
* @return void
|
|
*/
|
|
public function getStylesheetFiles(array &$files)
|
|
{
|
|
$files[] = "plugins/LoginOIDC/stylesheets/loginMod.css";
|
|
}
|
|
|
|
/**
|
|
* Register the new tables, so Matomo knows about them.
|
|
*
|
|
* @param array $allTablesInstalled
|
|
*/
|
|
public function getTablesInstalled(&$allTablesInstalled)
|
|
{
|
|
$allTablesInstalled[] = Common::prefixTable('loginoidc_provider');
|
|
}
|
|
|
|
/**
|
|
* Append custom user settings layout.
|
|
*
|
|
* @param string $out
|
|
* @return void
|
|
*/
|
|
public function renderLoginOIDCUserSettings(string &$out)
|
|
{
|
|
$content = FrontController::getInstance()->dispatch("LoginOIDC", "userSettings");
|
|
if (!empty($content)) {
|
|
$out .= $content;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Append login oauth button layout.
|
|
*
|
|
* @param string $out
|
|
* @param string|null $payload
|
|
* @return void
|
|
*/
|
|
public function renderLoginOIDCMod(string &$out, string $payload = null)
|
|
{
|
|
if (!empty($payload) && $payload === "bottom") {
|
|
$content = FrontController::getInstance()->dispatch("LoginOIDC", "loginMod");
|
|
if (!empty($content)) {
|
|
$out .= $content;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Append login oauth button layout.
|
|
* The password confirmation modal is not consistent enough to rely on this modification.
|
|
* It is recommended to use the `userRequiresPasswordConfirmation` event instead
|
|
*
|
|
* @param string $out
|
|
* @param string|null $payload
|
|
* @return void
|
|
*/
|
|
public function renderConfirmPasswordMod(string &$out, string $payload = null)
|
|
{
|
|
if (!empty($payload) && $payload === "bottom") {
|
|
$content = FrontController::getInstance()->dispatch("LoginOIDC", "confirmPasswordMod");
|
|
if (!empty($content)) {
|
|
$out .= $content;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Temporarily override logout url to the oidc provider end user session endpoint.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function logoutMod()
|
|
{
|
|
$settings = new SystemSettings();
|
|
$endSessionUrl = $settings->endSessionUrl->getValue();
|
|
if (!empty($endSessionUrl) && $_SESSION["loginoidc_auth"]) {
|
|
// make sure we properly unset the plugins session variable
|
|
unset($_SESSION['loginoidc_auth']);
|
|
$endSessionUrl = new Url($endSessionUrl);
|
|
if (isset($_SESSION["loginoidc_idtoken"])) {
|
|
$endSessionUrl->setQueryParameter("id_token_hint", $_SESSION["loginoidc_idtoken"]);
|
|
}
|
|
$originalLogoutUrl = Config::getInstance()->General['login_logout_url'];
|
|
if ($originalLogoutUrl) {
|
|
$endSessionUrl->setQueryParameter("post_logout_redirect_uri", $originalLogoutUrl);
|
|
}
|
|
Config::getInstance()->General['login_logout_url'] = $endSessionUrl->buildString();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable password confirmation when user signed up with LoginOIDC.
|
|
* This feature requires Matomo >4.12.0
|
|
*
|
|
* @return void
|
|
*/
|
|
public function userRequiresPasswordConfirmation(&$requiresPasswordConfirmation, $login) : void
|
|
{
|
|
$settings = new SystemSettings();
|
|
$disablePasswordConfirmation = $settings->disablePasswordConfirmation->getValue();
|
|
if ($disablePasswordConfirmation) {
|
|
// require password confirmation when user has not signed in with the plugin
|
|
$requiresPasswordConfirmation = !($_SESSION["loginoidc_auth"] ?? false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extend database.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function install()
|
|
{
|
|
// right now there is just one provider but we already add a column to support multiple providers later on
|
|
DbHelper::createTable("loginoidc_provider", "
|
|
`user` VARCHAR( 100 ) NOT NULL,
|
|
`provider_user` VARCHAR( 255 ) NOT NULL,
|
|
`provider` VARCHAR( 255 ) NOT NULL,
|
|
`date_connected` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
|
PRIMARY KEY ( `provider_user`, `provider` ),
|
|
UNIQUE KEY `user_provider` ( `user`, `provider` ),
|
|
FOREIGN KEY ( `user` ) REFERENCES " . Common::prefixTable("user") . " ( `login` ) ON DELETE CASCADE");
|
|
}
|
|
|
|
/**
|
|
* Undo database changes from install.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function uninstall()
|
|
{
|
|
Db::dropTables(Common::prefixTable("loginoidc_provider"));
|
|
}
|
|
}
|