diff --git a/.gitignore b/.gitignore
index 0761b29e6b907ee018a84872be9268bdbc02ef79..dcb5ce1ec603d783cc0a96825a4e5073cec2f63f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ composer.lock
 nbproject
 logs
 config.php
+test
diff --git a/auth/oauth2/facebook_token.php b/auth/oauth2/facebook_token.php
index b914131878a739a5f0f83468c9b5c84d6428a5e0..bd431656877232218597121b121086f3c0d85f09 100755
--- a/auth/oauth2/facebook_token.php
+++ b/auth/oauth2/facebook_token.php
@@ -96,5 +96,6 @@ if ($user === null) {
     $userHandler->saveUser($user);
 }
 
+$auditLog->info("LOGIN,Facebook," . $user->id);
 $callbackHandler->manageLoginRedirect($user, $session);
 ?>
diff --git a/auth/oauth2/google_token.php b/auth/oauth2/google_token.php
index a44c19af72e9d4670705ecc6916f0d86e7b4e7a8..8f056d5c5d17e0d88946f3dc0e6e426bf6c5274d 100644
--- a/auth/oauth2/google_token.php
+++ b/auth/oauth2/google_token.php
@@ -90,6 +90,7 @@ if ($client->getAccessToken()) {
         $userHandler->saveUser($user);
     }
 
+    $auditLog->info("LOGIN,Google," . $user->id);
     $callbackHandler->manageLoginRedirect($user, $session);
 
     die();
diff --git a/auth/oauth2/linkedin_token.php b/auth/oauth2/linkedin_token.php
index e2ec27534362001aaca7a09c6ac95b423a7dedb0..e38700ab76a7e4f19e32988de46ffe62936d3374 100644
--- a/auth/oauth2/linkedin_token.php
+++ b/auth/oauth2/linkedin_token.php
@@ -116,6 +116,7 @@ if ($info2['http_code'] === 200) {
         $userHandler->saveUser($user);
     }
 
+    $auditLog->info("LOGIN,LinkedIn," . $user->id);
     $callbackHandler->manageLoginRedirect($user, $session);
 } else {
     //show information regarding the error
diff --git a/auth/saml2/aai.php b/auth/saml2/aai.php
index cb93949c0107ae4b882c20e6ec8ce0bf6cb7ad67..59723e06f1b1a441606f7be8c9e11e05a8d1f173 100644
--- a/auth/saml2/aai.php
+++ b/auth/saml2/aai.php
@@ -47,6 +47,7 @@ if (isset($_SERVER['Shib-Session-ID'])) {
         $userHandler->saveUser($user);
     }
 
+    $auditLog->info("LOGIN,eduGAIN," . $user->id);
     $callbackHandler->manageLoginRedirect($user, $session);
 } else {
     http_response_code(500);
diff --git a/auth/x509/certlogin.php b/auth/x509/certlogin.php
index e0ce9ea501a7b91384bccabc39bedf00db736ea0..ba9c20e807b0c6c549994b2cd2000f9524e96b2d 100644
--- a/auth/x509/certlogin.php
+++ b/auth/x509/certlogin.php
@@ -77,4 +77,5 @@ if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name
     }
 }
 
+$auditLog->info("LOGIN,X.509," . $user->id);
 $callbackHandler->manageLoginRedirect($user, $session);
diff --git a/classes/MySQLDAO.php b/classes/MySQLDAO.php
index d93d82d2a8f8769d400df956651845cd38601dc2..03b492c7fe713d4daa83b04f0e915ddd78ced404 100644
--- a/classes/MySQLDAO.php
+++ b/classes/MySQLDAO.php
@@ -208,9 +208,11 @@ class MySQLDAO implements DAO {
                 . " i.`id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`"
                 . " FROM identity i"
                 . " JOIN `user` u on u.id = i.user_id"
+                . " WHERE i.user_id IN"
+                . " (SELECT user_id FROM identity"
                 . " WHERE `email` LIKE :email OR `email` LIKE :emailPart"
                 . " OR `name` LIKE :name OR `surname` LIKE :surname"
-                . " OR CONCAT(`name`,' ',`surname`) LIKE :namesurname";
+                . " OR CONCAT(`name`,' ',`surname`) LIKE :namesurname)";
 
         $stmt = $dbh->prepare($query);
 
diff --git a/config-example.php b/config-example.php
index d73e7e8587be9a22f682e3fbb897bac4b54626b4..8a66713140f79f84e89dce469264044cdf1a61b1 100644
--- a/config-example.php
+++ b/config-example.php
@@ -29,6 +29,7 @@ $PROTOCOL = stripos($_SERVER['SERVER_PROTOCOL'], 'https') ? 'https://' : 'http:/
 $BASE_PATH = $PROTOCOL . $_SERVER['HTTP_HOST'] . $CONTEXT_ROOT;
 
 $LOG_PATH = ROOT . "/logs/rap-service.log";
+$AUDIT_LOG_PATH = ROOT . "/logs/rap-audit.log";
 $LOG_LEVEL = Monolog\Logger::DEBUG;
 
 $CALLBACKS = [
@@ -48,25 +49,25 @@ $DATABASE = array(
     'dbtype' => 'MySQL',
     'hostname' => 'localhost',
     'port' => 3306,
-    'username' => 'rap',
-    'password' => '***REMOVED***',
+    'username' => 'XXXXXX',
+    'password' => 'XXXXXX',
     'dbname' => 'rap'
 );
 
 $AUTHENTICATION_METHODS = array(
     'eduGAIN' => array(),
     'Google' => array(
-        'id' => "***REMOVED***.apps.googleusercontent.com",
-        'secret' => "***REMOVED***",
+        'id' => "XXXXXX",
+        'secret' => "XXXXXX",
         'callback' => $BASE_PATH . "/auth/oauth2/google_token.php"),
     'Facebook' => array(
-        'id' => "***REMOVED***",
-        'secret' => "***REMOVED***",
+        'id' => "XXXXXX",
+        'secret' => "XXXXXX",
         'version' => "v2.2",
         'callback' => $BASE_PATH . "/auth/oauth2/facebook_token.php"),
     'LinkedIn' => array(
-        'id' => '***REMOVED***',
-        'secret' => '***REMOVED***',
+        'id' => 'XXXXXX',
+        'secret' => 'XXXXXX',
         'callback' => $BASE_PATH . '/auth/oauth2/linkedin_token.php'
     ),
     'X.509' => array(),
@@ -79,12 +80,7 @@ $AUTHENTICATION_METHODS = array(
 );
 
 $GROUPER = array(
-    'wsURL' => 'http://localhost:8087/grouper-ws/',
-    'user' => 'GrouperSystem',
-    'password' => '***REMOVED***'
+    'wsURL' => 'http://hostname/grouper-ws/',
+    'user' => 'XXXXXX',
+    'password' => 'XXXXXX'
 );
-/*$GROUPER = array(
-    'wsURL' => 'https://sso.ia2.inaf.it/grouper-ws/',
-    'user' => 'GrouperSystem',
-    'password' => '***REMOVED***321'
-);*/
diff --git a/include/front-controller.php b/include/front-controller.php
index 5010fcd46ea86dba2614df64244aba63e49eebd5..202806fc2992507d891b7834e9a2db5513805265 100644
--- a/include/front-controller.php
+++ b/include/front-controller.php
@@ -99,7 +99,7 @@ Flight::route('GET /confirm-join', function() {
 
 Flight::route('POST /confirm-join', function() {
 
-    global $dao, $userHandler;
+    global $dao, $userHandler, $auditLog;
 
     $token = Flight::request()->data['token'];
 
@@ -114,6 +114,8 @@ Flight::route('POST /confirm-join', function() {
         die("Invalid token");
     }
 
+    $auditLog->info("JOIN," . $userIds[0] . "," . $userIds[1]);
+
     $userHandler->joinUsers($userIds[0], $userIds[1]);
     $dao->deleteJoinRequest($token);
 
diff --git a/include/init.php b/include/init.php
index 28f658751c58c669460ffbc4ce90b422132fe4dc..568565e699046faa0de1d013862ef8d1cbf22945 100644
--- a/include/init.php
+++ b/include/init.php
@@ -44,6 +44,8 @@ include ROOT . '/config.php';
 date_default_timezone_set("Europe/Rome");
 $log = new Monolog\Logger('mainLogger');
 $log->pushHandler(new Monolog\Handler\StreamHandler($LOG_PATH, $LOG_LEVEL));
+$auditLog = new Monolog\Logger('auditLogger');
+$auditLog->pushHandler(new Monolog\Handler\StreamHandler($AUDIT_LOG_PATH, $LOG_LEVEL));
 
 switch ($DATABASE['dbtype']) {
     case 'MySQL':
diff --git a/sql/delete-user-procedure.sql b/sql/delete-user-procedure.sql
new file mode 100644
index 0000000000000000000000000000000000000000..836d8c70c7b9dc9b7ef45c52e99a913dc057ee0d
--- /dev/null
+++ b/sql/delete-user-procedure.sql
@@ -0,0 +1,8 @@
+DELIMITER //
+CREATE PROCEDURE delete_user (userId INT)
+BEGIN
+    UPDATE user SET primary_identity = NULL WHERE id = userId;
+    DELETE FROM identity WHERE user_id = userId;
+    DELETE FROM user WHERE id = userId;
+END; //
+DELIMITER ;