Commit e8fbea4d authored by Piotr Gawron's avatar Piotr Gawron
Browse files

plugin data entry is limited to 1MB + error handling added in rest

parent bcf83efa
Pipeline #26537 passed with stage
in 11 minutes and 28 seconds
...@@ -5,6 +5,7 @@ minerva (14.0.12) stable; urgency=medium ...@@ -5,6 +5,7 @@ minerva (14.0.12) stable; urgency=medium
CellDesigner (#1227) CellDesigner (#1227)
* Bug fix: doi annotation was inproperly parsed from CellDesigner file and * Bug fix: doi annotation was inproperly parsed from CellDesigner file and
resulted in not clickable link (#1231) resulted in not clickable link (#1231)
* Bug fix: when plugin data was too big 500 error was returned (#1232)
-- Piotr Gawron <piotr.gawron@uni.lu> Mon, 11 May 2020 17:00:00 +0200 -- Piotr Gawron <piotr.gawron@uni.lu> Mon, 11 May 2020 17:00:00 +0200
......
...@@ -33,10 +33,10 @@ public class PluginDataEntry implements Serializable { ...@@ -33,10 +33,10 @@ public class PluginDataEntry implements Serializable {
@ManyToOne(fetch = FetchType.LAZY, optional = false) @ManyToOne(fetch = FetchType.LAZY, optional = false)
private Plugin plugin; private Plugin plugin;
@Column(nullable = false) @Column(nullable = false, length = 1024)
private String key; private String key;
@Column(nullable = false) @Column(nullable = false, length = 1024 * 1024)
private String value; private String value;
public int getId() { public int getId() {
......
alter table plugin_data_entry_table alter COLUMN value type character varying(1048576);
...@@ -67,7 +67,7 @@ public class PluginController extends BaseController { ...@@ -67,7 +67,7 @@ public class PluginController extends BaseController {
Authentication authentication, Authentication authentication,
@PathVariable(value = "hash") String hash, @PathVariable(value = "hash") String hash,
@PathVariable(value = "key") String key, @PathVariable(value = "key") String key,
@RequestParam(value = "value", defaultValue = "") String value) throws ObjectNotFoundException { @RequestParam(value = "value", defaultValue = "") String value) throws QueryException {
User user = userService.getUserByLogin(authentication.getName()); User user = userService.getUserByLogin(authentication.getName());
return pluginRest.createPluginDataEntry(hash, user, key, value); return pluginRest.createPluginDataEntry(hash, user, key, value);
} }
...@@ -76,7 +76,7 @@ public class PluginController extends BaseController { ...@@ -76,7 +76,7 @@ public class PluginController extends BaseController {
public Map<String, Object> createPluginDataEntry( public Map<String, Object> createPluginDataEntry(
@PathVariable(value = "hash") String hash, @PathVariable(value = "hash") String hash,
@PathVariable(value = "key") String key, @PathVariable(value = "key") String key,
@RequestParam(value = "value", defaultValue = "") String value) throws ObjectNotFoundException { @RequestParam(value = "value", defaultValue = "") String value) throws QueryException {
return pluginRest.createPluginDataEntry(hash, null, key, value); return pluginRest.createPluginDataEntry(hash, null, key, value);
} }
......
package lcsb.mapviewer.api.plugins; package lcsb.mapviewer.api.plugins;
import java.io.UnsupportedEncodingException;
import java.util.*; import java.util.*;
import org.apache.commons.validator.routines.UrlValidator; import org.apache.commons.validator.routines.UrlValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -18,6 +21,8 @@ import lcsb.mapviewer.persist.dao.plugin.PluginDataEntryDao; ...@@ -18,6 +21,8 @@ import lcsb.mapviewer.persist.dao.plugin.PluginDataEntryDao;
@Service @Service
public class PluginRestImpl extends BaseRestImpl { public class PluginRestImpl extends BaseRestImpl {
Logger logger = LogManager.getLogger();
private PluginDao pluginDao; private PluginDao pluginDao;
private PluginDataEntryDao pluginDataEntryDao; private PluginDataEntryDao pluginDataEntryDao;
...@@ -28,7 +33,8 @@ public class PluginRestImpl extends BaseRestImpl { ...@@ -28,7 +33,8 @@ public class PluginRestImpl extends BaseRestImpl {
this.pluginDataEntryDao = pluginDataEntryDao; this.pluginDataEntryDao = pluginDataEntryDao;
} }
public Map<String, Object> createPlugin(String hash, String name, String version, String url, boolean isPublic) throws QueryException { public Map<String, Object> createPlugin(String hash, String name, String version, String url, boolean isPublic)
throws QueryException {
if (!new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS).isValid(url)) { if (!new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS).isValid(url)) {
throw new QueryException("Invalid url: " + url); throw new QueryException("Invalid url: " + url);
} }
...@@ -71,11 +77,22 @@ public class PluginRestImpl extends BaseRestImpl { ...@@ -71,11 +77,22 @@ public class PluginRestImpl extends BaseRestImpl {
} }
public Map<String, Object> createPluginDataEntry(String hash, User user, String key, String value) public Map<String, Object> createPluginDataEntry(String hash, User user, String key, String value)
throws ObjectNotFoundException { throws QueryException {
Plugin plugin = pluginDao.getByHash(hash); Plugin plugin = pluginDao.getByHash(hash);
if (plugin == null) { if (plugin == null) {
throw new ObjectNotFoundException("Plugin doesn't exist"); throw new ObjectNotFoundException("Plugin doesn't exist");
} }
int length = 0;
if (value != null) {
try {
length = value.getBytes("UTF-8").length;
} catch (UnsupportedEncodingException e) {
logger.error(e, e);
}
}
if (length >= 1024 * 1024) {
throw new QueryException("Data entry value too big (" + length + "; max length = " + 1024 * 1024 + ")");
}
PluginDataEntry entry = pluginDataEntryDao.getByKey(plugin, key, user); PluginDataEntry entry = pluginDataEntryDao.getByKey(plugin, key, user);
if (entry == null) { if (entry == null) {
entry = new PluginDataEntry(); entry = new PluginDataEntry();
......
...@@ -245,6 +245,24 @@ public class PluginControllerIntegrationTest extends ControllerIntegrationTest { ...@@ -245,6 +245,24 @@ public class PluginControllerIntegrationTest extends ControllerIntegrationTest {
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
} }
@Test
public void testSetInvalidGlobalPluginDataKey() throws Exception {
StringBuilder body = new StringBuilder("value=xxx");
for (int i = 0; i < 2000000; i++) {
body.append("y");
}
Plugin plugin = createPlugin();
RequestBuilder request = post("/plugins/" + plugin.getHash() + "/data/global/key/")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.content(body.toString());
mockMvc.perform(request)
.andExpect(status().isBadRequest())
.andReturn().getResponse().getContentAsString();
}
private Plugin createPlugin() { private Plugin createPlugin() {
Plugin plugin = new Plugin(); Plugin plugin = new Plugin();
plugin.setHash("XYZ"); plugin.setHash("XYZ");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment