From ab38f9d690b23f0ee6580e83affc6a1d5a023473 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 13 Oct 2017 15:48:36 +0200 Subject: [PATCH] adding new users implemented --- frontend-js/.idea/frontend-js.iml | 3 + frontend-js/src/main/js/Admin.js | 227 +++++++++--------- frontend-js/src/main/js/ServerConnector.js | 25 +- .../src/main/js/gui/admin/EditUserDialog.js | 35 ++- .../src/main/js/gui/admin/UsersAdminPanel.js | 14 ++ .../test/js/gui/admin/UserAdminPanel-test.js | 20 ++ .../java/lcsb/mapviewer/api/BaseRestImpl.java | 10 + .../api/projects/ProjectRestImpl.java | 10 - .../mapviewer/api/users/UserController.java | 14 +- .../mapviewer/api/users/UserRestImpl.java | 41 +++- 10 files changed, 262 insertions(+), 137 deletions(-) diff --git a/frontend-js/.idea/frontend-js.iml b/frontend-js/.idea/frontend-js.iml index 7d104eaca0..26f5495ad6 100644 --- a/frontend-js/.idea/frontend-js.iml +++ b/frontend-js/.idea/frontend-js.iml @@ -4,8 +4,11 @@ <content url="file://$MODULE_DIR$"> <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" /> <excludeFolder url="file://$MODULE_DIR$/.tmp" /> + <excludeFolder url="file://$MODULE_DIR$/coverage" /> <excludeFolder url="file://$MODULE_DIR$/dist" /> + <excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/temp" /> + <excludeFolder url="file://$MODULE_DIR$/testFiles" /> <excludeFolder url="file://$MODULE_DIR$/tmp" /> </content> <orderEntry type="inheritedJdk" /> diff --git a/frontend-js/src/main/js/Admin.js b/frontend-js/src/main/js/Admin.js index b492db71a5..d1b6113aca 100644 --- a/frontend-js/src/main/js/Admin.js +++ b/frontend-js/src/main/js/Admin.js @@ -12,9 +12,9 @@ var ObjectWithListeners = require('./ObjectWithListeners'); var CommentsAdminPanel = require('./gui/admin/CommentsAdminPanel'); var ConfigurationAdminPanel = require('./gui/admin/ConfigurationAdminPanel'); var MapsAdminPanel = require('./gui/admin/MapsAdminPanel'); -var ServicesAdminPanel = require('./gui/admin/ServicesAdminPanel'); var UsersAdminPanel = require('./gui/admin/UsersAdminPanel'); +// noinspection JSUnusedLocalSymbols var logger = require('./logger'); var Functions = require('./Functions'); @@ -26,163 +26,160 @@ var Functions = require('./Functions'); * creation */ function Admin(options) { - var self = this; - self._panels = []; - self._tabIdCount = 0; - if (!(options instanceof CustomMapOptions)) { - options = new CustomMapOptions(options); - } - self.setProject(options.getProject()); - self.setElement(options.getElement()); - - self.setConfiguration(options.getConfiguration()); - self.setGuiUtils(new GuiUtils()); - self._createGui(); + var self = this; + self._panels = []; + self._tabIdCount = 0; + if (!(options instanceof CustomMapOptions)) { + options = new CustomMapOptions(options); + } + self.setProject(options.getProject()); + self.setElement(options.getElement()); + + self.setConfiguration(options.getConfiguration()); + self.setGuiUtils(new GuiUtils()); + self._createGui(); } Admin.prototype = Object.create(ObjectWithListeners.prototype); Admin.prototype.constructor = ObjectWithListeners; Admin.prototype._createGui = function () { - var self = this; - self.getElement().innerHTML = ""; - var headerDiv = Functions.createElement({ - type: "div" - }); - self.setHeader(new Header({ - element: headerDiv, - customMap: null, - project: self.getProject(), - adminLink: false, - })); - self.getElement().appendChild(headerDiv); - - var panels = [{ - name: "COMMENTS", - panelClass: CommentsAdminPanel, - }, { - name: "PROJECTS", - panelClass: MapsAdminPanel, - }, { - name: "USERS", - panelClass: UsersAdminPanel, - }, { - name: "SERVICES", - panelClass: ServicesAdminPanel, - }, { - name: "CONFIGURATION", - panelClass: ConfigurationAdminPanel, - }]; - - var tabDiv = Functions.createElement({ - type: "div", - name: "tabView", - className: "tabbable boxed parentTabs" - }); - self.getElement().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); - - for (var i = 0; i < panels.length; i++) { - self.addTab(panels[i], tabMenuDiv, tabContentDiv); - } + var self = this; + self.getElement().innerHTML = ""; + var headerDiv = Functions.createElement({ + type: "div" + }); + self.setHeader(new Header({ + element: headerDiv, + customMap: null, + project: self.getProject(), + adminLink: false + })); + self.getElement().appendChild(headerDiv); + + var panels = [{ + name: "COMMENTS", + panelClass: CommentsAdminPanel + }, { + name: "PROJECTS", + panelClass: MapsAdminPanel + }, { + name: "USERS", + panelClass: UsersAdminPanel + }, { + name: "CONFIGURATION", + panelClass: ConfigurationAdminPanel + }]; + + var tabDiv = Functions.createElement({ + type: "div", + name: "tabView", + className: "tabbable boxed parentTabs" + }); + self.getElement().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); + + for (var i = 0; i < panels.length; i++) { + self.addTab(panels[i], tabMenuDiv, tabContentDiv); + } }; Admin.prototype.addTab = function (params, navElement, contentElement) { - var self = this; - - var tabId = "admin_panel_tab_" + this._tabIdCount; - self._tabIdCount++; - - var navLi = self.getGuiUtils().createTabMenuObject({ - id: tabId, - name: params.name, - navigationBar: navElement - }); - navElement.appendChild(navLi); - - var contentDiv = self.getGuiUtils().createTabContentObject({ - id: tabId, - navigationObject: navLi, - }); - - contentElement.appendChild(contentDiv); - - this._panels.push(new params.panelClass({ - element: contentDiv, - name: params.name, - project: self.getProject(), - configuration: self.getConfiguration(), - })); + var self = this; + + var tabId = "admin_panel_tab_" + this._tabIdCount; + self._tabIdCount++; + + var navLi = self.getGuiUtils().createTabMenuObject({ + id: tabId, + name: params.name, + navigationBar: navElement + }); + navElement.appendChild(navLi); + + var contentDiv = self.getGuiUtils().createTabContentObject({ + id: tabId, + navigationObject: navLi + }); + + contentElement.appendChild(contentDiv); + + this._panels.push(new params.panelClass({ + element: contentDiv, + name: params.name, + project: self.getProject(), + configuration: self.getConfiguration() + })); }; Admin.prototype.setProject = function (project) { - this._project = project; + this._project = project; }; Admin.prototype.getProject = function () { - return this._project; + return this._project; }; Admin.prototype.setElement = function (element) { - this._element = element; + this._element = element; }; Admin.prototype.getElement = function () { - return this._element; + return this._element; }; Admin.prototype.init = function () { - var promises = []; - for (var i = 0; i < this._panels.length; i++) { - promises.push(this._panels[i].init()); - } - promises.push(this.getHeader().init()); - return Promise.all(promises).then(function(){ - $(window).trigger('resize'); - }); + var promises = []; + for (var i = 0; i < this._panels.length; i++) { + promises.push(this._panels[i].init()); + } + promises.push(this.getHeader().init()); + return Promise.all(promises).then(function () { + $(window).trigger('resize'); + }); }; Admin.prototype.setConfiguration = function (configuration) { - this._configuration = configuration; + this._configuration = configuration; }; Admin.prototype.getConfiguration = function () { - return this._configuration; + return this._configuration; }; Admin.prototype.setHeader = function (header) { - this._header = header; + this._header = header; }; Admin.prototype.getHeader = function () { - return this._header; + return this._header; }; Admin.prototype.setGuiUtils = function (guiUtils) { - this._guiUtils = guiUtils; + this._guiUtils = guiUtils; }; Admin.prototype.getGuiUtils = function () { - return this._guiUtils; + return this._guiUtils; }; Admin.prototype.destroy = function () { - var self = this; - var promises = []; - promises.push(self.getHeader().destroy()); - for (var i = 0; i < self._panels.length; i++) { - promises.push(self._panels[i].destroy()); - } - return Promise.all(promises); + var self = this; + var promises = []; + promises.push(self.getHeader().destroy()); + for (var i = 0; i < self._panels.length; i++) { + promises.push(self._panels[i].destroy()); + } + return Promise.all(promises); }; module.exports = Admin; diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index e7786dd394..3b73e44a80 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -871,6 +871,8 @@ ServerConnector.getUser = function (login) { self._usersByLogin[user.getLogin()] = user; } return self._usersByLogin[user.getLogin()]; + }).then(null, function (error) { + return self.processNetworkError(error); }); }; @@ -893,6 +895,25 @@ ServerConnector.updateUser = function (user) { return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); }); +}; +ServerConnector.addUser = function (user) { + var self = this; + var queryParams = { + login: user.getLogin() + }; + var filterParams = { + login: user.getLogin(), + name: user.getName(), + surname: user.getSurname(), + password: user.getPassword(), + email: user.getEmail() + }; + return self.sendPostRequest(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) { @@ -1132,7 +1153,7 @@ ServerConnector.getReactions = function (params) { ServerConnector.getAliases = function (params) { var self = this; var queryParams = { - modelId: params.modelId, + modelId: params.modelId }; if (params.ids === undefined) { params.ids = []; @@ -1148,7 +1169,7 @@ ServerConnector.getAliases = function (params) { columns: params.columns, type: params.type, excludedCompartmentIds: params.excludedCompartmentIds, - includedCompartmentIds: params.includedCompartmentIds, + includedCompartmentIds: params.includedCompartmentIds }; return self.getProjectId(params.projectId).then(function (result) { diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js index 58f3c3ef8e..bb29f70660 100644 --- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js @@ -26,11 +26,19 @@ EditUserDialog.prototype.constructor = EditUserDialog; EditUserDialog.prototype.setUser = function (user) { this._user = user; + this.setIsNewUser(user.getLogin() === undefined); }; EditUserDialog.prototype.getUser = function () { return this._user; }; +EditUserDialog.prototype.setIsNewUser = function (isNewUser) { + this._isNewUser = isNewUser; +}; +EditUserDialog.prototype.getIsNewUser = function () { + return this._isNewUser; +}; + EditUserDialog.prototype.createGui = function () { var self = this; var element = self.getElement(); @@ -115,6 +123,13 @@ EditUserDialog.prototype.addTab = function (params) { params.tabContentDiv.appendChild(contentDiv); }; +function getStringIfDefined(value) { + if (value === undefined) { + return ""; + } + return value; +} + EditUserDialog.prototype.createGeneralTabContent = function () { var self = this; var user = self.getUser(); @@ -149,7 +164,7 @@ EditUserDialog.prototype.createGeneralTabContent = function () { loginRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userLogin' value='" + user.getLogin() + "' readonly/>" + content: "<input name='userLogin' value='" + getStringIfDefined(user.getLogin()) + "' readonly/>" })); } @@ -198,7 +213,7 @@ EditUserDialog.prototype.createGeneralTabContent = function () { nameRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userName' value='" + user.getName() + "'/>" + content: "<input name='userName' value='" + getStringIfDefined(user.getName()) + "'/>" })); var surnameRow = new Functions.createElement({ @@ -214,7 +229,7 @@ EditUserDialog.prototype.createGeneralTabContent = function () { surnameRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userSurname' value='" + user.getSurname() + "'/>" + content: "<input name='userSurname' value='" + getStringIfDefined(user.getSurname()) + "'/>" })); var emailRow = new Functions.createElement({ @@ -230,7 +245,7 @@ EditUserDialog.prototype.createGeneralTabContent = function () { emailRow.appendChild(new Functions.createElement({ type: "div", style: "display:table-cell", - content: "<input name='userEmail' value='" + user.getEmail() + "'/>" + content: "<input name='userEmail' value='" + getStringIfDefined(user.getEmail()) + "'/>" })); @@ -494,9 +509,13 @@ EditUserDialog.prototype.destroy = function () { EditUserDialog.prototype.open = function () { var self = this; var div = self.getElement(); + var title = self.getUser().getLogin(); + if (title === undefined) { + title = "NEW USER"; + } if (!$(div).hasClass("ui-dialog-content")) { $(div).dialog({ - title: self.getProject().getProjectId(), + title: title, width: window.innerWidth / 2, height: window.innerHeight / 2 }); @@ -513,7 +532,11 @@ EditUserDialog.prototype.onSaveClicked = function () { user.setEmail(self.getEmail()); user.setName(self.getName()); user.setSurname(self.getSurname()); - return ServerConnector.updateUser(user); + if (self.getIsNewUser()) { + return ServerConnector.addUser(user); + } else { + return ServerConnector.updateUser(user); + } }); }; diff --git a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js index 6ac46f3513..3db303562b 100644 --- a/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/UsersAdminPanel.js @@ -2,6 +2,7 @@ var AbstractAdminPanel = require('./AbstractAdminPanel'); var EditUserDialog = require('./EditUserDialog'); +var User = require("../../map/data/User"); var Functions = require('../../Functions'); var GuiConnector = require('../../GuiConnector'); @@ -234,4 +235,17 @@ UsersAdminPanel.prototype.destroy = function () { }; +UsersAdminPanel.prototype.onAddClicked = function () { + var self = this; + var user = new User({}); + GuiConnector.showProcessing(); + return self.getDialog(user).then(function (dialog) { + dialog.open(); + GuiConnector.hideProcessing(); + }).then(null, function (error) { + GuiConnector.hideProcessing(); + return Promise.reject(error); + }); +}; + module.exports = UsersAdminPanel; 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 76764bcf97..29ab789732 100644 --- a/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js +++ b/frontend-js/src/test/js/gui/admin/UserAdminPanel-test.js @@ -71,5 +71,25 @@ describe('UsersAdminPanel', function () { return mapTab.destroy(); }); }); + it('onAddClicked', 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.onAddClicked(); + }).then(function () { + return mapTab.destroy(); + }); + }); + }); diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java index 7729b2296f..0f82683334 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java @@ -298,4 +298,14 @@ public abstract class BaseRestImpl { return parser; } + protected String getFirstValue(List<Object> list) { + if (list == null) { + return null; + } + if (list.size() > 0) { + return (String) list.get(0); + } + return null; + } + } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java index 802493819f..2bca5632c6 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java @@ -485,7 +485,6 @@ public class ProjectRestImpl extends BaseRestImpl { public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, Object> data, String path) throws SecurityException, QueryException, IOException { - logger.info(data); AuthenticationToken authenticationToken = getUserService().getToken(token); User user = getUserService().getUserByToken(authenticationToken); Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); @@ -595,15 +594,6 @@ public class ProjectRestImpl extends BaseRestImpl { } } - private String getFirstValue(List<Object> list) { - if (list == null) { - return null; - } - if (list.size() > 0) { - return (String) list.get(0); - } - return null; - } /** * Method that computes md5 hash for a given {@link String}. 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 787825759e..81c3a5335d 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 @@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -30,7 +31,6 @@ 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 { @@ -155,7 +155,17 @@ public class UserController extends BaseController { return userRest.updateUser(token, login, data); } - + @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> addOverlay(// + @RequestBody MultiValueMap<String, Object> formData, // + @PathVariable(value = "login") String login, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, IOException, QueryException { + return userRest.addProject(token, login, formData); + + } + + /** * @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 5f6f44c17e..895042c011 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 @@ -10,13 +10,13 @@ import java.util.Set; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.MultiValueMap; import lcsb.mapviewer.api.BaseRestImpl; 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; @@ -28,7 +28,6 @@ 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 { @@ -448,4 +447,42 @@ public class UserRestImpl extends BaseRestImpl { return getUser(token, login, ""); } + public Map<String, Object> addProject(String token, String login, MultiValueMap<String, Object> userData) + throws QueryException, SecurityException { + logger.debug(userData); + AuthenticationToken authenticationToken = getUserService().getToken(token); + + User user = getUserService().getUserByLogin(login); + if (user != null) { + throw new QueryException("user exists"); + } + if (!getUserService().userHasPrivilege(authenticationToken, PrivilegeType.USER_MANAGEMENT)) { + throw new SecurityException("Access denied"); + } + user = new User(); + user.setLogin(login); + for (String key : userData.keySet()) { + String stringValue = getFirstValue((List<Object>) userData.get(key)); + 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(stringValue)) { + throw new QueryException("login must match url"); + } + } else { + throw new QueryException("Unknown parameter: " + key); + } + } + getUserService().addUser(user); + return getUser(token, login, ""); + } + } -- GitLab