diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 584e1a8d7e7a45f787765f4eaa9989da1daeaca0..e7786dd394f2d65c76ff0eb8bcc8662a6ed84301 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -204,7 +204,7 @@ ServerConnector.sendPatchRequest = function (url, json) { ServerConnector.getToken = function () { var self = this; - var login = self.getSessionData(null).getLogin() + var login = self.getSessionData(null).getLogin(); var token = self.getSessionData(null).getToken(); if (token === undefined || login === undefined) { return self.login(); @@ -858,7 +858,7 @@ ServerConnector.getLoggedUser = function () { ServerConnector.getUser = function (login) { var self = this; var queryParams = { - login: login, + login: login }; var filterParams = {}; @@ -874,10 +874,31 @@ ServerConnector.getUser = function (login) { }); }; +ServerConnector.updateUser = function (user) { + var self = this; + var queryParams = { + login: user.getLogin() + }; + var filterParams = { + user: { + name: user.getName(), + surname: user.getSurname(), + password: user.getPassword(), + email: user.getEmail() + } + }; + return self.sendPatchRequest(self.getUserUrl(queryParams), filterParams).then(function () { + return self.getConfiguration(); + }).then(function (configuration) { + return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); + }); + +}; + ServerConnector.updateUserPrivileges = function (params) { var self = this; var queryParams = { - login: params.user.getLogin(), + login: params.user.getLogin() }; return self.sendPatchRequest(self.getUpdateUserPrivilegesUrl(queryParams), { @@ -891,8 +912,27 @@ ServerConnector.updateUserPrivileges = function (params) { self._usersByLogin[user.getLogin()] = user; } return self._usersByLogin[user.getLogin()]; + }).then(null, function (error) { + return self.processNetworkError(error); }); }; + +ServerConnector.processNetworkError = function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.NOT_FOUND: + return null; + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } +}; + + ServerConnector.updateUserPreferences = function (params) { var self = this; var queryParams = { diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index b7293b8c72e741e49cd07f51b0e18e0a8d0f7885..cb84fb67409da81f879194e992467493dc4b940a 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -14,664 +14,664 @@ var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); function EditProjectDialog(params) { - AbstractGuiElement.call(this, params); - var self = this; - $(self.getElement()).addClass("minerva-edit-project-dialog"); + AbstractGuiElement.call(this, params); + var self = this; + $(self.getElement()).addClass("minerva-edit-project-dialog"); - self.createGui(); + self.createGui(); } EditProjectDialog.prototype = Object.create(AbstractGuiElement.prototype); EditProjectDialog.prototype.constructor = EditProjectDialog; EditProjectDialog.prototype.createGui = function () { - var self = this; - var element = self.getElement(); - - var tabDiv = Functions.createElement({ - type: "div", - name: "tabView", - className: "tabbable boxed parentTabs" - }); - element.appendChild(tabDiv); - - var tabMenuDiv = Functions.createElement({ - type: "ul", - className: "nav nav-tabs" - }); - tabDiv.appendChild(tabMenuDiv); - - var tabContentDiv = Functions.createElement({ - type: "div", - className: "tab-content" - }); - tabDiv.appendChild(tabContentDiv); - - self.createGeneralTab(tabMenuDiv, tabContentDiv); - self.createOverlaysTab(tabMenuDiv, tabContentDiv); - self.createUsersTab(tabMenuDiv, tabContentDiv); + var self = this; + var element = self.getElement(); + + var tabDiv = Functions.createElement({ + type: "div", + name: "tabView", + className: "tabbable boxed parentTabs" + }); + element.appendChild(tabDiv); + + var tabMenuDiv = Functions.createElement({ + type: "ul", + className: "nav nav-tabs" + }); + tabDiv.appendChild(tabMenuDiv); + + var tabContentDiv = Functions.createElement({ + type: "div", + className: "tab-content" + }); + tabDiv.appendChild(tabContentDiv); + + self.createGeneralTab(tabMenuDiv, tabContentDiv); + self.createOverlaysTab(tabMenuDiv, tabContentDiv); + self.createUsersTab(tabMenuDiv, tabContentDiv); }; EditProjectDialog.prototype.createGeneralTab = function (tabMenuDiv, tabContentDiv) { - var self = this; - self.addTab({ - tabMenuDiv: tabMenuDiv, - tabContentDiv: tabContentDiv, - name: "GENERAL", - id: self.getProject().getProjectId() + "_general_tab", - content: self.createGeneralTabContent(), - }); + var self = this; + self.addTab({ + tabMenuDiv: tabMenuDiv, + tabContentDiv: tabContentDiv, + name: "GENERAL", + id: self.getProject().getProjectId() + "_general_tab", + content: self.createGeneralTabContent(), + }); }; EditProjectDialog.prototype.addTab = function (params) { - var navLi = guiUtils.createTabMenuObject({ - id: params.id, - name: params.name, - navigationBar: params.tabMenuDiv - }); - params.tabMenuDiv.appendChild(navLi); - - var contentDiv = guiUtils.createTabContentObject({ - id: params.id, - navigationObject: navLi, - navigationBar: params.tabMenuDiv - }); - - if (params.content !== undefined) { - contentDiv.appendChild(params.content); - } - - params.tabContentDiv.appendChild(contentDiv); + var navLi = guiUtils.createTabMenuObject({ + id: params.id, + name: params.name, + navigationBar: params.tabMenuDiv + }); + params.tabMenuDiv.appendChild(navLi); + + var contentDiv = guiUtils.createTabContentObject({ + id: params.id, + navigationObject: navLi, + navigationBar: params.tabMenuDiv + }); + + if (params.content !== undefined) { + contentDiv.appendChild(params.content); + } + + params.tabContentDiv.appendChild(contentDiv); }; EditProjectDialog.prototype.createGeneralTabContent = function () { - var self = this; - var project = self.getProject(); - - var result = new Functions.createElement({ - type: "div", - }); - - var table = new Functions.createElement({ - type: "div", - style: "display:table" - }); - result.appendChild(table); - - var projectIdRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(projectIdRow); - projectIdRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "ProjectId", - })); - projectIdRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: project.getProjectId(), - })); - - var nameRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(nameRow); - nameRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "Name", - })); - nameRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "<input name='projectName' value='" + project.getName() + "'/>", - })); - - var versionRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(versionRow); - versionRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "Version", - })); - versionRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "<input name='projectVersion' value='" + project.getVersion() + "'/>", - })); - - var diseaseRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(diseaseRow); - diseaseRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "Disease", - })); - var disease = ""; - if (project.getDisease() !== undefined) { - disease = project.getDisease().getResource(); + var self = this; + var project = self.getProject(); + + var result = new Functions.createElement({ + type: "div", + }); + + var table = new Functions.createElement({ + type: "div", + style: "display:table" + }); + result.appendChild(table); + + var projectIdRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(projectIdRow); + projectIdRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "ProjectId", + })); + projectIdRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: project.getProjectId(), + })); + + var nameRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(nameRow); + nameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Name" + })); + nameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='projectName' value='" + project.getName() + "'/>", + })); + + var versionRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(versionRow); + versionRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Version" + })); + versionRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='projectVersion' value='" + project.getVersion() + "'/>", + })); + + var diseaseRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(diseaseRow); + diseaseRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Disease", + })); + var disease = ""; + if (project.getDisease() !== undefined) { + disease = project.getDisease().getResource(); + } + diseaseRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='projectDisease' value='" + disease + "'/>", + })); + + var organismRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(organismRow); + organismRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Organism", + })); + var organism = ""; + if (project.getOrganism() !== undefined) { + organism = project.getOrganism().getResource(); + } + organismRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='projectOrganism' value='" + organism + "'/>", + })); + + var emailRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(emailRow); + emailRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Notify email" + })); + var email = ""; + if (project.getNotifyEmail() !== undefined) { + email = project.getNotifyEmail(); + } + emailRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='projectNotifyEmail' value='" + email + "'/>", + })); + + var menuRow = Functions.createElement({ + type: "div", + className: "minerva-menu-row", + style: "display:table-row; margin:10px" + }); + result.appendChild(menuRow); + + var saveProjectButton = Functions.createElement({ + type: "button", + name: "saveProject", + content: '<span class="ui-icon ui-icon-disk"></span> SAVE', + onclick: function () { + return self.onSaveClicked().then(function () { + return self.close(); + }, GuiConnector.alert); } - diseaseRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "<input name='projectDisease' value='" + disease + "'/>", - })); - - var organismRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(organismRow); - organismRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "Organism", - })); - var organism = ""; - if (project.getOrganism() !== undefined) { - organism = project.getOrganism().getResource(); - } - organismRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "<input name='projectOrganism' value='" + organism + "'/>", - })); - - var emailRow = new Functions.createElement({ - type: "div", - style: "display:table-row" - }); - table.appendChild(emailRow); - emailRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "Notify email", - })); - var email = ""; - if (project.getNotifyEmail() !== undefined) { - email = project.getNotifyEmail(); - } - emailRow.appendChild(new Functions.createElement({ - type: "div", - style: "display:table-cell", - content: "<input name='projectNotifyEmail' value='" + email + "'/>", - })); - - var menuRow = Functions.createElement({ - type: "div", - className: "minerva-menu-row", - style: "display:table-row; margin:10px", - }); - result.appendChild(menuRow); - - var saveProjectButton = Functions.createElement({ - type: "button", - name: "saveProject", - content: '<span class="ui-icon ui-icon-disk"></span> SAVE', - onclick: function () { - return self.onSaveClicked().then(function () { - return self.close(); - }, GuiConnector.alert); - }, - }); - var cancelButton = Functions.createElement({ - type: "button", - name: "cancelProject", - content: '<span class="ui-icon ui-icon-cancel"></span> CANCEL', - onclick: function () { - return self.close(); - }, - }); - menuRow.appendChild(saveProjectButton); - menuRow.appendChild(cancelButton); - - return result; + }); + var cancelButton = Functions.createElement({ + type: "button", + name: "cancelProject", + content: '<span class="ui-icon ui-icon-cancel"></span> CANCEL', + onclick: function () { + return self.close(); + }, + }); + menuRow.appendChild(saveProjectButton); + menuRow.appendChild(cancelButton); + + return result; }; EditProjectDialog.prototype.createOverlaysTab = function (tabMenuDiv, tabContentDiv) { - var self = this; - self.addTab({ - tabMenuDiv: tabMenuDiv, - tabContentDiv: tabContentDiv, - name: "OVERLAYS", - id: self.getProject().getProjectId() + "_overlays_tab", - content: self.createOverlaysTabContent(), - }); + var self = this; + self.addTab({ + tabMenuDiv: tabMenuDiv, + tabContentDiv: tabContentDiv, + name: "OVERLAYS", + id: self.getProject().getProjectId() + "_overlays_tab", + content: self.createOverlaysTabContent(), + }); }; EditProjectDialog.prototype.createOverlaysTabContent = function () { - var self = this; - var result = Functions.createElement({ - type: "div", - }); - result.appendChild(self._createOverlayTable()); - return result; + var self = this; + var result = Functions.createElement({ + type: "div", + }); + result.appendChild(self._createOverlayTable()); + return result; }; EditProjectDialog.prototype._createOverlayTable = function () { - var self = this; - - var result = Functions.createElement({ - type: "div", - style: "margin-top:10px;", - }); - - var overlaysTable = Functions.createElement({ - type: "table", - name: "overlaysTable", - className: "display", - style: "width:100%", - }); - result.appendChild(overlaysTable); - - $(overlaysTable).DataTable({ - fnRowCallback: function (nRow, aData) { - nRow.setAttribute('id', "overlay-" + aData[0]); - }, - columns: [{ - title: 'Id', - }, { - title: 'Name', - }, { - title: 'Description', - }, { - title: 'Public', - }, { - title: 'Owner', - }, { - title: 'Data', - }, { - title: 'Update', - }, { - title: 'Remove', - },], - dom: '<"minerva-datatable-toolbar">frtip', - initComplete: function () { - $("div.minerva-datatable-toolbar", $(result)).html('<button name="addOverlay">Add overlay</button>'); - }, - - }); - - $(overlaysTable).on("click", "[name='removeOverlay']", function () { - var button = this; - return self.removeOverlay($(button).attr("data")).then(null, GuiConnector.alert); - }); - - $(overlaysTable).on("click", "[name='saveOverlay']", function () { - var button = this; - GuiConnector.showProcessing("Updating"); - return self.saveOverlay($(button).attr("data")).then(function () { - GuiConnector.hideProcessing(); - GuiConnector.info("Overlay updated successfully"); - }, function (error) { - GuiConnector.hideProcessing(); - GuiConnector.alert(error); - }); - }); - - $(overlaysTable).on("click", "[name='downloadSource']", function () { - var button = this; - return ServerConnector.getOverlaySourceDownloadUrl({ - overlayId: $(button).attr("data") - }).then(function (url) { - return self.downloadFile(url); - }).then(null, GuiConnector.alert); - }); - - $(result).on("click", "[name='addOverlay']", function () { - return self.openAddOverlayDialog(); - }); + var self = this; + + var result = Functions.createElement({ + type: "div", + style: "margin-top:10px;", + }); + + var overlaysTable = Functions.createElement({ + type: "table", + name: "overlaysTable", + className: "display", + style: "width:100%", + }); + result.appendChild(overlaysTable); + + $(overlaysTable).DataTable({ + fnRowCallback: function (nRow, aData) { + nRow.setAttribute('id', "overlay-" + aData[0]); + }, + columns: [{ + title: 'Id' + }, { + title: 'Name' + }, { + title: 'Description' + }, { + title: 'Public' + }, { + title: 'Owner' + }, { + title: 'Data' + }, { + title: 'Update' + }, { + title: 'Remove' + }], + dom: '<"minerva-datatable-toolbar">frtip', + initComplete: function () { + $("div.minerva-datatable-toolbar", $(result)).html('<button name="addOverlay">Add overlay</button>'); + } - return result; + }); + + $(overlaysTable).on("click", "[name='removeOverlay']", function () { + var button = this; + return self.removeOverlay($(button).attr("data")).then(null, GuiConnector.alert); + }); + + $(overlaysTable).on("click", "[name='saveOverlay']", function () { + var button = this; + GuiConnector.showProcessing("Updating"); + return self.saveOverlay($(button).attr("data")).then(function () { + GuiConnector.hideProcessing(); + GuiConnector.info("Overlay updated successfully"); + }, function (error) { + GuiConnector.hideProcessing(); + GuiConnector.alert(error); + }); + }); + + $(overlaysTable).on("click", "[name='downloadSource']", function () { + var button = this; + return ServerConnector.getOverlaySourceDownloadUrl({ + overlayId: $(button).attr("data") + }).then(function (url) { + return self.downloadFile(url); + }).then(null, GuiConnector.alert); + }); + + $(result).on("click", "[name='addOverlay']", function () { + return self.openAddOverlayDialog(); + }); + + return result; }; EditProjectDialog.prototype.createUsersTab = function (tabMenuDiv, tabContentDiv) { - var self = this; - self.addTab({ - tabMenuDiv: tabMenuDiv, - tabContentDiv: tabContentDiv, - name: "USERS", - id: self.getProject().getProjectId() + "_users_tab", - content: self.createUsersTabContent(), - }); + var self = this; + self.addTab({ + tabMenuDiv: tabMenuDiv, + tabContentDiv: tabContentDiv, + name: "USERS", + id: self.getProject().getProjectId() + "_users_tab", + content: self.createUsersTabContent(), + }); }; EditProjectDialog.prototype.createUsersTabContent = function () { - var self = this; - - var result = Functions.createElement({ - type: "div", - style: "margin-top:10px;", - }); - - var usersTable = Functions.createElement({ - type: "table", - name: "usersTable", - className: "display", - style: "width:100%", - }); - result.appendChild(usersTable); - - $(usersTable).on("click", "[name='saveUser']", function () { - var button = this; - GuiConnector.showProcessing("Updating"); - return self.saveUser($(button).attr("data")).then(function () { - GuiConnector.hideProcessing(); - GuiConnector.info("User updated successfully"); - }, function (error) { - GuiConnector.hideProcessing(); - GuiConnector.alert(error); - }); - }); - - return result; + var self = this; + + var result = Functions.createElement({ + type: "div", + style: "margin-top:10px;", + }); + + var usersTable = Functions.createElement({ + type: "table", + name: "usersTable", + className: "display", + style: "width:100%", + }); + result.appendChild(usersTable); + + $(usersTable).on("click", "[name='saveUser']", function () { + var button = this; + GuiConnector.showProcessing("Updating"); + return self.saveUser($(button).attr("data")).then(function () { + GuiConnector.hideProcessing(); + GuiConnector.info("User updated successfully"); + }, function (error) { + GuiConnector.hideProcessing(); + GuiConnector.alert(error); + }); + }); + + return result; }; EditProjectDialog.prototype.createUserPrivilegeColumns = function () { - var self = this; - - if (self._userPrivilegeColumns !== undefined) { - return Promise.resolve(self._userPrivilegeColumns); - } - - return ServerConnector.getConfiguration().then(function (configuration) { - self._userPrivilegeColumns = [{ - title: "Name" - }]; - var privilegeTypes = configuration.getPrivilegeTypes(); - for (var i = 0; i < privilegeTypes.length; i++) { - var type = privilegeTypes[i]; - if (type.getObjectType() === "Project") { - self._userPrivilegeColumns.push({ - "title": type.getCommonName(), - privilegeType: type, - }); - } - } + var self = this; + + if (self._userPrivilegeColumns !== undefined) { + return Promise.resolve(self._userPrivilegeColumns); + } + + return ServerConnector.getConfiguration().then(function (configuration) { + self._userPrivilegeColumns = [{ + title: "Name" + }]; + var privilegeTypes = configuration.getPrivilegeTypes(); + for (var i = 0; i < privilegeTypes.length; i++) { + var type = privilegeTypes[i]; + if (type.getObjectType() === "Project") { self._userPrivilegeColumns.push({ - "title": "Update" + "title": type.getCommonName(), + privilegeType: type }); - return self._userPrivilegeColumns; + } + } + self._userPrivilegeColumns.push({ + "title": "Update" }); + return self._userPrivilegeColumns; + }); }; EditProjectDialog.prototype.init = function () { - var self = this; - return self.initUsersTab().then(function () { - return self.refreshUsers(); - }).then(function () { - return self.refreshOverlays(); - }).then(function () { - $(window).trigger('resize'); - }); + var self = this; + return self.initUsersTab().then(function () { + return self.refreshUsers(); + }).then(function () { + return self.refreshOverlays(); + }).then(function () { + $(window).trigger('resize'); + }); }; EditProjectDialog.prototype.initUsersTab = function () { - var self = this; + var self = this; - var usersTable = $("[name=usersTable]", self.getElement())[0]; + var usersTable = $("[name=usersTable]", self.getElement())[0]; - return self.createUserPrivilegeColumns().then(function (columns) { - $(usersTable).DataTable({ - columns: columns, - }); + return self.createUserPrivilegeColumns().then(function (columns) { + $(usersTable).DataTable({ + columns: columns, }); + }); }; EditProjectDialog.prototype.refreshOverlays = function () { - var self = this; - return ServerConnector.getOverlays({ - projectId: self.getProject().getProjectId() - }).then(function (overlays) { - return self.setOverlays(overlays); - }); + var self = this; + return ServerConnector.getOverlays({ + projectId: self.getProject().getProjectId() + }).then(function (overlays) { + return self.setOverlays(overlays); + }); }; EditProjectDialog.prototype.refreshUsers = function () { - var self = this; - return ServerConnector.getUsers().then(function (users) { - return self.setUsers(users); - }); + var self = this; + return ServerConnector.getUsers().then(function (users) { + return self.setUsers(users); + }); }; EditProjectDialog.prototype.setOverlays = function (overlays) { - var self = this; - self._overlayById = []; - return ServerConnector.getUsers().then(function (users) { - var dataTable = $($("[name='overlaysTable']", self.getElement())[0]).DataTable(); - var data = []; - for (var i = 0; i < overlays.length; i++) { - var overlay = overlays[i]; - self._overlayById[overlay.getId()] = overlay; - var rowData = self.overlayToTableRow(overlay, users); - data.push(rowData); - } - dataTable.clear().rows.add(data).draw(); - }); + var self = this; + self._overlayById = []; + return ServerConnector.getUsers().then(function (users) { + var dataTable = $($("[name='overlaysTable']", self.getElement())[0]).DataTable(); + var data = []; + for (var i = 0; i < overlays.length; i++) { + var overlay = overlays[i]; + self._overlayById[overlay.getId()] = overlay; + var rowData = self.overlayToTableRow(overlay, users); + data.push(rowData); + } + dataTable.clear().rows.add(data).draw(); + }); }; EditProjectDialog.prototype.setUsers = function (users) { - var self = this; - self._userByLogin = []; - return self.createUserPrivilegeColumns().then(function (columns) { - var dataTable = $($("[name='usersTable']", self.getElement())[0]).DataTable(); - var data = []; - for (var i = 0; i < users.length; i++) { - var user = users[i]; - self._userByLogin[user.getLogin()] = user; - var rowData = self.userToTableRow(user, columns); - data.push(rowData); - } - dataTable.clear().rows.add(data).draw(); - }); + var self = this; + self._userByLogin = []; + return self.createUserPrivilegeColumns().then(function (columns) { + var dataTable = $($("[name='usersTable']", self.getElement())[0]).DataTable(); + var data = []; + for (var i = 0; i < users.length; i++) { + var user = users[i]; + self._userByLogin[user.getLogin()] = user; + var rowData = self.userToTableRow(user, columns); + data.push(rowData); + } + dataTable.clear().rows.add(data).draw(); + }); }; EditProjectDialog.prototype.userToTableRow = function (user, columns) { - var self = this; - var row = []; - var login = user.getLogin(); - - row[0] = user.getName() + " " + user.getSurname() + " (" + login + ")"; - for (var i = 1; i < columns.length; i++) { - var column = columns[i]; - if (column.privilegeType !== undefined) { - if (column.privilegeType.getValueType() === "boolean") { - var checked = ''; - if (user.hasPrivilege(column.privilegeType, self.getProject().getId())) { - checked = 'checked'; - } - row[i] = "<input type='checkbox' name='privilege-" + login + "' data='" + column.privilegeType.getName() + "' " - + checked + "/>"; - } else { - throw new Error("Unsupported type: " + column.privilegeType.getValueType()); - } + var self = this; + var row = []; + var login = user.getLogin(); + + row[0] = user.getName() + " " + user.getSurname() + " (" + login + ")"; + for (var i = 1; i < columns.length; i++) { + var column = columns[i]; + if (column.privilegeType !== undefined) { + if (column.privilegeType.getValueType() === "boolean") { + var checked = ''; + if (user.hasPrivilege(column.privilegeType, self.getProject().getId())) { + checked = 'checked'; } + row[i] = "<input type='checkbox' name='privilege-" + login + "' data='" + column.privilegeType.getName() + "' " + + checked + "/>"; + } else { + throw new Error("Unsupported type: " + column.privilegeType.getValueType()); + } } + } - row.push("<button name='saveUser' data='" + login + "'>SAVE</button>"); + row.push("<button name='saveUser' data='" + login + "'>SAVE</button>"); - return row; + return row; }; EditProjectDialog.prototype.overlayToTableRow = function (overlay, users) { - var row = []; - var id = overlay.getId(); - var creatorSelect; - if (overlay.getCreator() === "") { - creatorSelect = "<select name='creator-" + id + "' value=''>"; + var row = []; + var id = overlay.getId(); + var creatorSelect; + if (overlay.getCreator() === "") { + creatorSelect = "<select name='creator-" + id + "' value=''>"; + } else { + creatorSelect = "<select name='creator-" + id + "'>"; + } + + creatorSelect += "<option value='' >---</option>"; + for (var i = 0; i < users.length; i++) { + var selected = ""; + var user = users[i]; + if (overlay.getCreator() === user.getLogin()) { + selected = "selected"; } else { - creatorSelect = "<select name='creator-" + id + "'>"; + selected = ""; } - creatorSelect += "<option value='' >---</option>"; - for (var i = 0; i < users.length; i++) { - var selected = ""; - var user = users[i]; - if (overlay.getCreator() === user.getLogin()) { - selected = "selected"; - } else { - selected = ""; - } - - creatorSelect += "<option value='" + user.getLogin() + "' " + selected + ">" + user.getLogin() + "(" - + user.getName() + " " + user.getSurname() + ")</option>"; - } - creatorSelect += "</select>"; - - var checked = ''; - if (overlay.getPublicOverlay()) { - checked = "checked"; - } - var publicOverlayCheckbox = "<input type='checkbox' name='publicOverlay-" + id + "' " + checked + "/>"; - - var downloadSourceButton; - if (overlay.getInputDataAvailable()) { - downloadSourceButton = "<button name='downloadSource' data='" + id + "'>" - + "<span class='ui-icon ui-icon-arrowthickstop-1-s'></span>" + "</button>"; - } else { - downloadSourceButton = "N/A"; - } - - row[0] = id; - row[1] = "<input name='name-" + id + "' value='" + overlay.getName() + "'/>"; - row[2] = "<input name='description-" + id + "' value='" + overlay.getDescription() + "'/>"; - row[3] = publicOverlayCheckbox; - row[4] = creatorSelect; - row[5] = downloadSourceButton; - row[6] = "<button name='saveOverlay' data='" + id + "'>SAVE</button>"; - row[7] = "<button name='removeOverlay' data='" + id + "'>REMOVE</button>"; - - return row; + creatorSelect += "<option value='" + user.getLogin() + "' " + selected + ">" + user.getLogin() + "(" + + user.getName() + " " + user.getSurname() + ")</option>"; + } + creatorSelect += "</select>"; + + var checked = ''; + if (overlay.getPublicOverlay()) { + checked = "checked"; + } + var publicOverlayCheckbox = "<input type='checkbox' name='publicOverlay-" + id + "' " + checked + "/>"; + + var downloadSourceButton; + if (overlay.getInputDataAvailable()) { + downloadSourceButton = "<button name='downloadSource' data='" + id + "'>" + + "<span class='ui-icon ui-icon-arrowthickstop-1-s'></span>" + "</button>"; + } else { + downloadSourceButton = "N/A"; + } + + row[0] = id; + row[1] = "<input name='name-" + id + "' value='" + overlay.getName() + "'/>"; + row[2] = "<input name='description-" + id + "' value='" + overlay.getDescription() + "'/>"; + row[3] = publicOverlayCheckbox; + row[4] = creatorSelect; + row[5] = downloadSourceButton; + row[6] = "<button name='saveOverlay' data='" + id + "'>SAVE</button>"; + row[7] = "<button name='removeOverlay' data='" + id + "'>REMOVE</button>"; + + return row; }; EditProjectDialog.prototype.destroy = function () { - var self = this; - var div = self.getElement(); - var usersTable = $("[name=usersTable]", self.getElement())[0]; - var overlaysTable = $("[name=overlaysTable]", self.getElement())[0]; - if ($.fn.DataTable.isDataTable(usersTable)) { - $(usersTable).DataTable().destroy(); - } - if ($.fn.DataTable.isDataTable(overlaysTable)) { - $(overlaysTable).DataTable().destroy(); - } - - if ($(div).hasClass("ui-dialog-content")) { - $(div).dialog("destroy"); - } - if (self._addOverlayDialog !== undefined) { - self._addOverlayDialog.destroy(); - delete self._addOverlayDialog; - } + var self = this; + var div = self.getElement(); + var usersTable = $("[name=usersTable]", self.getElement())[0]; + var overlaysTable = $("[name=overlaysTable]", self.getElement())[0]; + if ($.fn.DataTable.isDataTable(usersTable)) { + $(usersTable).DataTable().destroy(); + } + if ($.fn.DataTable.isDataTable(overlaysTable)) { + $(overlaysTable).DataTable().destroy(); + } + + if ($(div).hasClass("ui-dialog-content")) { + $(div).dialog("destroy"); + } + if (self._addOverlayDialog !== undefined) { + self._addOverlayDialog.destroy(); + delete self._addOverlayDialog; + } }; EditProjectDialog.prototype.open = function () { - var self = this; - var div = self.getElement(); - if (!$(div).hasClass("ui-dialog-content")) { - $(div).dialog({ - title: self.getProject().getProjectId(), - width: window.innerWidth / 2, - height: window.innerHeight / 2, - }); - } - $(div).dialog("open"); + var self = this; + var div = self.getElement(); + if (!$(div).hasClass("ui-dialog-content")) { + $(div).dialog({ + title: self.getProject().getProjectId(), + width: window.innerWidth / 2, + height: window.innerHeight / 2, + }); + } + $(div).dialog("open"); }; var prepareMiriamData = function (type, resource) { - if (resource === "" || resource === undefined || resource === null) { - return null; - } else { - return new Annotation({ - type: type, - resource: resource - }); - } + if (resource === "" || resource === undefined || resource === null) { + return null; + } else { + return new Annotation({ + type: type, + resource: resource + }); + } }; EditProjectDialog.prototype.onSaveClicked = function () { - var self = this; - var project = self.getProject(); - var element = self.getElement(); - project.setName($("[name='projectName']", element)[0].value); - project.setVersion($("[name='projectVersion']", element)[0].value); - project.setNotifyEmail($("[name='projectNotifyEmail']", element)[0].value); - var organism = prepareMiriamData("TAXONOMY", $("[name='projectOrganism']", element)[0].value); - project.setOrganism(organism); - var disease = prepareMiriamData("MESH_2012", $("[name='projectDisease']", element)[0].value); - project.setDisease(disease); - return ServerConnector.updateProject(project); + var self = this; + var project = self.getProject(); + var element = self.getElement(); + project.setName($("[name='projectName']", element)[0].value); + project.setVersion($("[name='projectVersion']", element)[0].value); + project.setNotifyEmail($("[name='projectNotifyEmail']", element)[0].value); + var organism = prepareMiriamData("TAXONOMY", $("[name='projectOrganism']", element)[0].value); + project.setOrganism(organism); + var disease = prepareMiriamData("MESH_2012", $("[name='projectDisease']", element)[0].value); + project.setDisease(disease); + return ServerConnector.updateProject(project); }; EditProjectDialog.prototype.close = function () { - var self = this; - $(self.getElement()).dialog("close"); + var self = this; + $(self.getElement()).dialog("close"); }; EditProjectDialog.prototype.saveOverlay = function (overlayId) { - var self = this; - var overlay = self._overlayById[overlayId]; - overlay.setName($("[name='name-" + overlayId + "']", self.getElement())[0].value); - overlay.setDescription($("[name='description-" + overlayId + "']", self.getElement())[0].value); - overlay.setPublicOverlay($("[name='publicOverlay-" + overlayId + "']", self.getElement())[0].checked); - overlay.setCreator($("[name='creator-" + overlayId + "']", self.getElement())[0].value); - - return ServerConnector.updateOverlay(overlay); + var self = this; + var overlay = self._overlayById[overlayId]; + overlay.setName($("[name='name-" + overlayId + "']", self.getElement())[0].value); + overlay.setDescription($("[name='description-" + overlayId + "']", self.getElement())[0].value); + overlay.setPublicOverlay($("[name='publicOverlay-" + overlayId + "']", self.getElement())[0].checked); + overlay.setCreator($("[name='creator-" + overlayId + "']", self.getElement())[0].value); + + return ServerConnector.updateOverlay(overlay); }; EditProjectDialog.prototype.saveUser = function (login) { - var self = this; - var checkboxes = $("[name='privilege-" + login + "']", self.getElement()); - var privileges = {}; - for (var i = 0; i < checkboxes.length; i++) { - var checkbox = checkboxes[i]; - var privilege = {}; - privilege[self.getProject().getId()] = checkbox.checked; - privileges[$(checkbox).attr("data")] = privilege; - } - - return ServerConnector.updateUserPrivileges({ - user: self._userByLogin[login], - privileges: privileges - }); + var self = this; + var checkboxes = $("[name='privilege-" + login + "']", self.getElement()); + var privileges = {}; + for (var i = 0; i < checkboxes.length; i++) { + var checkbox = checkboxes[i]; + var privilege = {}; + privilege[self.getProject().getId()] = checkbox.checked; + privileges[$(checkbox).attr("data")] = privilege; + } + + return ServerConnector.updateUserPrivileges({ + user: self._userByLogin[login], + privileges: privileges + }); }; EditProjectDialog.prototype.removeOverlay = function (overlayId) { - var self = this; - return ServerConnector.removeOverlay({ - overlayId: overlayId - }).then(function () { - return self.refreshOverlays(); - }); + var self = this; + return ServerConnector.removeOverlay({ + overlayId: overlayId + }).then(function () { + return self.refreshOverlays(); + }); }; EditProjectDialog.prototype.openAddOverlayDialog = function () { - var self = this; - if (self._addOverlayDialog !== undefined) { - self._addOverlayDialog.destroy(); - } - self._addOverlayDialog = new AddOverlayDialog({ - project: self.getProject(), - customMap: null, - element: document.createElement("div"), - }); - self._addOverlayDialog.addListener("onAddOverlay", function () { - return self.refreshOverlays(); - }); - return self._addOverlayDialog.init().then(function () { - return self._addOverlayDialog.open(); - }); + var self = this; + if (self._addOverlayDialog !== undefined) { + self._addOverlayDialog.destroy(); + } + self._addOverlayDialog = new AddOverlayDialog({ + project: self.getProject(), + customMap: null, + element: document.createElement("div"), + }); + self._addOverlayDialog.addListener("onAddOverlay", function () { + return self.refreshOverlays(); + }); + return self._addOverlayDialog.init().then(function () { + return self._addOverlayDialog.open(); + }); }; module.exports = EditProjectDialog; diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js index f14ee87ede6c792b2b4c7be1e919ffd05cdb306f..21c1c09333a8759865122f92e921b05b27020dba 100644 --- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js @@ -5,8 +5,10 @@ var Promise = require("bluebird"); var AbstractGuiElement = require('../AbstractGuiElement'); var GuiConnector = require('../../GuiConnector'); +var ValidationError = require('../../ValidationError'); var Functions = require('../../Functions'); +// noinspection JSUnusedLocalSymbols var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); @@ -113,10 +115,98 @@ EditUserDialog.prototype.createGeneralTabContent = function () { style: "display:table-cell", content: "Login" })); - loginRow.appendChild(new Functions.createElement({ + if (user.getLogin() === undefined) { + loginRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='userLogin' value=''/>" + })); + } else { + loginRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='userLogin' value='" + user.getLogin() + "' readonly/>" + })); + } + + var passwordRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(passwordRow); + passwordRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Password" + })); + passwordRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input type=\"password\" name='userPassword' value=''/>" + })); + + var passwordRow2 = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(passwordRow2); + passwordRow2.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Confirm password" + })); + passwordRow2.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: user.getLogin() + content: "<input type=\"password\" name='userPassword2' value=''/>" + })); + + var nameRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(nameRow); + nameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Name" + })); + nameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='userName' value='" + user.getName() + "'/>" + })); + + var surnameRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(surnameRow); + surnameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Surname" + })); + surnameRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='userSurname' value='" + user.getSurname() + "'/>" + })); + + var emailRow = new Functions.createElement({ + type: "div", + style: "display:table-row" + }); + table.appendChild(emailRow); + emailRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "Email" + })); + emailRow.appendChild(new Functions.createElement({ + type: "div", + style: "display:table-cell", + content: "<input name='userEmail' value='" + user.getEmail() + "'/>" })); @@ -274,10 +364,74 @@ EditUserDialog.prototype.open = function () { EditUserDialog.prototype.onSaveClicked = function () { var self = this; var user = self.getUser(); + return self.checkValidity().then(function () { + user.setLogin(self.getLogin()); + user.setPassword(self.getPassword()); + user.setEmail(self.getEmail()); + user.setName(self.getName()); + user.setSurname(self.getSurname()); + return ServerConnector.updateUser(user); + }); +}; - return ServerConnector.updateUser(user); +EditUserDialog.prototype.checkValidity = function () { + var self = this; + var isValid = true; + var error = "<b>Some data is missing.</b><ul>"; + if (self.getPassword() !== self.getPassword2()) { + error += "<li>Password doesn't match</li>"; + isValid = false; + } + if (self.getLogin() === "" || self.getLogin() === undefined || self.getLogin() === null) { + error += "<li>Login must not be empty</li>"; + isValid = false; + } + var promise = Promise.resolve(); + if (self.getUser().getLogin() !== self.getLogin()) { + promise = ServerConnector.getUser(self.getLogin()).then(function (remoteUser) { + if (remoteUser !== null) { + error += "<li>Login already used</li>"; + isValid = false; + } + }); + } + return promise.then(function () { + if (isValid) { + return Promise.resolve(true); + } else { + return Promise.reject(new ValidationError(error)); + } + }); +}; + +EditUserDialog.prototype.getPassword = function () { + var self = this; + return $("[name='userPassword']", self.getElement()).val(); +}; +EditUserDialog.prototype.getPassword2 = function () { + var self = this; + return $("[name='userPassword2']", self.getElement()).val(); +}; + +EditUserDialog.prototype.getLogin = function () { + var self = this; + return $("[name='userLogin']", self.getElement()).val(); }; +EditUserDialog.prototype.getEmail = function () { + var self = this; + return $("[name='userEmail']", self.getElement()).val(); +}; +EditUserDialog.prototype.getName = function () { + var self = this; + return $("[name='userName']", self.getElement()).val(); +}; +EditUserDialog.prototype.getSurname = function () { + var self = this; + return $("[name='userSurname']", self.getElement()).val(); +}; + + EditUserDialog.prototype.close = function () { var self = this; $(self.getElement()).dialog("close"); diff --git a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js index 0508cd356ec81a5349624cb77e1b168e467553ed..725ef0f698ce69fcb64c28d396c6bc1ee438d6c1 100644 --- a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js @@ -66,7 +66,7 @@ MapsAdminPanel.prototype._createMenuRow = function () { content: '<span class="ui-icon ui-icon-refresh"></span> REFRESH', onclick: function () { return self.onRefreshClicked().then(null, GuiConnector.alert); - }, + } }); menuRow.appendChild(addProjectButton); menuRow.appendChild(refreshButton); @@ -77,36 +77,37 @@ MapsAdminPanel.prototype._createProjectTableRow = function () { var self = this; var projectsRow = Functions.createElement({ type: "div", - style: "display:table-row; width:100%", + style: "display:table-row; width:100%" }); var projectsTable = Functions.createElement({ type: "table", name: "projectsTable", className: "display", - style: "width:100%", + style: "width:100%" }); projectsRow.appendChild(projectsTable); + // noinspection JSUnusedGlobalSymbols $(projectsTable).DataTable({ fnRowCallback: function (nRow, aData) { nRow.setAttribute('id', aData[0]); }, columns: [{ - title: 'ProjectId', + title: 'ProjectId' }, { - title: 'Name', + title: 'Name' }, { - title: 'Disease', + title: 'Disease' }, { - title: 'Organism', + title: 'Organism' }, { - title: 'Status', + title: 'Status' }, { - title: 'Edit', + title: 'Edit' }, { - title: 'Remove', - },], + title: 'Remove' + }] }); $(projectsTable).on("click", "[name='removeProject']", function () { var button = this; diff --git a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js index c8951c68c983aa12220081b6f61b112bb8adf301..6ac46f3513d42db4f55faf5373032f099444af0a 100644 --- a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js @@ -1,9 +1,12 @@ "use strict"; var AbstractAdminPanel = require('./AbstractAdminPanel'); +var EditUserDialog = require('./EditUserDialog'); var Functions = require('../../Functions'); var GuiConnector = require('../../GuiConnector'); +// noinspection JSUnusedLocalSymbols +var logger = require('../../logger'); function UsersAdminPanel(params) { var self = this; @@ -79,7 +82,11 @@ UsersAdminPanel.prototype._createUsersTableRow = function () { }); projectsRow.appendChild(usersTable); + // noinspection JSUnusedGlobalSymbols $(usersTable).DataTable({ + fnRowCallback: function (nRow, aData) { + nRow.setAttribute('id', aData[0]); + }, columns: [{ title: 'Login' }, { @@ -107,6 +114,44 @@ UsersAdminPanel.prototype._createUsersTableRow = function () { return projectsRow; }; +UsersAdminPanel.prototype.showEditDialog = function (login) { + var self = this; + GuiConnector.showProcessing(); + return ServerConnector.getUser(login).then(function (user) { + return self.getDialog(user); + }).then(function (dialog) { + dialog.open(); + GuiConnector.hideProcessing(); + }).then(null, function (error) { + GuiConnector.hideProcessing(); + return Promise.reject(error); + }); +}; + +UsersAdminPanel.prototype.getDialog = function (user) { + var self = this; + if (self._dialogs === undefined) { + self._dialogs = []; + } + var dialog = self._dialogs[user.getLogin()]; + if (dialog === undefined) { + dialog = new EditUserDialog({ + element: Functions.createElement({ + type: "div" + }), + user: user, + project: self.getProject(), + customMap: null + }); + self._dialogs[user.getLogin()] = dialog; + return dialog.init().then(function () { + return dialog; + }); + } else { + return Promise.resolve(dialog); + } +}; + UsersAdminPanel.prototype.init = function () { var self = this; return ServerConnector.getUsers().then(function (users) { @@ -121,11 +166,36 @@ UsersAdminPanel.prototype.setUsers = function (users) { for (var i = 0; i < users.length; i++) { var user = users[i]; var rowData = self.userToTableRow(user); + self.addUpdateListener(user, rowData); data.push(rowData); } dataTable.clear().rows.add(data).draw(); }; +UsersAdminPanel.prototype.addUpdateListener = function (user, dataTableRow) { + var self = this; + + var listenerName = "USER_LIST_LISTENER"; + var listeners = user.getListeners("onreload"); + for (var i = 0; i < listeners.length; i++) { + if (listeners[i].listenerName === listenerName) { + user.removeListener("onreload", listeners[i]); + } + } + var listener = function () { + var login = user.getLogin().replace(".", "\\."); + self.userToTableRow(user, dataTableRow); + var row = $($("[name='usersTable']", self.getElement())[0]).DataTable().row("#" + login); + if (row.length > 0) { + row.data(dataTableRow).draw(); + } + + }; + listener.listenerName = listenerName; + user.addListener("onreload", listener); +}; + + UsersAdminPanel.prototype.userToTableRow = function (user, row) { if (row === undefined) { row = []; @@ -155,6 +225,13 @@ UsersAdminPanel.prototype.destroy = function () { if ($.fn.DataTable.isDataTable(table)) { $(table).DataTable().destroy(); } + + for (var key in self._dialogs) { + if (self._dialogs.hasOwnProperty(key)) { + self._dialogs[key].destroy(); + } + } + }; module.exports = UsersAdminPanel; diff --git a/frontend-js/src/main/js/map/data/User.js b/frontend-js/src/main/js/map/data/User.js index 410c37d506df89a17e14a410eb2183ca9cb16c17..09fc261d6ea549cd371f97dd65ab77202489c966 100644 --- a/frontend-js/src/main/js/map/data/User.js +++ b/frontend-js/src/main/js/map/data/User.js @@ -5,8 +5,14 @@ var logger = require('../../logger'); var UserPreferences = require('./UserPreferences'); +var ObjectWithListeners = require('../../ObjectWithListeners'); function User(javaObject) { + // call super constructor + ObjectWithListeners.call(this); + + this.registerListenerType("onreload"); + this.setLogin(javaObject.login); this.setName(javaObject.name); this.setSurname(javaObject.surname); @@ -19,6 +25,11 @@ function User(javaObject) { this.setSimpleColor(javaObject.simpleColor); } +// this class inherits from ObjectWithListeners class where generic methods for +// listeners are set +User.prototype = Object.create(ObjectWithListeners.prototype); +User.prototype.constructor = User; + User.prototype.setLogin = function (login) { this._login = login; }; @@ -83,6 +94,14 @@ User.prototype.getMaxColor = function () { return this._maxColor; }; +User.prototype.setPassword = function (password) { + this._password = password; +}; + +User.prototype.getPassword = function () { + return this._password; +}; + User.prototype.setPrivileges = function (privileges) { this._privileges = privileges; }; @@ -114,17 +133,44 @@ User.prototype.hasPrivilege = function (type, objectId) { return false; }; +User.prototype.privilegesToExport = function (configuration) { + var self = this; + var result = {}; + var validTypes = {}; + var i; + for (i = 0; i < configuration.getPrivilegeTypes().length; i++) { + validTypes[configuration.getPrivilegeTypes()[i].getName()] = true; + } + for (i = 0; i < self.getPrivileges().length; i++) { + var privilege = self.getPrivileges()[i]; + if (validTypes[privilege.type]) { + if (result[privilege.type] === undefined) { + result[privilege.type] = {}; + } + if (privilege.objectId !== undefined) { + result[privilege.type][privilege.objectId] = privilege.value; + } else { + result[privilege.type] = privilege.value; + } + } + } + return result; +}; + User.prototype.update = function (user) { - this.setLogin(user.getLogin()); - this.setName(user.getName()); - this.setSurname(user.getSurname()); - this.setEmail(user.getEmail()); - this.setRemoved(user.getRemoved()); - this.setPrivileges(user.getPrivileges()); - this.setPreferences(user.getPreferences()); - this.setMinColor(user.getMinColor()); - this.setMaxColor(user.getMaxColor()); - this.setSimpleColor(user.getSimpleColor()); + var self = this; + self.setLogin(user.getLogin()); + self.setName(user.getName()); + self.setSurname(user.getSurname()); + self.setEmail(user.getEmail()); + self.setRemoved(user.getRemoved()); + self.setPrivileges(user.getPrivileges()); + self.setPreferences(user.getPreferences()); + self.setMinColor(user.getMinColor()); + self.setMaxColor(user.getMaxColor()); + self.setSimpleColor(user.getSimpleColor()); + + return self.callListeners("onreload"); }; module.exports = User; 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 f249501a5387f657d534ce6c5591b4ccf1a52f96..afbb5f8dd65d187909bf4cff10388ce663ac2d4f 100644 --- a/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js @@ -6,8 +6,13 @@ require("../../mocha-config"); var EditUserDialog = require('../../../../main/js/gui/admin/EditUserDialog'); var User = require('../../../../main/js/map/data/User'); +var ValidationError = require('../../../../main/js/ValidationError'); + + +// noinspection JSUnusedLocalSymbols var logger = require('../../logger'); +// noinspection JSUnusedLocalSymbols var assert = require('assert'); describe('EditUserDialog', function () { @@ -32,4 +37,80 @@ describe('EditUserDialog', function () { }); }); + describe('checkValidity', function () { + it('empty user', function () { + var dialog; + var project; + var user = new User({}); + return ServerConnector.getProject().then(function (result) { + project = result; + dialog = new EditUserDialog({ + element: testDiv, + project: project, + user: user, + customMap: null + }); + return dialog.init(); + }).then(function () { + return dialog.checkValidity().then(function () { + assert.ok(null); + }, function (error) { + assert.ok(error instanceof ValidationError); + }); + }).then(function () { + dialog.destroy(); + }); + }); + + it('existing user', function () { + var dialog; + var project; + var user; + return ServerConnector.getUser("anonymous").then(function (result) { + user = result; + return ServerConnector.getProject(); + }).then(function (result) { + project = result; + dialog = new EditUserDialog({ + element: testDiv, + project: project, + user: user, + customMap: null + }); + return dialog.init(); + }).then(function () { + return dialog.checkValidity(); + }).then(function (result) { + assert.ok(result); + }).then(function () { + dialog.destroy(); + }); + }); + }); + + describe('onSaveClicked', function () { + it('existing user', function () { + var dialog; + var project; + var user; + return ServerConnector.getUser("anonymous").then(function (result) { + user = result; + return ServerConnector.getProject(); + }).then(function (result) { + project = result; + dialog = new EditUserDialog({ + element: testDiv, + project: project, + user: user, + customMap: null + }); + return dialog.init(); + }).then(function () { + return dialog.onSaveClicked(); + }).then(function () { + dialog.destroy(); + }); + }); + + }); }); diff --git a/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js b/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js index 6180140bef0ba0dc2cb9d1a798cd73a754079435..76764bcf97c1f5f4fa71fb9af829f71e5ab9e077 100644 --- a/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js +++ b/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js @@ -6,8 +6,10 @@ require("../../mocha-config"); var UsersAdminPanel = require('../../../../main/js/gui/admin/UsersAdminPanel'); +// noinspection JSUnusedLocalSymbols var logger = require('../../logger'); +// noinspection JSUnusedLocalSymbols var assert = require('assert'); describe('UsersAdminPanel', function () { @@ -50,4 +52,24 @@ describe('UsersAdminPanel', function () { }); }); + it('showEditDialog', function () { + var mapTab; + var project; + return ServerConnector.getProject().then(function (result) { + project = result; + return ServerConnector.getConfiguration(); + }).then(function (configuration) { + mapTab = new UsersAdminPanel({ + element: testDiv, + project: project, + configuration: configuration + }); + return mapTab.init(); + }).then(function () { + return mapTab.showEditDialog("anonymous"); + }).then(function () { + return mapTab.destroy(); + }); + }); + }); diff --git a/frontend-js/testFiles/apiCalls/users/anonymous/PATCH_token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/users/anonymous/PATCH_token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..ee0146adc4cef43f5f11fa07173a5f30de8fc712 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/users/anonymous/PATCH_token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"simpleColor":null,"privileges":[{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":18039},{"type":"USER_MANAGEMENT","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":10},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19186},{"type":"VIEW_PROJECT","value":1,"objectId":21},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19187},{"type":"VIEW_PROJECT","value":1,"objectId":1},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19184},{"type":"VIEW_PROJECT","value":1,"objectId":19},{"type":"CUSTOM_LAYOUTS","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":18039},{"type":"VIEW_PROJECT","value":1,"objectId":19102},{"type":"MANAGE_GENOMES","value":1},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":17051},{"type":"VIEW_PROJECT","value":1,"objectId":18305},{"type":"VIEW_PROJECT","value":1,"objectId":17},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":15763},{"type":"VIEW_PROJECT","value":1,"objectId":6},{"type":"VIEW_PROJECT","value":1,"objectId":15764},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":14898},{"type":"PROJECT_MANAGEMENT","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":17051},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19102},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":17051},{"type":"VIEW_PROJECT","value":1,"objectId":18115},{"type":"VIEW_PROJECT","value":1,"objectId":15763},{"type":"VIEW_PROJECT","value":1,"objectId":14898},{"type":"VIEW_PROJECT","value":1,"objectId":22},{"type":"VIEW_PROJECT","value":0,"objectId":19184},{"type":"VIEW_PROJECT","value":1,"objectId":20605},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":16668},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19103},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":14898},{"type":"CONFIGURATION_MANAGE","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":20},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":18115},{"type":"VIEW_PROJECT","value":1,"objectId":7},{"type":"VIEW_PROJECT","value":1,"objectId":18},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":15764},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":18115},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":16668},{"type":"VIEW_PROJECT","value":1,"objectId":19186},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":15764},{"type":"VIEW_PROJECT","value":1,"objectId":20603},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19103},{"type":"VIEW_PROJECT","value":1,"objectId":19187},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19184},{"type":"VIEW_PROJECT","value":1,"objectId":11},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19187},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":15763},{"type":"VIEW_PROJECT","value":1,"objectId":20604},{"type":"VIEW_PROJECT","value":1,"objectId":16668},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":18039},{"type":"LAYOUT_MANAGEMENT","value":0,"objectId":19102},{"type":"VIEW_PROJECT","value":1,"objectId":8},{"type":"ADD_MAP","value":0},{"type":"VIEW_PROJECT","value":1,"objectId":9},{"type":"VIEW_PROJECT","value":1,"objectId":19103},{"type":"EDIT_COMMENTS_PROJECT","value":0,"objectId":19186},{"type":"CUSTOM_LAYOUTS_AVAILABLE","value":0}],"preferences":{"element-required-annotations":{"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.Chemical":{"require-at-least-one":true,"annotation-list":["PUBCHEM_SUBSTANCE","PUBCHEM","CHEBI"]},"lcsb.mapviewer.model.map.species.Degraded":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.compartment.PathwayCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.species.SimpleMolecule":{"require-at-least-one":true,"annotation-list":["PUBCHEM_SUBSTANCE","PUBCHEM","CHEBI"]},"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.ReceptorProtein":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.Gene":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.compartment.OvalCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.Protein":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.BioEntity":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.species.GenericProtein":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.reaction.type.TransportReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.IonChannelProtein":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.Phenotype":{"require-at-least-one":true,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Drug":{"require-at-least-one":true,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Element":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.compartment.SquareCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Ion":{"require-at-least-one":true,"annotation-list":["PUBCHEM_SUBSTANCE","PUBCHEM","CHEBI"]},"lcsb.mapviewer.model.map.reaction.Reaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.AntisenseRna":{"require-at-least-one":true,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Complex":{"require-at-least-one":true,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Unknown":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.species.TruncatedProtein":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.compartment.Compartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Species":{"require-at-least-one":false,"annotation-list":[]},"lcsb.mapviewer.model.map.species.Rna":{"require-at-least-one":true,"annotation-list":["HGNC","HGNC_SYMBOL"]},"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]},"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":{"require-at-least-one":true,"annotation-list":["PUBMED"]}},"element-valid-annotations":{"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.Chemical":["PUBCHEM_SUBSTANCE","PUBMED","PUBCHEM","HMDB","CHEBI","KEGG_COMPOUND"],"lcsb.mapviewer.model.map.species.Degraded":["PUBMED"],"lcsb.mapviewer.model.map.compartment.PathwayCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.species.SimpleMolecule":["PUBCHEM_SUBSTANCE","PUBMED","PUBCHEM","HMDB","CHEBI","KEGG_COMPOUND"],"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.ReceptorProtein":["KEGG_GENES","INTERPRO","HGNC_SYMBOL","UNIPROT","CHEMBL_TARGET","ENSEMBL","PANTHER","EC","REFSEQ","PUBMED","HGNC","ENTREZ","MGD","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.Gene":["KEGG_GENES","REFSEQ","PUBMED","HGNC","HGNC_SYMBOL","UNIPROT","ENSEMBL","PANTHER","ENTREZ","MGD"],"lcsb.mapviewer.model.map.compartment.OvalCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.Protein":["KEGG_GENES","INTERPRO","HGNC_SYMBOL","UNIPROT","CHEMBL_TARGET","ENSEMBL","PANTHER","EC","REFSEQ","PUBMED","HGNC","ENTREZ","MGD","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.BioEntity":["PUBMED"],"lcsb.mapviewer.model.map.species.GenericProtein":["KEGG_GENES","INTERPRO","HGNC_SYMBOL","UNIPROT","CHEMBL_TARGET","ENSEMBL","PANTHER","EC","REFSEQ","PUBMED","HGNC","ENTREZ","MGD","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.reaction.type.TransportReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.IonChannelProtein":["KEGG_GENES","INTERPRO","HGNC_SYMBOL","UNIPROT","CHEMBL_TARGET","ENSEMBL","PANTHER","EC","REFSEQ","PUBMED","HGNC","ENTREZ","MGD","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.Phenotype":["PUBMED","OMIM","GO","MESH_2012"],"lcsb.mapviewer.model.map.species.Drug":["CHEMBL_COMPOUND","DRUGBANK","PUBMED","HMDB","CHEBI"],"lcsb.mapviewer.model.map.species.Element":["PUBMED"],"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.compartment.SquareCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.species.Ion":["PUBCHEM_SUBSTANCE","PUBMED","PUBCHEM","HMDB","CHEBI","KEGG_COMPOUND"],"lcsb.mapviewer.model.map.reaction.Reaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.AntisenseRna":["PUBMED"],"lcsb.mapviewer.model.map.species.Complex":["EC","PUBMED","INTERPRO","CHEMBL_TARGET","GO","MESH_2012"],"lcsb.mapviewer.model.map.species.Unknown":["PUBMED"],"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.species.TruncatedProtein":["KEGG_GENES","INTERPRO","HGNC_SYMBOL","UNIPROT","CHEMBL_TARGET","ENSEMBL","PANTHER","EC","REFSEQ","PUBMED","HGNC","ENTREZ","MGD","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.compartment.Compartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":["PUBMED","GO","MESH_2012"],"lcsb.mapviewer.model.map.species.Species":["PUBMED"],"lcsb.mapviewer.model.map.species.Rna":["KEGG_GENES","REFSEQ","PUBMED","HGNC","HGNC_SYMBOL","UNIPROT","ENSEMBL","PANTHER","ENTREZ","MGD"],"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"],"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":["PUBMED","COG","KEGG_REACTION","REACTOME","KEGG_PATHWAY"]},"element-annotators":{"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":[],"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":[],"lcsb.mapviewer.model.map.species.Chemical":["Chebi"],"lcsb.mapviewer.model.map.species.Degraded":[],"lcsb.mapviewer.model.map.compartment.PathwayCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.species.SimpleMolecule":["Chebi"],"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":[],"lcsb.mapviewer.model.map.species.ReceptorProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":[],"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":[],"lcsb.mapviewer.model.map.species.Gene":["HGNC"],"lcsb.mapviewer.model.map.compartment.OvalCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":[],"lcsb.mapviewer.model.map.species.Protein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":[],"lcsb.mapviewer.model.map.BioEntity":[],"lcsb.mapviewer.model.map.species.GenericProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.reaction.type.TransportReaction":[],"lcsb.mapviewer.model.map.species.IonChannelProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":[],"lcsb.mapviewer.model.map.species.Phenotype":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Drug":[],"lcsb.mapviewer.model.map.species.Element":[],"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":[],"lcsb.mapviewer.model.map.compartment.SquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Ion":["Chebi"],"lcsb.mapviewer.model.map.reaction.Reaction":[],"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":[],"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":[],"lcsb.mapviewer.model.map.species.AntisenseRna":[],"lcsb.mapviewer.model.map.species.Complex":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Unknown":[],"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":[],"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":[],"lcsb.mapviewer.model.map.species.TruncatedProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.compartment.Compartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Species":[],"lcsb.mapviewer.model.map.species.Rna":["HGNC"],"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":[],"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":[]},"project-upload":{"auto-resize":true,"sbgn":false,"cache-data":false,"semantic-zooming":false,"annotate-model":false,"validate-miriam":false}},"removed":false,"surname":"","minColor":null,"name":"","maxColor":null,"id":3,"login":"anonymous","email":""} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java index 36b1d4ee8681a1c420e78f6fe1b36da28ab4a9ed..787825759efd3dd3b7f0c8964d6e907a78418da9 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java @@ -30,6 +30,7 @@ import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.view.AuthenticationToken; +import lcsb.mapviewer.services.view.LayoutView; @RestController public class UserController extends BaseController { @@ -143,6 +144,18 @@ public class UserController extends BaseController { return result; } + @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.PATCH }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> updateUser(// + @RequestBody String body, // + @PathVariable(value = "login") String login, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, QueryException, IOException { + Map<String, Object> node = parseBody(body); + Map<String, Object> data = getData(node, "user"); + return userRest.updateUser(token, login, data); + } + + /** * @return the userService * @see #userService diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java index b3dbe1354330db2b53e19797776072ead5ffca71..5f6f44c17e084542f839f0c170bb82d2aa57c4d2 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java @@ -16,6 +16,7 @@ import lcsb.mapviewer.api.ObjectNotFoundException; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.layout.Layout; import lcsb.mapviewer.model.user.BasicPrivilege; import lcsb.mapviewer.model.user.ObjectPrivilege; import lcsb.mapviewer.model.user.PrivilegeType; @@ -27,377 +28,424 @@ import lcsb.mapviewer.model.user.UserClassValidAnnotations; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.interfaces.ILayoutService; import lcsb.mapviewer.services.view.AuthenticationToken; +import lcsb.mapviewer.services.view.LayoutView; @Transactional(value = "txManager") public class UserRestImpl extends BaseRestImpl { - /** - * Default class logger. - */ - @SuppressWarnings("unused") - private Logger logger = Logger.getLogger(UserRestImpl.class); - - @Autowired - private ILayoutService layoutService; - - public Map<String, Object> getUser(String token, String login, String columns) throws SecurityException, ObjectNotFoundException { - User ownUserData = getUserService().getUserByToken(token); - - Set<String> columnSet = createUserColumnSet(columns); - - boolean isAdmin = getUserService().userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT); - - if (ownUserData.getLogin().equals(login) || isAdmin) { - User user = getUserService().getUserByLogin(login); - if (user == null) { - throw new ObjectNotFoundException("User doesn't exist"); - } - return prepareUse(user, columnSet, isAdmin); - } else { - throw new SecurityException("You cannot access data of the user with given id"); - } - } - - private Set<String> createUserColumnSet(String columns) { - Set<String> columnsSet = new HashSet<>(); - if (columns.equals("")) { - columnsSet.add("id"); - columnsSet.add("login"); - columnsSet.add("name"); - columnsSet.add("surname"); - columnsSet.add("email"); - columnsSet.add("minColor"); - columnsSet.add("maxColor"); - columnsSet.add("simpleColor"); - columnsSet.add("removed"); - columnsSet.add("privileges"); - columnsSet.add("preferences"); - } else { - for (String str : columns.split(",")) { - columnsSet.add(str); - } - } - return columnsSet; - } - - private Map<String, Object> prepareUse(User user, Set<String> columnsSet, boolean admin) { - Map<String, Object> result = new HashMap<>(); - for (String string : columnsSet) { - String column = string.toLowerCase(); - Object value = null; - if (column.equals("id") || column.equals("idobject")) { - value = user.getId(); - } else if (column.equals("name")) { - value = user.getName(); - } else if (column.equals("surname")) { - value = user.getSurname(); - } else if (column.equals("login")) { - value = user.getLogin(); - } else if (column.equals("email")) { - value = user.getEmail(); - } else if (column.equals("mincolor")) { - value = user.getMinColor(); - } else if (column.equals("maxcolor")) { - value = user.getMaxColor(); - } else if (column.equals("simplecolor")) { - value = user.getSimpleColor(); - } else if (column.equals("removed")) { - value = user.isRemoved(); - } else if (column.equals("privileges") && admin) { - value = preparePrivileges(user); - } else if (column.equals("preferences")) { - value = preparePreferences(user); - } else { - value = "Unknown column"; - } - result.put(string, value); - } - return result; - } - - private Map<String, Object> preparePreferences(User user) { - Map<String, Object> result = new HashMap<>(); - UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(user); - result.put("project-upload", prepareProjectUploadPreferences(schema)); - result.put("element-annotators", prepareElementAnnotators(schema.getClassAnnotators())); - result.put("element-required-annotations", prepareRequiredAnnotations(schema.getClassRequiredAnnotators())); - result.put("element-valid-annotations", prepareValidAnnotations(schema.getClassValidAnnotators())); - return result; - } - - private Map<String, Object> prepareValidAnnotations(List<UserClassValidAnnotations> classValidAnnotators) { - Map<String, Object> result = new HashMap<>(); - for (UserClassValidAnnotations userClassAnnotators : classValidAnnotators) { - result.put(userClassAnnotators.getClassName(), new ArrayList<>(userClassAnnotators.getValidMiriamTypes())); - } - return result; - } - - private void updateValidAnnotations(UserAnnotationSchema schema, Map<String, Object> data) { - for (String key : data.keySet()) { - UserClassValidAnnotations annotator = null; - for (UserClassValidAnnotations userClassAnnotators : schema.getClassValidAnnotators()) { - if (userClassAnnotators.getClassName().equals(key)) { - annotator = userClassAnnotators; - } - } - if (annotator == null) { - annotator = new UserClassValidAnnotations(); - annotator.setClassName(key); - schema.addClassValidAnnotations(annotator); - } - annotator.getValidMiriamTypes().clear(); - for (Object row : (List<?>) data.get(key)) { - annotator.getValidMiriamTypes().add(MiriamType.valueOf((String) row)); - } - } - } - - private Map<String, Object> prepareRequiredAnnotations(List<UserClassRequiredAnnotations> classRequiredAnnotators) { - Map<String, Object> result = new HashMap<>(); - for (UserClassRequiredAnnotations requiredAnnotations : classRequiredAnnotators) { - Map<String, Object> row = new HashMap<>(); - row.put("require-at-least-one", requiredAnnotations.getRequireAtLeastOneAnnotation()); - List<String> miriamTypes = new ArrayList<>(); - - for (MiriamType mt : requiredAnnotations.getRequiredMiriamTypes()) { - miriamTypes.add(mt.name()); - } - row.put("annotation-list", miriamTypes); - result.put(requiredAnnotations.getClassName(), row); - } - return result; - } - - private void updateRequiredAnnotations(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException { - for (String key : data.keySet()) { - UserClassRequiredAnnotations annotator = null; - for (UserClassRequiredAnnotations userClassAnnotators : schema.getClassRequiredAnnotators()) { - if (userClassAnnotators.getClassName().equals(key)) { - annotator = userClassAnnotators; - } - } - if (annotator == null) { - annotator = new UserClassRequiredAnnotations(); - annotator.setClassName(key); - schema.addClassRequiredAnnotations(annotator); - } - updateAnnotator(annotator, (Map<String, Object>) data.get(key)); - } - } - - private void updateAnnotator(UserClassRequiredAnnotations annotator, Map<String, Object> data) throws QueryException { - for (String key : data.keySet()) { - if (key.equals("require-at-least-one")) { - annotator.setRequireAtLeastOneAnnotation((Boolean) data.get("require-at-least-one")); - } else if (key.equals("annotation-list")) { - annotator.getRequiredMiriamTypes().clear(); - for (Object row : (List<?>) data.get(key)) { - annotator.getRequiredMiriamTypes().add(MiriamType.valueOf((String) row)); - } - } else { - throw new QueryException("Unknown field: " + key); - } - } - - } - - private Map<String, Object> prepareElementAnnotators(List<UserClassAnnotators> classAnnotators) { - Map<String, Object> result = new HashMap<>(); - for (UserClassAnnotators userClassAnnotators : classAnnotators) { - result.put(userClassAnnotators.getClassName(), new ArrayList<>(userClassAnnotators.getAnnotators())); - } - return result; - } - - private void updateElementAnnotators(UserAnnotationSchema schema, Map<String, Object> data) { - for (String key : data.keySet()) { - UserClassAnnotators annotator = null; - for (UserClassAnnotators userClassAnnotators : schema.getClassAnnotators()) { - if (userClassAnnotators.getClassName().equals(key)) { - annotator = userClassAnnotators; - } - } - if (annotator == null) { - annotator = new UserClassAnnotators(); - annotator.setClassName(key); - schema.addClassAnnotator(annotator); - } - annotator.getAnnotators().clear(); - annotator.getAnnotators().addAll((List<String>) data.get(key)); - } - } - - private Map<String, Object> prepareProjectUploadPreferences(UserAnnotationSchema schema) { - Map<String, Object> result = new HashMap<>(); - result.put("validate-miriam", schema.getValidateMiriamTypes()); - result.put("annotate-model", schema.getAnnotateModel()); - result.put("cache-data", schema.getCacheData()); - result.put("auto-resize", schema.getAutoResizeMap()); - result.put("semantic-zooming", schema.getSemanticZooming()); - result.put("sbgn", schema.getSbgnFormat()); - return result; - } - - private List<Map<String, Object>> preparePrivileges(User user) { - List<Map<String, Object>> result = new ArrayList<>(); - for (BasicPrivilege privilege : user.getPrivileges()) { - if (privilege instanceof ObjectPrivilege) { - result.add(prepareObjectPrivilege((ObjectPrivilege) privilege)); - } else { - result.add(prepareBasicPrivilege(privilege)); - } - } - Map<String, Object> customLayouts = new HashMap<>(); - customLayouts.put("type", "CUSTOM_LAYOUTS_AVAILABLE"); - customLayouts.put("value", layoutService.getAvailableCustomLayoutsNumber(user)); - result.add(customLayouts); - return result; - } - - private Map<String, Object> prepareObjectPrivilege(ObjectPrivilege privilege) { - Map<String, Object> result = new HashMap<>(); - result.put("type", privilege.getType()); - result.put("value", privilege.getLevel()); - result.put("objectId", privilege.getIdObject()); - return result; - } - - private Map<String, Object> prepareBasicPrivilege(BasicPrivilege privilege) { - Map<String, Object> result = new HashMap<>(); - if (privilege.getClass().equals(BasicPrivilege.class)) { - result.put("type", privilege.getType()); - result.put("value", privilege.getLevel()); - return result; - } else { - throw new InvalidArgumentException("Don't know how to handle class: " + privilege.getClass()); - } - } - - /** - * @return the layoutService - * @see #layoutService - */ - public ILayoutService getLayoutService() { - return layoutService; - } - - /** - * @param layoutService - * the layoutService to set - * @see #layoutService - */ - public void setLayoutService(ILayoutService layoutService) { - this.layoutService = layoutService; - } - - public List<Map<String, Object>> getUsers(String token, String columns) throws SecurityException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - User ownUserData = getUserService().getUserByToken(token); - boolean isAdmin = getUserService().userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT); - - Set<String> columnSet = createUserColumnSet(columns); - - List<Map<String, Object>> result = new ArrayList<>(); - for (User user : getUserService().getUsers(authenticationToken)) { - result.add(prepareUse(user, columnSet, isAdmin)); - } - return result; - } - - public Map<String, Object> updatePrivileges(String token, String login, Map<String, Object> privilegesData) throws SecurityException, QueryException { - if (privilegesData == null) { - throw new QueryException("Privileges not defined"); - } - try { - AuthenticationToken authenticationToken = getUserService().getToken(token); - User modifiedUser = getUserService().getUserByLogin(login); - - for (String key : privilegesData.keySet()) { - Object value = privilegesData.get(key); - - PrivilegeType type = PrivilegeType.valueOf(key); - - if (type.getPrivilegeClassType().equals(BasicPrivilege.class)) { - getUserService().setUserPrivilege(modifiedUser, type, value, authenticationToken); - } else if (type.getPrivilegeClassType().equals(ObjectPrivilege.class)) { - if (value instanceof Map) { - Map<?, ?> objects = (Map<?, ?>) value; - for (Object objectId : objects.keySet()) { - getUserService().setUserPrivilege(modifiedUser, type, objects.get(objectId), Integer.valueOf((String) objectId), authenticationToken); - } - } else { - throw new QueryException("Invalid value for privilege: " + key); - } - } else { - throw new QueryException("Unknown privilege type: " + key); - } - - } - return getUser(token, login, ""); - } catch (IllegalArgumentException e) { - throw new QueryException("Invalid input", e); - } - } - - public Map<String, Object> updatePreferences(String token, String login, Map<String, Object> preferencesData) throws SecurityException, QueryException { - if (preferencesData == null) { - throw new QueryException("Preferences not defined"); - } - try { - AuthenticationToken authenticationToken = getUserService().getToken(token); - User modifiedUser = getUserService().getUserByLogin(login); - if (modifiedUser == null) { - throw new ObjectNotFoundException("User doesn't exist"); - } - - UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(modifiedUser); - - for (String key : preferencesData.keySet()) { - Map<String, Object> value = (Map<String, Object>) preferencesData.get(key); - - if (key.equals("project-upload")) { - updateUploadPreferences(schema, value); - } else if (key.equals("element-annotators")) { - updateElementAnnotators(schema, value); - } else if (key.equals("element-required-annotations")) { - updateRequiredAnnotations(schema, value); - } else if (key.equals("element-valid-annotations")) { - updateValidAnnotations(schema, value); - } else { - throw new QueryException("Unknown preferences field: " + key); - } - } - modifiedUser.setAnnotationSchema(schema); - getUserService().updateUser(modifiedUser, authenticationToken); - return getUser(token, login, ""); - } catch (IllegalArgumentException e) { - throw new QueryException("Invalid input", e); - } - } - - private void updateUploadPreferences(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException { - for (String key : data.keySet()) { - Boolean value = (Boolean) data.get(key); - if (value != null) { - if (key.equals("validate-miriam")) { - schema.setValidateMiriamTypes(value); - } else if (key.equals("annotate-model")) { - schema.setAnnotateModel(value); - } else if (key.equals("cache-data")) { - schema.setCacheData(value); - } else if (key.equals("auto-resize")) { - schema.setAutoResizeMap(value); - } else if (key.equals("semantic-zooming")) { - schema.setSemanticZooming(value); - } else if (key.equals("sbgn")) { - schema.setSbgnFormat(value); - } else { - throw new QueryException("Unknown upload preference field: " + key); - } - } - } - - } + /** + * Default class logger. + */ + @SuppressWarnings("unused") + private Logger logger = Logger.getLogger(UserRestImpl.class); + + @Autowired + private ILayoutService layoutService; + + public Map<String, Object> getUser(String token, String login, String columns) + throws SecurityException, ObjectNotFoundException { + User ownUserData = getUserService().getUserByToken(token); + + Set<String> columnSet = createUserColumnSet(columns); + + boolean isAdmin = getUserService().userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT); + + if (ownUserData.getLogin().equals(login) || isAdmin) { + User user = getUserService().getUserByLogin(login); + if (user == null) { + throw new ObjectNotFoundException("User doesn't exist"); + } + return prepareUse(user, columnSet, isAdmin); + } else { + throw new SecurityException("You cannot access data of the user with given id"); + } + } + + private Set<String> createUserColumnSet(String columns) { + Set<String> columnsSet = new HashSet<>(); + if (columns.equals("")) { + columnsSet.add("id"); + columnsSet.add("login"); + columnsSet.add("name"); + columnsSet.add("surname"); + columnsSet.add("email"); + columnsSet.add("minColor"); + columnsSet.add("maxColor"); + columnsSet.add("simpleColor"); + columnsSet.add("removed"); + columnsSet.add("privileges"); + columnsSet.add("preferences"); + } else { + for (String str : columns.split(",")) { + columnsSet.add(str); + } + } + return columnsSet; + } + + private Map<String, Object> prepareUse(User user, Set<String> columnsSet, boolean admin) { + Map<String, Object> result = new HashMap<>(); + for (String string : columnsSet) { + String column = string.toLowerCase(); + Object value = null; + if (column.equals("id") || column.equals("idobject")) { + value = user.getId(); + } else if (column.equals("name")) { + value = user.getName(); + } else if (column.equals("surname")) { + value = user.getSurname(); + } else if (column.equals("login")) { + value = user.getLogin(); + } else if (column.equals("email")) { + value = user.getEmail(); + } else if (column.equals("mincolor")) { + value = user.getMinColor(); + } else if (column.equals("maxcolor")) { + value = user.getMaxColor(); + } else if (column.equals("simplecolor")) { + value = user.getSimpleColor(); + } else if (column.equals("removed")) { + value = user.isRemoved(); + } else if (column.equals("privileges") && admin) { + value = preparePrivileges(user); + } else if (column.equals("preferences")) { + value = preparePreferences(user); + } else { + value = "Unknown column"; + } + result.put(string, value); + } + return result; + } + + private Map<String, Object> preparePreferences(User user) { + Map<String, Object> result = new HashMap<>(); + UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(user); + result.put("project-upload", prepareProjectUploadPreferences(schema)); + result.put("element-annotators", prepareElementAnnotators(schema.getClassAnnotators())); + result.put("element-required-annotations", prepareRequiredAnnotations(schema.getClassRequiredAnnotators())); + result.put("element-valid-annotations", prepareValidAnnotations(schema.getClassValidAnnotators())); + return result; + } + + private Map<String, Object> prepareValidAnnotations(List<UserClassValidAnnotations> classValidAnnotators) { + Map<String, Object> result = new HashMap<>(); + for (UserClassValidAnnotations userClassAnnotators : classValidAnnotators) { + result.put(userClassAnnotators.getClassName(), new ArrayList<>(userClassAnnotators.getValidMiriamTypes())); + } + return result; + } + + private void updateValidAnnotations(UserAnnotationSchema schema, Map<String, Object> data) { + for (String key : data.keySet()) { + UserClassValidAnnotations annotator = null; + for (UserClassValidAnnotations userClassAnnotators : schema.getClassValidAnnotators()) { + if (userClassAnnotators.getClassName().equals(key)) { + annotator = userClassAnnotators; + } + } + if (annotator == null) { + annotator = new UserClassValidAnnotations(); + annotator.setClassName(key); + schema.addClassValidAnnotations(annotator); + } + annotator.getValidMiriamTypes().clear(); + for (Object row : (List<?>) data.get(key)) { + annotator.getValidMiriamTypes().add(MiriamType.valueOf((String) row)); + } + } + } + + private Map<String, Object> prepareRequiredAnnotations(List<UserClassRequiredAnnotations> classRequiredAnnotators) { + Map<String, Object> result = new HashMap<>(); + for (UserClassRequiredAnnotations requiredAnnotations : classRequiredAnnotators) { + Map<String, Object> row = new HashMap<>(); + row.put("require-at-least-one", requiredAnnotations.getRequireAtLeastOneAnnotation()); + List<String> miriamTypes = new ArrayList<>(); + + for (MiriamType mt : requiredAnnotations.getRequiredMiriamTypes()) { + miriamTypes.add(mt.name()); + } + row.put("annotation-list", miriamTypes); + result.put(requiredAnnotations.getClassName(), row); + } + return result; + } + + private void updateRequiredAnnotations(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException { + for (String key : data.keySet()) { + UserClassRequiredAnnotations annotator = null; + for (UserClassRequiredAnnotations userClassAnnotators : schema.getClassRequiredAnnotators()) { + if (userClassAnnotators.getClassName().equals(key)) { + annotator = userClassAnnotators; + } + } + if (annotator == null) { + annotator = new UserClassRequiredAnnotations(); + annotator.setClassName(key); + schema.addClassRequiredAnnotations(annotator); + } + updateAnnotator(annotator, (Map<String, Object>) data.get(key)); + } + } + + private void updateAnnotator(UserClassRequiredAnnotations annotator, Map<String, Object> data) throws QueryException { + for (String key : data.keySet()) { + if (key.equals("require-at-least-one")) { + annotator.setRequireAtLeastOneAnnotation((Boolean) data.get("require-at-least-one")); + } else if (key.equals("annotation-list")) { + annotator.getRequiredMiriamTypes().clear(); + for (Object row : (List<?>) data.get(key)) { + annotator.getRequiredMiriamTypes().add(MiriamType.valueOf((String) row)); + } + } else { + throw new QueryException("Unknown field: " + key); + } + } + + } + + private Map<String, Object> prepareElementAnnotators(List<UserClassAnnotators> classAnnotators) { + Map<String, Object> result = new HashMap<>(); + for (UserClassAnnotators userClassAnnotators : classAnnotators) { + result.put(userClassAnnotators.getClassName(), new ArrayList<>(userClassAnnotators.getAnnotators())); + } + return result; + } + + private void updateElementAnnotators(UserAnnotationSchema schema, Map<String, Object> data) { + for (String key : data.keySet()) { + UserClassAnnotators annotator = null; + for (UserClassAnnotators userClassAnnotators : schema.getClassAnnotators()) { + if (userClassAnnotators.getClassName().equals(key)) { + annotator = userClassAnnotators; + } + } + if (annotator == null) { + annotator = new UserClassAnnotators(); + annotator.setClassName(key); + schema.addClassAnnotator(annotator); + } + annotator.getAnnotators().clear(); + annotator.getAnnotators().addAll((List<String>) data.get(key)); + } + } + + private Map<String, Object> prepareProjectUploadPreferences(UserAnnotationSchema schema) { + Map<String, Object> result = new HashMap<>(); + result.put("validate-miriam", schema.getValidateMiriamTypes()); + result.put("annotate-model", schema.getAnnotateModel()); + result.put("cache-data", schema.getCacheData()); + result.put("auto-resize", schema.getAutoResizeMap()); + result.put("semantic-zooming", schema.getSemanticZooming()); + result.put("sbgn", schema.getSbgnFormat()); + return result; + } + + private List<Map<String, Object>> preparePrivileges(User user) { + List<Map<String, Object>> result = new ArrayList<>(); + for (BasicPrivilege privilege : user.getPrivileges()) { + if (privilege instanceof ObjectPrivilege) { + result.add(prepareObjectPrivilege((ObjectPrivilege) privilege)); + } else { + result.add(prepareBasicPrivilege(privilege)); + } + } + Map<String, Object> customLayouts = new HashMap<>(); + customLayouts.put("type", "CUSTOM_LAYOUTS_AVAILABLE"); + customLayouts.put("value", layoutService.getAvailableCustomLayoutsNumber(user)); + result.add(customLayouts); + return result; + } + + private Map<String, Object> prepareObjectPrivilege(ObjectPrivilege privilege) { + Map<String, Object> result = new HashMap<>(); + result.put("type", privilege.getType()); + result.put("value", privilege.getLevel()); + result.put("objectId", privilege.getIdObject()); + return result; + } + + private Map<String, Object> prepareBasicPrivilege(BasicPrivilege privilege) { + Map<String, Object> result = new HashMap<>(); + if (privilege.getClass().equals(BasicPrivilege.class)) { + result.put("type", privilege.getType()); + result.put("value", privilege.getLevel()); + return result; + } else { + throw new InvalidArgumentException("Don't know how to handle class: " + privilege.getClass()); + } + } + + /** + * @return the layoutService + * @see #layoutService + */ + public ILayoutService getLayoutService() { + return layoutService; + } + + /** + * @param layoutService + * the layoutService to set + * @see #layoutService + */ + public void setLayoutService(ILayoutService layoutService) { + this.layoutService = layoutService; + } + + public List<Map<String, Object>> getUsers(String token, String columns) throws SecurityException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + User ownUserData = getUserService().getUserByToken(token); + boolean isAdmin = getUserService().userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT); + + Set<String> columnSet = createUserColumnSet(columns); + + List<Map<String, Object>> result = new ArrayList<>(); + for (User user : getUserService().getUsers(authenticationToken)) { + result.add(prepareUse(user, columnSet, isAdmin)); + } + return result; + } + + public Map<String, Object> updatePrivileges(String token, String login, Map<String, Object> privilegesData) + throws SecurityException, QueryException { + if (privilegesData == null) { + throw new QueryException("Privileges not defined"); + } + try { + AuthenticationToken authenticationToken = getUserService().getToken(token); + User modifiedUser = getUserService().getUserByLogin(login); + + for (String key : privilegesData.keySet()) { + Object value = privilegesData.get(key); + + PrivilegeType type = PrivilegeType.valueOf(key); + + if (type.getPrivilegeClassType().equals(BasicPrivilege.class)) { + getUserService().setUserPrivilege(modifiedUser, type, value, authenticationToken); + } else if (type.getPrivilegeClassType().equals(ObjectPrivilege.class)) { + if (value instanceof Map) { + Map<?, ?> objects = (Map<?, ?>) value; + for (Object objectId : objects.keySet()) { + getUserService().setUserPrivilege(modifiedUser, type, objects.get(objectId), + Integer.valueOf((String) objectId), authenticationToken); + } + } else { + throw new QueryException("Invalid value for privilege: " + key); + } + } else { + throw new QueryException("Unknown privilege type: " + key); + } + + } + return getUser(token, login, ""); + } catch (IllegalArgumentException e) { + throw new QueryException("Invalid input", e); + } + } + + public Map<String, Object> updatePreferences(String token, String login, Map<String, Object> preferencesData) + throws SecurityException, QueryException { + if (preferencesData == null) { + throw new QueryException("Preferences not defined"); + } + try { + AuthenticationToken authenticationToken = getUserService().getToken(token); + User modifiedUser = getUserService().getUserByLogin(login); + if (modifiedUser == null) { + throw new ObjectNotFoundException("User doesn't exist"); + } + + UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(modifiedUser); + + for (String key : preferencesData.keySet()) { + Map<String, Object> value = (Map<String, Object>) preferencesData.get(key); + + if (key.equals("project-upload")) { + updateUploadPreferences(schema, value); + } else if (key.equals("element-annotators")) { + updateElementAnnotators(schema, value); + } else if (key.equals("element-required-annotations")) { + updateRequiredAnnotations(schema, value); + } else if (key.equals("element-valid-annotations")) { + updateValidAnnotations(schema, value); + } else { + throw new QueryException("Unknown preferences field: " + key); + } + } + modifiedUser.setAnnotationSchema(schema); + getUserService().updateUser(modifiedUser, authenticationToken); + return getUser(token, login, ""); + } catch (IllegalArgumentException e) { + throw new QueryException("Invalid input", e); + } + } + + private void updateUploadPreferences(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException { + for (String key : data.keySet()) { + Boolean value = (Boolean) data.get(key); + if (value != null) { + if (key.equals("validate-miriam")) { + schema.setValidateMiriamTypes(value); + } else if (key.equals("annotate-model")) { + schema.setAnnotateModel(value); + } else if (key.equals("cache-data")) { + schema.setCacheData(value); + } else if (key.equals("auto-resize")) { + schema.setAutoResizeMap(value); + } else if (key.equals("semantic-zooming")) { + schema.setSemanticZooming(value); + } else if (key.equals("sbgn")) { + schema.setSbgnFormat(value); + } else { + throw new QueryException("Unknown upload preference field: " + key); + } + } + } + + } + + public Map<String, Object> updateUser(String token, String login, Map<String, Object> userData) + throws QueryException, SecurityException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + if (userData == null) { + throw new QueryException("user field cannot be undefined"); + } + User user = getUserService().getUserByLogin(login); + if (user == null) { + throw new ObjectNotFoundException("user doesn't exist"); + } + boolean isAdmin = getUserService().userHasPrivilege(authenticationToken, PrivilegeType.USER_MANAGEMENT); + if (!isAdmin && !login.equalsIgnoreCase(getUserService().getUserByToken(token).getLogin())) { + throw new SecurityException("Access denied"); + } + for (String key : userData.keySet()) { + Object value = userData.get(key); + String stringValue = null; + if (value instanceof String) { + stringValue = (String) value; + } + if (key.equalsIgnoreCase("name")) { + user.setName(stringValue); + } else if (key.equalsIgnoreCase("surname")) { + user.setSurname(stringValue); + } else if (key.equalsIgnoreCase("email")) { + user.setEmail(stringValue); + } else if (key.equalsIgnoreCase("password")) { + if (stringValue != null && !stringValue.trim().isEmpty()) { + user.setCryptedPassword(getUserService().encodePassword(stringValue)); + } + } else if (key.equalsIgnoreCase("login")) { + if (!user.getLogin().equals((String) value)) { + throw new QueryException("login cannot be modified"); + } + } else { + throw new QueryException("Unknown parameter: " + key); + } + } + getUserService().updateUser(user); + return getUser(token, login, ""); + } }