Add CSRF protection to cell, history, column and expr commands

This commit is contained in:
Antonin Delpeuch 2019-10-11 12:24:44 +01:00
parent 51ddd27909
commit 70e37b9085
43 changed files with 616 additions and 93 deletions

View File

@ -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);

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -48,7 +48,11 @@ 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");

View File

@ -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)

View File

@ -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(

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -66,6 +66,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 {

View File

@ -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());
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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());
}
} }

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -56,6 +56,7 @@ import org.testng.annotations.Test;
import com.google.refine.ProjectManager; import com.google.refine.ProjectManager;
import com.google.refine.RefineTest; import com.google.refine.RefineTest;
import com.google.refine.commands.Command;
import com.google.refine.commands.history.CancelProcessesCommand; import com.google.refine.commands.history.CancelProcessesCommand;
import com.google.refine.model.Project; import com.google.refine.model.Project;
import com.google.refine.process.ProcessManager; import com.google.refine.process.ProcessManager;
@ -159,6 +160,7 @@ public class CancelProcessesCommandTests extends RefineTest {
// mock dependencies // mock dependencies
when(request.getParameter("project")).thenReturn(PROJECT_ID); when(request.getParameter("project")).thenReturn(PROJECT_ID);
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
when(projMan.getProject(anyLong())).thenReturn(proj); when(projMan.getProject(anyLong())).thenReturn(proj);
when(proj.getProcessManager()).thenReturn(processMan); when(proj.getProcessManager()).thenReturn(processMan);
try { try {
@ -197,6 +199,7 @@ public class CancelProcessesCommandTests extends RefineTest {
public void doPostThrowsIfCommand_getProjectReturnsNull(){ public void doPostThrowsIfCommand_getProjectReturnsNull(){
// mock dependencies // mock dependencies
when(request.getParameter("project")).thenReturn(PROJECT_ID); when(request.getParameter("project")).thenReturn(PROJECT_ID);
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
when(projMan.getProject(anyLong())) when(projMan.getProject(anyLong()))
.thenReturn(null); .thenReturn(null);
try { try {
@ -225,6 +228,7 @@ public class CancelProcessesCommandTests extends RefineTest {
// mock dependencies // mock dependencies
when(request.getParameter("project")).thenReturn(PROJECT_ID); when(request.getParameter("project")).thenReturn(PROJECT_ID);
when(request.getParameter("csrf_token")).thenReturn(Command.csrfFactory.getFreshToken());
when(projMan.getProject(anyLong())).thenReturn(proj); when(projMan.getProject(anyLong())).thenReturn(proj);
when(proj.getProcessManager()).thenReturn(processMan); when(proj.getProcessManager()).thenReturn(processMan);
try { try {

View File

@ -157,13 +157,15 @@ ExpressionPreviewDialog.Widget.prototype.getExpression = function(commit) {
s = this._getLanguage() + ":" + s; s = this._getLanguage() + ":" + s;
if (commit) { if (commit) {
$.post( Refine.wrapCSRF(function(token) {
"command/core/log-expression?" + $.param({ project: theProject.id }), $.post(
{ expression: s }, "command/core/log-expression?" + $.param({ project: theProject.id }),
function(data) { { expression: s, csrf_token: token },
}, function(data) {
"json" },
); "json"
);
});
} }
return s; return s;
@ -284,16 +286,21 @@ ExpressionPreviewDialog.Widget.prototype._renderExpressionHistory = function(dat
.addClass(entry.starred ? "data-table-star-on" : "data-table-star-off") .addClass(entry.starred ? "data-table-star-on" : "data-table-star-off")
.appendTo(tr.insertCell(0)) .appendTo(tr.insertCell(0))
.click(function() { .click(function() {
$.post( Refine.wrapCSRF(function(token) {
"command/core/toggle-starred-expression", $.post(
{ expression: entry.code }, "command/core/toggle-starred-expression",
function(data) { {
entry.starred = !entry.starred; expression: entry.code,
renderEntry(self,tr,entry); csrf_token: token
self._renderStarredExpressionsTab(); },
}, function(data) {
"json" entry.starred = !entry.starred;
); renderEntry(self,tr,entry);
self._renderStarredExpressionsTab();
},
"json"
);
});
}); });
$('<a href="javascript:{}">'+$.i18n('core-dialogs/reuse')+'</a>').appendTo(tr.insertCell(1)).click(function() { $('<a href="javascript:{}">'+$.i18n('core-dialogs/reuse')+'</a>').appendTo(tr.insertCell(1)).click(function() {
@ -348,15 +355,17 @@ ExpressionPreviewDialog.Widget.prototype._renderStarredExpressions = function(da
var o = Scripting.parse(entry.code); var o = Scripting.parse(entry.code);
$('<a href="javascript:{}">'+$.i18n('core-dialogs/remove')+'</a>').appendTo(tr.insertCell(0)).click(function() { $('<a href="javascript:{}">'+$.i18n('core-dialogs/remove')+'</a>').appendTo(tr.insertCell(0)).click(function() {
$.post( Refine.wrapCSRF(function(token) {
"command/core/toggle-starred-expression", $.post(
{ expression: entry.code, returnList: true }, "command/core/toggle-starred-expression",
function(data) { { expression: entry.code, returnList: true, csrf_token: token },
self._renderStarredExpressions(data); function(data) {
self._renderExpressionHistoryTab(); self._renderStarredExpressions(data);
}, self._renderExpressionHistoryTab();
"json" },
); "json"
);
});
}); });
$('<a href="javascript:{}">Reuse</a>').appendTo(tr.insertCell(1)).click(function() { $('<a href="javascript:{}">Reuse</a>').appendTo(tr.insertCell(1)).click(function() {

View File

@ -271,5 +271,8 @@ Refine.CreateProjectUI.composeErrorMessage = function(job) {
}; };
Refine.CreateProjectUI.cancelImportingJob = function(jobID) { Refine.CreateProjectUI.cancelImportingJob = function(jobID) {
$.post("command/core/cancel-importing-job?" + $.param({ "jobID": jobID })); Refine.wrapCSRF(function(token) {
$.post("command/core/cancel-importing-job?" + $.param({ "jobID": jobID }),
{csrf_token: token});
});
}; };

View File

@ -78,61 +78,63 @@ Refine.DefaultImportingController.prototype.startImportJob = function(form, prog
return this.value === ""; return this.value === "";
}).attr("disabled", "disabled"); }).attr("disabled", "disabled");
$.post( Refine.wrapCSRF(function(token) {
"command/core/create-importing-job", $.post(
null, "command/core/create-importing-job",
function(data) { { csrf_token: token },
var jobID = self._jobID = data.jobID; function(data) {
var jobID = self._jobID = data.jobID;
form.attr("method", "post") form.attr("method", "post")
.attr("enctype", "multipart/form-data") .attr("enctype", "multipart/form-data")
.attr("accept-charset", "UTF-8") .attr("accept-charset", "UTF-8")
.attr("target", "create-project-iframe") .attr("target", "create-project-iframe")
.attr("action", "command/core/importing-controller?" + $.param({ .attr("action", "command/core/importing-controller?" + $.param({
"controller": "core/default-importing-controller", "controller": "core/default-importing-controller",
"jobID": jobID, "jobID": jobID,
"subCommand": "load-raw-data" "subCommand": "load-raw-data"
})); }));
form[0].submit(); form[0].submit();
var start = new Date(); var start = new Date();
var timerID = window.setInterval( var timerID = window.setInterval(
function() { function() {
self._createProjectUI.pollImportJob( self._createProjectUI.pollImportJob(
start, jobID, timerID, start, jobID, timerID,
function(job) { function(job) {
return job.config.hasData; return job.config.hasData;
}, },
function(jobID, job) { function(jobID, job) {
self._job = job; self._job = job;
self._onImportJobReady(); self._onImportJobReady();
if (callback) { if (callback) {
callback(jobID, job); callback(jobID, job);
}
},
function(job) {
alert(job.config.error + '\n' + job.config.errorDetails);
self._startOver();
} }
}, );
function(job) { },
alert(job.config.error + '\n' + job.config.errorDetails); 1000
self._startOver();
}
); );
}, self._createProjectUI.showImportProgressPanel(progressMessage, function() {
1000 // stop the iframe
); $('#create-project-iframe')[0].contentWindow.stop();
self._createProjectUI.showImportProgressPanel(progressMessage, function() {
// stop the iframe
$('#create-project-iframe')[0].contentWindow.stop();
// stop the timed polling // stop the timed polling
window.clearInterval(timerID); window.clearInterval(timerID);
// explicitly cancel the import job // explicitly cancel the import job
Refine.CreateProjectUI.cancelImportingJob(jobID); Refine.CreateProjectUI.cancelImportingJob(jobID);
self._createProjectUI.showSourceSelectionPanel(); self._createProjectUI.showSourceSelectionPanel();
}); });
}, },
"json" "json"
); );
});
}; };
Refine.DefaultImportingController.prototype._onImportJobReady = function() { Refine.DefaultImportingController.prototype._onImportJobReady = function() {

View File

@ -388,22 +388,18 @@ Refine.postProcess = function(moduleName, command, params, body, updateOptions,
Refine.setAjaxInProgress(); Refine.setAjaxInProgress();
// Get a CSRF token first Refine.wrapCSRF(
$.get( function(token) {
"command/core/get-csrf-token",
{},
function(response) {
// Add it to the body and submit it as a POST request // Add it to the body and submit it as a POST request
body['csrf_token'] = response['token']; body['csrf_token'] = token;
$.post( $.post(
"command/" + moduleName + "/" + command + "?" + $.param(params), "command/" + moduleName + "/" + command + "?" + $.param(params),
body, body,
onDone, onDone,
"json" "json"
); );
}, }
"json"
); );
window.setTimeout(function() { window.setTimeout(function() {
@ -413,6 +409,19 @@ Refine.postProcess = function(moduleName, command, params, body, updateOptions,
}, 500); }, 500);
}; };
// Requests a CSRF token and calls the supplied callback
// with the token
Refine.wrapCSRF = function(onCSRF) {
$.get(
"command/core/get-csrf-token",
{},
function(response) {
onCSRF(response['token']);
},
"json"
);
};
Refine.setAjaxInProgress = function() { Refine.setAjaxInProgress = function() {
$(document.body).attr("ajax_in_progress", "true"); $(document.body).attr("ajax_in_progress", "true");
}; };

View File

@ -124,15 +124,17 @@ ProcessPanel.prototype.undo = function() {
ProcessPanel.prototype._cancelAll = function() { ProcessPanel.prototype._cancelAll = function() {
var self = this; var self = this;
$.post( Refine.wrapCSRF(function(token) {
"command/core/cancel-processes?" + $.param({ project: theProject.id }), $.post(
null, "command/core/cancel-processes?" + $.param({ project: theProject.id }),
function(o) { { csrf_token: token },
self._data = null; function(o) {
self._runOnDones(); self._data = null;
}, self._runOnDones();
"json" },
); "json"
);
});
}; };
ProcessPanel.prototype._render = function(newData) { ProcessPanel.prototype._render = function(newData) {