Merge pull request #2182 from OpenRefine/issue-2164-csrf
Add CSRF protection to POST endpoints
This commit is contained in:
commit
10c046698a
@ -69,7 +69,7 @@ DatabaseExtension.handleConnectClicked = function(connectionName) {
|
|||||||
databaseConfig.initialDatabase = savedConfig.databaseName;
|
databaseConfig.initialDatabase = savedConfig.databaseName;
|
||||||
databaseConfig.initialSchema = savedConfig.databaseSchema;
|
databaseConfig.initialSchema = savedConfig.databaseSchema;
|
||||||
|
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/database/connect",
|
"command/database/connect",
|
||||||
databaseConfig,
|
databaseConfig,
|
||||||
|
|
||||||
@ -101,8 +101,8 @@ DatabaseExtension.handleConnectClicked = function(connectionName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"json"
|
"json",
|
||||||
).fail(function( jqXhr, textStatus, errorThrown ){
|
function( jqXhr, textStatus, errorThrown ){
|
||||||
alert( textStatus + ':' + errorThrown );
|
alert( textStatus + ':' + errorThrown );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,14 +65,16 @@ Refine.DatabaseImportController.prototype.startImportingDocument = function(quer
|
|||||||
//alert(queryInfo.query);
|
//alert(queryInfo.query);
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/core/create-importing-job",
|
"command/core/create-importing-job",
|
||||||
null,
|
null,
|
||||||
function(data) {
|
function(data) {
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "database/database-import-controller",
|
"controller": "database/database-import-controller",
|
||||||
"subCommand": "initialize-parser-ui"
|
"subCommand": "initialize-parser-ui",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
queryInfo,
|
queryInfo,
|
||||||
|
|
||||||
@ -92,6 +94,7 @@ Refine.DatabaseImportController.prototype.startImportingDocument = function(quer
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
@ -248,11 +251,13 @@ Refine.DatabaseImportController.prototype._updatePreview = function() {
|
|||||||
this._queryInfo.options = JSON.stringify(this.getOptions());
|
this._queryInfo.options = JSON.stringify(this.getOptions());
|
||||||
//alert("options:" + this._queryInfo.options);
|
//alert("options:" + this._queryInfo.options);
|
||||||
|
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "database/database-import-controller",
|
"controller": "database/database-import-controller",
|
||||||
"jobID": this._jobID,
|
"jobID": self._jobID,
|
||||||
"subCommand": "parse-preview"
|
"subCommand": "parse-preview",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
|
|
||||||
this._queryInfo,
|
this._queryInfo,
|
||||||
@ -282,6 +287,7 @@ Refine.DatabaseImportController.prototype._updatePreview = function() {
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.DatabaseImportController.prototype._getPreviewData = function(callback, numRows) {
|
Refine.DatabaseImportController.prototype._getPreviewData = function(callback, numRows) {
|
||||||
@ -329,11 +335,13 @@ Refine.DatabaseImportController.prototype._createProject = function() {
|
|||||||
options.projectName = projectName;
|
options.projectName = projectName;
|
||||||
|
|
||||||
this._queryInfo.options = JSON.stringify(options);
|
this._queryInfo.options = JSON.stringify(options);
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "database/database-import-controller",
|
"controller": "database/database-import-controller",
|
||||||
"jobID": this._jobID,
|
"jobID": self._jobID,
|
||||||
"subCommand": "create-project"
|
"subCommand": "create-project",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
this._queryInfo,
|
this._queryInfo,
|
||||||
function(o) {
|
function(o) {
|
||||||
@ -376,4 +384,5 @@ Refine.DatabaseImportController.prototype._createProject = function() {
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -268,7 +268,7 @@ Refine.DatabaseSourceUI.prototype._executeQuery = function(jdbcQueryInfo) {
|
|||||||
|
|
||||||
var dismiss = DialogSystem.showBusy($.i18n('database-import/checking'));
|
var dismiss = DialogSystem.showBusy($.i18n('database-import/checking'));
|
||||||
|
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/database/test-query",
|
"command/database/test-query",
|
||||||
jdbcQueryInfo,
|
jdbcQueryInfo,
|
||||||
function(jdbcConnectionResult) {
|
function(jdbcConnectionResult) {
|
||||||
@ -277,8 +277,8 @@ Refine.DatabaseSourceUI.prototype._executeQuery = function(jdbcQueryInfo) {
|
|||||||
self._controller.startImportingDocument(jdbcQueryInfo);
|
self._controller.startImportingDocument(jdbcQueryInfo);
|
||||||
|
|
||||||
},
|
},
|
||||||
"json"
|
"json",
|
||||||
).fail(function( jqXhr, textStatus, errorThrown ){
|
function( jqXhr, textStatus, errorThrown ){
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
alert( textStatus + ':' + errorThrown );
|
alert( textStatus + ':' + errorThrown );
|
||||||
@ -288,7 +288,7 @@ Refine.DatabaseSourceUI.prototype._executeQuery = function(jdbcQueryInfo) {
|
|||||||
|
|
||||||
Refine.DatabaseSourceUI.prototype._saveConnection = function(jdbcConnectionInfo) {
|
Refine.DatabaseSourceUI.prototype._saveConnection = function(jdbcConnectionInfo) {
|
||||||
var self = this;
|
var self = this;
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/database/saved-connection",
|
"command/database/saved-connection",
|
||||||
jdbcConnectionInfo,
|
jdbcConnectionInfo,
|
||||||
function(settings) {
|
function(settings) {
|
||||||
@ -307,8 +307,8 @@ Refine.DatabaseSourceUI.prototype._saveConnection = function(jdbcConnectionInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"json"
|
"json",
|
||||||
).fail(function( jqXhr, textStatus, errorThrown ){
|
function( jqXhr, textStatus, errorThrown ){
|
||||||
alert( textStatus + ':' + errorThrown );
|
alert( textStatus + ':' + errorThrown );
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ Refine.DatabaseSourceUI.prototype._loadSavedConnections = function() {
|
|||||||
Refine.DatabaseSourceUI.prototype._testDatabaseConnect = function(jdbcConnectionInfo) {
|
Refine.DatabaseSourceUI.prototype._testDatabaseConnect = function(jdbcConnectionInfo) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/database/test-connect",
|
"command/database/test-connect",
|
||||||
jdbcConnectionInfo,
|
jdbcConnectionInfo,
|
||||||
function(jdbcConnectionResult) {
|
function(jdbcConnectionResult) {
|
||||||
@ -357,8 +357,8 @@ Refine.DatabaseSourceUI.prototype._testDatabaseConnect = function(jdbcConnection
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"json"
|
"json",
|
||||||
).fail(function( jqXhr, textStatus, errorThrown ){
|
function( jqXhr, textStatus, errorThrown ){
|
||||||
alert( textStatus + ':' + errorThrown );
|
alert( textStatus + ':' + errorThrown );
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -366,7 +366,7 @@ Refine.DatabaseSourceUI.prototype._testDatabaseConnect = function(jdbcConnection
|
|||||||
Refine.DatabaseSourceUI.prototype._connect = function(jdbcConnectionInfo) {
|
Refine.DatabaseSourceUI.prototype._connect = function(jdbcConnectionInfo) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/database/connect",
|
"command/database/connect",
|
||||||
jdbcConnectionInfo,
|
jdbcConnectionInfo,
|
||||||
function(databaseInfo) {
|
function(databaseInfo) {
|
||||||
@ -398,8 +398,8 @@ Refine.DatabaseSourceUI.prototype._connect = function(jdbcConnectionInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"json"
|
"json",
|
||||||
).fail(function( jqXhr, textStatus, errorThrown ){
|
function( jqXhr, textStatus, errorThrown ){
|
||||||
alert( textStatus + ':' + errorThrown );
|
alert( textStatus + ':' + errorThrown );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,6 +56,10 @@ public class ConnectCommand extends DatabaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
||||||
if(logger.isDebugEnabled()) {
|
if(logger.isDebugEnabled()) {
|
||||||
|
@ -56,7 +56,10 @@ public class ExecuteQueryCommand extends DatabaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
||||||
String query = request.getParameter("queryString");
|
String query = request.getParameter("queryString");
|
||||||
|
@ -228,6 +228,10 @@ public class SavedConnectionCommand extends DatabaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(logger.isDebugEnabled()) {
|
if(logger.isDebugEnabled()) {
|
||||||
logger.debug("doPost Connection: {}", request.getParameter("connectionName"));
|
logger.debug("doPost Connection: {}", request.getParameter("connectionName"));
|
||||||
|
@ -54,7 +54,10 @@ public class TestConnectCommand extends DatabaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
DatabaseConfiguration databaseConfiguration = getJdbcConfiguration(request);
|
||||||
if(logger.isDebugEnabled()) {
|
if(logger.isDebugEnabled()) {
|
||||||
|
@ -56,6 +56,10 @@ public class TestQueryCommand extends DatabaseCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseConfiguration dbConfig = getJdbcConfiguration(request);
|
DatabaseConfiguration dbConfig = getJdbcConfiguration(request);
|
||||||
String query = request.getParameter("query");
|
String query = request.getParameter("query");
|
||||||
|
@ -20,6 +20,7 @@ import org.testng.annotations.Parameters;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.extension.database.DBExtensionTests;
|
import com.google.refine.extension.database.DBExtensionTests;
|
||||||
import com.google.refine.extension.database.DatabaseConfiguration;
|
import com.google.refine.extension.database.DatabaseConfiguration;
|
||||||
import com.google.refine.extension.database.DatabaseService;
|
import com.google.refine.extension.database.DatabaseService;
|
||||||
@ -75,6 +76,7 @@ public class ConnectCommandTest extends DBExtensionTests {
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
@ -94,5 +96,18 @@ public class ConnectCommandTest extends DBExtensionTests {
|
|||||||
Assert.assertNotNull(databaseInfo);
|
Assert.assertNotNull(databaseInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
when(response.getWriter()).thenReturn(pw);
|
||||||
|
ConnectCommand connectCommand = new ConnectCommand();
|
||||||
|
|
||||||
|
connectCommand.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(sw.toString(), ObjectNode.class));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.testng.annotations.Parameters;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.extension.database.DBExtensionTests;
|
import com.google.refine.extension.database.DBExtensionTests;
|
||||||
import com.google.refine.extension.database.DatabaseConfiguration;
|
import com.google.refine.extension.database.DatabaseConfiguration;
|
||||||
import com.google.refine.extension.database.DatabaseService;
|
import com.google.refine.extension.database.DatabaseService;
|
||||||
@ -72,6 +73,7 @@ public class ExecuteQueryCommandTest extends DBExtensionTests {
|
|||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
when(request.getParameter("queryString")).thenReturn("SELECT count(*) FROM " + testTable);
|
when(request.getParameter("queryString")).thenReturn("SELECT count(*) FROM " + testTable);
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
@ -93,4 +95,17 @@ public class ExecuteQueryCommandTest extends DBExtensionTests {
|
|||||||
Assert.assertNotNull(queryResult);
|
Assert.assertNotNull(queryResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
when(response.getWriter()).thenReturn(pw);
|
||||||
|
ConnectCommand connectCommand = new ConnectCommand();
|
||||||
|
|
||||||
|
connectCommand.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(sw.toString(), ObjectNode.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
|||||||
import com.google.refine.ProjectManager;
|
import com.google.refine.ProjectManager;
|
||||||
import com.google.refine.ProjectMetadata;
|
import com.google.refine.ProjectMetadata;
|
||||||
import com.google.refine.RefineServlet;
|
import com.google.refine.RefineServlet;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.extension.database.DBExtensionTestUtils;
|
import com.google.refine.extension.database.DBExtensionTestUtils;
|
||||||
import com.google.refine.extension.database.DBExtensionTests;
|
import com.google.refine.extension.database.DBExtensionTests;
|
||||||
import com.google.refine.extension.database.DatabaseConfiguration;
|
import com.google.refine.extension.database.DatabaseConfiguration;
|
||||||
@ -125,6 +126,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
@ -150,6 +152,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
@ -187,6 +190,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
@ -227,6 +231,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
SUT.doPut(request, response);
|
SUT.doPut(request, response);
|
||||||
|
|
||||||
@ -309,6 +314,7 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
@ -320,7 +326,18 @@ public class SavedConnectionCommandTest extends DBExtensionTests{
|
|||||||
verify(response, times(1)).sendError(HttpStatus.SC_BAD_REQUEST, "Connection Name is Invalid. Expecting [a-zA-Z0-9._-]");
|
verify(response, times(1)).sendError(HttpStatus.SC_BAD_REQUEST, "Connection Name is Invalid. Expecting [a-zA-Z0-9._-]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
when(response.getWriter()).thenReturn(pw);
|
||||||
|
|
||||||
|
SUT.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(sw.toString(), ObjectNode.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.testng.annotations.Parameters;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.extension.database.DBExtensionTests;
|
import com.google.refine.extension.database.DBExtensionTests;
|
||||||
import com.google.refine.extension.database.DatabaseConfiguration;
|
import com.google.refine.extension.database.DatabaseConfiguration;
|
||||||
import com.google.refine.extension.database.DatabaseService;
|
import com.google.refine.extension.database.DatabaseService;
|
||||||
@ -74,6 +75,7 @@ public class TestConnectCommandTest extends DBExtensionTests{
|
|||||||
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
when(request.getParameter("databaseUser")).thenReturn(testDbConfig.getDatabaseUser());
|
||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
@ -93,4 +95,18 @@ public class TestConnectCommandTest extends DBExtensionTests{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
when(response.getWriter()).thenReturn(pw);
|
||||||
|
ConnectCommand connectCommand = new ConnectCommand();
|
||||||
|
|
||||||
|
connectCommand.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(sw.toString(), ObjectNode.class));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.testng.annotations.Parameters;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.extension.database.DBExtensionTests;
|
import com.google.refine.extension.database.DBExtensionTests;
|
||||||
import com.google.refine.extension.database.DatabaseConfiguration;
|
import com.google.refine.extension.database.DatabaseConfiguration;
|
||||||
import com.google.refine.extension.database.DatabaseService;
|
import com.google.refine.extension.database.DatabaseService;
|
||||||
@ -73,7 +74,7 @@ public class TestQueryCommandTest extends DBExtensionTests {
|
|||||||
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
when(request.getParameter("databasePassword")).thenReturn(testDbConfig.getDatabasePassword());
|
||||||
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
when(request.getParameter("initialDatabase")).thenReturn(testDbConfig.getDatabaseName());
|
||||||
when(request.getParameter("query")).thenReturn("SELECT count(*) FROM " + testTable);
|
when(request.getParameter("query")).thenReturn("SELECT count(*) FROM " + testTable);
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
|
|
||||||
@ -95,4 +96,18 @@ public class TestQueryCommandTest extends DBExtensionTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
when(response.getWriter()).thenReturn(pw);
|
||||||
|
TestQueryCommand connectCommand = new TestQueryCommand();
|
||||||
|
|
||||||
|
connectCommand.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(sw.toString(), ObjectNode.class));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,10 +109,12 @@ Refine.GDataSourceUI.prototype._listDocuments = function() {
|
|||||||
this._elmts.progressPage.show();
|
this._elmts.progressPage.show();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "gdata/gdata-importing-controller",
|
"controller": "gdata/gdata-importing-controller",
|
||||||
"subCommand": "list-documents"
|
"subCommand": "list-documents",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
null,
|
null,
|
||||||
function(o) {
|
function(o) {
|
||||||
@ -120,6 +122,7 @@ Refine.GDataSourceUI.prototype._listDocuments = function() {
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.GDataSourceUI.prototype._renderDocuments = function(o) {
|
Refine.GDataSourceUI.prototype._renderDocuments = function(o) {
|
||||||
|
@ -71,16 +71,18 @@ Refine.GDataImportingController.prototype.startImportingDocument = function(doc)
|
|||||||
var dismiss = DialogSystem.showBusy($.i18n('gdata-import/preparing'));
|
var dismiss = DialogSystem.showBusy($.i18n('gdata-import/preparing'));
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/core/create-importing-job",
|
"command/core/create-importing-job",
|
||||||
null,
|
null,
|
||||||
function(data) {
|
function(data) {
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "gdata/gdata-importing-controller",
|
"controller": "gdata/gdata-importing-controller",
|
||||||
"subCommand": "initialize-parser-ui",
|
"subCommand": "initialize-parser-ui",
|
||||||
"docUrl": doc.docSelfLink,
|
"docUrl": doc.docSelfLink,
|
||||||
"docType": doc.type
|
"docType": doc.type,
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
null,
|
null,
|
||||||
function(data2) {
|
function(data2) {
|
||||||
@ -98,6 +100,7 @@ Refine.GDataImportingController.prototype.startImportingDocument = function(doc)
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
@ -315,14 +318,16 @@ Refine.GDataImportingController.prototype._updatePreview = function() {
|
|||||||
this._parsingPanelElmts.dataPanel.hide();
|
this._parsingPanelElmts.dataPanel.hide();
|
||||||
this._parsingPanelElmts.progressPanel.show();
|
this._parsingPanelElmts.progressPanel.show();
|
||||||
|
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "gdata/gdata-importing-controller",
|
"controller": "gdata/gdata-importing-controller",
|
||||||
"jobID": this._jobID,
|
"jobID": self._jobID,
|
||||||
"subCommand": "parse-preview"
|
"subCommand": "parse-preview",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
"options" : JSON.stringify(this.getOptions())
|
"options" : JSON.stringify(self.getOptions())
|
||||||
},
|
},
|
||||||
function(result) {
|
function(result) {
|
||||||
if (result.status == "ok") {
|
if (result.status == "ok") {
|
||||||
@ -340,6 +345,7 @@ Refine.GDataImportingController.prototype._updatePreview = function() {
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.GDataImportingController.prototype._getPreviewData = function(callback, numRows) {
|
Refine.GDataImportingController.prototype._getPreviewData = function(callback, numRows) {
|
||||||
@ -385,11 +391,13 @@ Refine.GDataImportingController.prototype._createProject = function() {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var options = this.getOptions();
|
var options = this.getOptions();
|
||||||
options.projectName = projectName;
|
options.projectName = projectName;
|
||||||
|
Refine.wrapCSRF(function(token) {
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "gdata/gdata-importing-controller",
|
"controller": "gdata/gdata-importing-controller",
|
||||||
"jobID": this._jobID,
|
"jobID": self._jobID,
|
||||||
"subCommand": "create-project"
|
"subCommand": "create-project",
|
||||||
|
"csrf_token": token
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
"options" : JSON.stringify(options)
|
"options" : JSON.stringify(options)
|
||||||
@ -433,4 +441,5 @@ Refine.GDataImportingController.prototype._createProject = function() {
|
|||||||
},
|
},
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -54,7 +54,7 @@ $.i18n().load(dictionary, lang);
|
|||||||
var name = window.prompt(prompt, theProject.metadata.name);
|
var name = window.prompt(prompt, theProject.metadata.name);
|
||||||
if (name) {
|
if (name) {
|
||||||
var dismiss = DialogSystem.showBusy($.i18n('gdata-exporter/uploading'));
|
var dismiss = DialogSystem.showBusy($.i18n('gdata-exporter/uploading'));
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/gdata/upload",
|
"command/gdata/upload",
|
||||||
{
|
{
|
||||||
"project" : theProject.id,
|
"project" : theProject.id,
|
||||||
|
@ -66,7 +66,9 @@
|
|||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${surefire.version}</version>
|
<version>${surefire.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<skip>true</skip>
|
<suiteXmlFiles>
|
||||||
|
<suiteXmlFile>tests/conf/tests.xml</suiteXmlFile>
|
||||||
|
</suiteXmlFiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -162,6 +164,12 @@
|
|||||||
<version>6.9.10</version>
|
<version>6.9.10</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>2.23.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -43,6 +43,10 @@ public class UploadCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String token = TokenCookie.getToken(request);
|
String token = TokenCookie.getToken(request);
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
|
14
extensions/gdata/tests/conf/tests.xml
Normal file
14
extensions/gdata/tests/conf/tests.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
|
||||||
|
|
||||||
|
<suite name="GData extension">
|
||||||
|
<test name="tests">
|
||||||
|
<groups>
|
||||||
|
<run>
|
||||||
|
<exclude name="broken" />
|
||||||
|
</run>
|
||||||
|
</groups>
|
||||||
|
<packages>
|
||||||
|
<package name="com.google.refine.extension.gdata.*" />
|
||||||
|
</packages>
|
||||||
|
</test>
|
||||||
|
</suite>
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.google.refine.extension.gdata;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
|
public class UploadCommandTest {
|
||||||
|
protected HttpServletRequest request = null;
|
||||||
|
protected HttpServletResponse response = null;
|
||||||
|
protected Command command = null;
|
||||||
|
protected StringWriter writer = null;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpRequestResponse() {
|
||||||
|
request = mock(HttpServletRequest.class);
|
||||||
|
response = mock(HttpServletResponse.class);
|
||||||
|
writer = new StringWriter();
|
||||||
|
command = new UploadCommand();
|
||||||
|
try {
|
||||||
|
when(response.getWriter()).thenReturn(new PrintWriter(writer));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
Assert.assertEquals(
|
||||||
|
ParsingUtilities.mapper.readValue("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", ObjectNode.class),
|
||||||
|
ParsingUtilities.mapper.readValue(writer.toString(), ObjectNode.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,7 @@ ManageAccountDialog.display = function(logged_in_username, saved_credentials, ca
|
|||||||
|
|
||||||
elmts.loginButton.click(function() {
|
elmts.loginButton.click(function() {
|
||||||
frame.hide();
|
frame.hide();
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/wikidata/login",
|
"command/wikidata/login",
|
||||||
elmts.loginForm.serialize(),
|
elmts.loginForm.serialize(),
|
||||||
function(data) {
|
function(data) {
|
||||||
@ -71,7 +71,7 @@ ManageAccountDialog.display = function(logged_in_username, saved_credentials, ca
|
|||||||
});
|
});
|
||||||
|
|
||||||
elmts.logoutButton.click(function() {
|
elmts.logoutButton.click(function() {
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/wikidata/login",
|
"command/wikidata/login",
|
||||||
"logout=true",
|
"logout=true",
|
||||||
function(data) {
|
function(data) {
|
||||||
|
@ -94,7 +94,7 @@ PerformEditsDialog.checkAndLaunch = function () {
|
|||||||
ManageAccountDialog.ensureLoggedIn(function(logged_in_username) {
|
ManageAccountDialog.ensureLoggedIn(function(logged_in_username) {
|
||||||
if (logged_in_username) {
|
if (logged_in_username) {
|
||||||
var discardWaiter = DialogSystem.showBusy($.i18n('perform-wikidata-edits/analyzing-edits'));
|
var discardWaiter = DialogSystem.showBusy($.i18n('perform-wikidata-edits/analyzing-edits'));
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/wikidata/preview-wikibase-schema?" + $.param({ project: theProject.id }),
|
"command/wikidata/preview-wikibase-schema?" + $.param({ project: theProject.id }),
|
||||||
{ engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
{ engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
||||||
function(data) {
|
function(data) {
|
||||||
|
@ -1283,7 +1283,7 @@ SchemaAlignmentDialog.preview = function() {
|
|||||||
$('.invalid-schema-warning').show();
|
$('.invalid-schema-warning').show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.post(
|
Refine.postCSRF(
|
||||||
"command/wikidata/preview-wikibase-schema?" + $.param({ project: theProject.id }),
|
"command/wikidata/preview-wikibase-schema?" + $.param({ project: theProject.id }),
|
||||||
{ schema: JSON.stringify(schema), engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
{ schema: JSON.stringify(schema), engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
||||||
function(data) {
|
function(data) {
|
||||||
|
@ -41,6 +41,11 @@ public class LoginCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String username = request.getParameter("wb-username");
|
String username = request.getParameter("wb-username");
|
||||||
String password = request.getParameter("wb-password");
|
String password = request.getParameter("wb-password");
|
||||||
String remember = request.getParameter("remember-credentials");
|
String remember = request.getParameter("remember-credentials");
|
||||||
|
@ -46,6 +46,13 @@ import com.google.refine.model.Project;
|
|||||||
|
|
||||||
public class PreviewWikibaseSchemaCommand extends Command {
|
public class PreviewWikibaseSchemaCommand extends Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST but is left CSRF-unprotected since it does not
|
||||||
|
* incur a side effect or state change in the backend.
|
||||||
|
* The reason why it uses POST is to make sure large schemas and engines
|
||||||
|
* can be passed as parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -46,6 +46,10 @@ public class SaveWikibaseSchemaCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.openrefine.wikidata.commands;
|
package org.openrefine.wikidata.commands;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -9,6 +10,9 @@ import javax.servlet.ServletException;
|
|||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
import com.google.refine.util.TestUtils;
|
||||||
|
|
||||||
public class LoginCommandTest extends CommandTest {
|
public class LoginCommandTest extends CommandTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
@ -18,8 +22,16 @@ public class LoginCommandTest extends CommandTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoCredentials() throws ServletException, IOException {
|
public void testNoCredentials() throws ServletException, IOException {
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
command.doPost(request, response);
|
command.doPost(request, response);
|
||||||
|
|
||||||
assertEquals("{\"logged_in\":false,\"username\":null}", writer.toString());
|
assertEquals("{\"logged_in\":false,\"username\":null}", writer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
TestUtils.assertEqualAsJson("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", writer.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ import javax.servlet.ServletException;
|
|||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
import com.google.refine.util.TestUtils;
|
||||||
|
|
||||||
public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest {
|
public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest {
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
@ -44,6 +47,8 @@ public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testValidSchema()
|
public void testValidSchema()
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
String schemaJson = jsonFromFile("schema/inception.json").toString();
|
String schemaJson = jsonFromFile("schema/inception.json").toString();
|
||||||
when(request.getParameter("schema")).thenReturn(schemaJson);
|
when(request.getParameter("schema")).thenReturn(schemaJson);
|
||||||
|
|
||||||
@ -54,6 +59,8 @@ public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidSchema() throws ServletException, IOException {
|
public void testInvalidSchema() throws ServletException, IOException {
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
String schemaJson = "{\"itemDocuments\":[{\"statementGroups\":[{\"statements\":[]}],"
|
String schemaJson = "{\"itemDocuments\":[{\"statementGroups\":[{\"statements\":[]}],"
|
||||||
+"\"nameDescs\":[]}],\"wikibasePrefix\":\"http://www.wikidata.org/entity/\"}";
|
+"\"nameDescs\":[]}],\"wikibasePrefix\":\"http://www.wikidata.org/entity/\"}";
|
||||||
|
|
||||||
@ -62,4 +69,13 @@ public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest {
|
|||||||
|
|
||||||
assertTrue(writer.toString().contains("\"error\""));
|
assertTrue(writer.toString().contains("\"error\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCsrfProtection() throws ServletException, IOException {
|
||||||
|
String schemaJson = jsonFromFile("schema/inception.json").toString();
|
||||||
|
when(request.getParameter("schema")).thenReturn(schemaJson);
|
||||||
|
|
||||||
|
command.doPost(request, response);
|
||||||
|
TestUtils.assertEqualAsJson("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", writer.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import javax.servlet.ServletException;
|
|||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.util.ParsingUtilities;
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public abstract class SchemaCommandTest extends CommandTest {
|
public abstract class SchemaCommandTest extends CommandTest {
|
||||||
@ -39,9 +40,11 @@ public abstract class SchemaCommandTest extends CommandTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testNoSchema()
|
public void testNoSchema()
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
command.doPost(request, response);
|
command.doPost(request, response);
|
||||||
|
|
||||||
assertEquals("{\"code\":\"error\",\"message\":\"No Wikibase schema provided.\"}", writer.toString());
|
assertEquals(writer.toString(), "{\"code\":\"error\",\"message\":\"No Wikibase schema provided.\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
94
main/src/com/google/refine/commands/CSRFTokenFactory.java
Normal file
94
main/src/com/google/refine/commands/CSRFTokenFactory.java
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates CSRF tokens and checks their validity.
|
||||||
|
* @author Antonin Delpeuch
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CSRFTokenFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps each token to the time it was generated
|
||||||
|
*/
|
||||||
|
protected final LoadingCache<String, Instant> tokenCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to live for tokens, in seconds
|
||||||
|
*/
|
||||||
|
protected final long timeToLive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of the tokens to generate
|
||||||
|
*/
|
||||||
|
protected final int tokenLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Random number generator used to create tokens
|
||||||
|
*/
|
||||||
|
protected final SecureRandom rng;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new CSRF token factory.
|
||||||
|
*
|
||||||
|
* @param timeToLive
|
||||||
|
* Time to live for tokens, in seconds
|
||||||
|
* @param tokenLength
|
||||||
|
* Length of the tokens generated
|
||||||
|
*/
|
||||||
|
public CSRFTokenFactory(long timeToLive, int tokenLength) {
|
||||||
|
tokenCache = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(timeToLive, TimeUnit.SECONDS)
|
||||||
|
.build(
|
||||||
|
new CacheLoader<String, Instant>() {
|
||||||
|
@Override
|
||||||
|
public Instant load(String key) {
|
||||||
|
return Instant.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
this.timeToLive = timeToLive;
|
||||||
|
this.rng = new SecureRandom();
|
||||||
|
this.tokenLength = tokenLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a fresh CSRF token, which will remain valid for the configured amount of time.
|
||||||
|
*/
|
||||||
|
public String getFreshToken() {
|
||||||
|
// Generate a random token
|
||||||
|
String token = RandomStringUtils.random(tokenLength, 0, 0, true, true, null, rng);
|
||||||
|
// Put it in the cache
|
||||||
|
try {
|
||||||
|
tokenCache.get(token);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
// cannot happen
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that a given CSRF token is valid.
|
||||||
|
* @param token
|
||||||
|
* the token to verify
|
||||||
|
* @return
|
||||||
|
* true if the token is valid
|
||||||
|
*/
|
||||||
|
public boolean validToken(String token) {
|
||||||
|
Map<String, Instant> map = tokenCache.asMap();
|
||||||
|
Instant cutoff = Instant.now().minusSeconds(timeToLive);
|
||||||
|
return map.containsKey(token) && map.get(token).isAfter(cutoff);
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,8 @@ import java.io.IOException;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
@ -67,6 +69,8 @@ public abstract class Command {
|
|||||||
|
|
||||||
final static protected Logger logger = LoggerFactory.getLogger("command");
|
final static protected Logger logger = LoggerFactory.getLogger("command");
|
||||||
|
|
||||||
|
final static public CSRFTokenFactory csrfFactory = new CSRFTokenFactory(3600, 32);
|
||||||
|
|
||||||
protected RefineServlet servlet;
|
protected RefineServlet servlet;
|
||||||
|
|
||||||
public void init(RefineServlet servlet) {
|
public void init(RefineServlet servlet) {
|
||||||
@ -215,6 +219,42 @@ public abstract class Command {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method for retrieving the CSRF token stored in the "csrf_token" parameter of the request,
|
||||||
|
* and checking that it is valid.
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
* @throws ServletException
|
||||||
|
*/
|
||||||
|
protected boolean hasValidCSRFToken(HttpServletRequest request) throws ServletException {
|
||||||
|
if (request == null) {
|
||||||
|
throw new IllegalArgumentException("parameter 'request' should not be null");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String token = request.getParameter("csrf_token");
|
||||||
|
return token != null && csrfFactory.validToken(token);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
throw new ServletException("Can't find CSRF token: missing or bad URL parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the validity of a CSRF token, without reading the whole POST body.
|
||||||
|
* Useful when we need to control how the POST body is read (for instance if it
|
||||||
|
* contains files).
|
||||||
|
*/
|
||||||
|
protected boolean hasValidCSRFTokenAsGET(HttpServletRequest request) {
|
||||||
|
if (request == null) {
|
||||||
|
throw new IllegalArgumentException("parameter 'request' should not be null");
|
||||||
|
}
|
||||||
|
Properties options = ParsingUtilities.parseUrlParameters(request);
|
||||||
|
String token = options.getProperty("csrf_token");
|
||||||
|
return token != null && csrfFactory.validToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
protected static class HistoryEntryResponse {
|
protected static class HistoryEntryResponse {
|
||||||
@JsonProperty("code")
|
@JsonProperty("code")
|
||||||
protected String getCode() { return "ok"; }
|
protected String getCode() { return "ok"; }
|
||||||
@ -277,7 +317,7 @@ public abstract class Command {
|
|||||||
w.close();
|
w.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected void respondJSON(HttpServletResponse response, Object o)
|
public static void respondJSON(HttpServletResponse response, Object o)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
respondJSON(response, o, new Properties());
|
respondJSON(response, o, new Properties());
|
||||||
@ -298,6 +338,13 @@ public abstract class Command {
|
|||||||
w.close();
|
w.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static protected void respondCSRFError(HttpServletResponse response) throws IOException {
|
||||||
|
Map<String, String> responseJSON = new HashMap<>();
|
||||||
|
responseJSON.put("code", "error");
|
||||||
|
responseJSON.put("message", "Missing or invalid csrf_token parameter");
|
||||||
|
respondJSON(response, responseJSON);
|
||||||
|
}
|
||||||
|
|
||||||
static protected void respondException(HttpServletResponse response, Exception e)
|
static protected void respondException(HttpServletResponse response, Exception e)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
|
@ -70,6 +70,10 @@ abstract public class EngineDependentCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -46,6 +46,10 @@ import com.google.refine.model.Project;
|
|||||||
import com.google.refine.preference.PreferenceStore;
|
import com.google.refine.preference.PreferenceStore;
|
||||||
|
|
||||||
public class GetAllPreferencesCommand extends Command {
|
public class GetAllPreferencesCommand extends Command {
|
||||||
|
/**
|
||||||
|
* The command uses POST (not sure why?) but does not actually modify any state
|
||||||
|
* so it does not require CSRF.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
18
main/src/com/google/refine/commands/GetCSRFTokenCommand.java
Normal file
18
main/src/com/google/refine/commands/GetCSRFTokenCommand.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a fresh CSRF token.
|
||||||
|
*/
|
||||||
|
public class GetCSRFTokenCommand extends Command {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
respondJSON(response, Collections.singletonMap("token", csrfFactory.getFreshToken()));
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,10 @@ public class OpenWorkspaceDirCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String serverName = request.getServerName();
|
String serverName = request.getServerName();
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
package com.google.refine.commands;
|
package com.google.refine.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -49,6 +50,10 @@ public class SetPreferenceCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Project project = request.getParameter("project") != null ? getProject(request) : null;
|
Project project = request.getParameter("project") != null ? getProject(request) : null;
|
||||||
PreferenceStore ps = project != null ?
|
PreferenceStore ps = project != null ?
|
||||||
@ -63,7 +68,7 @@ public class SetPreferenceCommand extends Command {
|
|||||||
|
|
||||||
ps.put(prefName, PreferenceStore.loadObject(o));
|
ps.put(prefName, PreferenceStore.loadObject(o));
|
||||||
|
|
||||||
respond(response, "{ \"code\" : \"ok\" }");
|
respondJSON(response, Collections.singletonMap("code", "ok"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
respondException(response, e);
|
respondException(response, e);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,10 @@ public class ComputeClustersCommand extends Command {
|
|||||||
|
|
||||||
final static Logger logger = LoggerFactory.getLogger("compute-clusters_command");
|
final static Logger logger = LoggerFactory.getLogger("compute-clusters_command");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST (probably to allow for larger parameters) but does not actually modify any state
|
||||||
|
* so we do not add CSRF protection to it.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -44,6 +44,11 @@ import com.google.refine.commands.Command;
|
|||||||
import com.google.refine.model.Project;
|
import com.google.refine.model.Project;
|
||||||
|
|
||||||
public class ComputeFacetsCommand extends Command {
|
public class ComputeFacetsCommand extends Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST (probably to allow for larger parameters) but does not actually modify any state
|
||||||
|
* so we do not add CSRF protection to it.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -84,6 +84,10 @@ public class EditOneCellCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request.setCharacterEncoding("UTF-8");
|
request.setCharacterEncoding("UTF-8");
|
||||||
|
@ -50,6 +50,10 @@ public class JoinMultiValueCellsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class KeyValueColumnizeCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -52,6 +52,10 @@ public class SplitMultiValueCellsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class TransposeColumnsIntoRowsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class TransposeRowsIntoColumnsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class MoveColumnCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class RemoveColumnCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -50,6 +50,10 @@ public class RenameColumnCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -48,6 +48,10 @@ public class LogExpressionCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String expression = request.getParameter("expression");
|
String expression = request.getParameter("expression");
|
||||||
|
@ -111,6 +111,10 @@ public class PreviewExpressionCommand extends Command {
|
|||||||
this.results = evaluated;
|
this.results = evaluated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* The command uses POST but does not actually modify any state so it does
|
||||||
|
* not require CSRF.
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
@ -40,6 +40,11 @@ public class ToggleStarredExpressionCommand extends Command {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String expression = request.getParameter("expression");
|
String expression = request.getParameter("expression");
|
||||||
|
|
||||||
TopList starredExpressions = ((TopList) ProjectManager.singleton.getPreferenceStore().get(
|
TopList starredExpressions = ((TopList) ProjectManager.singleton.getPreferenceStore().get(
|
||||||
|
@ -54,6 +54,10 @@ public class ApplyOperationsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
String jsonString = request.getParameter("operations");
|
String jsonString = request.getParameter("operations");
|
||||||
|
@ -53,6 +53,10 @@ public class CancelProcessesCommand extends Command {
|
|||||||
if( response == null ) {
|
if( response == null ) {
|
||||||
throw new IllegalArgumentException("parameter 'request' should not be null");
|
throw new IllegalArgumentException("parameter 'request' should not be null");
|
||||||
}
|
}
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -48,6 +48,10 @@ public class UndoRedoCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@ public class CancelImportingJobCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long jobID = Long.parseLong(request.getParameter("jobID"));
|
long jobID = Long.parseLong(request.getParameter("jobID"));
|
||||||
ImportingJob job = ImportingManager.getJob(jobID);
|
ImportingJob job = ImportingManager.getJob(jobID);
|
||||||
|
@ -52,6 +52,10 @@ public class CreateImportingJobCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long id = ImportingManager.createJob().id;
|
long id = ImportingManager.createJob().id;
|
||||||
|
|
||||||
|
@ -49,6 +49,10 @@ public class GetImportingConfigurationCommand extends Command {
|
|||||||
@JsonProperty("config")
|
@JsonProperty("config")
|
||||||
ImportingConfiguration config = new ImportingConfiguration();
|
ImportingConfiguration config = new ImportingConfiguration();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This command uses POST but does not actually modify any state so
|
||||||
|
* it is not CSRF-protected.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -34,7 +34,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
package com.google.refine.commands.importing;
|
package com.google.refine.commands.importing;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -46,7 +45,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
import com.google.refine.commands.Command;
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.importing.ImportingJob;
|
import com.google.refine.importing.ImportingJob;
|
||||||
import com.google.refine.importing.ImportingManager;
|
import com.google.refine.importing.ImportingManager;
|
||||||
import com.google.refine.util.ParsingUtilities;
|
|
||||||
|
|
||||||
public class GetImportingJobStatusCommand extends Command {
|
public class GetImportingJobStatusCommand extends Command {
|
||||||
protected static class JobStatusResponse {
|
protected static class JobStatusResponse {
|
||||||
@ -66,6 +64,10 @@ public class GetImportingJobStatusCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST but does not actually modify any state so
|
||||||
|
* it is not CSRF-protected.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
@ -73,11 +75,10 @@ public class GetImportingJobStatusCommand extends Command {
|
|||||||
long jobID = Long.parseLong(request.getParameter("jobID"));
|
long jobID = Long.parseLong(request.getParameter("jobID"));
|
||||||
ImportingJob job = ImportingManager.getJob(jobID);
|
ImportingJob job = ImportingManager.getJob(jobID);
|
||||||
|
|
||||||
Writer w = response.getWriter();
|
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
ParsingUtilities.defaultWriter.writeValue(w, new JobStatusResponse("error", "No such import job", null));
|
respondJSON(response, new JobStatusResponse("error", "No such import job", null));
|
||||||
} else {
|
} else {
|
||||||
ParsingUtilities.defaultWriter.writeValue(w, new JobStatusResponse("ok", null, job));
|
respondJSON(response, new JobStatusResponse("ok", null, job));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,9 +56,15 @@ public class ImportingControllerCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFTokenAsGET(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ImportingController controller = getController(request);
|
ImportingController controller = getController(request);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
controller.doPost(request, response);
|
controller.doPost(request, response);
|
||||||
} else {
|
} else {
|
||||||
HttpUtilities.respond(response, "error", "No such import controller");
|
HttpUtilities.respond(response, "error", "No such import controller");
|
||||||
@ -71,6 +77,8 @@ public class ImportingControllerCommand extends Command {
|
|||||||
|
|
||||||
ImportingController controller = getController(request);
|
ImportingController controller = getController(request);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
controller.doPost(request, response);
|
controller.doPost(request, response);
|
||||||
} else {
|
} else {
|
||||||
HttpUtilities.respond(response, "error", "No such import controller");
|
HttpUtilities.respond(response, "error", "No such import controller");
|
||||||
|
@ -93,12 +93,6 @@ public class GetLanguagesCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
doPost(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
|
|
||||||
String modname = request.getParameter("module");
|
String modname = request.getParameter("module");
|
||||||
if (modname == null) {
|
if (modname == null) {
|
||||||
|
@ -63,10 +63,15 @@ public class LoadLanguageCommand extends Command {
|
|||||||
doPost(request, response);
|
doPost(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST is supported but does not actually change any state so we do
|
||||||
|
* not add CSRF protection to it. This ensures existing extensions will not
|
||||||
|
* have to be updated to add a CSRF token to their requests (2019-11-10)
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
||||||
String modname = request.getParameter("module");
|
String modname = request.getParameter("module");
|
||||||
if (modname == null) {
|
if (modname == null) {
|
||||||
modname = "core";
|
modname = "core";
|
||||||
|
@ -64,6 +64,10 @@ public class CreateProjectCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFTokenAsGET(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProjectManager.singleton.setBusy(true);
|
ProjectManager.singleton.setBusy(true);
|
||||||
try {
|
try {
|
||||||
|
@ -49,6 +49,11 @@ public class DeleteProjectCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
response.setHeader("Content-Type", "application/json");
|
response.setHeader("Content-Type", "application/json");
|
||||||
try {
|
try {
|
||||||
long projectID = Long.parseLong(request.getParameter("project"));
|
long projectID = Long.parseLong(request.getParameter("project"));
|
||||||
|
@ -47,6 +47,10 @@ import com.google.refine.model.Project;
|
|||||||
|
|
||||||
public class ExportProjectCommand extends Command {
|
public class ExportProjectCommand extends Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST but is left CSRF-unprotected as it does not incur a state change.
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -62,6 +62,10 @@ import com.google.refine.model.Project;
|
|||||||
public class ExportRowsCommand extends Command {
|
public class ExportRowsCommand extends Command {
|
||||||
private static final Logger logger = LoggerFactory.getLogger("ExportRowsCommand");
|
private static final Logger logger = LoggerFactory.getLogger("ExportRowsCommand");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST but is left CSRF-unprotected as it does not incur a state change.
|
||||||
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
static public Properties getRequestParameters(HttpServletRequest request) {
|
static public Properties getRequestParameters(HttpServletRequest request) {
|
||||||
Properties options = new Properties();
|
Properties options = new Properties();
|
||||||
|
@ -55,6 +55,11 @@ import com.google.refine.model.Project;
|
|||||||
import com.google.refine.model.RecordModel;
|
import com.google.refine.model.RecordModel;
|
||||||
|
|
||||||
public class GetModelsCommand extends Command {
|
public class GetModelsCommand extends Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command uses POST but is left CSRF-unprotected as it does not incur a state change.
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -63,6 +63,10 @@ public class ImportProjectCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFTokenAsGET(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProjectManager.singleton.setBusy(true);
|
ProjectManager.singleton.setBusy(true);
|
||||||
try {
|
try {
|
||||||
|
@ -46,6 +46,10 @@ public class RenameProjectCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String name = request.getParameter("name");
|
String name = request.getParameter("name");
|
||||||
|
@ -41,6 +41,10 @@ public class SetProjectMetadataCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Project project = request.getParameter("project") != null ? getProject(request) : null;
|
Project project = request.getParameter("project") != null ? getProject(request) : null;
|
||||||
String metaName = request.getParameter("name");
|
String metaName = request.getParameter("name");
|
||||||
|
@ -43,6 +43,11 @@ public class SetProjectTagsCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
response.setHeader("Content-Type", "application/json");
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
Project project;
|
Project project;
|
||||||
|
@ -93,6 +93,10 @@ public class GuessTypesOfColumnCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -79,6 +79,10 @@ public class PreviewExtendDataCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -75,6 +75,10 @@ public class ReconClearOneCellCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -59,6 +59,10 @@ public class ReconJudgeOneCellCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request.setCharacterEncoding("UTF-8");
|
request.setCharacterEncoding("UTF-8");
|
||||||
|
@ -50,6 +50,10 @@ public class AnnotateOneRowCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
response.setCharacterEncoding("UTF-8");
|
response.setCharacterEncoding("UTF-8");
|
||||||
response.setHeader("Content-Type", "application/json");
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
@ -50,6 +50,10 @@ public class DenormalizeCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Project project = getProject(request);
|
Project project = getProject(request);
|
||||||
|
@ -111,6 +111,10 @@ public class GetRowsCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command accepts both POST and GET. It is not CSRF-protected as it does not incur any state change.
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
@ -50,6 +50,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
|
|||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.google.refine.RefineServlet;
|
import com.google.refine.RefineServlet;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.commands.HttpUtilities;
|
import com.google.refine.commands.HttpUtilities;
|
||||||
import com.google.refine.importing.ImportingManager.Format;
|
import com.google.refine.importing.ImportingManager.Format;
|
||||||
import com.google.refine.util.JSONUtilities;
|
import com.google.refine.util.JSONUtilities;
|
||||||
@ -218,7 +219,7 @@ public class DefaultImportingController implements ImportingController {
|
|||||||
JSONUtilities.safePut(result, "status", "ok");
|
JSONUtilities.safePut(result, "status", "ok");
|
||||||
JSONUtilities.safePut(result, "options", options);
|
JSONUtilities.safePut(result, "options", options);
|
||||||
|
|
||||||
HttpUtilities.respond(response, result.toString());
|
Command.respondJSON(response, result);
|
||||||
} else {
|
} else {
|
||||||
HttpUtilities.respond(response, "error", "Unrecognized format or format has no parser");
|
HttpUtilities.respond(response, "error", "Unrecognized format or format has no parser");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class CSRFTokenFactoryTests {
|
||||||
|
|
||||||
|
static class CSRFTokenFactoryStub extends CSRFTokenFactory{
|
||||||
|
public CSRFTokenFactoryStub(long timeToLive, int tokenLength) {
|
||||||
|
super(timeToLive, tokenLength);
|
||||||
|
}
|
||||||
|
public void tamperWithToken(String token, Instant newGenerationTime) {
|
||||||
|
tokenCache.asMap().put(token, newGenerationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateValidToken() {
|
||||||
|
CSRFTokenFactory factory = new CSRFTokenFactory(10, 25);
|
||||||
|
// Generate a fresh token
|
||||||
|
String token = factory.getFreshToken();
|
||||||
|
// Immediately after, the token is still valid
|
||||||
|
assertTrue(factory.validToken(token));
|
||||||
|
// The token has the right length
|
||||||
|
assertEquals(25, token.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidToken() {
|
||||||
|
CSRFTokenFactory factory = new CSRFTokenFactory(10, 25);
|
||||||
|
assertFalse(factory.validToken("bogusToken"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOldToken() {
|
||||||
|
CSRFTokenFactoryStub stub = new CSRFTokenFactoryStub(10, 25);
|
||||||
|
// Generate a fresh token
|
||||||
|
String token = stub.getFreshToken();
|
||||||
|
// Manually change the generation time
|
||||||
|
stub.tamperWithToken(token, Instant.now().minusSeconds(100));
|
||||||
|
// The token should now be invalid
|
||||||
|
assertFalse(stub.validToken(token));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
|
||||||
|
import com.google.refine.util.TestUtils;
|
||||||
|
|
||||||
|
public class CommandTestBase {
|
||||||
|
protected HttpServletRequest request = null;
|
||||||
|
protected HttpServletResponse response = null;
|
||||||
|
protected Command command = null;
|
||||||
|
protected StringWriter writer = null;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpRequestResponse() {
|
||||||
|
request = mock(HttpServletRequest.class);
|
||||||
|
response = mock(HttpServletResponse.class);
|
||||||
|
writer = new StringWriter();
|
||||||
|
try {
|
||||||
|
when(response.getWriter()).thenReturn(new PrintWriter(writer));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to check that CSRF protection was triggered
|
||||||
|
*/
|
||||||
|
protected void assertCSRFCheckFailed() {
|
||||||
|
TestUtils.assertEqualAsJson("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", writer.toString());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.browsing.EngineConfig;
|
||||||
|
import com.google.refine.model.AbstractOperation;
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
|
||||||
|
public class EngineDependentCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
private static class EngineDependentCommandStub extends EngineDependentCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractOperation createOperation(Project project, HttpServletRequest request,
|
||||||
|
EngineConfig engineConfig) throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new EngineDependentCommandStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
|
public class GetCSRFTokenCommandTest {
|
||||||
|
protected HttpServletRequest request = null;
|
||||||
|
protected HttpServletResponse response = null;
|
||||||
|
protected StringWriter writer = null;
|
||||||
|
protected Command command = null;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUp() {
|
||||||
|
request = mock(HttpServletRequest.class);
|
||||||
|
response = mock(HttpServletResponse.class);
|
||||||
|
command = new GetCSRFTokenCommand();
|
||||||
|
writer = new StringWriter();
|
||||||
|
try {
|
||||||
|
when(response.getWriter()).thenReturn(new PrintWriter(writer));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetToken() throws JsonParseException, JsonMappingException, IOException, ServletException {
|
||||||
|
command.doGet(request, response);
|
||||||
|
ObjectNode result = ParsingUtilities.mapper.readValue(writer.toString(), ObjectNode.class);
|
||||||
|
String token = result.get("token").asText();
|
||||||
|
assertTrue(Command.csrfFactory.validToken(token));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class OpenWorkspaceDirCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new OpenWorkspaceDirCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.google.refine.commands;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class SetPreferenceCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new SetPreferenceCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.RefineTest;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
import com.google.refine.util.TestUtils;
|
||||||
|
|
||||||
|
public class EditOneCellCommandTests extends RefineTest {
|
||||||
|
|
||||||
|
protected Project project = null;
|
||||||
|
protected HttpServletRequest request = null;
|
||||||
|
protected HttpServletResponse response = null;
|
||||||
|
protected Command command = null;
|
||||||
|
protected StringWriter writer = null;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpProject() {
|
||||||
|
project = createCSVProject(
|
||||||
|
"first_column,second_column\n"
|
||||||
|
+ "a,b\n"
|
||||||
|
+ "c,d\n");
|
||||||
|
command = new EditOneCellCommand();
|
||||||
|
request = mock(HttpServletRequest.class);
|
||||||
|
response = mock(HttpServletResponse.class);
|
||||||
|
writer = new StringWriter();
|
||||||
|
try {
|
||||||
|
when(response.getWriter()).thenReturn(new PrintWriter(writer));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEditOneCell() throws ServletException, IOException {
|
||||||
|
when(request.getParameter("project")).thenReturn(Long.toString(project.id));
|
||||||
|
when(request.getParameter("row")).thenReturn("1");
|
||||||
|
when(request.getParameter("cell")).thenReturn("0");
|
||||||
|
when(request.getParameter("type")).thenReturn("string");
|
||||||
|
when(request.getParameter("value")).thenReturn("e");
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
|
|
||||||
|
command.doPost(request, response);
|
||||||
|
|
||||||
|
assertEquals("a", project.rows.get(0).cells.get(0).value);
|
||||||
|
assertEquals("b", project.rows.get(0).cells.get(1).value);
|
||||||
|
assertEquals("e", project.rows.get(1).cells.get(0).value);
|
||||||
|
assertEquals("d", project.rows.get(1).cells.get(1).value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingCSRFToken() throws ServletException, IOException {
|
||||||
|
when(request.getParameter("project")).thenReturn(Long.toString(project.id));
|
||||||
|
when(request.getParameter("row")).thenReturn("1");
|
||||||
|
when(request.getParameter("cell")).thenReturn("0");
|
||||||
|
when(request.getParameter("type")).thenReturn("string");
|
||||||
|
when(request.getParameter("value")).thenReturn("e");
|
||||||
|
|
||||||
|
command.doPost(request, response);
|
||||||
|
|
||||||
|
assertEquals("c", project.rows.get(1).cells.get(0).value);
|
||||||
|
TestUtils.assertEqualAsJson("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", writer.toString());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import com.google.refine.commands.cell.JoinMultiValueCellsCommand;
|
||||||
|
|
||||||
|
public class JoinMultiValueCellsCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new JoinMultiValueCellsCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
|
||||||
|
public class KeyValueColumnizeCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new KeyValueColumnizeCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
|
||||||
|
public class SplitMultiValueCellsCommandTests extends CommandTestBase {
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new SplitMultiValueCellsCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
|
||||||
|
public class TransposeColumnsIntoRowsCommandTests extends CommandTestBase {
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new TransposeColumnsIntoRowsCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.google.refine.commands.cell;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
|
||||||
|
public class TransposeRowsIntoColumnsCommandTests extends CommandTestBase {
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new TransposeRowsIntoColumnsCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.google.refine.commands.column;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class MoveColumnCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new MoveColumnCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.column;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class RemoveColumnCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new RemoveColumnCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.column;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class RenameColumnCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new RenameColumnCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.expr;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class LogExpressionCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new LogExpressionCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,9 @@ import javax.servlet.ServletException;
|
|||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
import com.google.refine.commands.expr.ToggleStarredExpressionCommand;
|
import com.google.refine.commands.expr.ToggleStarredExpressionCommand;
|
||||||
|
import com.google.refine.util.TestUtils;
|
||||||
|
|
||||||
public class ToggleStarredExpressionCommandTests extends ExpressionCommandTestBase {
|
public class ToggleStarredExpressionCommandTests extends ExpressionCommandTestBase {
|
||||||
|
|
||||||
@ -70,7 +72,14 @@ public class ToggleStarredExpressionCommandTests extends ExpressionCommandTestBa
|
|||||||
" }";
|
" }";
|
||||||
when(request.getParameter("expression")).thenReturn("grel:facetCount(value, 'value', 'Column 1')");
|
when(request.getParameter("expression")).thenReturn("grel:facetCount(value, 'value', 'Column 1')");
|
||||||
when(request.getParameter("returnList")).thenReturn("yes");
|
when(request.getParameter("returnList")).thenReturn("yes");
|
||||||
|
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
|
||||||
command.doPost(request, response);
|
command.doPost(request, response);
|
||||||
assertResponseJsonIs(json);
|
assertResponseJsonIs(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
TestUtils.assertEqualAsJson("{\"code\":\"error\",\"message\":\"Missing or invalid csrf_token parameter\"}", writer.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.google.refine.commands.history;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class ApplyOperationsCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new ApplyOperationsCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.history;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class CancelProcessesCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new CancelProcessesCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.history;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class UndoRedoCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new UndoRedoCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.google.refine.commands.importing;
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class CancelImportingJobCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new CancelImportingJobCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.google.refine.commands.importing;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class CreateImportingJobCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new CreateImportingJobCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.google.refine.commands.importing;
|
||||||
|
|
||||||
|
import com.google.refine.commands.CommandTestBase;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class ImportingControllerCommandTests extends CommandTestBase {
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUpCommand() {
|
||||||
|
command = new ImportingControllerCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCSRFProtection() throws ServletException, IOException {
|
||||||
|
command.doPost(request, response);
|
||||||
|
assertCSRFCheckFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user