From 26aa8885514d564e9f2e9d8b881633cfbd09a971 Mon Sep 17 00:00:00 2001
From: William Enright <william.enright@savoirfairelinux.com>
Date: Mon, 15 Jun 2020 17:51:03 -0400
Subject: [PATCH] cleanup for local users display

Change-Id: I9183edf6201b556f04367dc041664b744f51d06d
---
 .../jami/jams/ad/connector/ADConnector.java   |   3 +-
 clean.sh                                      |   5 -
 .../jami/datastore/dao/UserProfileDao.java    |  33 ++-
 .../net/jami/datastore/main/DataStore.java    |  25 +-
 .../authentication/AuthenticationSource.java  |   2 +-
 .../jams/common/objects/user/UserProfile.java |  57 ++++-
 jams-server/pom.xml                           |   6 +
 .../directory/DirectoryEntryServlet.java      |   8 +-
 .../servlets/api/admin/users/UserServlet.java |   6 +-
 .../directory/SearchDirectoryServlet.java     |   2 +-
 .../servlets/api/auth/user/UserServlet.java   |   1 +
 .../api/install/StartInstallServlet.java      |   2 +-
 .../src/main/resources/webapp/js/api.js       |  21 +-
 .../src/main/resources/webapp/js/search.js    | 231 ++++++++++--------
 .../jams/ldap/connector/LDAPConnector.java    |   3 +-
 15 files changed, 261 insertions(+), 144 deletions(-)
 delete mode 100755 clean.sh

diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
index df800f55..d4e5a626 100644
--- a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
+++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java
@@ -97,8 +97,9 @@ public class ADConnector implements AuthenticationSource {
     }
 
     @Override
-    public void setUserProfile(UserProfile userProfile) {
+    public boolean setUserProfile(UserProfile userProfile) {
         //does nothing as we cannot edit user profiles.
+        return false;
     }
 
     @Override
diff --git a/clean.sh b/clean.sh
deleted file mode 100755
index 96b22e13..00000000
--- a/clean.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-rm -rf jams
-rm derby.log
-rm oauth.key
-rm oauth.pub
-
diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
index e2df4511..4e6bdd4c 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
@@ -39,11 +39,21 @@ public class UserProfileDao extends AbstractDao<UserProfile> {
         try {
             this.setTableName("local_directory");
             this.setTClass(UserProfile.class);
-            String createTable = "CREATE TABLE directory (" +
+
+            String createTable  = "CREATE TABLE local_directory (" +
                     "username varchar(255), " +
-                    "telephone varchar(5000), "+
-                    "picture varchar(5000)," +
+                    "firstName varchar(255), " +
+                    "lastName varchar(255), " +
+                    "email varchar(255), " +
+                    "profilePicture long varchar, " +
+                    "organization varchar(255), " +
+                    "phoneNumber varchar(255), " +
+                    "phoneNumberExtension varchar(255), " +
+                    "faxNumber varchar(255), " +
+                    "mobileNumber varchar(255), " +
                     "PRIMARY KEY (username))";
+
+
             PreparedStatement ps = connection.getConnection().prepareStatement(createTable);
             ps.execute();
         }
@@ -57,6 +67,21 @@ public class UserProfileDao extends AbstractDao<UserProfile> {
 
     @Override
     public boolean storeObject(UserProfile object) {
-        return false;
+
+        SQLConnection connection = DataStore.connectionPool.getConnection();
+        try{
+            PreparedStatement ps = connection.getConnection().prepareStatement("INSERT INTO local_directory " +
+                    "(username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)" +
+                    " VALUES " + "(?,?,?,?,?,?,?,?,?,?)");
+            ps = object.getInsert(ps);
+            return ps.executeUpdate() != 0;
+        }
+        catch (Exception e){
+            log.error("An error has occurred while trying to store a user profile: " + e.toString());
+            return false;
+        }
+        finally {
+            DataStore.connectionPool.returnConnection(connection);
+        }
     }
 }
diff --git a/datastore/src/main/java/net/jami/datastore/main/DataStore.java b/datastore/src/main/java/net/jami/datastore/main/DataStore.java
index d29529ed..5c6cba38 100644
--- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java
+++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java
@@ -24,11 +24,15 @@ package net.jami.datastore.main;
 
 import lombok.Getter;
 import lombok.Setter;
+<<<<<<< HEAD
 import net.jami.datastore.dao.ContactDao;
 import net.jami.datastore.dao.DeviceDao;
 import net.jami.datastore.dao.JwtDao;
 import net.jami.datastore.dao.SystemDao;
 import net.jami.datastore.dao.UserDao;
+=======
+import net.jami.datastore.dao.*;
+>>>>>>> 18375d3... cleanup for local users display
 import net.jami.jams.common.authentication.AuthenticationSource;
 import net.jami.jams.common.authentication.AuthenticationSourceInfo;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
@@ -50,8 +54,9 @@ public class DataStore implements AuthenticationSource {
     private SystemDao systemDao;
     private ContactDao contactDao;
     private JwtDao jwtDao;
+    private UserProfileDao userProfileDao;
 
-    //Implicitly connect to debry.
+    //Implicitly connect to derby.
     public DataStore(String connectionString) {
         connectionPool = new ConnectionPool(connectionString);
         userDao = new UserDao();
@@ -59,6 +64,7 @@ public class DataStore implements AuthenticationSource {
         systemDao = new SystemDao();
         contactDao = new ContactDao();
         jwtDao = new JwtDao();
+        userProfileDao = new UserProfileDao();
     }
 
     public boolean userExists(String username){
@@ -73,15 +79,24 @@ public class DataStore implements AuthenticationSource {
     public boolean createUser(User user) {
         return userDao.storeObject(user);
     }
-
     @Override
     public UserProfile[] getUserProfile(String queryString, String field) {
-        return null;
+        List<UserProfile> userList;
+
+        if (!queryString.equals("*")) {
+            StatementList statementList = new StatementList();
+            StatementElement statementElement = new StatementElement("username","=",queryString,"");
+            statementList.addStatement(statementElement);
+            userList = userProfileDao.getObjects(statementList);
+        } else
+            userList = userProfileDao.getObjects(null);
+
+        return userList.toArray(new UserProfile[userList.size()]);
     }
 
     @Override
-    public void setUserProfile(UserProfile userProfile) {
-        //TODO: Implement this.
+    public boolean setUserProfile(UserProfile userProfile) {
+        return userProfileDao.storeObject(userProfile);
     }
 
     @Override
diff --git a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java
index 9b3cb620..d1b56425 100644
--- a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java
+++ b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java
@@ -29,7 +29,7 @@ public interface AuthenticationSource {
 
     boolean createUser(User user);
     UserProfile[] getUserProfile(String queryString, String field);
-    void setUserProfile(UserProfile userProfile);
+    boolean setUserProfile(UserProfile userProfile);
     boolean authenticate(String username, String password);
     AuthenticationSourceInfo getInfo();
     boolean test();
diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
index 9c6d99d0..c82f15bc 100644
--- a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
+++ b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserProfile.java
@@ -31,18 +31,27 @@ import ezvcard.parameter.ImageType;
 import ezvcard.parameter.TelephoneType;
 import ezvcard.property.Photo;
 import ezvcard.property.StructuredName;
+import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
+import net.jami.jams.common.authentication.AuthenticationSourceType;
+import net.jami.jams.common.serialization.database.DatabaseObject;
+import net.jami.jams.common.utils.X509Utils;
 import org.bouncycastle.util.encoders.Base64;
 
 import java.lang.reflect.Method;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.util.HashMap;
 
+@AllArgsConstructor
+@NoArgsConstructor
 @Getter
 @Setter
-public class UserProfile {
+public class UserProfile implements DatabaseObject {
 
     public static HashMap<String, Method> exposedMethods = new HashMap<>();
 
@@ -56,13 +65,26 @@ public class UserProfile {
     private String username;
     private String firstName;
     private String lastName;
+    private String email;
+    private String profilePicture;
+    private String organization;
     private String phoneNumber;
     private String phoneNumberExtension;
-    private String mobileNumber;
     private String faxNumber;
-    private String profilePicture;
-    private String email;
-    private String organization;
+    private String mobileNumber;
+
+    public UserProfile(ResultSet rs) throws Exception {
+        this.username = rs.getString("username");
+        this.firstName = rs.getString("firstName");
+        this.lastName = rs.getString("lastName");
+        this.email = rs.getString("email");
+        this.profilePicture = rs.getString("profilePicture");
+        this.organization = rs.getString("organization");
+        this.phoneNumber = rs.getString("phoneNumber");
+        this.phoneNumberExtension = rs.getString("phoneNumberExtension");
+        this.faxNumber = rs.getString("faxNumber");
+        this.mobileNumber = rs.getString("mobileNumber");
+    }
 
     @JsonIgnore
     //Ignore this if we pass through JSON iterator.
@@ -90,4 +112,29 @@ public class UserProfile {
         return Ezvcard.write(vCard).version(VCardVersion.V3_0).go();
     }
 
+    @Override
+    public PreparedStatement getInsert(PreparedStatement ps) throws Exception {
+        ps.setString(1, username);
+        ps.setString(2, firstName);
+        ps.setString(3, lastName);
+        ps.setString(4, email);
+        ps.setString(5, profilePicture);
+        ps.setString(6, organization);
+        ps.setString(7, phoneNumber);
+        ps.setString(8, phoneNumberExtension);
+        ps.setString(9, faxNumber);
+        ps.setString(10, mobileNumber);
+        return ps;
+    }
+
+    @Override
+    public PreparedStatement getDelete(PreparedStatement ps) throws Exception {
+        return null;
+    }
+
+    @Override
+    public PreparedStatement getUpdate(PreparedStatement ps) throws Exception {
+        return null;
+    }
+
 }
diff --git a/jams-server/pom.xml b/jams-server/pom.xml
index 36a22d69..5bd4a31c 100644
--- a/jams-server/pom.xml
+++ b/jams-server/pom.xml
@@ -61,6 +61,12 @@
             <artifactId>asm</artifactId>
             <version>${asm.version}</version>
         </dependency>
+        <dependency>
+            <groupId>net.jami</groupId>
+            <artifactId>authentication-module</artifactId>
+            <version>2.0</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
index 35729351..9d277f68 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java
@@ -23,6 +23,7 @@
 package net.jami.jams.server.servlets.api.admin.directory;
 
 import com.jsoniter.JsonIterator;
+import com.jsoniter.output.JsonStream;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.annotation.WebServlet;
 import jakarta.servlet.http.HttpServlet;
@@ -34,6 +35,7 @@ import net.jami.jams.common.authmodule.AuthModuleKey;
 import net.jami.jams.common.objects.user.UserProfile;
 
 import java.io.IOException;
+import java.util.HashMap;
 
 import static net.jami.jams.server.Server.userAuthenticationModule;
 
@@ -45,11 +47,15 @@ public class DirectoryEntryServlet extends HttpServlet {
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //Create a user profile.
         try {
-            String realm = req.getParameter("directory");
+            String realm = "LOCAL";
             UserProfile userProfile = JsonIterator.deserialize(req.getInputStream().readAllBytes(), UserProfile.class);
             userAuthenticationModule.getAuthSources().get(new AuthModuleKey(realm, AuthenticationSourceType.LOCAL))
                     .setUserProfile(userProfile);
+
             resp.setStatus(200);
+            HashMap<String,String> profileName = new HashMap<>();
+            profileName.put("username", userProfile.getUsername());
+            resp.getOutputStream().write(JsonStream.serialize(profileName).getBytes());
         }
         catch (Exception e){
             log.error("Could not store a user profile with error {}",e.getMessage());
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
index 2128e21e..ce6f0915 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java
@@ -22,6 +22,7 @@
 */
 package net.jami.jams.server.servlets.api.admin.users;
 
+import com.jsoniter.JsonIterator;
 import com.jsoniter.output.JsonStream;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.annotation.WebServlet;
@@ -31,8 +32,11 @@ import jakarta.servlet.http.HttpServletResponse;
 import net.jami.jams.common.authentication.AuthenticationSourceType;
 import net.jami.jams.common.dao.StatementElement;
 import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.jami.NameRegistrationRequest;
+import net.jami.jams.common.objects.requests.CreateAuthSourceRequest;
 import net.jami.jams.common.objects.responses.DeviceRevocationResponse;
 import net.jami.jams.common.objects.user.User;
+import net.jami.jams.common.objects.user.UserProfile;
 import net.jami.jams.server.core.workflows.RevokeUserFlow;
 
 import java.io.IOException;
@@ -46,7 +50,7 @@ public class UserServlet extends HttpServlet {
 
     //Get the user profile.
     @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         StatementList statementList = new StatementList();
         StatementElement st1 = new StatementElement("username","=",req.getParameter("username"),"");
         statementList.addStatement(st1);
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
index e7a5e858..1f940c8b 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/SearchDirectoryServlet.java
@@ -68,7 +68,7 @@ public class SearchDirectoryServlet extends HttpServlet {
      * @apiError (500) {null} null could not return any authentication sources
      */
     @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         List<UserProfile> userProfiles = new ArrayList<>();
         userAuthenticationModule.getAuthSources().forEach( (k,v) ->{
                 UserProfile[] profiles = v.getUserProfile(req.getParameter("queryString"),"FULL_TEXT_NAME");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
index 51991a34..c4ad339f 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java
@@ -39,6 +39,7 @@ import java.io.IOException;
 
 import static net.jami.jams.server.Server.certificateAuthority;
 import static net.jami.jams.server.Server.dataStore;
+import static net.jami.jams.server.Server.nameServer;
 
 @WebServlet("/api/auth/user")
 public class UserServlet extends HttpServlet {
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
index 7c9d6780..e15bc234 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/install/StartInstallServlet.java
@@ -52,7 +52,7 @@ public class StartInstallServlet extends HttpServlet {
         //Here we must decide which page to show - login or sign-up
         StatementList statementList = new StatementList();
         statementList.addStatement(new StatementElement("username","=","*",""));
-        if(dataStore != null && dataStore.getUserDao() != null && dataStore.getUserDao().getObjects(null).size() > 0)
+        if(dataStore != null && dataStore.getUserDao() != null && !dataStore.getUserDao().getObjects(null).isEmpty())
             resp.setHeader("showLogin","true");
         else
             resp.setHeader("showLogin","false");
diff --git a/jams-server/src/main/resources/webapp/js/api.js b/jams-server/src/main/resources/webapp/js/api.js
index 0ea61e32..c0a35a78 100644
--- a/jams-server/src/main/resources/webapp/js/api.js
+++ b/jams-server/src/main/resources/webapp/js/api.js
@@ -42,29 +42,26 @@ var api_path_post_install_ca = '/api/install/ca';
 var api_path_post_install_auth = '/api/install/auth';
 var api_path_post_install_server = '/api/install/settings';
 var api_path_get_install_lastKnownStep = '/api/install/lastStep';
-var api_path_get_user = '/api/auth/user';
 var api_path_get_auth_user_search = '/api/auth/users';
 var api_path_get_auth_devices = '/api/auth/devices';
 var api_path_delete_auth_user_revoke = '/api/auth/user';
 var api_path_delete_auth_device_revoke = '/api/auth/device';
 var api_path_rename_device = '/api/auth/device';
 var api_path_get_server_status = '/api/info';
-var api_path_post_api_check = '/api/auth/check';
-var api_path_get_logout = '/api/auth/logout';
 var api_path_get_post_configuration_auth_service = '/api/configuration/authservice';
 var api_path_get_post_configuration_global_settings = '/api/configuration/globalsettings';
 var api_path_post_configuration_change_password = '/api/configuration/changepassword';
 var api_path_post_configuration_register_license = '/api/subscription';
-var api_path_get_subscription_status = '/api/subscription';
+var api_path_get_subscription_status = '/api/admin/subscription';
 var api_path_get_directories = '/api/auth/directories';
-var api_path_get_needs_update = '/api/update';
-var api_path_get_start_update = '/api/update';
-var api_path_post_create_user = '/api/user/create';
-var api_path_post_update_user = '/api/user/update';
-var api_path_post_exists_user = '/api/user/exists';
+var api_path_get_needs_update = '/api/admin/update';
+var api_path_get_start_update = '/api/admin/update';
+var api_path_post_create_user = '/api/admin/user';
+var api_path_put_update_user = '/api/admin/user';
+var api_path_get_exists_user = '/api/admin/user';
 var api_path_get_user_directory_search ='/api/auth/directory/search';
-var api_path_get_user_directory_entry ='/api/auth/directory/entry';
 var api_path_get_user_needs_reset ='/api/user/needsreset';
+var api_path_post_create_user_profile = '/api/admin/directory/entry';
 
 
 function ajaxApiCall(api_path, request_type, data, credentials, callBackFunction, async) {
@@ -100,7 +97,7 @@ function ajaxApiCall(api_path, request_type, data, credentials, callBackFunction
     // pass data in the header
     if (data) {
         if (api_path == api_path_get_user_directory_search || api_path == api_path_get_auth_user_search ||
-            api_path == api_path_get_user || api_path == api_path_get_user_needs_reset)
+            api_path == api_path_get_user_needs_reset || (api_path == api_path_post_create_user && request_type == 'POST'))
             isSearch = true;
 
         // search dataType
@@ -169,4 +166,4 @@ function set_installation_response(url) {
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/jams-server/src/main/resources/webapp/js/search.js b/jams-server/src/main/resources/webapp/js/search.js
index 4172cbea..56ea4384 100644
--- a/jams-server/src/main/resources/webapp/js/search.js
+++ b/jams-server/src/main/resources/webapp/js/search.js
@@ -59,7 +59,7 @@ $(document).ready(function() {
                 var data = {
                     "username": input
                 }
-                ajaxApiCall(api_path_post_exists_user, 'POST', data, null, handleUserExists);
+                ajaxApiCall(api_path_get_exists_user, 'GET', data, null, handleUserExists);
             }
         });
 
@@ -69,16 +69,16 @@ $(document).ready(function() {
             e.preventDefault();
 
             var data = {
-                'givenName': $('#input-givenName').val(),
-                'sn': $('#input-sn').val(),
-                'CN': $('#input-cn').val(),
-                'mail': $('#input-mail').val(),
-                'jpegPhoto': b64,
-                'o': $('#input-o').val(),
-                'facsimileTelephoneNumber': $('#input-facsimileTelephoneNumber').val(),
-                'telephoneNumber': $('#input-telephoneNumber').val(),
-                'extension': $('#input-extension').val(),
-                'mobile': $('#input-mobile').val()
+                'firstName': $('#input-givenName').val(),
+                'lastName': $('#input-sn').val(),
+                'username': $('#input-cn').val(),
+                'email': $('#input-mail').val(),
+                'profilePicture': b64,
+                'organization': $('#input-o').val(),
+                'faxNumber': $('#input-facsimileTelephoneNumber').val(),
+                'phoneNumber': $('#input-telephoneNumber').val(),
+                'phoneNumberExtension': $('#input-extension').val(),
+                'mobileNumber': $('#input-mobile').val()
             }
 
             // send post request
@@ -114,45 +114,45 @@ $('#search').keyup(function(e) {
 
 function listAllUsers(data, statusCode, jqXHR)
 {
-  if (jqXHR.status == 200 && data.length != 0) {
-    var resultSet = data;
-    var userRow = '';
-    // build table row for each User item
-    for (i = 0; i < resultSet.length; i++) {
-      var firstName = '';
-      var lastName = '';
-
-      if (resultSet[i].firstName)
-          firstName = resultSet[i].firstName;
-      else
-          firstName = "Unavailable";
-
-      if (resultSet[i].lastName)
-          lastName = resultSet[i].lastName;
-      else
-          lastName = "Unavailable";
-
-      userRow +=
-        '<tr class="user-data bubble"><td data-href="aa" class="mobile">Username</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + resultSet[i].username +
-        '</td><td class="mobile">First Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + firstName + '' +
-        '</td><td class="mobile">Last Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + lastName +
-        '</td><td class="mobile">Devices</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) +'"><i class="fa fa-mobile"></i></td><td class="spacer--table">spacer</td>' +
-        '<td class="mobile">Actions</td><td class="user-information-search"><button class="edit-user" title="Edit User" style="display: none;" user-id="' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-edit"></i></button>' +
-        '<button type="button" id="de-authorize-user" class="btn-danger de-authorize-user" title="Revoke User" user-id="' + encodeURIComponent(resultSet[i].username) + '"' + '><i class="fa fa-trash"></i></button>' +
-        '</td><td class="spacer--table">spacer</td></tr>'
-    }
+    if (jqXHR.status == 200 && data.length != 0) {
+        var resultSet = data;
+        var userRow = '';
+        // build table row for each User item
+        for (i = 0; i < resultSet.length; i++) {
+            var firstName = '';
+            var lastName = '';
+
+            if (resultSet[i].firstName)
+                firstName = resultSet[i].firstName;
+            else
+                firstName = "Unavailable";
+
+            if (resultSet[i].lastName)
+                lastName = resultSet[i].lastName;
+            else
+                lastName = "Unavailable";
+
+            userRow +=
+                '<tr class="user-data bubble"><td data-href="aa" class="mobile">Username</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + resultSet[i].username +
+                '</td><td class="mobile">First Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + firstName + '' +
+                '</td><td class="mobile">Last Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + lastName +
+                '</td><td class="mobile">Devices</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) +'"><i class="fa fa-mobile"></i></td><td class="spacer--table">spacer</td>' +
+                '<td class="mobile">Actions</td><td class="user-information-search"><button class="edit-user" title="Edit User" style="display: none;" user-id="' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-edit"></i></button>' +
+                '<button type="button" id="de-authorize-user" class="btn-danger de-authorize-user" title="Revoke User" user-id="' + encodeURIComponent(resultSet[i].username) + '"' + '><i class="fa fa-trash"></i></button>' +
+                '</td><td class="spacer--table">spacer</td></tr>'
+        }
 
-    $('.empty-results').remove();
-    $('tbody').empty();
-    $('tbody').append(userRow).fadeIn('slow');
-  }
-  else {
-    $('tbody').append('<tr class="empty-results bubble"><td colspan="5" class="text-alert">No users found</td></tr>').fadeIn('slow');
-  }
+        $('.empty-results').remove();
+        $('tbody').empty();
+        $('tbody').append(userRow).fadeIn('slow');
+    }
+    else {
+        $('tbody').append('<tr class="empty-results bubble"><td colspan="5" class="text-alert">No users found</td></tr>').fadeIn('slow');
+    }
 
-  $('*[data-href]').on('click', function() {
-    window.location = $(this).data("href");
-  });
+    $('*[data-href]').on('click', function() {
+        window.location = $(this).data("href");
+    });
 
     setTimeout(function() {
         ajaxApiCall(api_path_get_directories, 'GET', null, null, isLocalDB);
@@ -214,7 +214,7 @@ function addListenersForActions() {
             }
 
             // send post request
-            ajaxApiCall(api_path_post_update_user, 'POST', data, null, handleUserUpdate);
+            ajaxApiCall(api_path_put_update_user, 'POST', data, null, handleUserUpdate);
         });
 
     });
@@ -265,48 +265,48 @@ function isActivated(data) {
 }
 
 function searchFunction(data, statusCode, jqXHR) {
-  if (jqXHR.status == 200 && data.length != 0) {
-    // parse JSON response
-    var resultSet = data;
-    var userRow = '';
-    // build table row for each User item
-    for (i = 0; i < resultSet.length; i++) {
-      var status = '';
-      // determine User status
-        var firstName = '';
-        var lastName = '';
-        if (resultSet[i].firstName)
-            firstName = resultSet[i].firstName;
-        else
-            firstName = "Unavailable";
-
-        if (resultSet[i].lastName)
-            lastName = resultSet[i].lastName;
-        else
-            lastName = "Unavailable";
-
-        userRow +=
-            '<tr class="user-data bubble"><td data-href="aa" class="mobile">Username</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + resultSet[i].username +
-            '</td><td class="mobile">First Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + firstName + '' +
-            '</td><td class="mobile">Last Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + lastName +
-            '</td><td class="mobile">Devices</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-mobile"></i></td><td class="spacer--table">spacer</td>' +
-            '<td class="mobile">Actions</td><td class="user-information-search"><button class="edit-user" user-id="' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-edit"></i></button>' +
-            '<button type="button" id="de-authorize-user" class="btn-danger de-authorize-user" user-id="' + encodeURIComponent(resultSet[i].username) + '"' + '><i class="fa fa-trash"></i></button>' +
-            '</td><td class="spacer--table">spacer</td></tr>'
-    }
+    if (jqXHR.status == 200 && data.length != 0) {
+        // parse JSON response
+        var resultSet = data;
+        var userRow = '';
+        // build table row for each User item
+        for (i = 0; i < resultSet.length; i++) {
+            var status = '';
+            // determine User status
+            var firstName = '';
+            var lastName = '';
+            if (resultSet[i].firstName)
+                firstName = resultSet[i].firstName;
+            else
+                firstName = "Unavailable";
+
+            if (resultSet[i].lastName)
+                lastName = resultSet[i].lastName;
+            else
+                lastName = "Unavailable";
+
+            userRow +=
+                '<tr class="user-data bubble"><td data-href="aa" class="mobile">Username</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + resultSet[i].username +
+                '</td><td class="mobile">First Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + firstName + '' +
+                '</td><td class="mobile">Last Name</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '">' + lastName +
+                '</td><td class="mobile">Devices</td><td style="cursor:pointer;" data-href="user.html?username=' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-mobile"></i></td><td class="spacer--table">spacer</td>' +
+                '<td class="mobile">Actions</td><td class="user-information-search"><button class="edit-user" user-id="' + encodeURIComponent(resultSet[i].username) + '"><i class="fa fa-edit"></i></button>' +
+                '<button type="button" id="de-authorize-user" class="btn-danger de-authorize-user" user-id="' + encodeURIComponent(resultSet[i].username) + '"' + '><i class="fa fa-trash"></i></button>' +
+                '</td><td class="spacer--table">spacer</td></tr>'
+        }
 
-    $('.empty-results').remove();
-    $('tbody').empty();
-    $('tbody').append(userRow).fadeIn('slow');
-  }
-  else {
-    // reset table
-    $('.user-data').remove();
-    if($('.empty-results').length == 0)
-    $('tbody').append('<tr class="empty-results bubble"><td colspan="5" class="text-alert">No users found</td></tr>').fadeIn('slow');
-  }
+        $('.empty-results').remove();
+        $('tbody').empty();
+        $('tbody').append(userRow).fadeIn('slow');
+    }
+    else {
+        // reset table
+        $('.user-data').remove();
+        if($('.empty-results').length == 0)
+            $('tbody').append('<tr class="empty-results bubble"><td colspan="5" class="text-alert">No users found</td></tr>').fadeIn('slow');
+    }
 
-  addListenersForActions();
+    addListenersForActions();
 }
 
 function handleUpdate(data, statusCode, jqXHR) {
@@ -342,31 +342,23 @@ function handleUpdateStart() {
 
 // send post request
 function submitForm(data) {
-    ajaxApiCall(api_path_post_create_user, 'POST', data, null, handleUserCreation);
+    ajaxApiCall(api_path_post_create_user_profile, 'POST', data, null, handleUserProfileCreation);
 }
 
-function handleUserCreation(data, statusCode, jqXHR) {
-    $('#user-pw-modal-body').text("");
-    $('#userPasswordModalCenter').modal('show');
-
-    if (data.status == 567)
-        $('#user-pw-modal-body').text("Username is already in use on the public nameserver. Please choose another one.");
-    else if (data.pw == null)
-        $('#user-pw-modal-body').text("Failed to create new user. Please try again.");
-    else
-        $('#user-pw-modal-body').text("New user successfully created. Here is the one time password: " + data.pw);
-
-    ajaxApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null, listAllUsers);
+function handleUserProfileCreation(data) {
+    console.log(data);
+    ajaxApiCall(api_path_post_create_user, 'POST', {"username": data.username}, null, handleUserCreation);
 }
 
 function handleUserUpdate() {
     ajaxApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null, listAllUsers);
+    ajaxApiCall(api_path_post_create_user_profile, 'GET', {"username":"*"}, null, listAllUsers);
 }
 
 function handleUserExists(data) {
     $('#valid-cn').text("");
 
-    if (data != null && data.exists == "true"){
+    if (data == '[]'){
         $('#valid-cn').text("Username is already taken!");
         $('#valid-cn').css('color', '#bd2130');
     }
@@ -420,6 +412,7 @@ function revokeUser(data, statusCode, jqXHR) {
     }
 
     ajaxApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null, listAllUsers);
+    ajaxApiCall(api_path_post_create_user_profile, 'GET', {"username":"*"}, null, listAllUsers);
     userRevoke = '';
 }
 
@@ -440,10 +433,36 @@ function handleUserAutofill(data, statusCode, jqXHR) {
 }
 
 function isLocalDB(data, statusCode, jqXHR){
-    if (jqXHR.status == 200) {
-        if (data[0].type === "LOCAL" && data[0].realm === "LOCAL") {
+    if (jqXHR.status == 200 && data.length != 0) {
+        var firstFound = false;
+        if (data.length == 1 && data[0].type === "LOCAL" && data[0].realm === "LOCAL") {
             $('.user-create-div').show();
             $('.edit-user').show();
         }
+
+        for (i = 0; i < data.length; i++) {
+            if (firstFound && data[i].type === "LOCAL" && data[i].realm === "LOCAL") {
+                $('.user-create-div').show();
+                $('.edit-user').show();
+                break;
+            }
+            if (!firstFound && data[i].type === "LOCAL" && data[i].realm === "LOCAL")
+                firstFound = true;
+
+        }
     }
-}
\ No newline at end of file
+}
+
+function handleUserCreation(data) {
+    $('#user-pw-modal-body').text("");
+    $('#userPasswordModalCenter').modal('show');
+
+    if (data.status == 500)
+        $('#user-pw-modal-body').text("Failed to create new user. This is either because the username is already in use" +
+            " on the public nameserver, or another unknown error has occurred. " +
+            "Please choose another one.");
+    else
+        $('#user-pw-modal-body').text("New user successfully created. Here is the one time password: " + data.pw);
+
+    ajaxApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null, listAllUsers);
+}
diff --git a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java
index b6489bfa..7669e7b2 100644
--- a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java
+++ b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java
@@ -72,8 +72,9 @@ public class LDAPConnector implements AuthenticationSource {
     }
 
     @Override
-    public void setUserProfile(UserProfile userProfile) {
+    public boolean setUserProfile(UserProfile userProfile) {
         //does nothing since we cannot edit LDAP profiles.
+        return false;
     }
 
     @Override
-- 
GitLab