From b1024c93bd8c0cb2be2f5029313e7f594505224d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andrej=20Rama=C5=A1euski?= <andrej@x2.cz>
Date: Wed, 20 Oct 2021 23:54:51 +0200
Subject: [PATCH] Version up

---
 .gitlab-ci.yml               |  6 +++---
 Dockerfile                   |  2 +-
 LoginOIDC/Controller.php     | 13 ++++++++++++
 LoginOIDC/LoginOIDC.php      | 38 +++++++++++++++++++-----------------
 LoginOIDC/SystemSettings.php | 24 +++++++++++++++++++++++
 LoginOIDC/lang/de.json       |  2 ++
 LoginOIDC/lang/en.json       |  2 ++
 7 files changed, 65 insertions(+), 22 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0f3df05..2d78b56 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 503236a..5344f92 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 b10e7e1..1c7c07e 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 57bbf0b..6e5789e 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 f99c306..f78a008 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 d54a562..e2a1dc7 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 aa2136d..43b6373 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).",
-- 
GitLab