From 8c5ec6010a9d8cc39a3c13df89d96c06be62693a Mon Sep 17 00:00:00 2001 From: Mats Rydberg Date: Tue, 11 Oct 2016 11:27:57 +0200 Subject: [PATCH] Add testing of legacy Cypher HTTP endpoint This works very much like the transactional REST/HTTP endpoint, so it inherits and uses most of the pre-existing functionality, with some minor alterations in the JSON input and output. --- ...ypherRESTAuthScenariosInteractionTest.java | 50 +++++++++ ...rRESTBuiltInProceduresInteractionTest.java | 50 +++++++++ .../rest/security/CypherRESTInteraction.java | 105 ++++++++++++++++++ ...erManagementProceduresInteractionTest.java | 50 +++++++++ .../server/rest/security/RESTInteraction.java | 27 +++-- 5 files changed, 273 insertions(+), 9 deletions(-) create mode 100644 enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTAuthScenariosInteractionTest.java create mode 100644 enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTBuiltInProceduresInteractionTest.java create mode 100644 enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTInteraction.java create mode 100644 enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTUserManagementProceduresInteractionTest.java diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTAuthScenariosInteractionTest.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTAuthScenariosInteractionTest.java new file mode 100644 index 0000000000000..b25bd4b1016ac --- /dev/null +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTAuthScenariosInteractionTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.server.rest.security; + +import org.junit.Rule; + +import java.util.Map; + +import org.neo4j.server.security.enterprise.auth.AuthScenariosInteractionTestBase; +import org.neo4j.server.security.enterprise.auth.NeoInteractionLevel; +import org.neo4j.test.rule.SuppressOutput; + +import static org.neo4j.test.rule.SuppressOutput.suppressAll; + +public class CypherRESTAuthScenariosInteractionTest extends AuthScenariosInteractionTestBase +{ + @Rule + public SuppressOutput suppressOutput = suppressAll(); + + public CypherRESTAuthScenariosInteractionTest() + { + super(); + CHANGE_PWD_ERR_MSG = "User is required to change their password."; + PWD_CHANGE_CHECK_FIRST = true; + IS_EMBEDDED = false; + } + + @Override + protected NeoInteractionLevel setUpNeoServer( Map config ) throws Throwable + { + return new CypherRESTInteraction( config ); + } +} diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTBuiltInProceduresInteractionTest.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTBuiltInProceduresInteractionTest.java new file mode 100644 index 0000000000000..3bd9524af3998 --- /dev/null +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTBuiltInProceduresInteractionTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.server.rest.security; + +import org.junit.Rule; + +import java.util.Map; + +import org.neo4j.server.security.enterprise.auth.BuiltInProceduresInteractionTestBase; +import org.neo4j.server.security.enterprise.auth.NeoInteractionLevel; +import org.neo4j.test.rule.SuppressOutput; + +import static org.neo4j.test.rule.SuppressOutput.suppressAll; + +public class CypherRESTBuiltInProceduresInteractionTest extends BuiltInProceduresInteractionTestBase +{ + @Rule + public SuppressOutput suppressOutput = suppressAll(); + + public CypherRESTBuiltInProceduresInteractionTest() + { + super(); + CHANGE_PWD_ERR_MSG = "User is required to change their password."; + PWD_CHANGE_CHECK_FIRST = true; + IS_EMBEDDED = false; + } + + @Override + public NeoInteractionLevel setUpNeoServer( Map config ) throws Throwable + { + return new CypherRESTInteraction( config ); + } +} diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTInteraction.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTInteraction.java new file mode 100644 index 0000000000000..78cf81b372632 --- /dev/null +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTInteraction.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.server.rest.security; + +import org.codehaus.jackson.JsonNode; + +import java.io.IOException; +import java.util.Map; +import java.util.function.Consumer; +import javax.ws.rs.core.HttpHeaders; + +import org.neo4j.graphdb.ResourceIterator; +import org.neo4j.server.rest.domain.JsonHelper; +import org.neo4j.server.rest.domain.JsonParseException; +import org.neo4j.test.server.HTTP; + +import static org.junit.Assert.fail; +import static org.neo4j.test.server.HTTP.RawPayload.quotedJson; + +class CypherRESTInteraction extends RESTInteraction +{ + + @Override + String commitPath() + { + return "db/data/cypher"; + } + + CypherRESTInteraction( Map config ) throws IOException + { + super( config ); + } + + @Override + public String executeQuery( RESTSubject subject, String call, Map params, + Consumer>> resultConsumer ) + { + HTTP.RawPayload payload = constructQuery( call ); + HTTP.Response response = HTTP.withHeaders( HttpHeaders.AUTHORIZATION, subject.principalCredentials ) + .request( POST, commitURL(), payload ); + + try + { + String error = parseErrorMessage( response ); + if ( !error.isEmpty() ) + { + return error; + } + JsonNode data = JsonHelper.jsonNode( response.rawContent() ); + if ( data.has( "data" ) && data.get( "data" ).has( 0 ) ) + { + resultConsumer.accept( new CypherRESTResult( data ) ); + } + } + catch ( JsonParseException e ) + { + fail( "Unexpected error parsing Json!" ); + } + + return ""; + } + + private HTTP.RawPayload constructQuery( String query ) + { + return quotedJson( " { 'query': '" + query.replace( "'", "\\'" ).replace( "\"", "\\\"" ) + "' }" ); + } + + @Override + protected HTTP.Response authenticate( String principalCredentials ) + { + return HTTP.withHeaders( HttpHeaders.AUTHORIZATION, principalCredentials ) + .request( POST, commitURL(), constructQuery( "RETURN 1" ) ); + } + + private class CypherRESTResult extends RESTResult + { + CypherRESTResult( JsonNode fullResult ) + { + super( fullResult ); + } + + @Override + JsonNode getRow( JsonNode data, int i ) + { + return data.get( i ); + } + } +} diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTUserManagementProceduresInteractionTest.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTUserManagementProceduresInteractionTest.java new file mode 100644 index 0000000000000..4da3436a79aa9 --- /dev/null +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/CypherRESTUserManagementProceduresInteractionTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.server.rest.security; + +import org.junit.Rule; + +import java.util.Map; + +import org.neo4j.server.security.enterprise.auth.AuthProceduresInteractionTestBase; +import org.neo4j.server.security.enterprise.auth.NeoInteractionLevel; +import org.neo4j.test.rule.SuppressOutput; + +import static org.neo4j.test.rule.SuppressOutput.suppressAll; + +public class CypherRESTUserManagementProceduresInteractionTest extends AuthProceduresInteractionTestBase +{ + @Rule + public SuppressOutput suppressOutput = suppressAll(); + + public CypherRESTUserManagementProceduresInteractionTest() + { + super(); + CHANGE_PWD_ERR_MSG = "User is required to change their password."; + PWD_CHANGE_CHECK_FIRST = true; + IS_EMBEDDED = false; + } + + @Override + public NeoInteractionLevel setUpNeoServer( Map config ) throws Throwable + { + return new CypherRESTInteraction( config ); + } +} diff --git a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/RESTInteraction.java b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/RESTInteraction.java index 6c2cc6ecc1c87..d02982da9cc31 100644 --- a/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/RESTInteraction.java +++ b/enterprise/server-enterprise/src/test/java/org/neo4j/server/rest/security/RESTInteraction.java @@ -64,10 +64,14 @@ class RESTInteraction extends CommunityServerTestBase implements NeoInteractionLevel { - private String COMMIT_PATH = "db/data/transaction/commit"; - private String POST = "POST"; + String commitPath() + { + return "db/data/transaction/commit"; + } + + static final String POST = "POST"; - EnterpriseAuthManager authManager; + private EnterpriseAuthManager authManager; RESTInteraction( Map config ) throws IOException { @@ -161,7 +165,7 @@ public RESTSubject login( String username, String password ) throws Exception return new RESTSubject( username, password, principalCredentials ); } - private HTTP.Response authenticate( String principalCredentials ) + protected HTTP.Response authenticate( String principalCredentials ) { return HTTP.withHeaders( HttpHeaders.AUTHORIZATION, principalCredentials ).request( POST, commitURL() ); } @@ -222,7 +226,7 @@ public String getConnectionDetails() return "server-session"; } - private String parseErrorMessage( HTTP.Response response ) + String parseErrorMessage( HTTP.Response response ) { try { @@ -243,12 +247,12 @@ private String parseErrorMessage( HTTP.Response response ) return ""; } - private String commitURL() + String commitURL() { - return server.baseUri().resolve( COMMIT_PATH ).toString(); + return server.baseUri().resolve( commitPath() ).toString(); } - private class RESTResult implements ResourceIterator> + class RESTResult implements ResourceIterator> { private JsonNode data; private JsonNode columns; @@ -275,7 +279,7 @@ public boolean hasNext() @Override public Map next() { - JsonNode row = data.get( index++ ).get( "row" ); + JsonNode row = getRow( data, index++ ); TreeMap map = new TreeMap<>(); for ( int i = 0; i < columns.size(); i++ ) { @@ -285,6 +289,11 @@ public Map next() } return map; } + + JsonNode getRow( JsonNode data, int i ) + { + return data.get( i ).get( "row" ); + } } private Object getValue( JsonNode valueNode )