diff --git a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
index e33bc036bd6ae74f8c9003a62f7d8accd23c3787..045136c89bac0c790a8ac83c9bf4f366cef8f8fd 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/GroupDao.java
@@ -22,7 +22,7 @@ public class GroupDao extends AbstractDao<Group>{
         SQLConnection connection = DataStore.connectionPool.getConnection();
         try{
             PreparedStatement ps = connection.getConnection().prepareStatement("INSERT INTO groups " +
-                    "(name, blueprint) VALUES (?, ?)");
+                    "(id, name, blueprint) VALUES (?, ?, ?)");
             ps = object.getInsert(ps);
             return ps.executeUpdate() != 0;
         }
@@ -38,17 +38,17 @@ public class GroupDao extends AbstractDao<Group>{
     @Override
     public boolean updateObject(StatementList update, StatementList constraints) {
 
-        String name = update.getStatements().get(0).getValue();
-        String blueprint = update.getStatements().get(1).getValue();
-        String oldName = constraints.getStatements().get(0).getValue();
+        String id = update.getStatements().get(0).getValue();
+        String name = update.getStatements().get(1).getValue();
+        String blueprint = update.getStatements().get(2).getValue();
 
         SQLConnection connection = DataStore.connectionPool.getConnection();
 
         try{
-            PreparedStatement ps = connection.getConnection().prepareStatement("UPDATE groups SET name = ?, blueprint = ? WHERE name = ?");
+            PreparedStatement ps = connection.getConnection().prepareStatement("UPDATE groups SET name = ?, blueprint = ? WHERE id = ?");
             ps.setString(1, name);
             ps.setString(2, blueprint);
-            ps.setString(3, oldName);
+            ps.setString(3, id);
             return ps.executeUpdate() != 0;
         }
         catch (SQLException e){
@@ -63,12 +63,12 @@ public class GroupDao extends AbstractDao<Group>{
     @Override
     public boolean deleteObject(StatementList constraints) {
 
-        String name = constraints.getStatements().get(0).getValue();
+        String id = constraints.getStatements().get(0).getValue();
         SQLConnection connection = DataStore.connectionPool.getConnection();
 
         try {
-            PreparedStatement ps = connection.getConnection().prepareStatement("DELETE FROM groups WHERE name = ?");
-            ps.setString(1, name);
+            PreparedStatement ps = connection.getConnection().prepareStatement("DELETE FROM groups WHERE id = ?");
+            ps.setString(1, id);
             return ps.executeUpdate() != 0;
         } catch (SQLException e){
             log.error("An error has occurred while trying to delete a group: " + e.toString());
diff --git a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
index 9e576cf818e59272bd9cceeccfa37a742691810d..c58b31aa1cfc694e794c18195c59bdb36ebdc107 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserGroupMappingsDao.java
@@ -7,6 +7,7 @@ import net.jami.jams.common.dao.connectivity.SQLConnection;
 import net.jami.jams.common.objects.user.UserGroupMapping;
 
 import java.sql.PreparedStatement;
+import java.sql.SQLException;
 
 @Slf4j
 public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping>{
@@ -22,7 +23,7 @@ public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping>{
         SQLConnection connection = DataStore.connectionPool.getConnection();
         try {
             PreparedStatement ps = connection.getConnection().prepareStatement("INSERT INTO usergroupmappings " +
-                    "(username, groups)" + " VALUES " + "(?,?)");
+                    "(username, groupId)" + " VALUES " + "(?,?)");
             ps = object.getInsert(ps);
             return ps.executeUpdate() != 0;
         } catch (Exception e) {
@@ -34,22 +35,30 @@ public class UserGroupMappingsDao extends AbstractDao<UserGroupMapping>{
     }
 
     @Override
-    public boolean updateObject(StatementList update, StatementList constraints) {
+    public boolean deleteObject(StatementList constraints) {
 
-        String groups = update.getStatements().get(0).getValue();
         String username = constraints.getStatements().get(0).getValue();
-
+        String groupId = constraints.getStatements().get(1).getValue();
         SQLConnection connection = DataStore.connectionPool.getConnection();
+
         try {
-            PreparedStatement ps = connection.getConnection().prepareStatement("UPDATE usergroupmappings SET groups = ? WHERE username = ?");
-            ps.setString(1, groups);
-            ps.setString(2, username);
-            return ps.executeUpdate() != 0;
-        } catch (Exception e) {
-            log.error("An error has occurred while trying to update a user profile: " + e.toString());
+            if(username.equals("*")){
+                PreparedStatement ps = connection.getConnection().prepareStatement("DELETE FROM usergroupmappings WHERE groupId = ?");
+                ps.setString(1, groupId);
+                return ps.executeUpdate() != 0;
+            }
+            else {
+                PreparedStatement ps = connection.getConnection().prepareStatement("DELETE FROM usergroupmappings WHERE username = ? AND groupId = ?");
+                ps.setString(1, username);
+                ps.setString(2, groupId);
+                return ps.executeUpdate() != 0;
+            }
+        } catch (SQLException e){
+            log.error("An error has occurred while trying to delete a group member: " + e.toString());
             return false;
         } finally {
             DataStore.connectionPool.returnConnection(connection);
         }
     }
+
 }
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 56d06de63995072ce7e05a415638e76f42ec586a..7fa7a52e4e1489f464f6a026576aba2264e7ad2c 100644
--- a/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
+++ b/datastore/src/main/java/net/jami/datastore/dao/UserProfileDao.java
@@ -46,8 +46,8 @@ public class UserProfileDao extends AbstractDao<UserProfile> {
         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, groupMemberships)" +
-                " VALUES " + "(?,?,?,?,?,?,?,?,?,?,?)");
+                "(username, firstName, lastName, email, profilePicture, organization, phoneNumber, phoneNumberExtension, faxNumber, mobileNumber)" +
+                " VALUES " + "(?,?,?,?,?,?,?,?,?,?)");
             ps = object.getInsert(ps);
             return ps.executeUpdate() != 0;
         } catch (Exception e) {
@@ -63,7 +63,7 @@ public class UserProfileDao extends AbstractDao<UserProfile> {
 
         SQLConnection connection = DataStore.connectionPool.getConnection();
         try {
-            PreparedStatement ps = connection.getConnection().prepareStatement("UPDATE local_directory SET firstname = ?, lastName = ?, email = ?, profilePicture = ?, organization = ?, phoneNumber = ?, phoneNumberExtension = ?, faxNumber = ?, mobileNumber = ?, groupMemberships = ? WHERE username = ?");
+            PreparedStatement ps = connection.getConnection().prepareStatement("UPDATE local_directory SET firstname = ?, lastName = ?, email = ?, profilePicture = ?, organization = ?, phoneNumber = ?, phoneNumberExtension = ?, faxNumber = ?, mobileNumber = ? WHERE username = ?");
             for (int i = 1; i < update.getStatements().size(); i++) {
                 ps.setString(i, update.getStatements().get(i).getValue());
             }
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 15cb8c23b8b6e5ec908a80eb113790ac45b51a2f..ae4c229c3d80b6f17cfad1718564c34033823ead 100644
--- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java
+++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java
@@ -144,27 +144,6 @@ public class DataStore implements AuthenticationSource {
         return userProfileDao.storeObject(userProfile);
     }
 
-    public boolean updateUserGroupMappings (UserProfile userProfile) {
-        StatementList statementList = new StatementList();
-        statementList.addStatement(new StatementElement("username", "=", userProfile.getUsername(), ""));
-        if (getUserGroupMappingsDao().getObjects(statementList) != null && !getUserGroupMappingsDao().getObjects(statementList).isEmpty()) {
-            UserGroupMapping mapping = getUserGroupMappingsDao().getObjects(statementList).get(0);
-            List<String> list = new ArrayList<>();
-            if (mapping.getUsername().equals(userProfile.getUsername())) {
-                String[] splits = mapping.getGroups().split(",");
-
-                for (int i = 0; i < splits.length; i++)
-                    list.add(splits[i]);
-            }
-            if (!list.isEmpty())
-                userProfile.setGroupMemberships(list);
-
-            return (updateUserProfile(userProfile));
-        }
-
-        return true;
-    }
-
     public boolean updateUserProfile(UserProfile userProfile){
 
         StatementList update = new StatementList();
@@ -178,18 +157,6 @@ public class DataStore implements AuthenticationSource {
         update.addStatement(new StatementElement("phoneNumberExtension","=",userProfile.getPhoneNumberExtension(),""));
         update.addStatement(new StatementElement("faxNumber","=",userProfile.getFaxNumber(),""));
         update.addStatement(new StatementElement("mobileNumber","=",userProfile.getMobileNumber(),""));
-        if (userProfile.getGroupMemberships() != null && !userProfile.getGroupMemberships().isEmpty()) {
-            String groups = "";
-            for (String s: userProfile.getGroupMemberships()) {
-                if (groups.equals(""))
-                    groups = s;
-                else
-                    groups = groups.concat("," + s);
-            }
-            update.addStatement(new StatementElement("groupMemberships","=", groups ,""));
-        } else
-            update.addStatement(new StatementElement("groupMemberships","=", "" ,""));
-
 
         return userProfileDao.updateObject(update, null);
     }
diff --git a/datastore/src/main/resources/db/migration/V27__UserGroupMappings.sql b/datastore/src/main/resources/db/migration/V27__UserGroupMappings.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f8567a237d566869d2b40604ee886d68b9d47bc3
--- /dev/null
+++ b/datastore/src/main/resources/db/migration/V27__UserGroupMappings.sql
@@ -0,0 +1,6 @@
+ALTER TABLE usergroupmappings DROP PRIMARY KEY;
+ALTER TABLE usergroupmappings ADD COLUMN GROUPID varchar(36);
+UPDATE usergroupmappings SET GROUPID = groups;
+ALTER TABLE usergroupmappings DROP COLUMN groups;
+ALTER TABLE usergroupmappings ADD id int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1);
+ALTER TABLE usergroupmappings ADD PRIMARY KEY (id);
\ No newline at end of file
diff --git a/datastore/src/main/resources/db/migration/V35__Group.sql b/datastore/src/main/resources/db/migration/V35__Group.sql
new file mode 100644
index 0000000000000000000000000000000000000000..a8ca7fb4705c16f01062d0bb72de44d6c2958667
--- /dev/null
+++ b/datastore/src/main/resources/db/migration/V35__Group.sql
@@ -0,0 +1,2 @@
+ALTER TABLE groups DROP PRIMARY KEY;
+ALTER TABLE groups ADD ID varchar(36) PRIMARY KEY not null default '';
\ No newline at end of file
diff --git a/datastore/src/test/resources/db/migration/V17__UserGroupMappings.sql b/datastore/src/test/resources/db/migration/V17__UserGroupMappings.sql
index d9b8deb1d998a7288617435c88902c52d1ed2817..2bcd6e18669b3eab87546bd5e9ba9aa337fb5236 100644
--- a/datastore/src/test/resources/db/migration/V17__UserGroupMappings.sql
+++ b/datastore/src/test/resources/db/migration/V17__UserGroupMappings.sql
@@ -1,3 +1,3 @@
 CREATE TABLE usergroupmappings (username varchar(255),
-groupMemberships CLOB,
+groups varchar(5000),
 PRIMARY KEY (username));
\ No newline at end of file
diff --git a/datastore/src/test/resources/db/migration/V27__UserGroupMappings.sql b/datastore/src/test/resources/db/migration/V27__UserGroupMappings.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f8567a237d566869d2b40604ee886d68b9d47bc3
--- /dev/null
+++ b/datastore/src/test/resources/db/migration/V27__UserGroupMappings.sql
@@ -0,0 +1,6 @@
+ALTER TABLE usergroupmappings DROP PRIMARY KEY;
+ALTER TABLE usergroupmappings ADD COLUMN GROUPID varchar(36);
+UPDATE usergroupmappings SET GROUPID = groups;
+ALTER TABLE usergroupmappings DROP COLUMN groups;
+ALTER TABLE usergroupmappings ADD id int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1);
+ALTER TABLE usergroupmappings ADD PRIMARY KEY (id);
\ No newline at end of file
diff --git a/datastore/src/test/resources/db/migration/V35__Group.sql b/datastore/src/test/resources/db/migration/V35__Group.sql
new file mode 100644
index 0000000000000000000000000000000000000000..a8ca7fb4705c16f01062d0bb72de44d6c2958667
--- /dev/null
+++ b/datastore/src/test/resources/db/migration/V35__Group.sql
@@ -0,0 +1,2 @@
+ALTER TABLE groups DROP PRIMARY KEY;
+ALTER TABLE groups ADD ID varchar(36) PRIMARY KEY not null default '';
\ No newline at end of file
diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/user/Group.java b/jams-common/src/main/java/net/jami/jams/common/objects/user/Group.java
index 0bd5a5d883a3c17ae8c5b950e6f3b8ec2c5e5b71..a77b95c193f512e6c444b1b7145a17197db5e9b8 100644
--- a/jams-common/src/main/java/net/jami/jams/common/objects/user/Group.java
+++ b/jams-common/src/main/java/net/jami/jams/common/objects/user/Group.java
@@ -17,20 +17,21 @@ import java.util.List;
 @Getter
 @Setter
 public class Group implements DatabaseObject {
+    private String id;
     private String name;
     private String blueprint;
-    private List<String> groupMembers;
 
     public Group(ResultSet rs) throws SQLException {
+        this.id = rs.getString("id");
         this.name = rs.getString("name");
         this.blueprint = rs.getString("blueprint");
-        this.groupMembers = new ArrayList<>();
     }
 
     @Override
     public PreparedStatement getInsert(PreparedStatement ps) throws SQLException {
-        ps.setString(1, name);
-        ps.setString(2, blueprint);
+        ps.setString(1, id);
+        ps.setString(2, name);
+        ps.setString(3, blueprint);
         return ps;
     }
 
@@ -43,4 +44,14 @@ public class Group implements DatabaseObject {
     public PreparedStatement getUpdate(PreparedStatement ps) throws Exception {
         return null;
     }
+
+    public boolean isEmpty() {
+        if(this.id == null && this.name  == null) return true;
+        return false;
+    }
+
+    public boolean hasBlueprint() {
+        if(this.blueprint == null || this.blueprint.equals("")) return false;
+        return true;
+    }
 }
diff --git a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserGroupMapping.java b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserGroupMapping.java
index 46f477a9cd89d47d07c77cd8230dcc7ea362f038..2925ebd6574128af58fca49d8ab1602809272f17 100644
--- a/jams-common/src/main/java/net/jami/jams/common/objects/user/UserGroupMapping.java
+++ b/jams-common/src/main/java/net/jami/jams/common/objects/user/UserGroupMapping.java
@@ -16,35 +16,17 @@ import java.sql.ResultSet;
 public class UserGroupMapping implements DatabaseObject {
 
     private String username;
-    private String groups;
+    private String groupId;
 
     public UserGroupMapping(ResultSet rs) throws Exception {
         this.username = rs.getString("username");
-        this.groups = rs.getString("groups");
-    }
-
-    public void addGroup(String s) {
-        if (this.groups.equals(""))
-            this.groups = s;
-        else
-            this.groups = this.groups.concat("," + s);
-    }
-
-    public void removeGroup(String s) {
-        if (this.groups.contains(s) ) {
-            if (this.groups.contains(",")) {
-                this.groups = this.groups.replace(s + ",", "");
-                this.groups = this.groups.replace("," + s, "");
-            }
-            else
-                this.groups = "";
-        }
+        this.groupId = rs.getString("groupId");
     }
 
     @Override
     public PreparedStatement getInsert(PreparedStatement ps) throws Exception {
         ps.setString(1, username);
-        ps.setString(2, groups);
+        ps.setString(2, groupId);
         return ps;
     }
 
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 b9a67de117c6306898f77bc4603362217c2113c6..23e56b572372e83cfb0d8a4a2fc289ca7f259f88 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
@@ -75,7 +75,6 @@ public class UserProfile implements DatabaseObject {
     private String faxNumber;
     private String mobileNumber;
     private String id;
-    private List<String> groupMemberships;
 
     public UserProfile(ResultSet rs) throws Exception {
         this.username = rs.getString("username");
@@ -88,7 +87,6 @@ public class UserProfile implements DatabaseObject {
         this.phoneNumberExtension = rs.getString("phoneNumberExtension");
         this.faxNumber = rs.getString("faxNumber");
         this.mobileNumber = rs.getString("mobileNumber");
-        this.groupMemberships = new ArrayList<>(Arrays.asList(rs.getString("groupMemberships").split(",")));
     }
 
     @JsonIgnore
@@ -130,10 +128,6 @@ public class UserProfile implements DatabaseObject {
         ps.setString(8, phoneNumberExtension);
         ps.setString(9, faxNumber);
         ps.setString(10, mobileNumber);
-        if (!groupMemberships.isEmpty())
-            ps.setString(11, JsonStream.serialize(groupMemberships));
-        else
-            ps.setString(11, "");
         return ps;
     }
 
@@ -176,8 +170,6 @@ public class UserProfile implements DatabaseObject {
             this.faxNumber = "";
         if (this.mobileNumber == null)
             this.mobileNumber = "";
-        if (this.groupMemberships == null)
-            this.groupMemberships = new ArrayList<>();
     }
 
 }
diff --git a/jams-react-client/public/locales/en/translation.json b/jams-react-client/public/locales/en/translation.json
index 9ef108cebc783872bec8c454c19a12691bb0af21..0ca38adde08d25a48b0ee2afb4b9225d9bbdc0f0 100644
--- a/jams-react-client/public/locales/en/translation.json
+++ b/jams-react-client/public/locales/en/translation.json
@@ -235,5 +235,6 @@
     "add_user_to_group": "Add user to group ...",
     "add_user_to_a_group": "Add user to a group",
     "remove_from_group": "Remove from group",
-    "myprofile": "My profile"
+    "myprofile": "My profile",
+    "select_blueprint": "Select a blueprint"
 }
diff --git a/jams-react-client/public/locales/fr/translation.json b/jams-react-client/public/locales/fr/translation.json
index 5aad0beffe2cdce47eb835da9ad81325e2147216..9e037d6eeb81e050c255894ae0a6797f1581c291 100644
--- a/jams-react-client/public/locales/fr/translation.json
+++ b/jams-react-client/public/locales/fr/translation.json
@@ -235,5 +235,6 @@
     "add_user_to_group": "Ajouter un utilisateur au groupe...",
     "add_user_to_a_group": "Ajouter l'utilisateur à un groupe",
     "remove_from_group": "Retirer du groupe",
-    "myprofile": "Mon profil"
+    "myprofile": "My profile",
+    "select_blueprint": "Select a blueprint"
 }
diff --git a/jams-react-client/src/assets/img/favicon_jami.png b/jams-react-client/src/assets/img/favicon_jami.png
new file mode 100644
index 0000000000000000000000000000000000000000..794f3628e2eb68df1f8c287ee4ed9f37e73fb9c0
Binary files /dev/null and b/jams-react-client/src/assets/img/favicon_jami.png differ
diff --git a/jams-react-client/src/components/Drawer/Drawer.js b/jams-react-client/src/components/Drawer/Drawer.js
index 267c939ac7db6ce3b51db304abd27fb254616de0..6cb438483107c600b28110cae9dba2db59b13ded 100644
--- a/jams-react-client/src/components/Drawer/Drawer.js
+++ b/jams-react-client/src/components/Drawer/Drawer.js
@@ -77,7 +77,7 @@ export default function TemporaryDrawer(props) {
           button
           key={target.name}
           onClick={() => {
-            props.addElementToTarget(target.name);
+            props.addElementToTarget(target);
             props.setOpenDrawer(false);
           }}
         >
diff --git a/jams-react-client/src/globalUrls.js b/jams-react-client/src/globalUrls.js
index 85565dc03b6289195fa520f770d5ccc74a9b42b6..9d7f89c414d1973260595bbf25a7705faf02e06e 100644
--- a/jams-react-client/src/globalUrls.js
+++ b/jams-react-client/src/globalUrls.js
@@ -17,9 +17,11 @@ const api_path_delete_auth_user_revoke = "/api/auth/user";
 const api_path_delete_admin_device_revoke = "/api/admin/device";
 const api_path_delete_auth_device_revoke = "/api/auth/device";
 const api_path_rename_device = "/api/auth/device";
-const api_path_get_list_group = "/api/admin/group";
-const api_path_delete_group = "/api/admin/group";
-const api_path_put_update_group = "/api/admin/group";
+const api_path_get_list_group = "/api/admin/groups";
+const api_path_post_create_group = "/api/admin/group";
+const api_path_delete_group = "/api/admin/group/";
+const api_path_put_update_group = "/api/admin/group/";
+const api_path_get_group = "/api/admin/group/";
 const api_path_get_server_status = "/api/info";
 const api_path_get_post_configuration_auth_service =
   "/api/configuration/authservice";
@@ -31,7 +33,6 @@ const api_path_get_subscription_status = "/api/admin/subscription";
 const api_path_get_directories = "/api/auth/directories";
 const api_path_get_needs_update = "/api/admin/update";
 const api_path_get_start_update = "/api/admin/update";
-const api_path_post_create_group = "/api/admin/group";
 const api_path_post_create_user = "/api/admin/user";
 const api_path_put_update_user = "/api/admin/user";
 const api_path_get_auth_user = "/api/auth/user";
@@ -50,6 +51,10 @@ const api_path_blueprints = "/api/admin/policy";
 const api_path_get_user_profile = "/api/auth/userprofile/";
 const api_path_get_ns_name_from_addr = "/api/nameserver/addr/";
 const api_path_get_ns_addr_from_name = "/api/nameserver/name/";
+const api_path_get_group_members = "/api/admin/group/members/";
+const api_path_post_group_member = "/api/admin/group/members/";
+const api_path_delete_group_member = "/api/admin/group/members/";
+const api_path_get_admin_user_groups = "/api/admin/user/groups/";
 
 module.exports = {
   uri,
@@ -98,8 +103,13 @@ module.exports = {
   api_path_get_list_group,
   api_path_post_create_group,
   api_path_put_update_group,
+  api_path_get_group,
   api_path_blueprints,
   api_path_get_user_profile,
   api_path_get_ns_name_from_addr,
   api_path_get_ns_addr_from_name,
+  api_path_get_group_members,
+  api_path_post_group_member,
+  api_path_delete_group_member,
+  api_path_get_admin_user_groups
 };
diff --git a/jams-react-client/src/index.js b/jams-react-client/src/index.js
index 587dbcdf0964e6616ab20a4cb89194c75e92cac9..117ab849fc49b886c2411185b68b949c5a7b0e59 100644
--- a/jams-react-client/src/index.js
+++ b/jams-react-client/src/index.js
@@ -52,7 +52,7 @@ auth.isServerInstalled(() => {
               <ProtectedRoute path="/user/:username" component={UserRoute} />
               <ProtectedRoute path="/createuser" component={CreateUserRoute} />
               <ProtectedRoute path="/groups" component={GroupsRoute} />
-              {/* <ProtectedRoute path="/group/:groupname" component={GroupRoute} /> */}
+              <ProtectedRoute path="/group/:groupid" component={GroupRoute} />
               <ProtectedRoute path="/blueprints" component={BlueprintsRoute} />
               <ProtectedRoute path="/blueprint/:blueprintname" component={BlueprintRoute} />
               <ProtectedRoute path="/settings" component={SettingsRoute} />
diff --git a/jams-react-client/src/routes/BlueprintRoute.js b/jams-react-client/src/routes/BlueprintRoute.js
index 182d9901069503604ace5eafce6670e79f5ccabd..d9f873043b4cc16fe6faedaa767556c8d6142ef9 100644
--- a/jams-react-client/src/routes/BlueprintRoute.js
+++ b/jams-react-client/src/routes/BlueprintRoute.js
@@ -3,7 +3,7 @@ import React from "react";
 import BaseLayout from "layouts/BaseLayout.js";
 import Blueprint from "views/Blueprint/Blueprint";
 
-export default function UsersRoute (props) {
+export default function BlueprintRoute (props) {
     return (
         <BaseLayout component={<Blueprint blueprintName={props.match.params.blueprintname} />} />
     )
diff --git a/jams-react-client/src/routes/BlueprintsRoute.js b/jams-react-client/src/routes/BlueprintsRoute.js
index cd7657009979b8207e33ba8d545c288379ceec4f..35037ee61b7476ead9dd4d1e805768c85f5a99b0 100644
--- a/jams-react-client/src/routes/BlueprintsRoute.js
+++ b/jams-react-client/src/routes/BlueprintsRoute.js
@@ -4,7 +4,7 @@ import Blueprints from "views/Blueprints/Blueprints.js";
 
 import ListLayout from "layouts/ListLayout.js";
 
-export default function UsersRoute () {
+export default function BlueprintsRoute () {
     return (
         <ListLayout component={<Blueprints />} />
     )
diff --git a/jams-react-client/src/routes/GroupRoute.js b/jams-react-client/src/routes/GroupRoute.js
index 4fe4eb49fb407c4d3539f3e32472a5194f16c35f..d33110e1ef064dec3122e017ea14734cc2c75c23 100644
--- a/jams-react-client/src/routes/GroupRoute.js
+++ b/jams-react-client/src/routes/GroupRoute.js
@@ -1,11 +1,10 @@
 import React from "react";
 
+import ListLayout from "layouts/ListLayout.js";
 import EditGroup from "views/Groups/EditGroup.js";
 
-import BaseLayout from "layouts/BaseLayout.js";
-
-export default function UsersRoute (props) {
+export default function GroupRoute (props) {
     return (
-        <BaseLayout component={<EditGroup groupName={props.match.params.groupname} />} />
+        <ListLayout component={<EditGroup groupid={props.match.params.groupid} />} />
     )
 }
\ No newline at end of file
diff --git a/jams-react-client/src/routes/GroupsRoute.js b/jams-react-client/src/routes/GroupsRoute.js
index ea731f5c42aaa0397bddaa2e8f25ea65afa2aab1..db4bc7133b07d4316194805b972f6993acb899f5 100644
--- a/jams-react-client/src/routes/GroupsRoute.js
+++ b/jams-react-client/src/routes/GroupsRoute.js
@@ -1,10 +1,9 @@
 import React from "react";
 
-import Groups from "views/Groups/Groups.js";
-
 import ListLayout from "layouts/ListLayout.js";
+import Groups from "views/Groups/Groups.js";
 
-export default function UsersRoute () {
+export default function GroupsRoute () {
     return (
         <ListLayout component={<Groups />} />
     )
diff --git a/jams-react-client/src/routes/SettingsRoute.js b/jams-react-client/src/routes/SettingsRoute.js
index 60fd2a61988b26b930a2375aa81c4593b4d899fa..c645ee93c07a9c2fdf3a6d3a67cf22cb53a00a74 100644
--- a/jams-react-client/src/routes/SettingsRoute.js
+++ b/jams-react-client/src/routes/SettingsRoute.js
@@ -4,7 +4,7 @@ import Settings from "views/Settings/Settings.js";
 
 import BaseLayout from "layouts/BaseLayout.js";
 
-export default function UsersRoute (props) {
+export default function SettingsRoute (props) {
     return (
         <BaseLayout component={<Settings />} />
     )
diff --git a/jams-react-client/src/views/Groups/EditGroup.js b/jams-react-client/src/views/Groups/EditGroup.js
index e84c6899964295f229156cfc04ea17aa361b06b4..4c0ddf6ce201e03563e2be83241be5bc3b03bae7 100644
--- a/jams-react-client/src/views/Groups/EditGroup.js
+++ b/jams-react-client/src/views/Groups/EditGroup.js
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useCallback } from "react";
 import { Link, useHistory } from "react-router-dom";
 import classnames from "classnames";
 
@@ -23,6 +23,8 @@ import TableHead from '@material-ui/core/TableHead';
 import TableRow from "@material-ui/core/TableRow";
 import TableBody from "@material-ui/core/TableBody";
 import TableCell from "@material-ui/core/TableCell";
+import InputLabel from "@material-ui/core/InputLabel";
+
 
 import Select from "@material-ui/core/Select";
 
@@ -37,9 +39,14 @@ import axios from "axios"
 import configApiCall from "../../api"
 import {
     api_path_get_list_group,
+    api_path_get_group,
     api_path_put_update_group,
     api_path_get_user_directory_search,
-    api_path_get_user_profile
+    api_path_get_user_profile,
+    api_path_blueprints,
+    api_path_get_group_members,
+    api_path_post_group_member,
+    api_path_delete_group_member
 } from "../../globalUrls"
 
 import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
@@ -55,6 +62,8 @@ import i18next from "i18next";
 
 import auth from "auth.js";
 
+import { debounce } from "lodash";
+
 const useStyles = makeStyles((theme) => ({
     ...devicesStyle,
     ...dashboardStyle,
@@ -95,6 +104,9 @@ const useStyles = makeStyles((theme) => ({
         maxHeight: '60vh',
         minWidth: '80vh',
         maxWidth: '80vh'
+    },
+    inputBottomMargin: {
+      marginBottom: "1rem"
     }
 }));
 
@@ -102,11 +114,16 @@ export default function EditGroup(props) {
     const classes = useStyles();
     const history = useHistory();
 
-    const [name, setName] = React.useState(props.groupName);
-    const [newName, setNewName] = React.useState(props.groupName);
-    const [blueprint, setBlueprint] = React.useState(null);
+    const [name, setName] = React.useState("");
+    const [newName, setNewName] = React.useState("");
+    const [blueprints, setBlueprints] = React.useState([]);
+    const [selectedBlueprint, setSelectedBlueprint] = React.useState({
+        value: 0,
+        label: "No blueprint",
+      });
     const [groupMembers, setGroupMembers] = React.useState([]);
     const [openDrawer, setOpenDrawer] = React.useState(false);
+    const [groupNameExits, setGroupNameExits] = React.useState(false);
     const [users, setUsers] = React.useState([]);
 
     const getUserInfo = username => new Promise((resolve, reject) => {
@@ -126,89 +143,91 @@ export default function EditGroup(props) {
             });
     })
 
-    const getUsersInformation = userNames => {
-        userNames.forEach((username)=> {
-            getUserInfo(username).then((userInfo) => setGroupMembers(groupMembers.push(userInfo)))
-        })
-    }
-
     const getGroup = () => {
-        axios(configApiCall(api_path_get_list_group+"?groupName="+props.groupName, 'GET', null, null)).then((response) => {
-            let groups=response.data;
-            if(groups.length > 1){
-                groups.map((group) => {
-                    if(group.name === props.groupName){
-                        props.getBlueprintsOptions().forEach((blueprintOption) => {
-                            if(blueprintOption.label === group["blueprint"]){
-                                console.log("Group option value : " + blueprintOption.value);
-                                setBlueprint(blueprintOption.value);
-                            }
-                        })
-                        
-                            getUserInfo(group["groupMembers"]).then((userInfo) => {
-                                let newGroupMembers = groupMembers;
-                                newGroupMembers.push(userInfo);
-                                setGroupMembers(newGroupMembers);
-                            })
-                    }
+        axios(configApiCall(api_path_get_group + props.groupid, 'GET', null, null)).then((response) => {
+            let group = response.data;
+
+            axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null))
+            .then((response) => {
+                setBlueprints(response.data);
+                let index = 0;
+                response.data.map((blueprint) => {
+                    if(blueprint.name == group["blueprint"])
+                        setSelectedBlueprint({ value: index, label: blueprint.name });
+                    index += 1;
+                });
+            })
+            .catch((error) => {
+              console.log(error);
+              if (error.response.status === 401) {
+                auth.authenticated = false;
+                history.push("/");
+              }
+              if (error.response.status === 500) {
+                setBlueprints([]);
+              }
+            });
+
+            axios(configApiCall(api_path_get_group_members + props.groupid, 'GET', null, null)).then((response) => {
+                let members = response.data;
+                members.forEach((member) => {
+                    getUserInfo(member.username).then((userInfo) => {
+                        let newGroupMembers = groupMembers;
+                        newGroupMembers.push(userInfo);
+                        setGroupMembers(newGroupMembers);
+
+                        //This state update is added to force the groupMembers to displayed on first page loading
+                        setOpenDrawer(true);
+                        setOpenDrawer(false);
+                    })
                 })
-            }
-            else{
-                if(groups.name === props.groupName){
-                    props.getBlueprintsOptions().forEach((blueprintOption) => {
-                        if(blueprintOption.label === groups["blueprint"]){
-                            setBlueprint(blueprintOption.value)
-                        }
-                    })
-                    groups["groupMembers"].forEach((username)=> {
-                        getUserInfo(username).then((userInfo) => {
-                            let newGroupMembers = groupMembers;
-                            newGroupMembers.push(userInfo);
-                            setGroupMembers(newGroupMembers);
-                        })
-                    })
- 
+            }).catch((error) => {
+                if (error.response.status === 404) {
+                    setGroupMembers([]);
                 }
-            }
+                else
+                    console.log(error);
+            })
+
+
+            setName(group.name);
+            setNewName(group.name);
 
         }).catch((error) => {
-            console.log("Error fetching group members of: " + props.groupName + " " + error)
+            console.log("Error fetching group members of: " + props.name + " " + error)
         })
     }
 
-    const getGroupsOptions = () => {
-        let blueprintsOptions = []
-        let index = 0
-        if(props.blueprints.length === 0)
-            blueprintsOptions.push({value: index, label: "No blueprint found"})
+    const getBlueprintsOptions = (inputs) => {
+        let blueprintsOptions = [];
+        let index = 0;
+        if (blueprints.length === 0)
+          blueprintsOptions.push({ value: index, label: "No blueprint found" });
         else {
-            props.blueprints.map((blueprintElement) => {
-                blueprintsOptions.push({value: index, label: blueprintElement.name});
-                index += 1
-            })
+          blueprints.map((blueprint) => {
+            blueprintsOptions.push({ value: index, label: blueprint.name });
+            index += 1;
+          });
         }
-        return blueprintsOptions
-    }
+        return blueprintsOptions;
+      };
 
-    const blueprintsOptionsItems = tool.buildSelectMenuItems(getGroupsOptions());
+    const blueprintsOptionsItems = tool.buildSelectMenuItems(getBlueprintsOptions(blueprints));
 
     React.useEffect(()=>{
         getGroup();
         searchUsers();
     }, [])
 
-    const handleUpdateGroup = (blueprintValue) => {
+    const updateGroup = (blueprintValue) => {
 
-        let url = '';
-        if(blueprintValue == null){
-            url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+name+"&blueprintName=&groupMembers=";
-        }else{
-            url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+name+"&blueprintName="+props.getBlueprintsOptions()[blueprintValue].label+"&groupMembers=";
+        let data = {
+            "name": newName,
+            "blueprint": blueprintValue ? blueprintValue : selectedBlueprint.label
         }
 
-        axios(configApiCall(url, 'PUT', null, null)).then((response) => {
-            setNewName(name);
-            setBlueprint(blueprintValue);
+        axios(configApiCall(api_path_put_update_group + props.groupid, 'PUT', data, null)).then((response) => {
+            setName(newName);
         }).catch((error) => {
             console.log("Error updating group: " + error)
         })
@@ -245,29 +264,83 @@ export default function EditGroup(props) {
           });
       };
 
-    const updateUserInGroup = (user) => {
-        let url = '';
-        if(blueprint == null){
-            url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+props.groupName+"&blueprintName=&groupMembers="+[user.username,];
-        }else{
-            url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+props.groupName+"&blueprintName="+props.getBlueprintsOptions()[blueprint].label+"&groupMembers="+[user.username,];
+    const addUserInGroup = (user) => {
+        let data = {
+            "username": user.username
         }
+        axios(configApiCall(api_path_post_group_member + props.groupid, 'POST', data, null)).then((response) => {
+            let newGroupMembers = groupMembers;
+            newGroupMembers.push(user);
+            setGroupMembers(newGroupMembers);
 
-        axios(configApiCall(url, 'PUT', null, null)).then((response) => {
+            //This state update is added to force the groupMembers to refreshed displayed
+            setOpenDrawer(true);
+            setOpenDrawer(false);
+        }).catch((error) => {
+            if (error.response.status === 409) {
+                alert(`${user.username} is already part of ${name}`);
+            }
+            else
+                console.log("Error updating group: " + error)
+        })
+    }
+
+    const deleteUserFromGroup = (user) => {
+        let data = {
+            "username": user.username
+        }
+        axios(configApiCall(api_path_delete_group_member + props.groupid, 'DELETE', data, null)).then((response) => {
             let newGroupMembers = groupMembers;
-            if(newGroupMembers.includes(user)) newGroupMembers.splice(newGroupMembers.indexOf(user), 1);
-            else newGroupMembers.push(user);
+            newGroupMembers.splice(newGroupMembers.indexOf(user), 1);
             setGroupMembers(newGroupMembers);
+            
+            //This state update is added to force the groupMembers to refreshed displayed
+            setOpenDrawer(true);
+            setOpenDrawer(false);
         }).catch((error) => {
             console.log("Error updating group: " + error)
         })
     }
 
-    const handleBlueprintsChange = (blueprintValue) => {
-        setBlueprint(blueprintValue)
-        handleUpdateGroup(blueprintValue)
+    const handleBlueprintsChange = (e) => {
+        updateGroup(getBlueprintsOptions()[e.target.value].label !== "No blueprint found" ? getBlueprintsOptions()[e.target.value].label : "");
+        setSelectedBlueprint(getBlueprintsOptions()[e.target.value]);
     }
 
+    const initCheckGroupNameExists = useCallback(
+        debounce(
+          (searchGroupNameValue) =>
+            handleCheckGroupNameExists(searchGroupNameValue),
+          500
+        ),
+        []
+      );
+
+
+    const handleCheckGroupNameExists = (searchGroupNameValue) => {
+
+        axios(
+          configApiCall(
+            api_path_get_list_group + "?groupName=" + searchGroupNameValue,
+            "GET",
+            null,
+            null
+          )
+        )
+          .then((response) => {
+            setGroupNameExits(false);
+            response.data.forEach((group) => {
+              if(searchGroupNameValue === group.name){
+                setGroupNameExits(true);
+              }
+            });
+          })
+          .catch((error) => {
+            console.log(error);
+            setGroupNameExits(false);
+          });
+      };
+
     const tableCellClasses = classnames(classes.tableCell);
 
     return(
@@ -279,7 +352,7 @@ export default function EditGroup(props) {
                 placeholder={i18next.t("add_user_to_group", "Add user to group ...")} 
                 searchTargets={searchUsers} 
                 targets={users}
-                addElementToTarget={updateUserInGroup}
+                addElementToTarget={addUserInGroup}
                 targetName={name}
                 type="user"
             />
@@ -290,50 +363,51 @@ export default function EditGroup(props) {
                             <CardIcon color="info">
                                 <EditIcon />
                             </CardIcon>
-                                <p className={classes.cardCategory}>{i18next.t("edit_group", "Edit group")}</p>
-                            <h3 className={classes.cardTitle}>{newName}</h3>
+                            <p className={classes.cardCategory}>{i18next.t("edit_group", "Edit group")}</p>
+                            <h3 className={classes.cardTitle}>{name}</h3>
                         </CardHeader>
                         <CardBody profile>
                             <div className={classes.root}>
                                 <Grid container spacing={2}>
                                     <Grid item xs={12} sm={12} md={12}>
-                                        <FormControl className={classes.margin} size="medium" error={props.groupNameExits}>
+                                        <FormControl className={classes.margin} size="medium" error={groupNameExits}>
                                             <Input
                                                 id="name"
-                                                placeholder={props.groupName}
+                                                placeholder={name}
                                                 startAdornment={
                                                     <InputAdornment position="start">
                                                         <PeopleOutlineIcon />
                                                     </InputAdornment>
                                                 }
                                                 endAdornment={
-                                                    <IconButton color="primary" aria-label="upload picture" component="span"
+                                                    <IconButton color="primary" aria-label="update name" component="span"
                                                         onClick={() => {
-                                                            handleUpdateGroup(blueprint);
+                                                            updateGroup();
                                                         }} 
-                                                        disabled={props.groupNameExits}
+                                                        disabled={groupNameExits || name == newName}
                                                     >
                                                         <SaveIcon />
                                                     </IconButton>
                                                 }
                                                 onChange={e => {
-                                                    setName(e.target.value);
-                                                    props.initCheckGroupNameExists(e.target.value)
+                                                    setNewName(e.target.value);
+                                                    initCheckGroupNameExists(e.target.value)
                                                 }}
                                             />
                                         </FormControl>                                        
                                     </Grid>
                                     <Grid item xs={12} sm={12} md={12}>
+                                        <InputLabel className={classes.inputBottomMargin} htmlFor="blueprint">{i18next.t("select_blueprint", "Select a blueprint")}</InputLabel>
                                         <FormControl className={classes.margin} fullWidth>
                                             <Select
                                                 labelId="demo-simple-select-label"
                                                 fullWidth
-                                                value={blueprint}
-                                                onChange={(e) => handleBlueprintsChange(e.target.value)}
+                                                value={selectedBlueprint.value}
+                                                onChange={handleBlueprintsChange}
                                                 variant="outlined"
                                                 children={blueprintsOptionsItems}
-                                                disabled={props.blueprints.length === 0}
-                                            />
+                                                disabled={blueprints.length === 0}
+                                            /> 
                                         </FormControl>
                                     </Grid>
                                 </Grid>
@@ -342,7 +416,7 @@ export default function EditGroup(props) {
                     </Card>
                 </GridItem>
                 <GridItem xs={12} sm={12} md={12}>
-                    <Button color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_user_to", "Add user to")} {props.groupName}</Button>
+                    <Button color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_user_to", "Add user to")} {name}</Button>
                     <Table className={classes.table}>
                         <TableHead>
                             <TableRow>
@@ -379,7 +453,7 @@ export default function EditGroup(props) {
                                         <Link to={`/user/${user.username}`}>{user.lastName}</Link>
                                     </TableCell>
                                     <TableCell align="right" className={classes.tableActions}>
-                                        <Button color="primary" onClick={() => updateUserInGroup(user)}>{i18next.t("remove_user", "Remove user")}</Button>
+                                        <Button color="primary" onClick={() => deleteUserFromGroup(user)}>{i18next.t("remove_user", "Remove user")}</Button>
                                     </TableCell>
                                 </TableRow>
                             )}
diff --git a/jams-react-client/src/views/Groups/Groups.js b/jams-react-client/src/views/Groups/Groups.js
index a26eb1b3a09c4acb62ad29fdfc3276618bcc7a91..aba42d2c3c053ca62063d77febfb3356cc37274c 100644
--- a/jams-react-client/src/views/Groups/Groups.js
+++ b/jams-react-client/src/views/Groups/Groups.js
@@ -1,5 +1,5 @@
 import React, { useEffect, useState, useCallback } from "react";
-import { useHistory } from "react-router-dom";
+import { Link, useHistory } from "react-router-dom";
 // @material-ui/core components
 import { makeStyles } from "@material-ui/core/styles";
 import InputLabel from "@material-ui/core/InputLabel";
@@ -32,6 +32,7 @@ import {
   api_path_get_list_group,
   api_path_delete_group,
   api_path_blueprints,
+  api_path_get_group_members
 } from "globalUrls";
 
 import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline";
@@ -86,6 +87,9 @@ const styles = {
   },
   whiteButtonText: {
     color: "white",
+  },
+  inputBottomMargin: {
+    marginBottom: "1rem"
   }
 };
 
@@ -95,9 +99,8 @@ export default function Groups() {
   const classes = useStyles();
   const history = useHistory();
   const [groups, setGroups] = React.useState([]);
-  const [selectedGroupName, setSelectedGroupName] = React.useState("");
   const [loading, setLoading] = React.useState(false);
-  const [zeroGroup, setZeroGroup] = React.useState(true);
+  const [zeroGroup, setZeroGroup] = React.useState(false);
   const [progress, setProgress] = React.useState(0);
   const [searchValue, setSearchValue] = React.useState(null);
 
@@ -107,31 +110,34 @@ export default function Groups() {
   const [groupName, setGroupName] = React.useState("");
   const [groupNameExits, setGroupNameExits] = React.useState(false);
 
-  const [removedGroup, setRemovedGroup] = React.useState();
+  const [removedGroup, setRemovedGroup] = React.useState({
+    "id": 0,
+    "name": "groupeName"
+  });
   const [openRemoveDialog, setOpenRemoveDialog] = React.useState();
 
   const [disableCreate, setDisableCreate] = React.useState(true);
 
-  const handleRemoveGroup = (groupRemovedName) => {
-    setRemovedGroup(groupRemovedName);
+  const handleRemoveGroup = (group) => {
+    setRemovedGroup(group);
     setOpenRemoveDialog(true);
   };
 
   const removeGroup = () => {
     axios(
       configApiCall(
-        api_path_delete_group + "?groupName=" + removedGroup,
+        api_path_delete_group + removedGroup.id,
         "DELETE",
         null,
         null
       )
     )
       .then((response) => {
-        console.log("Successfully deleted " + removedGroup);
+        console.log("Successfully deleted " + removedGroup.name);
         setOpenRemoveDialog(false);
       })
       .catch((error) => {
-        console.log("Could not delete " + removedGroup + " " + error);
+        console.log("Could not delete " + removedGroup.name + " " + error);
         setOpenRemoveDialog(false);
       });
 
@@ -152,6 +158,24 @@ export default function Groups() {
     return blueprintsOptions;
   };
 
+  const getBlueprints = () => {
+    axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null))
+    .then((response) => {
+      setBlueprints(response.data);
+      setSelectedBlueprint(getBlueprintsOptions()[0]);
+    })
+    .catch((error) => {
+      console.log(error);
+      if (error.response.status === 401) {
+        auth.authenticated = false;
+        history.push("/");
+      }
+      if (error.response.status === 500) {
+        setBlueprints([]);
+      }
+    });
+  }
+
   useEffect(() => {
     setLoading(true);
     const timer = setInterval(() => {
@@ -165,30 +189,26 @@ export default function Groups() {
     }, 500);
 
     axios(
-      configApiCall(api_path_get_list_group + "?groupName=*", "GET", null, null)
+      configApiCall(api_path_get_list_group, "GET", null, null)
     )
       .then((response) => {
         let allGroups = response.data;
-        if (allGroups.length === 0) setZeroGroup(true);
-        else {
-          setZeroGroup(false);
-        }
-        setGroups(allGroups);
-        axios(configApiCall(api_path_blueprints + "?name=*", "GET", null, null))
-        .then((response) => {
-          setBlueprints(response.data);
-          setSelectedBlueprint(getBlueprintsOptions()[0]);
+
+        allGroups.forEach((group)=> {
+          axios(configApiCall(api_path_get_group_members + group.id, 'GET', null, null)).then((response) => {
+            group["groupMembersLength"] = response.data.length;
+          }).catch((error) => {
+            if (error.response.status === 401) {
+              auth.authenticated = false;
+              history.push("/");
+            }
+            if (error.response.status === 404) {
+              group["groupMembersLength"] = 0;
+            }
+          });
         })
-        .catch((error) => {
-          console.log(error);
-          if (error.response.status === 401) {
-            auth.authenticated = false;
-            history.push("/");
-          }
-          if (error.response.status === 500) {
-            setBlueprints([]);
-          }
-        });
+        setGroups(allGroups);
+        getBlueprints();
         setLoading(false);
       })
       .catch((error) => {
@@ -197,20 +217,16 @@ export default function Groups() {
           auth.authenticated = false;
           history.push("/");
         }
+        if (error.response.status === 404){
+          getBlueprints();
+          setZeroGroup(true);
+        }
       });
     return () => {
       clearInterval(timer);
     };
   }, [openCreate, openRemoveDialog, history]);
 
-  const [selectedGroup, setSelectedGroup] = useState(false);
-
-  const redirectToGroup = (e, name) => {
-    e.preventDefault();
-    setSelectedGroup(true);
-    setSelectedGroupName(name);
-  };
-
   const handleCheckGroupNameExists = (searchGroupNameValue) => {
     setDisableCreate(true);
     axios(
@@ -222,8 +238,15 @@ export default function Groups() {
       )
     )
       .then((response) => {
-        setDisableCreate(true);
-        setGroupNameExits(true);
+        let allGroups = response.data;
+        setDisableCreate(false);
+        setGroupNameExits(false);
+        allGroups.forEach((group) => {
+          if(searchGroupNameValue === group.name){
+            setDisableCreate(true);
+            setGroupNameExits(true);
+          }
+        });
       })
       .catch((error) => {
         console.log(error);
@@ -262,15 +285,15 @@ export default function Groups() {
         null
       )
     )
-      .then(() => {
+      .then((response) => {
         console.log("Successfully  created " + groupName);
         setOpenCreate(false);
+        history.push(`/group/${response.data.id}`);
       })
       .catch((error) => {
-        console.log("Error creating group: " + error);
+        alert("Error creating group: " + error);
         setOpenCreate(false);
       });
-    history.push(`/group/${groupName}`);
   };
 
   const blueprintsOptionsItems = tool.buildSelectMenuItems(
@@ -294,22 +317,8 @@ export default function Groups() {
         </h4>
       </div>
     );
-  } else if (selectedGroup && auth.hasAdminScope()) {
-    return (
-      <div>
-        <EditGroup
-          groupName={selectedGroupName}
-          initCheckGroupNameExists={initCheckGroupNameExists}
-          groupNameExits={groupNameExits}
-          blueprintsOptionsItems={blueprintsOptionsItems}
-          handleBlueprintsChange={handleBlueprintsChange}
-          getBlueprintsOptions={getBlueprintsOptions}
-          blueprints={blueprints}
-          disableCreate={disableCreate}
-        />
-      </div>
-    );
-  } else {
+  } 
+  else {
     return (
       <div>
         <Dialog
@@ -351,6 +360,7 @@ export default function Groups() {
                   )}
                 </Grid>
                 <Grid item xs={12} sm={12} md={12}>
+                  <InputLabel className={classes.inputBottomMargin} htmlFor="blueprint">{i18next.t("select_blueprint", "Select a blueprint")}</InputLabel>
                   <Select
                     labelId="demo-simple-select-label"
                     fullWidth
@@ -387,7 +397,7 @@ export default function Groups() {
           <DialogTitle id="alert-dialog-title">{i18next.t("remove_group", "Remove group")}</DialogTitle>
           <DialogContent>
             <DialogContentText id="alert-dialog-description">
-            {i18next.t("are_you_sure_you_want_to_delete", "Are you sure you want to delete")} <strong>{removedGroup}</strong> ?
+            {i18next.t("are_you_sure_you_want_to_delete", "Are you sure you want to delete")} <strong>{removedGroup.name}</strong> ?
             </DialogContentText>
           </DialogContent>
           <DialogActions>
@@ -428,7 +438,7 @@ export default function Groups() {
               )}
               {!zeroGroup && <Search />}
               <div className={classes.loading}>
-                {loading && (
+                {!zeroGroup  && loading && (
                   <LinearProgress variant="determinate" value={progress} />
                 )}
               </div>
@@ -438,7 +448,7 @@ export default function Groups() {
             <div className={classes.groupsNotFound}>
               <InfoIcon /> <p style={{ marginLeft: "10px" }}>{i18next.t("no_groups_found", "No groups Found")}</p>
             </div>
-          ) : groups.length >= 1 ? (
+          ) : (
             groups
               .filter((data) => {
                 if (searchValue === null) {
@@ -458,10 +468,7 @@ export default function Groups() {
                   xl={2} 
                   key={group.name}>
                   <Card profile>
-                      <a
-                        href="#"
-                        onClick={(e) => redirectToGroup(e, group.name)}
-                      >
+                    <Link to={`/group/${group.id}`}>
                       <CardBody profile>
                         <h3 className={classes.cardTitle}>{group.name}</h3>
                         <ul>
@@ -471,7 +478,7 @@ export default function Groups() {
                               style={{ marginRight: "10px" }}
                             />
                             <strong style={{ marginRight: "5px" }}>
-                              {group.groupMembers.length}
+                              {group.groupMembersLength}
                             </strong>
                             {i18next.t("users", "users")}
                           </li>
@@ -487,12 +494,12 @@ export default function Groups() {
                           </li>
                         </ul>
                       </CardBody>
-                    </a>
+                    </Link>
                     <CardFooter>
                       <IconButton
                         color="secondary"
                         onClick={() => {
-                          handleRemoveGroup(group.name);
+                          handleRemoveGroup(group);
                         }}
                       >
                         <DeleteOutlineIcon />
@@ -501,51 +508,6 @@ export default function Groups() {
                   </Card>
                 </GridItem>
               ))
-          ) : (
-            <GridItem xs={12} sm={12} md={2} key={groups.name}>
-              <Card profile>
-
-                <a href="#" onClick={(e) => redirectToGroup(e, groups.name)}>
-                <CardBody profile>
-                    <h3 className={classes.cardTitle}>{groups.name}</h3>
-                    <ul>
-                      <li>
-                        <PersonIcon
-                          fontSize="small"
-                          style={{ marginRight: "10px" }}
-                        />
-                        <strong style={{ marginRight: "5px" }}>
-                          {typeof groups.groupMembers !== "undefined"
-                            ? groups.groupMembers
-                            : 0}
-                        </strong>
-                        {i18next.t("users", "users")}
-                      </li>
-                      <li>
-                        <MailOutlineIcon
-                          fontSize="small"
-                          style={{ marginRight: "10px" }}
-                        />
-                        <strong style={{ marginRight: "5px" }}>
-                          {i18next.t("blueprint", "Blueprint")}
-                        </strong>
-                        {selectedBlueprint.label}
-                      </li>
-                    </ul>
-                    </CardBody>
-                  </a>
-                <CardFooter>
-                  <IconButton
-                    color="secondary"
-                    onClick={() => {
-                      handleRemoveGroup(groups.name);
-                    }}
-                  >
-                    <DeleteOutlineIcon />
-                  </IconButton>
-                </CardFooter>
-              </Card>
-            </GridItem>
           )}
         </GridContainer>
       </div>
diff --git a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
index d115c82cf6b6caded4a46b2421127e40d55a9f4e..d5bcfa316d51b773181226ef3d71f8449b6fc3b0 100644
--- a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
+++ b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
@@ -1,5 +1,5 @@
 import React, { useEffect } from "react";
-import { useHistory } from "react-router-dom";
+import { Link, useHistory } from "react-router-dom";
 import classnames from "classnames";
 
 // @material-ui/core components
@@ -58,7 +58,10 @@ import {
   api_path_get_user_profile,
   api_path_delete_admin_user_revoke,
   api_path_get_list_group,
-  api_path_put_update_group,
+  api_path_get_group,
+  api_path_post_group_member,
+  api_path_get_admin_user_groups,
+  api_path_delete_group_member
 } from "globalUrls";
 
 import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
@@ -249,50 +252,49 @@ export default function DisplayUserProfile(props) {
       });
   }
 
-  const updateUserInGroup = (group) => {
+  const removeUserFromGroup = (group) => {
+
+    let data = {
+      "username": props.username
+    }
+
     axios(
       configApiCall(
-        api_path_get_list_group + "?groupName=" + group,
-        "GET",
-        null,
+        api_path_delete_group_member + group.groupId,
+        "DELETE",
+        data,
         null
       )
     ).then((response)=>{
-      
-      let url = "";
-      let oldGroup = response.data.name;
-      if (response.data.blueprint == null) {
-        url =
-          api_path_put_update_group +
-          "?groupName=" +
-          response.data.name +
-          "&newName=" +
-          response.data.name +
-          "&blueprintName=&groupMembers=" +
-          [props.username];
-      } else {
-        url =
-          api_path_put_update_group +
-          "?groupName=" +
-          response.data.name +
-          "&newName=" +
-          response.data.name +
-          "&blueprintName=" +
-          response.data.blueprint +
-          "&groupMembers=" +
-          [props.username];
-      }
-  
-      axios(configApiCall(url, "PUT", null, null))
-        .then(() => {
-          let newGroupMemberships = groupMemberships;
-          if(newGroupMemberships.includes(oldGroup)) newGroupMemberships.splice(newGroupMemberships.indexOf(oldGroup), 1);
-          else newGroupMemberships.push(oldGroup);
-          setGroupMemberships(newGroupMemberships);
-        })
-        .catch((error) => {
-          console.log("Error updating group: " + error);
-        });
+        let newGroupMemberships = groupMemberships;
+        newGroupMemberships.splice(newGroupMemberships.indexOf(group), 1);
+        setGroupMemberships(newGroupMemberships);
+    }).catch((error)=>{console.log(error)})
+
+  };
+
+  const addUserToGroup = (group) => {
+
+    let data = {
+      "username": props.username
+    }
+
+    axios(
+      configApiCall(
+        api_path_post_group_member + group.id,
+        "POST",
+        data,
+        null
+      )
+    ).then((response)=>{      
+        let newGroupMemberships = groupMemberships;
+        newGroupMemberships.push(
+          {
+            "groupId": group.id,
+            "name": group.name
+          }
+        );
+        setGroupMemberships(newGroupMemberships);
     }).catch((error)=>{console.log(error)})
 
   };
@@ -329,10 +331,28 @@ export default function DisplayUserProfile(props) {
             )
               .then((response) => {
                 setUser(response.data);
-                if(response.data.groupMemberships.length === 1 && response.data.groupMemberships[0] === "") {
-                  setGroupMemberships([]);
-                }
-                else setGroupMemberships(response.data.groupMemberships)
+                axios(configApiCall(api_path_get_admin_user_groups + props.username,
+                  "GET",
+                  null,
+                  null
+                )).then((userGroups) => {
+                  let userGroupsData = userGroups.data;
+                  userGroupsData.forEach((group) => {
+                    axios(configApiCall(api_path_get_group + group.groupId, 'GET', null, null)).then((groupInfo) =>{
+                      group["name"] = groupInfo.data.name;
+                    });
+                  });
+                  setGroupMemberships(userGroupsData);
+                }).catch((error) => {
+                  console.log(error);
+                  if (error.response.status === 401) {
+                    auth.authenticated = false;
+                    history.push("/");
+                  }
+                  if (error.response.status === 404) {
+                    setGroupMemberships([]);
+                  }
+                })
                 searchGroups("*")
                 setLoading(false);
               })
@@ -367,10 +387,28 @@ export default function DisplayUserProfile(props) {
             )
               .then((response) => {
                 setUser(response.data);
-                if(response.data.groupMemberships.length === 1 && response.data.groupMemberships[0] === "") {
-                  setGroupMemberships([]);
-                }
-                else setGroupMemberships(response.data.groupMemberships)
+                axios(configApiCall(api_path_get_admin_user_groups + props.username,
+                  "GET",
+                  null,
+                  null
+                )).then((userGroups) => {
+                  let userGroupsData = userGroups.data;
+                  userGroupsData.forEach((group) => {
+                    axios(configApiCall(api_path_get_group + group.groupId, 'GET', null, null)).then((groupInfo) =>{
+                      group["name"] = groupInfo.data.name;
+                    });
+                  });
+                  setGroupMemberships(userGroupsData);
+                }).catch((error) => {
+                  console.log(error);
+                  if (error.response.status === 401) {
+                    auth.authenticated = false;
+                    history.push("/");
+                  }
+                  if (error.response.status === 404) {
+                    setGroupMemberships([]);
+                  }
+                })
                 setLoading(false);
               })
               .catch((error) => {
@@ -497,7 +535,7 @@ export default function DisplayUserProfile(props) {
           placeholder={i18next.t("add_user_to_group", "Add user to group ...")} 
           searchTargets={searchGroups} 
           targets={groups}
-          addElementToTarget={updateUserInGroup}
+          addElementToTarget={addUserToGroup}
           targetName={props.username}
           type="group"
       />
@@ -668,13 +706,15 @@ export default function DisplayUserProfile(props) {
                         </TableRow>
                     </TableHead>
                     <TableBody>
-                        {groupMemberships !== [""] && groupMemberships.map(group =>
+                        {groupMemberships !== [] && groupMemberships.map(group =>
                             <TableRow key={group} className={classes.tableRow}>
                                 <TableCell className={tableCellClasses}>
-                                    {group}
+                                  <Link to={`/group/${group.groupId}`}>
+                                    {group.name}
+                                  </Link>
                                 </TableCell>
                                 <TableCell align="right" className={classes.tableActions}>
-                                    <Button color="primary" onClick={() => updateUserInGroup(group)}>{i18next.t("remove_from_group", "Remove from group")}</Button>
+                                    <Button color="primary" onClick={() => removeUserFromGroup(group)}>{i18next.t("remove_from_group", "Remove from group")}</Button>
                                 </TableCell>
                             </TableRow>
                         ) }
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/AddUserToGroupFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/AddUserToGroupFlow.java
deleted file mode 100644
index 00f57cbf0f973b4aac83eee9bcdf0ead2d862ab7..0000000000000000000000000000000000000000
--- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/AddUserToGroupFlow.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package net.jami.jams.server.core.workflows;
-
-import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.objects.user.UserGroupMapping;
-import net.jami.jams.common.objects.user.UserProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import static net.jami.jams.server.Server.dataStore;
-import static net.jami.jams.server.Server.userAuthenticationModule;
-
-@Slf4j
-public class AddUserToGroupFlow {
-
-    public static void addUserToGroup(String groupName, String username) {
-        userAuthenticationModule.getAuthSources().forEach((k, v) -> {
-            UserProfile profile = v.getUserProfile(username);
-            List<UserProfile> groupProfiles = v.searchUserProfiles(username, "LOGON_NAME", Optional.empty());
-            if (!groupProfiles.isEmpty()) {
-                UserGroupMapping mapping = null;
-                StatementList statementList = new StatementList();
-                statementList.addStatement(new StatementElement("username", "=", username, ""));
-                if (dataStore.getUserGroupMappingsDao().getObjects(statementList).isEmpty()) {
-                    // if the mapping doesn't exist, create it and add the group directly.
-
-                    try {
-                        mapping = new UserGroupMapping();
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    mapping.setUsername(username);
-                    mapping.setGroups("");
-                    mapping.addGroup(groupName);
-                    dataStore.getUserGroupMappingsDao().storeObject(mapping);
-
-                } else {
-                    // otherwise, update the object.
-
-                    mapping = dataStore.getUserGroupMappingsDao().getObjects(statementList).get(0);
-                    if (!mapping.getGroups().contains(groupName)) {
-                        mapping.addGroup(groupName);
-                        String newGroups = mapping.getGroups();
-
-                        StatementList update = new StatementList();
-                        StatementElement st0 = new StatementElement("groups", "=", newGroups, "");
-                        update.addStatement(st0);
-                        StatementList constraint = new StatementList();
-                        StatementElement st1 = new StatementElement("username", "=", username, "");
-                        constraint.addStatement(st1);
-                        dataStore.getUserGroupMappingsDao().updateObject(update, constraint);
-                    }
-                }
-
-                if (profile != null) {
-                    if (profile.getGroupMemberships() == null)
-                        profile.setGroupMemberships(new ArrayList<>());
-
-                    if (!profile.getGroupMemberships().contains(groupName))
-                        profile.getGroupMemberships().add(groupName);
-
-                    dataStore.updateUserProfile(profile);
-                }
-            }
-        });
-    }
-}
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
index 81f22b94f2b864329f6216c392da6ff8f32703fa..8bb441d86d9bab88bc4bf761dd3383c27c45450a 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/workflows/RegisterDeviceFlow.java
@@ -32,6 +32,8 @@ import net.jami.jams.common.objects.requests.DeviceRegistrationRequest;
 import net.jami.jams.common.objects.responses.DeviceRegistrationResponse;
 import net.jami.jams.common.objects.user.*;
 import net.jami.jams.dht.DeviceReceiptGenerator;
+import net.jami.jams.common.objects.user.Group;
+
 
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -70,57 +72,40 @@ public class RegisterDeviceFlow {
             }
             dataStore.getDeviceDao().storeObject(device);
 
+            Group group = new Group();
+
             statementList = new StatementList();
             statementList.addStatement(new StatementElement("username", "=", username, ""));
             if (dataStore.getUserGroupMappingsDao().getObjects(statementList) != null && !dataStore.getUserGroupMappingsDao().getObjects(statementList).isEmpty()) {
                 UserGroupMapping mapping = dataStore.getUserGroupMappingsDao().getObjects(statementList).get(0);
-                List<String> list = new ArrayList<>();
-                if (mapping.getUsername().equals(userProfile.getUsername())) {
-                    String[] splits = mapping.getGroups().split(",");
-
-                    for (int i = 0; i < splits.length; i++)
-                        list.add(splits[i]);
-                }
-                if (!list.isEmpty())
-                    userProfile.setGroupMemberships(list);
+                statementList = new StatementList();
+                statementList.addStatement(new StatementElement("id", "=", mapping.getGroupId(), ""));
+                group =  dataStore.getGroupDao().getObjects(statementList).get(0);
             }
 
-            // Now we build this response out.
             DeviceRegistrationResponse response = new DeviceRegistrationResponse();
-            if (userProfile.getGroupMemberships() != null) {
-                userProfile.getGroupMemberships().forEach(e -> {
-                    if (!e.equals("")) {
-                        StatementElement st = new StatementElement("name", "=", e, "");
-                        StatementList statementList1 = new StatementList();
-                        statementList1.addStatement(st);
-
-                        Group group = dataStore.getGroupDao().getObjects(statementList1).get(0);
-                        String policyName = group.getBlueprint();
-                        if (group != null && policyName != null) {
-                            StatementElement st2 = new StatementElement("name", "=", policyName, "");
-                            StatementList statementList2 = new StatementList();
-                            statementList2.addStatement((st2));
-                            try {
-                                Policy policy = dataStore.getPolicyDao().getObjects(statementList2).get(0);
-                                response.setPolicyData(policy.getPolicyData());
-                            } catch (Exception e1) {
-                                log.warn("No policy available for user - not adding a policy component to response");
-                            }
-                        }
-                    }
-                });
+            if (!group.isEmpty() && group.hasBlueprint()) {
+                StatementElement st2 = new StatementElement("name", "=", group.getBlueprint(), "");
+                StatementList statementList2 = new StatementList();
+                statementList2.addStatement((st2));
+                try {
+                    Policy policy = dataStore.getPolicyDao().getObjects(statementList2).get(0);
+                    response.setPolicyData(policy.getPolicyData());
+                } catch (Exception e1) {
+                    log.warn("No policy available for user - not adding a policy component to response");
+                }
             }
-            // We need to set the device receipt....
+            // Device receipt
             String[] devReceipt = DeviceReceiptGenerator.generateReceipt(user.getPrivateKey(),
                     user.getCertificate().getPublicKey(), device.getCertificate().getPublicKey(), user.getEthAddress());
             response.setDeviceReceipt(devReceipt[0]);
             response.setReceiptSignature(devReceipt[1]);
             response.setDisplayName(userProfile.getFirstName() + " " + userProfile.getLastName());
-            // We need to set
+
             response.setNameServer(nameServer.getURI());
             if (userProfile.getProfilePicture() != null)
                 response.setUserPhoto(userProfile.getProfilePicture());
-            // Finally we set the certificate chain.
+            // Chain certificate
             response.setCertificateChain(new X509Certificate[] { certificateAuthority.getCA(), user.getCertificate(),
                     device.getCertificate() });
             return response;
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 472680dabbf2452e64a29cf00eac7b30138966ea..33c6804f7dbbe599c3b637decb395fbccdd713f6 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
@@ -78,7 +78,6 @@ public class DirectoryEntryServlet extends HttpServlet {
         userProfile.setFaxNumber(obj.get("faxNumber").toString());
         userProfile.setMobileNumber(obj.get("mobileNumber").toString());
         userProfile.setId(obj.get("jamiId").toString());
-        userProfile.setGroupMemberships(new ArrayList<>());
 
         userAuthenticationModule.getAuthSources().get(new AuthModuleKey(realm, AuthenticationSourceType.LOCAL))
             .setUserProfile(userProfile);
@@ -112,7 +111,7 @@ public class DirectoryEntryServlet extends HttpServlet {
         if (callingUser.getAccessLevel() == AccessLevel.ADMIN || (callingUser.getAccessLevel() == AccessLevel.USER && callingUser.getUsername().equals(targetUser.getUsername()))) {
             select = new StatementList();
             select.addStatement(new StatementElement("username", "=", userProfile.getUsername(), ""));
-            if (dataStore.updateUserProfile(userProfile) && dataStore.updateUserGroupMappings(userProfile))
+            if (dataStore.updateUserProfile(userProfile))
                 resp.setStatus(200);
             else
                 resp.sendError(500, "Could not update the users's profile information");
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/AddGroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/AddGroupServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..c29f498ab4a57efb2e4f2c4b072df47a99e33355
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/AddGroupServlet.java
@@ -0,0 +1,42 @@
+package net.jami.jams.server.servlets.api.admin.group;
+
+import com.google.gson.JsonObject;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.common.annotations.JsonContent;
+import net.jami.jams.common.annotations.ScopedServletMethod;
+import net.jami.jams.common.objects.user.AccessLevel;
+import net.jami.jams.common.objects.user.Group;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import static net.jami.jams.server.Server.dataStore;
+
+@WebServlet("/api/admin/group")
+@Slf4j
+public class AddGroupServlet extends HttpServlet {
+
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        Group group = new Group();
+        UUID uuid = UUID.randomUUID();
+        group.setId(uuid.toString());
+        group.setName(req.getParameter("name"));
+        group.setBlueprint(req.getParameter("blueprintName"));
+        if (dataStore.getGroupDao().storeObject(group)) {
+            JsonObject data = new JsonObject();
+            data.addProperty("id", uuid.toString());
+            resp.getOutputStream().write(data.toString().getBytes());
+            resp.setStatus(200);
+        }
+        else
+            resp.sendError(500, "Could not create a group successfully!");
+    }
+}
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupProfileServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupProfileServlet.java
deleted file mode 100644
index b78615b41ccc778040880b8c766c910f416ecf79..0000000000000000000000000000000000000000
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupProfileServlet.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package net.jami.jams.server.servlets.api.admin.group;
-
-import com.jsoniter.output.JsonStream;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.annotation.WebServlet;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import net.jami.jams.common.annotations.JsonContent;
-import net.jami.jams.common.annotations.ScopedServletMethod;
-import net.jami.jams.common.dao.StatementElement;
-import net.jami.jams.common.dao.StatementList;
-import net.jami.jams.common.objects.user.AccessLevel;
-import net.jami.jams.common.objects.user.Group;
-import net.jami.jams.common.objects.user.UserProfile;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static net.jami.jams.server.Server.dataStore;
-
-@WebServlet("/api/admin/group/*")
-@Slf4j
-public class GroupProfileServlet extends HttpServlet {
-
-
-    @Override
-    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
-    @JsonContent
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
-        List<Group> groups = new ArrayList<>();
-        Group singleGroup = null;
-        String groupName = req.getPathInfo().replace("/","");
-
-        if (!groupName.equals("*")) {
-            StatementList statementList = new StatementList();
-            StatementElement st = new StatementElement("name", "=", groupName, "");
-
-            statementList.addStatement(st);
-            if (!dataStore.getGroupDao().getObjects(statementList).isEmpty())
-                singleGroup = dataStore.getGroupDao().getObjects(statementList).get(0);
-        } else {
-            groups = dataStore.getGroupDao().getObjects(null);
-        }
-
-        if (singleGroup != null) {
-            Group finalSingleGroup = singleGroup;
-            List<UserProfile> profiles = dataStore.getUserProfileDao().getObjects(null).stream().filter(profile ->
-                    profile.getGroupMemberships().contains(finalSingleGroup.getName())).collect(Collectors.toList());
-
-            profiles.forEach(profile ->
-                    finalSingleGroup.getGroupMembers().add(profile.getUsername()));
-
-            resp.getOutputStream().write(JsonStream.serialize(finalSingleGroup).getBytes());
-            resp.setStatus(200);
-        }
-        if (!groups.isEmpty()) {
-            List<UserProfile> profiles = dataStore.getUserProfileDao().getObjects(null);
-            for (Group group: groups) {
-                for (UserProfile p: profiles) {
-                    if (p.getGroupMemberships().contains(group.getName()))
-                        group.getGroupMembers().add(p.getUsername());
-                }
-            }
-
-            resp.getOutputStream().write(JsonStream.serialize(groups).getBytes());
-            resp.setStatus(200);
-        }
-        else {
-            log.info("No existing groups were found.");
-            resp.setStatus(200);
-        }
-    }
-}
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
index 77d0d0e4288b5e4eca6d24491e8d60be3393a7b6..88cf7bc1c6279fd73655c81d0ae953741c9b97f0 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupServlet.java
@@ -13,66 +13,41 @@ import net.jami.jams.common.dao.StatementElement;
 import net.jami.jams.common.dao.StatementList;
 import net.jami.jams.common.objects.user.AccessLevel;
 import net.jami.jams.common.objects.user.Group;
-import net.jami.jams.common.objects.user.UserGroupMapping;
 import net.jami.jams.common.objects.user.UserProfile;
-import net.jami.jams.server.core.workflows.AddUserToGroupFlow;
+import org.json.JSONObject;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
 import static net.jami.jams.server.Server.dataStore;
-import static net.jami.jams.server.Server.userAuthenticationModule;
 
-@WebServlet("/api/admin/group")
+@WebServlet("/api/admin/group/*")
 @Slf4j
 public class GroupServlet extends HttpServlet {
 
+
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
-        List<Group> groups = new ArrayList<>();
         Group singleGroup = null;
+        String id = req.getPathInfo().replace("/","");
 
-        if (!req.getParameter("groupName").equals("*")) {
-            StatementList statementList = new StatementList();
-            StatementElement st = new StatementElement("name", "=", req.getParameter("groupName"), "");
+        StatementList statementList = new StatementList();
+        StatementElement st = new StatementElement("id", "=", id, "");
 
-            statementList.addStatement(st);
+        statementList.addStatement(st);
+        if (!dataStore.getGroupDao().getObjects(statementList).isEmpty())
             singleGroup = dataStore.getGroupDao().getObjects(statementList).get(0);
-        } else {
-            groups = dataStore.getGroupDao().getObjects(null);
-        }
 
         if (singleGroup != null) {
-            Group finalSingleGroup = singleGroup;
-            List<UserProfile> profiles = dataStore.getUserProfileDao().getObjects(null).stream().filter(profile ->
-                    profile.getGroupMemberships().contains(finalSingleGroup.getName())).collect(Collectors.toList());
-
-            profiles.forEach(profile ->
-                    finalSingleGroup.getGroupMembers().add(profile.getUsername()));
-
-            resp.getOutputStream().write(JsonStream.serialize(finalSingleGroup).getBytes());
-            resp.setStatus(200);
-        }
-        if (!groups.isEmpty()) {
-            List<UserProfile> profiles = dataStore.getUserProfileDao().getObjects(null);
-            for (Group group: groups) {
-                for (UserProfile p: profiles) {
-                    if (p.getGroupMemberships().contains(group.getName()))
-                        group.getGroupMembers().add(p.getUsername());
-                }
-            }
-
-            resp.getOutputStream().write(JsonStream.serialize(groups).getBytes());
+            resp.getOutputStream().write(JsonStream.serialize(singleGroup).getBytes());
             resp.setStatus(200);
         }
         else {
-            log.info("No existing groups were found.");
-            resp.setStatus(200);
+            log.info("No group with this id was found!" );
+            resp.setStatus(404);
         }
     }
 
@@ -80,125 +55,54 @@ public class GroupServlet extends HttpServlet {
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        String name = req.getParameter("groupName");
-        String newName = req.getParameter("newName");
-        String blueprint = req.getParameter("blueprintName");
-        StatementList statementList = new StatementList();
-        StatementElement st = new StatementElement("name", "=", name, "");
 
-        statementList.addStatement(st);
-        Group targetGroup = dataStore.getGroupDao().getObjects(statementList).get(0);
-        List<UserProfile> profiles = dataStore.getUserProfileDao().getObjects(null).stream().filter(profile ->
-                profile.getGroupMemberships().contains(targetGroup.getName())).collect(Collectors.toList());
-
-        profiles.forEach(profile ->
-                targetGroup.getGroupMembers().add(profile.getUsername()));
-
-        String groupMembers = req.getParameter("groupMembers");
-
-        // if the username sent isn't already part of the group members, then we add it
-        if (!targetGroup.getGroupMembers().contains(groupMembers)) {
-            AddUserToGroupFlow.addUserToGroup(name, req.getParameter("groupMembers"));
-        } else {
-            // otherwise remove the group from the user's memberships.
-            statementList = new StatementList();
-            st = new StatementElement("username", "=", groupMembers, "");
-            statementList.addStatement(st);
-
-            UserProfile targetProfile = dataStore.getUserProfileDao().getObjects(statementList).get(0);
-            UserGroupMapping mapping = dataStore.getUserGroupMappingsDao().getObjects(statementList).get(0);
-            mapping.removeGroup(name);
-
-            StatementList update = new StatementList();
-            StatementElement st0 = new StatementElement("groups", "=", mapping.getGroups(), "");
-            update.addStatement(st0);
-            StatementList constraint = new StatementList();
-            StatementElement st1 = new StatementElement("username", "=", mapping.getUsername(), "");
-            constraint.addStatement(st1);
-
-            // update user mappings
-            dataStore.getUserGroupMappingsDao().updateObject(update, constraint);
-
-            List<String> groups = targetProfile.getGroupMemberships();
-            groups.remove(name);
-            // TODO: LDAP/AD handling
-            dataStore.updateUserProfile(targetProfile);
-        }
+        String id = req.getPathInfo().replace("/","");
 
-        StatementList update = new StatementList();
-        StatementElement st0;
+        final JSONObject obj = new JSONObject(req.getReader().lines().collect(Collectors.joining(System.lineSeparator())));
 
-        if (newName != null)
-            st0 = new StatementElement("name", "=", newName, "");
-        else
-            st0 = new StatementElement("name", "=", name, "");
+        String name = obj.getString("name");
+        String blueprint = obj.getString("blueprint");
 
-        StatementElement st1 = new StatementElement("blueprint", "=", blueprint, "");
+        StatementList update = new StatementList();
+
+        StatementElement st0 = new StatementElement("id", "=", id, "");
         update.addStatement(st0);
+
+        StatementElement st1 = new StatementElement("name", "=", name, "");
         update.addStatement(st1);
+
+        StatementElement st2 = new StatementElement("blueprint", "=", blueprint, "");
+        update.addStatement(st2);
+
         StatementList constraint = new StatementList();
-        StatementElement st2 = new StatementElement("name", "=", name, "");
-        constraint.addStatement(st2);
 
         if (dataStore.getGroupDao().updateObject(update, constraint)) resp.setStatus(200);
-        else resp.sendError(500, "could not update the group's name!");
-    }
-
-    @Override
-    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
-    @JsonContent
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        Group group = new Group();
-        group.setName(req.getParameter("name"));
-        group.setBlueprint(req.getParameter("blueprintName"));
-        group.setGroupMembers(new ArrayList<String>());
-        if (dataStore.getGroupDao().storeObject(group))
-            resp.setStatus(200);
-        else
-            resp.sendError(500, "Could not create a group successfully!");
+        else resp.sendError(500, "Could not update group!");
     }
 
     @Override
     @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
     @JsonContent
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        String id = req.getPathInfo().replace("/","");
+
+        StatementElement statementElement = new StatementElement("id", "=", id, "");
 
-        StatementElement statementElement = new StatementElement("name", "=", req.getParameter("groupName"), "");
         StatementList constraint = new StatementList();
         constraint.addStatement(statementElement);
         if (dataStore.getGroupDao().deleteObject(constraint)) {
-            // if deletion was successful, cascade the deletion onto the users
-            List<UserProfile> validProfiles = dataStore.getUserProfileDao().getObjects(null).stream().filter(profile ->
-                    profile.getGroupMemberships().remove(req.getParameter("groupName"))).collect(Collectors.toList());
-
-            validProfiles.parallelStream().forEach(profile -> {
-
-                StatementList statementList = new StatementList();
-                StatementElement st = new StatementElement("username", "=", profile.getUsername(), "");
-                statementList.addStatement(st);
-
-                UserGroupMapping mapping = dataStore.getUserGroupMappingsDao().getObjects(statementList).get(0);
-                mapping.removeGroup(req.getParameter("groupName"));
-
-                StatementList update = new StatementList();
-                StatementElement st0 = new StatementElement("groups", "=", mapping.getGroups(), "");
-                update.addStatement(st0);
-                StatementList constraint2 = new StatementList();
-                StatementElement st1 = new StatementElement("username", "=", mapping.getUsername(), "");
-                constraint2.addStatement(st1);
-
-                // update user mappings
-                dataStore.getUserGroupMappingsDao().updateObject(update, constraint2);
-
-                // then update the profile itself
-                dataStore.updateUserProfile(profile);
-            });
-
-
-            resp.setStatus(200);
+            StatementElement statementElement1 = new StatementElement("username", "=", "*", "");
+            StatementElement statementElement2 = new StatementElement("groupId", "=", id, "");
+            StatementList constraintMapping = new StatementList();
+            constraintMapping.addStatement(statementElement1);
+            constraintMapping.addStatement(statementElement2);
+            if (dataStore.getUserGroupMappingsDao().deleteObject(constraintMapping))
+                resp.setStatus(200);
+            else
+                resp.sendError(500, "Could not delete the group mappings successfully!");
         }
         else {
             resp.sendError(500, "Could not delete the group successfully!");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fe101f2a94bc6acfd09b3407308ef5f22e247c4
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/GroupsServlet.java
@@ -0,0 +1,46 @@
+package net.jami.jams.server.servlets.api.admin.group;
+
+import com.google.gson.JsonObject;
+import com.jsoniter.output.JsonStream;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.common.annotations.JsonContent;
+import net.jami.jams.common.annotations.ScopedServletMethod;
+import net.jami.jams.common.dao.StatementElement;
+import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.objects.user.AccessLevel;
+import net.jami.jams.common.objects.user.Group;
+import net.jami.jams.common.objects.user.UserProfile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static net.jami.jams.server.Server.dataStore;
+
+@WebServlet("/api/admin/groups")
+@Slf4j
+public class GroupsServlet extends HttpServlet {
+
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+        List<Group> groups = dataStore.getGroupDao().getObjects(null);
+
+        if (!groups.isEmpty()) {
+            resp.getOutputStream().write(JsonStream.serialize(groups).getBytes());
+            resp.setStatus(200);
+        }
+        else {
+            resp.setStatus(404);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..82666f4d172513792af28e2524741934eac8c677
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/group/UserGroupServlet.java
@@ -0,0 +1,123 @@
+package net.jami.jams.server.servlets.api.admin.group;
+
+import com.google.gson.JsonObject;
+import com.jsoniter.output.JsonStream;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.common.annotations.JsonContent;
+import net.jami.jams.common.annotations.ScopedServletMethod;
+import net.jami.jams.common.dao.StatementElement;
+import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.objects.user.AccessLevel;
+import net.jami.jams.common.objects.user.UserGroupMapping;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static net.jami.jams.server.Server.dataStore;
+
+@WebServlet("/api/admin/group/members/*")
+@Slf4j
+public class UserGroupServlet extends HttpServlet {
+    /**
+     * @apiVersion 1.0.0
+     * @api {get} /api/admin/group/[groupId]/members/ Get JAMS groups members
+     * @apiName getGroupMembers
+     * @apiGroup Group
+     *
+     * @apiSuccess (200) {body} Array of usernames
+     * @apiSuccessExample {json} Success-Response:
+     * {
+     *      "usernames": ["user1", "user2", "user3"]
+     * }
+     * @apiError (404) {null} null could not find members for this groups
+     */
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+
+        String groupId = req.getPathInfo().replace("/","");
+
+        StatementList statementList = new StatementList();
+        StatementElement st = new StatementElement("groupId", "=", groupId, "");
+
+        statementList.addStatement(st);
+
+        List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getObjects(statementList);
+
+        if (result.isEmpty())
+            resp.sendError(404, "No users found for this group!");
+        else {
+            resp.getOutputStream().write(JsonStream.serialize(result).getBytes());
+            resp.setStatus(200);
+        }
+    }
+
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+
+        String groupId = req.getPathInfo().replace("/","");
+
+        final JSONObject obj = new JSONObject(req.getReader().lines().collect(Collectors.joining(System.lineSeparator())));
+
+        String username = obj.getString("username");
+
+        StatementList statementList = new StatementList();
+        statementList.addStatement(new StatementElement("groupId", "=", groupId, "AND"));
+        statementList.addStatement(new StatementElement("username", "=", username, ""));
+
+        if (!dataStore.getUserGroupMappingsDao().getObjects(statementList).isEmpty()) {
+            resp.sendError( 409, "The user already part of the group!");
+            return;
+        }
+
+        UserGroupMapping mapping = new UserGroupMapping();
+
+        mapping.setGroupId(groupId);
+        mapping.setUsername(username);
+
+        if (dataStore.getUserGroupMappingsDao().storeObject(mapping)) {
+            resp.setStatus(200);
+        }
+        else
+            resp.sendError(500, "Could not add user to group!");
+
+    }
+
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+
+        String groupId = req.getPathInfo().replace("/","");
+
+        final JSONObject obj = new JSONObject(req.getReader().lines().collect(Collectors.joining(System.lineSeparator())));
+
+        String username = obj.getString("username");
+
+
+        StatementElement statementElement1 = new StatementElement("username", "=", username, "AND");
+        StatementElement statementElement2 = new StatementElement("groupId", "=", groupId, "");
+
+        StatementList constraint = new StatementList();
+        constraint.addStatement(statementElement1);
+        constraint.addStatement(statementElement2);
+        if (dataStore.getUserGroupMappingsDao().deleteObject(constraint)) {
+            resp.setStatus(200);
+        }
+        else {
+            resp.sendError(500, "Could not delete mapping between user and group!");
+        }
+    }
+}
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..696eb145b4e5ac577bd8a03db9c7f6aa81e0fb10
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserGroupsServlet.java
@@ -0,0 +1,59 @@
+package net.jami.jams.server.servlets.api.admin.users;
+
+import com.jsoniter.output.JsonStream;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.common.annotations.JsonContent;
+import net.jami.jams.common.annotations.ScopedServletMethod;
+import net.jami.jams.common.dao.StatementElement;
+import net.jami.jams.common.dao.StatementList;
+import net.jami.jams.common.objects.user.AccessLevel;
+import net.jami.jams.common.objects.user.UserGroupMapping;
+
+import java.io.IOException;
+import java.util.List;
+
+import static net.jami.jams.server.Server.dataStore;
+
+@WebServlet("/api/admin/user/groups/*")
+@Slf4j
+public class UserGroupsServlet extends HttpServlet {
+
+    /**
+     * @apiVersion 1.0.0
+     * @api {get} /api/admin/user/[username]/groups/ Get JAMS user groups
+     * @apiName getUserGroups
+     * @apiGroup User
+     *
+     * @apiSuccess (200) {body} User json user object representation
+     * @apiSuccessExample {json} Success-Response:
+     * {
+     *      "groups": ["a5085350-3348-11eb-adc1-0242ac120002", "abde9b76-3348-11eb-adc1-0242ac120002"]
+     * }
+     * @apiError (404) {null} null could not find groups for this user
+     */
+    @Override
+    @ScopedServletMethod(securityGroups = {AccessLevel.ADMIN})
+    @JsonContent
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+
+        String username = req.getPathInfo().replace("/","");
+
+        StatementList statementList = new StatementList();
+        StatementElement st = new StatementElement("username", "=", username, "");
+
+        statementList.addStatement(st);
+
+        List<UserGroupMapping> result = dataStore.getUserGroupMappingsDao().getObjects(statementList);
+
+        if (result.isEmpty())
+            resp.sendError(404, "No groups found for this user!");
+        else {
+            resp.getOutputStream().write(JsonStream.serialize(result).getBytes());
+            resp.setStatus(200);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserProfileServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserProfileServlet.java
index 7705069ed6784b9e82b1d204aeaa5d9587754a73..fc28c2bf7e74ca3a1dd4c6f6745cb16343cdafd2 100644
--- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserProfileServlet.java
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserProfileServlet.java
@@ -51,7 +51,6 @@ public class UserProfileServlet extends HttpServlet {
             if (v.getUserProfile(username) != null)
                 profile[0] = v.getUserProfile(username);
         });
-        dataStore.updateUserGroupMappings(profile[0]);
 
         if (profile[0] != null) {
             resp.getOutputStream().write(JsonStream.serialize(profile[0]).getBytes());