Skip to content

Commit 5a4c48e

Browse files
vagishaclaude
andcommitted
Restricted mock NCBI publication search test actions to dev mode
* The three actions (SetupMockNcbiService, RestoreNcbiService, RegisterMockPublication) swap a process-wide service and were reachable on production via a forge-able GET (ReadOnlyApiAction does no CSRF check), despite @RequiresSiteAdmin * Added requireDevModeForMockNcbiService(): the actions now return 404 in non-dev mode * Changed actions to MutatingApiAction (correct type for state mutation; also enforces a CSRF token) * Updated PublicationSearchTest to use SimplePostCommand; verified passing with the mock (POST path) and against real NCBI Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d3d8590 commit 5a4c48e

2 files changed

Lines changed: 21 additions & 7 deletions

File tree

‎panoramapublic/src/org/labkey/panoramapublic/PanoramaPublicController.java‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.labkey.api.action.FormHandlerAction;
3333
import org.labkey.api.action.FormViewAction;
3434
import org.labkey.api.action.LabKeyError;
35+
import org.labkey.api.action.MutatingApiAction;
3536
import org.labkey.api.action.ReadOnlyApiAction;
3637
import org.labkey.api.action.ReturnUrlForm;
3738
import org.labkey.api.action.SimpleErrorView;
@@ -11233,34 +11234,47 @@ public static ActionURL getCatalogImageDownloadUrl(ExperimentAnnotations expAnno
1123311234

1123411235
// ======================== Support actions for Selenium tests ========================
1123511236

11237+
// These actions swap the process-wide NCBI publication search service to a mock so that Selenium tests
11238+
// run without calling the live NCBI API. They must never be reachable on a production server (non-dev-mode)
11239+
private static void requireDevModeForMockNcbiService()
11240+
{
11241+
if (!AppProps.getInstance().isDevMode())
11242+
{
11243+
throw new NotFoundException("Mock NCBI publication search service actions are only available on a server running in dev mode.");
11244+
}
11245+
}
11246+
1123611247
@RequiresSiteAdmin
11237-
public static class SetupMockNcbiServiceAction extends ReadOnlyApiAction<Object>
11248+
public static class SetupMockNcbiServiceAction extends MutatingApiAction<Object>
1123811249
{
1123911250
@Override
1124011251
public Object execute(Object form, BindException errors)
1124111252
{
11253+
requireDevModeForMockNcbiService();
1124211254
NcbiPublicationSearchServiceImpl.setInstance(new MockNcbiPublicationSearchService());
1124311255
return new ApiSimpleResponse("mock", true);
1124411256
}
1124511257
}
1124611258

1124711259
@RequiresSiteAdmin
11248-
public static class RestoreNcbiServiceAction extends ReadOnlyApiAction<Object>
11260+
public static class RestoreNcbiServiceAction extends MutatingApiAction<Object>
1124911261
{
1125011262
@Override
1125111263
public Object execute(Object form, BindException errors)
1125211264
{
11265+
requireDevModeForMockNcbiService();
1125311266
NcbiPublicationSearchServiceImpl.setInstance(new NcbiPublicationSearchServiceImpl());
1125411267
return new ApiSimpleResponse("restored", true);
1125511268
}
1125611269
}
1125711270

1125811271
@RequiresSiteAdmin
11259-
public static class RegisterMockPublicationAction extends ReadOnlyApiAction<RegisterMockPublicationForm>
11272+
public static class RegisterMockPublicationAction extends MutatingApiAction<RegisterMockPublicationForm>
1126011273
{
1126111274
@Override
1126211275
public Object execute(RegisterMockPublicationForm form, BindException errors)
1126311276
{
11277+
requireDevModeForMockNcbiService();
1126411278
NcbiPublicationSearchService service = NcbiPublicationSearchServiceImpl.getInstance();
1126511279
if (!(service instanceof MockNcbiPublicationSearchService mock))
1126611280
{

‎panoramapublic/test/src/org/labkey/test/tests/panoramapublic/PublicationSearchTest.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import org.junit.experimental.categories.Category;
66
import org.labkey.remoteapi.CommandException;
77
import org.labkey.remoteapi.Connection;
8-
import org.labkey.remoteapi.SimpleGetCommand;
8+
import org.labkey.remoteapi.SimplePostCommand;
99
import org.labkey.remoteapi.query.Filter;
1010
import org.labkey.remoteapi.query.SelectRowsCommand;
1111
import org.labkey.remoteapi.query.SelectRowsResponse;
@@ -341,7 +341,7 @@ private void initMockNcbiService()
341341
try
342342
{
343343
Connection connection = createDefaultConnection();
344-
SimpleGetCommand command = new SimpleGetCommand("panoramapublic", "setupMockNcbiService");
344+
SimplePostCommand command = new SimplePostCommand("panoramapublic", "setupMockNcbiService");
345345
command.execute(connection, "/");
346346
_useMockNcbi = true;
347347
log("Using mock NCBI service");
@@ -417,7 +417,7 @@ private void registerMockPublication(String database, String id, String searchKe
417417
try
418418
{
419419
Connection connection = createDefaultConnection();
420-
SimpleGetCommand command = new SimpleGetCommand("panoramapublic", "registerMockPublication");
420+
SimplePostCommand command = new SimplePostCommand("panoramapublic", "registerMockPublication");
421421
Map<String, Object> params = new HashMap<>();
422422
params.put("database", database);
423423
params.put("id", id);
@@ -447,7 +447,7 @@ private void restoreNcbiService()
447447
try
448448
{
449449
Connection connection = createDefaultConnection();
450-
SimpleGetCommand command = new SimpleGetCommand("panoramapublic", "restoreNcbiService");
450+
SimplePostCommand command = new SimplePostCommand("panoramapublic", "restoreNcbiService");
451451
command.execute(connection, "/");
452452
log("Restored real NCBI service");
453453
}

0 commit comments

Comments
 (0)