diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f3df0588b432163b3f819f63e961ec74db06497..2d78b5611abf40e85a21dbc405b68fd7f184f74b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,11 @@ -image: docker:19.03.12 +image: docker:20.10.9 variables: DOCKER_TLS_CERTDIR: "/certs" - IMAGE_VER: 4.4.1-oidc-4.0.0 + IMAGE_VER: 4.5.0-oidc-4.0.0 services: - - docker:19.03.12-dind + - docker:20.10.9-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY diff --git a/Dockerfile b/Dockerfile index 503236a8ae24d74860e63a5b42214dea9427c9ee..5344f9244a53cc77802c2e9ac84b78b290579006 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM matomo:4.4.1 +FROM matomo:4.5.0 MAINTAINER Andrej Ramašeuski <andrej.ramaseuski@pirati.cz> COPY LoginOIDC /var/www/html/plugins/LoginOIDC diff --git a/LoginOIDC/Controller.php b/LoginOIDC/Controller.php index b10e7e1bf13f7d06884b2d0a9b5fb5f5dbcda006..1c7c07efc1633c5414081858b97bd78cf749af91 100644 --- a/LoginOIDC/Controller.php +++ b/LoginOIDC/Controller.php @@ -259,6 +259,19 @@ class Controller extends \Piwik\Plugin\Controller $user = $this->getUserByRemoteId("oidc", $providerUserId); + // auto linking + // if setting is activated, the oidc account is automatically linked, if the user ID of the OpenID Connect Provider is equal to the internal matomo user ID + if ($settings->autoLinking->getValue()) { + $userModel = new Model(); + $matomoUser = $userModel->getUser($providerUserId); + if (!empty($matomoUser)) { + if (empty($user)) { + $this->linkAccount($providerUserId, $providerUserId); + } + $user = $this->getUserByRemoteId("oidc", $providerUserId); + } + } + if (empty($user)) { if (Piwik::isUserIsAnonymous()) { // user with the remote id is currently not in our database diff --git a/LoginOIDC/LoginOIDC.php b/LoginOIDC/LoginOIDC.php index 57bbf0be493ba5babcdfe630c51fe29601f71148..6e5789ee66fd331014da5023aeb19856ab6ce7ae 100644 --- a/LoginOIDC/LoginOIDC.php +++ b/LoginOIDC/LoginOIDC.php @@ -13,6 +13,7 @@ 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; @@ -76,6 +77,16 @@ class LoginOIDC extends \Piwik\Plugin $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. * @@ -153,24 +164,15 @@ class LoginOIDC extends \Piwik\Plugin */ public function install() { - try { - // right now there is just one provider but we already add a column to support multiple providers later on - $sql = "CREATE TABLE " . Common::prefixTable("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 - ) ENGINE=InnoDB"; - Db::exec($sql); - } catch(Exception $e) { - // ignore error if table already exists (1050 code is for 'table already exists') - if (!Db::get()->isErrNo($e, "1050")) { - throw $e; - } - } + // 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"); } /** diff --git a/LoginOIDC/SystemSettings.php b/LoginOIDC/SystemSettings.php index f99c3063439517327da50817bcd67e682f645dae..f78a008a36f4f1940d7a8d6947c57316f8794803 100644 --- a/LoginOIDC/SystemSettings.php +++ b/LoginOIDC/SystemSettings.php @@ -43,9 +43,18 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings /** * Bypass 2nd factor when login with OIDC + * + * @var bool */ public $bypassTwoFa; + /** + * Enable auto linking of accounts + * + * @var bool + */ + public $autoLinking; + /** * The name of the oauth provider, which is also shown on the login screen. * @@ -134,6 +143,7 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings $this->disableDirectLoginUrl = $this->createDisableDirectLoginUrlSetting(); $this->allowSignup = $this->createAllowSignupSetting(); $this->bypassTwoFa = $this->createBypassTwoFaSetting(); + $this->autoLinking = $this->createAutoLinkingSetting(); $this->authenticationName = $this->createAuthenticationNameSetting(); $this->authorizeUrl = $this->createAuthorizeUrlSetting(); $this->tokenUrl = $this->createTokenUrlSetting(); @@ -203,6 +213,20 @@ class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings }); } + /** + * Add autoLinking setting. + * + * @return SystemSetting + */ + private function createAutoLinkingSetting() : SystemSetting + { + return $this->makeSetting("autoLinking", $default = false, FieldConfig::TYPE_BOOL, function(FieldConfig $field) { + $field->title = Piwik::translate("LoginOIDC_SettingAutoLinking"); + $field->description = Piwik::translate("LoginOIDC_SettingAutoLinkingHelp"); + $field->uiControl = FieldConfig::UI_CONTROL_CHECKBOX; + }); + } + /** * Add authentication name setting. * diff --git a/LoginOIDC/lang/de.json b/LoginOIDC/lang/de.json index d54a5624148078c7f86122bae1e4fa3fad1138d5..e2a1dc7d7e8bd8018e11c7470f4193829dd85f31 100644 --- a/LoginOIDC/lang/de.json +++ b/LoginOIDC/lang/de.json @@ -28,6 +28,8 @@ "SettingRedirectUriOverrideHelp": "In manchen Fällen ist es nützlich, die Redirect URI, die an den OpenID Connect Provider übergeben wird, zu überschreiben. Bei Unklarheit sollte dieses Feld freigelassen werden.", "SettingAllowedSignupDomains": "Erlaubte Domains für Accounterstellung", "SettingAllowedSignupDomainsHelp": "Wenn das Feld freigelassen wird, können sich Benutzer mit beliebiger E-Mail Adresse registrieren. Mehrere Domains können in separaten Zeilen angegeben werden.", + "SettingAutoLinking": "Aktiviere Auto Linking", + "SettingAutoLinkingHelp": "Aktiviert Auto Linking von Accounts, die die selbe User ID in Matomo und dem OpenID Connect Provider haben.", "OpenIDConnect": "OpenID Connect", "OIDCIntro": "Dies erlaubt es Dir, Dich über einen externen Service bei Matomo einzuloggen.", "AccountLinked": "Dein Account ist zur Zeit verknüpft (Entfernte Benutzer-ID: %1$s).", diff --git a/LoginOIDC/lang/en.json b/LoginOIDC/lang/en.json index aa2136d56329a6d21055b46a925378b8d21b757f..43b6373f770a17896068d08d8ba905f7ce7dffda 100644 --- a/LoginOIDC/lang/en.json +++ b/LoginOIDC/lang/en.json @@ -30,6 +30,8 @@ "SettingRedirectUriOverrideHelp": "In some cases it might be useful to manipulate the redirect uri which is given to the OpenID Connect provider. If you are unsure, just leave this field empty.", "SettingAllowedSignupDomains": "Restrict user creation to domains", "SettingAllowedSignupDomainsHelp": "List of email domains which should be allowed to create new accounts. Multiple domains have to be separated by line breaks. When empty, any email domain will be accepted.", + "SettingAutoLinking": "Enable auto linking", + "SettingAutoLinkingHelp": "Enables auto linking of accounts which have the same user id in Matomo and the OIDC provider", "OpenIDConnect": "OpenID Connect", "OIDCIntro": "This allows you to sign in using an external authentication service.", "AccountLinked": "Your account is currently linked (Remote User ID: %1$s).",