From 1505765399c37fc44b3b334d96b3919d07c3e445 Mon Sep 17 00:00:00 2001
From: Sonia Zorba <sonia.zorba@inaf.it>
Date: Tue, 2 Mar 2021 17:19:18 +0100
Subject: [PATCH] Started autojoin implementation

---
 classes/datalayer/UserDAO.php            |  2 ++
 classes/datalayer/mysql/MySQLUserDAO.php | 27 ++++++++++++++++++++++++
 classes/model/SessionData.php            | 10 +++++++++
 include/front-controller.php             |  1 +
 sql/setup-database.sql                   |  9 ++++++++
 views/confirm-join.php                   |  9 +++++++-
 6 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/classes/datalayer/UserDAO.php b/classes/datalayer/UserDAO.php
index ffd5695..ea9be27 100644
--- a/classes/datalayer/UserDAO.php
+++ b/classes/datalayer/UserDAO.php
@@ -79,4 +79,6 @@ interface UserDAO {
     function isAdmin($userId): bool;
 
     function updateIdentity(Identity $identity): void;
+
+    function findJoinableUsers($userId): array;
 }
diff --git a/classes/datalayer/mysql/MySQLUserDAO.php b/classes/datalayer/mysql/MySQLUserDAO.php
index 6c2ed71..a188f27 100644
--- a/classes/datalayer/mysql/MySQLUserDAO.php
+++ b/classes/datalayer/mysql/MySQLUserDAO.php
@@ -301,4 +301,31 @@ class MySQLUserDAO extends BaseMySQLDAO implements UserDAO {
         $stmt->execute();
     }
 
+    function findJoinableUsers($userId): array {
+
+        $dbh = $this->getDBHandler();
+
+        $query = "SELECT DISTINCT(i3.user_id)\n"
+                . "FROM user u\n"
+                . "JOIN identity i ON i.user_id = u.id\n"
+                . "JOIN identity i2 ON i.user_id = i2.user_id\n"
+                . "JOIN identity i3 ON i2.email = i3.email\n"
+                . "WHERE i.email IN (SELECT email FROM identity where user_id = :user_id)\n"
+                . "AND i3.user_id NOT IN (SELECT :user_id UNION\n"
+                . "SELECT user_id2 FROM keep_separated WHERE user_id1 = :user_id\n"
+                . "UNION\n"
+                . "SELECT user_id1 FROM keep_separated WHERE user_id2 = :user_id)";
+
+        $stmt = $dbh->prepare($query);
+        $stmt->bindParam(':user_id', $userId);
+
+        $stmt->execute();
+
+        $results = [];
+        foreach ($stmt->fetchAll() as $row) {
+            array_push($results, $row['user_id']);
+        }
+        return $results;
+    }
+
 }
diff --git a/classes/model/SessionData.php b/classes/model/SessionData.php
index 54806ae..ba0e3ba 100644
--- a/classes/model/SessionData.php
+++ b/classes/model/SessionData.php
@@ -38,6 +38,7 @@ class SessionData {
     private $oauth2RequestData;
     private $action;
     private $loginIdentityType;
+    private $autojoin = false;
 
     public function setUser(?User $user): void {
         $this->user = $user;
@@ -57,6 +58,15 @@ class SessionData {
         return $this->userToJoin;
     }
 
+    public function setAutojoin(bool $autojoin): void {
+        $this->autojoin = $autojoin;
+        $this->save();
+    }
+
+    public function isAutojoin(): bool {
+        return $this->autojoin;
+    }
+
     public function setLoginIdentityType(string $loginIdentityType): void {
         $this->loginIdentityType = $loginIdentityType;
         $this->save();
diff --git a/include/front-controller.php b/include/front-controller.php
index 41e2b5d..9685ca4 100644
--- a/include/front-controller.php
+++ b/include/front-controller.php
@@ -297,6 +297,7 @@ Flight::route('GET /confirm-join', function() {
         die("User data not retrieved.");
     } else {
         Flight::render('confirm-join.php', array('title' => 'Confirm join',
+            'autojoin' => $locator->getSession()->isAutojoin(),
             'user' => $locator->getSession()->getUser(),
             'user_to_join' => $locator->getSession()->getUserToJoin(),
             'version' => $locator->getVersion(),
diff --git a/sql/setup-database.sql b/sql/setup-database.sql
index e87e196..df4ef7b 100644
--- a/sql/setup-database.sql
+++ b/sql/setup-database.sql
@@ -58,6 +58,15 @@ CREATE TABLE `identity` (
 ALTER TABLE identity ADD CONSTRAINT eppn_unique UNIQUE(eppn);
 ALTER TABLE identity ADD CONSTRAINT typed_id_unique UNIQUE(typed_id);
 
+-- remember that a user decided to avoid a join
+CREATE TABLE `keep_separated` (
+  `user_id1` bigint(20) NOT NULL,
+  `user_id2` bigint(20) NOT NULL,
+  PRIMARY KEY (`user_id1`, `user_id2`),
+  FOREIGN KEY (`user_id1`) REFERENCES `user`(`id`),
+  FOREIGN KEY (`user_id2`) REFERENCES `user`(`id`)
+);
+
 SET FOREIGN_KEY_CHECKS=0;
 ALTER TABLE `user` ADD FOREIGN KEY (`primary_identity`) REFERENCES `identity`(`id`);
 SET FOREIGN_KEY_CHECKS=1;
diff --git a/views/confirm-join.php b/views/confirm-join.php
index 7eb2095..6a4e12f 100644
--- a/views/confirm-join.php
+++ b/views/confirm-join.php
@@ -4,7 +4,14 @@ include 'include/header.php';
 
 <br/>
 <div class="text-center">
-    <h3>Following identities will be joined:</h3><br/>
+    <?php if ($autojoin) { ?>
+        <h3>Multiple accounts detected</h3><br/>
+        <p>The system found multiple accounts associated with the same e-mail address. We suggest you to join them, so that
+            they will be seen as a single user. If you prefer to keep these accounts separated you can click on "Reject join" button.
+        </p>
+    <?php } else { ?>
+        <h3>Following identities will be joined:</h3><br/>
+    <?php } ?>
 </div>
 
 <div class="row">
-- 
GitLab