diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c8e77f73dc9ab17d7d6cec19defa40c7f5d9f30 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,12 @@ +image: node + +before_script: + - cd frontend-js + - npm install + - cd .. + +test_frontend: + script: + - cd frontend-js + - npm test + \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG index 5ddd8c6f4e09fcd6ca9040e2e1f8b6b705d83b68..1eb8ddc1b403c90693a938fee296419777858e4b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +minerva (11.0.1) stable; urgency=medium + * Bug fix: logout caused issues with session data + + -- Piotr Gawron <piotr.gawron@uni.lu> Fri, 08 Sep 2017 12:00:00 +0200 + minerva (11.0.0) stable; urgency=medium * Bug fix: security issue - access to specific map can be restricted diff --git a/README.md b/README.md index c8bb6d65f4fc5cbd20d1234135c1e1d56efa5339..1c4a3a4035e872ea0c8f7505b3bbc12d039678ff 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[](https://git-r3lab.uni.lu/piotr.gawron/minerva/commits/207-continous-integration-tests) + # Rest API (version 11) ## Introduction diff --git a/frontend-js/.idea/preferred-vcs.xml b/frontend-js/.idea/preferred-vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..848cfc44550cbfba31b047a54bb77ecd25feb0c7 --- /dev/null +++ b/frontend-js/.idea/preferred-vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="PreferredVcsStorage"> + <preferredVcsName>ApexVCS</preferredVcsName> + </component> +</project> \ No newline at end of file diff --git a/frontend-js/package.json b/frontend-js/package.json index 00e5bf58452424cfffd5ad900c0d90ba0c644a85..85fe7d0c95ad112e1c40c4e065ff83c9d56f190f 100644 --- a/frontend-js/package.json +++ b/frontend-js/package.json @@ -38,12 +38,14 @@ "uglifyjs": "^2.4.10" }, "dependencies": { + "del": "^3.0.0", "dual-listbox": "^1.0.7", "file-saver": "^1.3.3", "http-status-codes": "^1.1.6", "js-cookie": "^2.1.3", "jstree": "^3.3.4", "log4js": "0.6.38", + "mkdirp": "^0.5.1", "pileup": "^0.6.8", "request": "^2.79.0" } diff --git a/frontend-js/src/main/js/GuiConnector.js b/frontend-js/src/main/js/GuiConnector.js index 43406b51aa027a542c0a5c7bb22ae22653be023b..0b80b2c90bfff5dd1e496652569ddce87497c0da 100644 --- a/frontend-js/src/main/js/GuiConnector.js +++ b/frontend-js/src/main/js/GuiConnector.js @@ -8,7 +8,6 @@ var ValidationError = require('./ValidationError'); var GuiMessageError = require('./gui/GuiMessageError'); var NetworkError = require('./NetworkError'); - /** * This static global object contains set of functions that returns/set data in * the Gui (html). diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 54a5ffc45dd568da95e2ac9052a2f9b2da0da47c..a7750836d8cb43ba18f5b8cf108712e132d24021 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -73,7 +73,7 @@ ServerConnector.registerListenerType("onDataLoadStart"); ServerConnector.registerListenerType("onDataLoadStop"); ServerConnector.init(); -ServerConnector.getMinOverlayColorInt = function () { +ServerConnector.getMinOverlayColorInt = function() { var self = this; return self.getLoggedUser().then(function (user) { var userColor = user.getMinColor(); @@ -96,7 +96,7 @@ ServerConnector.returnUserOrSystemColor = function (userColor, systemPromisedCol ServerConnector.getSimpleOverlayColorInt = function () { var self = this; - return self.getLoggedUser().then(function (user) { + return self.getLoggedUser().then(function(user) { var userColor = user.getSimpleColor(); return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.SIMPLE_COLOR_VAL)); }); @@ -152,7 +152,10 @@ ServerConnector._sendRequest = function (params) { return new Promise(function (resolve, reject) { request(params, function (error, response, body) { if (error) { - reject(error); + reject(new NetworkError(error.message, { + content: body, + url: url + })); } else if (response.statusCode !== 200) { reject(new NetworkError(params.url + " rejected with status code: " + response.statusCode, { content: body, @@ -198,8 +201,9 @@ ServerConnector.sendPatchRequest = function (url, json) { ServerConnector.getToken = function () { var self = this; + var login = self.getSessionData(null).getLogin() var token = self.getSessionData(null).getToken(); - if (token === undefined) { + if (token === undefined || login === undefined) { return self.login(); } else { // if the project is not initialized then check if we can download data @@ -331,6 +335,12 @@ ServerConnector.loginUrl = function () { }); }; +ServerConnector.logoutUrl = function () { + return this.getApiUrl({ + type: "/doLogout", + }); +}; + ServerConnector.getSuggestedQueryListUrl = function (queryParams, filterParams) { return this.getApiUrl({ url: this.getBioEntitiesUrl(queryParams) + "suggestedQueryList/", @@ -580,10 +590,7 @@ ServerConnector.getUpdateUserPreferencesUrl = function (queryParams, filterParam }); }; -ServerConnector.getConfiguration = function (params) { - if (params === undefined) { - params = {}; - } +ServerConnector.getConfiguration = function () { var self = this; if (this._configuration === undefined) { return self.sendGetRequest(self.getConfigurationUrl()).then(function (content) { @@ -609,7 +616,7 @@ ServerConnector.getModels = function (projectId) { var queryParams = {}; var filterParams = {}; var self = this; - return self.getProjectId(projectId).then(function (result) { + return self.getProjectId(projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getModelsUrl(queryParams, filterParams)); }).then(function (content) { @@ -640,7 +647,7 @@ ServerConnector.getProject = function (projectId) { } project = self._projectsById[projectId]; return self.getModels(projectId); - }).then(function (models) { + }).then(function(models) { project.setModel(models[0]); return self.getLoggedUser(); }).then(function (user) { @@ -792,13 +799,13 @@ ServerConnector.getProjectStatistics = function (projectId) { var filterParams = {}; var self = this; var content; - return self.getProjectId(projectId).then(function (result) { + return self.getProjectId(projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getProjectStatisticsUrl(queryParams, filterParams)); }).then(function (result) { content = JSON.parse(result); return self.getConfiguration(); - }).then(function (configuration) { + }).then(function(configuration) { return new ProjectStatistics(content, configuration); }); }; @@ -923,17 +930,17 @@ ServerConnector.getOverlays = function (params) { }); }; -ServerConnector.getOverlayElements = function (overlayId, projectId) { +ServerConnector.getOverlayElements = function(overlayId, projectId) { var self = this; if (overlayId === undefined) { throw new Error("Layout id must be defined"); } var queryParams = { - overlayId: overlayId, - modelId: "*", + overlayId : overlayId, + modelId : "*", }; var filterParams = {}; - return self.getProjectId(projectId).then(function (result) { + return self.getProjectId(projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getOverlayElementsUrl(queryParams, filterParams)); }).then(function (content) { @@ -1031,7 +1038,7 @@ ServerConnector.getReactions = function (params) { columns: params.columns, participantId: params.participantId, }; - return self.getProjectId(params.projectId).then(function (result) { + return self.getProjectId(params.projectId).then(function(result) { queryParams.projectId = result; if (filterParams.id.length > 100 || filterParams.participantId.length > 100) { return self.sendPostRequest(self.getReactionsUrl(queryParams), filterParams); @@ -1049,10 +1056,10 @@ ServerConnector.getReactions = function (params) { }); }; -ServerConnector.getAliases = function (params) { +ServerConnector.getAliases = function(params) { var self = this; var queryParams = { - modelId: params.modelId, + modelId : params.modelId, }; if (params.ids === undefined) { params.ids = []; @@ -1071,14 +1078,14 @@ ServerConnector.getAliases = function (params) { includedCompartmentIds: params.includedCompartmentIds, }; - return self.getProjectId(params.projectId).then(function (result) { + return self.getProjectId(params.projectId).then(function(result) { queryParams.projectId = result; if (filterParams.id.length > 100) { return self.sendPostRequest(self.getAliasesUrl(queryParams), filterParams); } else { return self.sendGetRequest(self.getAliasesUrl(queryParams, filterParams)); } - }).then(function (content) { + }).then(function(content) { var array = JSON.parse(content); var result = []; for (var i = 0; i < array.length; i++) { @@ -1088,22 +1095,22 @@ ServerConnector.getAliases = function (params) { }); }; -ServerConnector.getLightComments = function (params) { - params.columns = ["id", "elementId", "modelId", "type", "icon", "removed", "pinned"]; +ServerConnector.getLightComments = function(params) { + params.columns = [ "id", "elementId", "modelId", "type", "icon", "removed", "pinned" ]; return this.getComments(params); }; -ServerConnector.getComments = function (params) { +ServerConnector.getComments = function(params) { var self = this; var queryParams = { - elementId: params.elementId, - elementType: params.elementType, - coordinates: params.coordinates, + elementId : params.elementId, + elementType : params.elementType, + coordinates : params.coordinates, }; var filterParams = { - columns: params.columns + columns : params.columns }; - return self.getProjectId(params.projectId).then(function (result) { + return self.getProjectId(params.projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getCommentsUrl(queryParams, filterParams)); }).then(function (content) { @@ -1151,7 +1158,7 @@ ServerConnector.getClosestElementsByCoordinates = function (params) { ServerConnector.login = function (login, password) { var self = this; var params = {}; - if (login !== undefined) { + if (login !== undefined && login !== "") { params.login = login; params.password = password; } else { @@ -1174,7 +1181,7 @@ ServerConnector.logout = function () { var self = this; self.getSessionData().setToken(undefined); self.getSessionData().setLogin(undefined); - return Promise.resolve(); + return self.sendGetRequest(self.logoutUrl()); }; ServerConnector.getElementsByQuery = function (params) { @@ -1219,13 +1226,13 @@ ServerConnector.getDrugsByQuery = function (params) { }); }; -ServerConnector.getMiRnasByQuery = function (params) { +ServerConnector.getMiRnasByQuery = function(params) { var self = this; var queryParams = {}; var filterParams = { - query: params.query + query : params.query }; - return self.getProjectId(params.projectId).then(function (result) { + return self.getProjectId(params.projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getSearchMiRnasUrl(queryParams, filterParams)); }).then(function (content) { @@ -1516,7 +1523,7 @@ ServerConnector.getPublications = function (params) { sortOrder: params.sortOrder, search: params.search, }; - return self.getProjectId(params.projectId).then(function (result) { + return self.getProjectId(params.projectId).then(function(result) { queryParams.projectId = result; return self.sendGetRequest(self.getPublicationsUrl(queryParams, filterParams)); }).then(function (content) { @@ -1524,7 +1531,7 @@ ServerConnector.getPublications = function (params) { }); }; -ServerConnector.getReferenceGenome = function (params) { +ServerConnector.getReferenceGenome = function(params) { var self = this; var filterParams = {}; return self.sendGetRequest(self.getReferenceGenomeUrl(params, filterParams)).then(function (content) { diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js index 937538e0ea799d3f991e4443b13b437429c77351..b78dc728ab4ed3fc4cb752f5e0a19e7e646f5394 100644 --- a/frontend-js/src/main/js/gui/AddOverlayDialog.js +++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js @@ -8,7 +8,7 @@ var GuiUtils = require('./leftPanel/GuiUtils'); var LayoutData = require('../map/data/LayoutData'); var NetworkError = require('../NetworkError'); -var Functions = require('../functions'); +var Functions = require('../Functions'); var logger = require('../logger'); var HttpStatus = require('http-status-codes'); diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 5f03de03494b0d8db8a87b41e892a8aeee8b0c11..5811bd86c8e30480f3682a6b2c5893a37006d79b 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -9,7 +9,7 @@ var ChooseValidatorsDialog = require('./ChooseValidatorsDialog'); var GuiConnector = require('../../GuiConnector'); var UserPreferences = require("../../map/data/UserPreferences"); -var Functions = require('../../functions'); +var Functions = require('../../Functions'); var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index 1f0f64165f22aec5a0b2fca3acdb6f6cdf3a14c1..b7293b8c72e741e49cd07f51b0e18e0a8d0f7885 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -8,7 +8,7 @@ var AddOverlayDialog = require('../AddOverlayDialog'); var Annotation = require('../../map/data/Annotation'); var GuiConnector = require('../../GuiConnector'); -var Functions = require('../../functions'); +var Functions = require('../../Functions'); var logger = require('../../logger'); var guiUtils = new (require('../leftPanel/GuiUtils'))(); diff --git a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js index 59a9c11b038ce6328d372d3801fa8aaa8fd67762..0fd22a3ee66b605e0b4bd1a3a207b7e63a962543 100644 --- a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js @@ -299,13 +299,13 @@ OverlayPanel.prototype.refresh = function () { var generalOverlays = []; var overlay; - var overlays = self.getMap().getLayouts(); - for (var i = 0; i < overlays.length; i++) { - overlay = overlays[i]; - if (overlay.getCreator() === undefined || overlay.getCreator() === "") { - generalOverlays.push(overlay); + var overlays = self.getMap().getLayouts(); + for (var i = 0; i < overlays.length; i++) { + overlay = overlays[i]; + if (overlay.getCreator() === undefined || overlay.getCreator() === "") { + generalOverlays.push(overlay); + } } - } var table = self.getControlElement(PanelControlElementType.OVERLAY_GENERAL_OVERLAY_TABLE); table.appendChild(self.createTableHeader()); diff --git a/frontend-js/testFiles/apiCalls/doLogout b/frontend-js/testFiles/apiCalls/doLogout new file mode 100644 index 0000000000000000000000000000000000000000..1a36cf5fc27a0920a9f3668225f9d7aec239566e --- /dev/null +++ b/frontend-js/testFiles/apiCalls/doLogout @@ -0,0 +1 @@ +{"status":"ok"} \ No newline at end of file diff --git a/persist/src/db/11.0.1/fix_db_20170908.sql b/persist/src/db/11.0.1/fix_db_20170908.sql new file mode 100644 index 0000000000000000000000000000000000000000..a33b6ad89d4881c84fb355b8c56d309760e66b70 --- /dev/null +++ b/persist/src/db/11.0.1/fix_db_20170908.sql @@ -0,0 +1 @@ +-- empty file to force directory to be commited to git repo 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 5b8e4672b56384b49e27ea69a1f509b94cd90894..041ac88052890ba222fc58db0307c450f3fb8e20 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 @@ -114,11 +114,27 @@ public class UserController extends BaseController { } @RequestMapping(value = "/doLogout", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, String> logout(@CookieValue(value = Configuration.AUTH_TOKEN) String token) throws SecurityException { + public Map<String, String> logout(@CookieValue(value = Configuration.AUTH_TOKEN) String token, + HttpServletResponse response // + ) throws SecurityException, IOException { userService.logout(token); - Map<String, String> response = new HashMap<>(); - response.put("status", "OK"); - return response; + Map<String, String> result = new HashMap<>(); + result.put("status", "OK"); + + final Boolean useSecureCookie = false; + final String cookiePath = "/"; + + Cookie cookie = new Cookie("MINERVA_AUTH_TOKEN", token); + + cookie.setSecure(useSecureCookie); + cookie.setMaxAge(0); + cookie.setPath(cookiePath); + + response.addCookie(cookie); + response.getWriter().write("{\"status\":\"OK\"}"); + response.getWriter().flush(); + response.getWriter().close(); + return result; } /**