From eda9c1f744826557748136a1a7f8a13faf879e90 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 16 Jul 2019 20:44:25 +0200
Subject: [PATCH] updating privileges is using new interface

---
 frontend-js/src/main/js/ServerConnector.js    | 79 +++++++++++------
 .../main/js/gui/admin/EditProjectDialog.js    | 39 +++++++--
 .../src/main/js/gui/admin/EditUserDialog.js   | 86 +++++++++----------
 frontend-js/src/main/js/map/data/User.js      | 10 ++-
 .../test/js/gui/admin/EditUserDialog-test.js  | 26 ------
 ...EW_PROJECT.14898=true&token=MOCK_TOKEN_ID& |  1 -
 ...ileges.IS_ADMIN=true&token=ADMIN_TOKEN_ID& |  1 +
 7 files changed, 131 insertions(+), 111 deletions(-)
 delete mode 100644 frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.EDIT_COMMENTS_PROJECT.14898=false&privileges.LAYOUT_MANAGEMENT.14898=false&privileges.VIEW_PROJECT.14898=true&token=MOCK_TOKEN_ID&
 create mode 100644 frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.IS_ADMIN=true&token=ADMIN_TOKEN_ID&

diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js
index c44e6bca39..a0a810beda 100644
--- a/frontend-js/src/main/js/ServerConnector.js
+++ b/frontend-js/src/main/js/ServerConnector.js
@@ -1390,28 +1390,7 @@ ServerConnector.updateUser = function (user) {
       connectedToLdap: user.isConnectedToLdap()
     }
   };
-
-  var canModifyPrivileges = false;
-  return self.sendPatchRequest(self.getUserUrl(queryParams), filterParams)
-
-    .then(function () {
-      var currentLogin = ServerConnector.getSessionData().getLogin();
-      return self.sendGetRequest(self.getUserUrl({login: currentLogin}, {}));
-    })
-
-    .then(function (response) {
-      canModifyPrivileges = JSON.parse(response).privileges.some(function (privilege) {
-        return (privilege.type === PrivilegeType.USER_MANAGEMENT) && parseInt(privilege.value) === 1;
-      });
-      return self.getConfiguration();
-    })
-
-    .then(function (configuration) {
-      if (!canModifyPrivileges) {
-        return Promise.resolve(user);
-      }
-      return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)});
-    });
+  return self.sendPatchRequest(self.getUserUrl(queryParams), filterParams);
 };
 
 /**
@@ -1454,7 +1433,7 @@ ServerConnector.addUser = function (user) {
     }).then(function () {
       return self.getConfiguration();
     }).then(function (configuration) {
-      return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)});
+      return self.grantUserPrivileges({user: user, privileges: user.getPrivileges()});
     });
 };
 
@@ -1475,18 +1454,66 @@ ServerConnector.removeUser = function (login) {
  *
  * @param {Object} params
  * @param {User} params.user
- * @param {Object} params.privileges
+ * @param {Authority[]} params.privileges
  *
  * @returns {Promise}
  */
-ServerConnector.updateUserPrivileges = function (params) {
+ServerConnector.grantUserPrivileges = function (params) {
   var self = this;
   var queryParams = {
     login: params.user.getLogin()
   };
+  var privileges = {};
+  for (var i = 0; i < params.privileges.length; i++) {
+    var privilege = params.privileges[i];
+    if (privilege.objectId !== undefined && privilege.objectId !== null) {
+      privileges[privilege.privilegeType + ":" + privilege.objectId] = true;
+    } else {
+      privileges[privilege.privilegeType] = true;
+    }
+  }
+
+  return self.sendPatchRequest(self.getUpdateUserPrivilegesUrl(queryParams), {
+    privileges: privileges
+  }).then(function (content) {
+    var obj = JSON.parse(content);
+    var user = new User(obj);
+    if (self._usersByLogin[user.getLogin()] !== undefined) {
+      self._usersByLogin[user.getLogin()].update(user);
+    } else {
+      self._usersByLogin[user.getLogin()] = user;
+    }
+    return self._usersByLogin[user.getLogin()];
+  }).then(null, function (error) {
+    return self.processNetworkError(error);
+  });
+};
+
+/**
+ *
+ * @param {Object} params
+ * @param {User} params.user
+ * @param {Authority[]} params.privileges
+ *
+ * @returns {Promise}
+ */
+ServerConnector.revokeUserPrivileges = function (params) {
+  var self = this;
+  var queryParams = {
+    login: params.user.getLogin()
+  };
+  var privileges = {};
+  for (var i = 0; i < params.privileges.length; i++) {
+    var privilege = params.privileges[i];
+    if (privilege.objectId !== undefined && privilege.objectId !== null) {
+      privileges[privilege.privilegeType + ":" + privilege.objectId] = false;
+    } else {
+      privileges[privilege.privilegeType] = false;
+    }
+  }
 
   return self.sendPatchRequest(self.getUpdateUserPrivilegesUrl(queryParams), {
-    privileges: params.privileges
+    privileges: privileges
   }).then(function (content) {
     var obj = JSON.parse(content);
     var user = new User(obj);
diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
index 3d8329b42e..237083d3ab 100644
--- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
+++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js
@@ -593,13 +593,19 @@ EditProjectDialog.prototype.createUsersTabContent = function () {
   result.appendChild(usersTable);
 
   $(usersTable).on("change", "[name='privilege']", function () {
-    var privileges = {};
     var type = $(this).attr("data").split(",")[0];
     var login = $(this).attr("data").split(",")[1];
-    var privilege = {};
-    privilege[self.getProject().getId()] = $(this).prop("checked");
-    privileges[type] = privilege;
-    return self.updatePrivileges(self._userByLogin[login], privileges);
+    if ($(this).prop("checked")) {
+      return self.grantPrivilege(self._userByLogin[login], {
+        privilegeType: type,
+        objectId: self.getProject().getProjectId()
+      });
+    } else {
+      return self.revokePrivilege(self._userByLogin[login], {
+        privilegeType: type,
+        objectId: self.getProject().getProjectId()
+      });
+    }
   });
 
   return result;
@@ -1134,15 +1140,30 @@ EditProjectDialog.prototype.updateMap = function (map) {
 /**
  *
  * @param {User} user
- * @param {Object} privileges
+ * @param {Authority} privilege
+ * @returns {Promise}
+ */
+EditProjectDialog.prototype.grantPrivilege = function (user, privilege) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().grantUserPrivileges({
+    user: user,
+    privileges: [privilege]
+  }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing);
+};
+
+/**
+ *
+ * @param {User} user
+ * @param {Authority} privilege
  * @returns {Promise}
  */
-EditProjectDialog.prototype.updatePrivileges = function (user, privileges) {
+EditProjectDialog.prototype.revokePrivilege = function (user, privilege) {
   var self = this;
   GuiConnector.showProcessing();
-  return self.getServerConnector().updateUserPrivileges({
+  return self.getServerConnector().revokeUserPrivileges({
     user: user,
-    privileges: privileges
+    privileges: [privilege]
   }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing);
 };
 
diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js
index cc51dcc12c..970ff877b2 100644
--- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js
+++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js
@@ -349,7 +349,6 @@ EditUserDialog.prototype.initProjectsTab = function () {
 
   var projectsTable = $("[name=projectsTable]", self.getElement())[0];
 
-  var configuration = self.getConfiguration();
   var columns = self.createUserPrivilegeColumns();
   $(projectsTable).DataTable({
     columns: columns
@@ -358,15 +357,10 @@ EditUserDialog.prototype.initProjectsTab = function () {
     var data = $(this).attr("data").split("-");
     var privilegeType = data[0];
     var objectId = data[1];
-    for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-      var privilege = configuration.getPrivilegeTypes()[i];
-      if (privilege.getName() === privilegeType) {
-        if ($(this).is(":checked")) {
-          return self.grantPrivilege({type: privilege, objectId: objectId});
-        } else {
-          return self.revokePrivilege({type: privilege, objectId: objectId});
-        }
-      }
+    if ($(this).is(":checked")) {
+      return self.grantPrivilege({privilegeType: privilegeType, objectId: objectId});
+    } else {
+      return self.revokePrivilege({privilegeType: privilegeType, objectId: objectId});
     }
   });
 
@@ -374,15 +368,10 @@ EditUserDialog.prototype.initProjectsTab = function () {
     var data = $(this).attr("data").split("-");
     var privilegeType = data[0];
     var objectId = "*";
-    for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-      var privilege = configuration.getPrivilegeTypes()[i];
-      if (privilege.getName() === privilegeType) {
-        if ($(this).is(":checked")) {
-          return self.grantPrivilege({type: privilege, objectId: objectId});
-        } else {
-          return self.revokePrivilege({type: privilege, objectId: objectId});
-        }
-      }
+    if ($(this).is(":checked")) {
+      return self.grantPrivilege({privilegeType: privilegeType, objectId: objectId});
+    } else {
+      return self.revokePrivilege({privilegeType: privilegeType, objectId: objectId});
     }
   });
 };
@@ -405,41 +394,44 @@ EditUserDialog.prototype.initPrivilegesTab = function () {
     columns: columns
   });
 
-  var configuration = self.getConfiguration();
   $(privilegesTable).on("click", "[name='privilege-checkbox']", function () {
     var privilegeType = $(this).attr("data");
-    for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-      var privilege = configuration.getPrivilegeTypes()[i];
-      if (privilege.getName() === privilegeType) {
-        var value = $(this).is(":checked") ? 1 : 0;
-        self.getUser().setPrivilege({type: privilege, value: value});
-      }
-    }
-    if (!self.getIsNewUser()) {
-      return self.updateUser();
-    }
-  });
-  $(privilegesTable).on("change", "[name='privilege-int']", function () {
-    var privilegeType = $(this).attr("data");
-    var value = $(this).val();
-    value = parseInt(value);
-    if (Functions.isInt(value)) {
-      for (var i = 0; i < configuration.getPrivilegeTypes().length; i++) {
-        var privilege = configuration.getPrivilegeTypes()[i];
-        if (privilege.getName() === privilegeType) {
-          self.getUser().setPrivilege({type: privilege, value: value});
-        }
-      }
-      $(this).css("background-color", "");
-      if (!self.getIsNewUser()) {
-        return self.updateUser();
-      }
+    if ($(this).is(":checked")) {
+      return self.grantPrivilege({privilegeType: privilegeType});
     } else {
-      $(this).css("background-color", "red");
+      return self.revokePrivilege({privilegeType: privilegeType});
     }
   });
 };
 
+/**
+ *
+ * @param {Authority} privilege
+ * @returns {Promise}
+ */
+EditUserDialog.prototype.grantPrivilege = function (privilege) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().grantUserPrivileges({
+    user: self.getUser(),
+    privileges: [privilege]
+  }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing);
+};
+
+/**
+ *
+ * @param {Authority} privilege
+ * @returns {Promise}
+ */
+EditUserDialog.prototype.revokePrivilege = function (privilege) {
+  var self = this;
+  GuiConnector.showProcessing();
+  return self.getServerConnector().revokeUserPrivileges({
+    user: self.getUser(),
+    privileges: [privilege]
+  }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing);
+};
+
 /**
  *
  */
diff --git a/frontend-js/src/main/js/map/data/User.js b/frontend-js/src/main/js/map/data/User.js
index ab00235258..70cb9a3879 100644
--- a/frontend-js/src/main/js/map/data/User.js
+++ b/frontend-js/src/main/js/map/data/User.js
@@ -1,5 +1,11 @@
 "use strict";
 
+/**
+ * @typedef {Object} Authority
+ * @property {string} privilegeType
+ * @property {string|?null} [objectId]
+ */
+
 /* exported logger */
 
 // noinspection JSUnusedLocalSymbols
@@ -204,7 +210,7 @@ User.prototype.getPassword = function () {
 
 /**
  *
- * @param {Object[]} privileges
+ * @param {Authority[]} privileges
  */
 User.prototype.setPrivileges = function (privileges) {
   this._privileges = privileges;
@@ -217,7 +223,7 @@ User.prototype.setPrivileges = function (privileges) {
 
 /**
  *
- * @returns {Array}
+ * @returns {Authority[]}
  */
 User.prototype.getPrivileges = function () {
   return this._privileges;
diff --git a/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js b/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js
index 47919a1c86..0d29778603 100644
--- a/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js
+++ b/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js
@@ -130,31 +130,5 @@ describe('EditUserDialog', function () {
         dialog.destroy();
       });
     });
-
-  });
-  describe('change privilege int value', function () {
-    it('existing user', function () {
-      helper.loginAsAdmin();
-      var dialog;
-      var project;
-      var user;
-      var serializedPrivileges;
-      return ServerConnector.getUser("anonymous").then(function (result) {
-        user = result;
-        serializedPrivileges = user.privilegesToExport(helper.getConfiguration());
-        return ServerConnector.getProject();
-      }).then(function (result) {
-        project = result;
-        dialog = createEditUserDialog(project, user);
-        return dialog.init();
-      }).then(function () {
-        var element = $("[name=privilege-int]", dialog.getElement())[0];
-        $(element).val("101010");
-        return helper.triggerJqueryEvent(element, "change");
-      }).then(function () {
-        expect(serializedPrivileges).not.to.deep.equal(user.privilegesToExport(helper.getConfiguration()));
-        dialog.destroy();
-      });
-    });
   });
 });
diff --git a/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.EDIT_COMMENTS_PROJECT.14898=false&privileges.LAYOUT_MANAGEMENT.14898=false&privileges.VIEW_PROJECT.14898=true&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.EDIT_COMMENTS_PROJECT.14898=false&privileges.LAYOUT_MANAGEMENT.14898=false&privileges.VIEW_PROJECT.14898=true&token=MOCK_TOKEN_ID&
deleted file mode 100644
index 719fd551f8..0000000000
--- a/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.EDIT_COMMENTS_PROJECT.14898=false&privileges.LAYOUT_MANAGEMENT.14898=false&privileges.VIEW_PROJECT.14898=true&token=MOCK_TOKEN_ID&
+++ /dev/null
@@ -1 +0,0 @@
-{"simpleColor":null,"privileges":[{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19103},{"type":"VIEW_PROJECT","value":1,"objectId":9},{"type":"VIEW_PROJECT","value":1,"objectId":19186},{"type":"VIEW_PROJECT","value":1,"objectId":19},{"type":"MANAGE_GENOMES","value":1},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":18039},{"type":"VIEW_PROJECT","value":1,"objectId":11},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":18115},{"type":"VIEW_PROJECT","value":1,"objectId":18305},{"type":"VIEW_PROJECT","value":1,"objectId":18039},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":18039},{"type":"VIEW_PROJECT","value":0,"objectId":19184},{"type":"USER_MANAGEMENT","value":0},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19102},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19102},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":16668},{"type":"VIEW_PROJECT","value":1,"objectId":15764},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":15764},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19186},{"type":"VIEW_PROJECT","value":1,"objectId":10},{"type":"CUSTOM_LAYOUTS","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":16668},{"type":"VIEW_PROJECT","value":1,"objectId":15763},{"type":"VIEW_PROJECT","value":1,"objectId":19102},{"type":"ADD_MAP","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":21},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19184},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":17051},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":15763},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":18115},{"type":"VIEW_PROJECT","value":1,"objectId":8},{"type":"VIEW_PROJECT","value":1,"objectId":19187},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":15763},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19187},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19186},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19187},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":17051},{"type":"VIEW_PROJECT","value":1,"objectId":22},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":14898},{"type":"VIEW_PROJECT","value":1,"objectId":17},{"type":"VIEW_PROJECT","value":1,"objectId":1},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19184},{"type":"VIEW_PROJECT","value":1,"objectId":17051},{"type":"VIEW_PROJECT","value":1,"objectId":18},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":16668},{"type":"CONFIGURATION_MANAGE","value":0},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":15764},{"type":"VIEW_PROJECT","value":1,"objectId":20},{"type":"VIEW_PROJECT","value":1,"objectId":19103},{"type":"VIEW_PROJECT","value":1,"objectId":6},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19103},{"type":"PROJECT_MANAGEMENT","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":18115},{"type":"VIEW_PROJECT","value":1,"objectId":7},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":14898},{"type":"VIEW_PROJECT","value":1,"objectId":14898},{"type":"CUSTOM_LAYOUTS_AVAILABLE","value":0}],"removed":false,"surname":"","minColor":null,"name":"","maxColor":null,"id":3,"login":"anonymous","email":""}
\ No newline at end of file
diff --git a/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.IS_ADMIN=true&token=ADMIN_TOKEN_ID& b/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.IS_ADMIN=true&token=ADMIN_TOKEN_ID&
new file mode 100644
index 0000000000..2fd3a0360c
--- /dev/null
+++ b/frontend-js/testFiles/apiCalls/users/anonymous.updatePrivileges/PATCH_privileges.IS_ADMIN=true&token=ADMIN_TOKEN_ID&
@@ -0,0 +1 @@
+{"connectedToLdap":false,"email":"","id":3,"ldapAccountAvailable":false,"login":"anonymous","maxColor":null,"minColor":null,"name":"","neutralColor":null,"privileges":[{"objectId":null,"privilegeType":"IS_ADMIN"}, {"objectId":"empty","privilegeType":"READ_PROJECT"},{"objectId":"parameter","privilegeType":"READ_PROJECT"},{"objectId":"drug_target_sample","privilegeType":"READ_PROJECT"},{"objectId":"GSTP1_subnetwork_220214","privilegeType":"READ_PROJECT"},{"objectId":"pdmap_jun16_test","privilegeType":"READ_PROJECT"},{"objectId":"CDlayerin_v2-semantic","privilegeType":"READ_PROJECT"},{"objectId":"PD_150625_3","privilegeType":"READ_PROJECT"},{"objectId":"doi","privilegeType":"READ_PROJECT"},{"objectId":"complex_model_with_images","privilegeType":"READ_PROJECT"},{"objectId":"complex_model_with_submaps","privilegeType":"READ_PROJECT"},{"objectId":"images","privilegeType":"READ_PROJECT"},{"objectId":"kinteics_test","privilegeType":"READ_PROJECT"},{"objectId":"species_with_boundary_cond","privilegeType":"READ_PROJECT"},{"objectId":"sample","privilegeType":"READ_PROJECT"},{"objectId":"complex_model_with_layouts","privilegeType":"READ_PROJECT"},{"objectId":"pdmap_jan17","privilegeType":"READ_PROJECT"},{"objectId":"ASTHMA_V40_Test9","privilegeType":"READ_PROJECT"},{"objectId":"CDlayerin_v2","privilegeType":"READ_PROJECT"}],"removed":false,"simpleColor":null,"surname":"","termsOfUseConsent":false}
\ No newline at end of file
-- 
GitLab