From edff48c5c22f86791364c5e4954cf88c109768bb Mon Sep 17 00:00:00 2001 From: Stefan Plantikow Date: Mon, 12 Sep 2016 11:31:09 +0200 Subject: [PATCH] Use InvalidArgumentsException in BuiltInProcedures o InvalidArgumentsException is now a generic exception and no longer tied to security o Wrote some utility code for tunneling checked exceptions out of stream pipelines --- .../security/auth/BasicAuthentication.java | 2 +- .../integration/AuthenticationIT.java | 4 +- .../org/neo4j/function/ThrowingFunction.java | 52 ++++++++++++++ .../org/neo4j/function/ThrowingFunctions.java | 32 ++------- .../function/UncaughtCheckedException.java | 49 +++++++++++++ .../neo4j/kernel/api/exceptions/Status.java | 2 +- .../InvalidArgumentsException.java | 13 ++-- .../kernel/api/security/AuthSubject.java | 2 +- .../security/auth/AbstractUserRepository.java | 2 +- .../server/security/auth/AuthProcedures.java | 2 +- .../security/auth/BasicAuthManager.java | 2 +- .../security/auth/BasicAuthSubject.java | 2 +- .../security/auth/BasicPasswordPolicy.java | 2 +- .../server/security/auth/PasswordPolicy.java | 2 +- .../server/security/auth/UserManager.java | 2 +- .../server/security/auth/UserRepository.java | 2 +- .../admin/security/CommandTestBase.java | 2 +- .../security/auth/AuthProceduresIT.java | 2 +- .../security/auth/BasicAuthManagerTest.java | 2 +- .../neo4j/server/rest/dbms/UserService.java | 2 +- .../server/rest/dbms/UserServiceTest.java | 2 +- .../api/security/EnterpriseAuthSubject.java | 2 +- .../builtinprocs/BuiltInProcedures.java | 72 +++++++++++++------ .../enterprise/builtinprocs/QueryId.java | 14 ++-- .../enterprise/builtinprocs/QueryIdTest.java | 26 +++---- .../auth/AbstractRoleRepository.java | 2 +- .../enterprise/auth/AuthProcedures.java | 2 +- .../auth/EnterpriseUserManager.java | 2 +- .../auth/InternalFlatFileRealm.java | 2 +- .../enterprise/auth/RoleRepository.java | 2 +- .../auth/StandardEnterpriseAuthSubject.java | 2 +- .../AuthProceduresInteractionTestBase.java | 2 +- ...eddedBuiltInProceduresInteractionTest.java | 2 +- .../auth/MultiRealmAuthManagerTest.java | 2 +- .../auth/ProcedureInteractionTestBase.java | 2 +- .../bolt/BoltConnectionManagementIT.java | 2 +- 36 files changed, 218 insertions(+), 100 deletions(-) create mode 100644 community/common/src/main/java/org/neo4j/function/UncaughtCheckedException.java rename community/kernel/src/main/java/org/neo4j/kernel/api/{security/exception => exceptions}/InvalidArgumentsException.java (81%) diff --git a/community/bolt/src/main/java/org/neo4j/bolt/security/auth/BasicAuthentication.java b/community/bolt/src/main/java/org/neo4j/bolt/security/auth/BasicAuthentication.java index 36cc86d44972f..268cf863388dc 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/security/auth/BasicAuthentication.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/security/auth/BasicAuthentication.java @@ -27,7 +27,7 @@ import org.neo4j.kernel.api.security.AuthManager; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthToken; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import org.neo4j.logging.Log; import org.neo4j.logging.LogProvider; diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java index cae592f5531b5..2f90fc8f76a0c 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java @@ -320,7 +320,7 @@ public void shouldFailWhenReusingTheSamePassword() throws Throwable PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgFailure(Status.Security.InvalidArguments, + assertThat( client, eventuallyReceives( msgFailure(Status.General.InvalidArguments, "Old password and new password cannot be the same.") ) ); } @@ -344,7 +344,7 @@ public void shouldFailWhenSubmittingEmptyPassword() throws Throwable PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgFailure(Status.Security.InvalidArguments, + assertThat( client, eventuallyReceives( msgFailure(Status.General.InvalidArguments, "A password cannot be empty.") ) ); } diff --git a/community/common/src/main/java/org/neo4j/function/ThrowingFunction.java b/community/common/src/main/java/org/neo4j/function/ThrowingFunction.java index 78370e66ccc4d..6c26baee53f09 100644 --- a/community/common/src/main/java/org/neo4j/function/ThrowingFunction.java +++ b/community/common/src/main/java/org/neo4j/function/ThrowingFunction.java @@ -19,6 +19,9 @@ */ package org.neo4j.function; +import java.util.Optional; +import java.util.function.Function; + /** * Represents a function that accepts one argument and produces a result, or throws an exception. * @@ -36,4 +39,53 @@ public interface ThrowingFunction * @throws E an exception if the function fails */ R apply( T t ) throws E; + + /** + * Construct a regular function that calls a throwing function and catches all checked exceptions + * declared and thrown by the throwing function and rethrows them as {@link UncaughtCheckedException} + * for handling further up the stack. + * + * @see UncaughtCheckedException + * + * @param throwing the throwing function to wtap + * @param type of arguments + * @param type of results + * @param type of checked exceptions thrown by the throwing function + * @return a new, non-throwing function + * @throws IllegalStateException if an unexpected exception is caught (ie. neither of type E or a runtime exception) + */ + static Function catchThrown( Class clazz, ThrowingFunction throwing ) + { + return input -> + { + try + { + return throwing.apply( input ); + } + catch ( Exception e ) + { + if ( clazz.isInstance( e ) ) + { + throw new UncaughtCheckedException( throwing, clazz.cast( e ) ); + } + else if ( e instanceof RuntimeException ) + { + throw (RuntimeException) e; + } + else + { + throw new IllegalStateException( "Unexpected exception", e ); + } + } + }; + } + + @SuppressWarnings( "OptionalUsedAsFieldOrParameterType" ) + static void throwIfPresent( Optional exception ) throws E + { + if ( exception.isPresent() ) + { + throw exception.get(); + } + } } diff --git a/community/common/src/main/java/org/neo4j/function/ThrowingFunctions.java b/community/common/src/main/java/org/neo4j/function/ThrowingFunctions.java index 708d251d84721..e3e515166f677 100644 --- a/community/common/src/main/java/org/neo4j/function/ThrowingFunctions.java +++ b/community/common/src/main/java/org/neo4j/function/ThrowingFunctions.java @@ -24,14 +24,7 @@ */ public final class ThrowingFunctions { - private static final ThrowingUnaryOperator IDENTITY = new ThrowingUnaryOperator() - { - @Override - public Object apply( Object value ) - { - return value; - } - }; + private static final ThrowingUnaryOperator IDENTITY = value -> value; @SuppressWarnings( "unchecked" ) public static ThrowingUnaryOperator identity() @@ -39,28 +32,17 @@ public static ThrowingUnaryOperator identity() return IDENTITY; } - public static ThrowingFunction fromConsumer( final ThrowingConsumer consumer ) + public static ThrowingFunction fromConsumer( ThrowingConsumer consumer ) { - return new ThrowingFunction() + return t -> { - @Override - public Void apply( T t ) throws E - { - consumer.accept( t ); - return null; - } + consumer.accept( t ); + return null; }; } - public static ThrowingFunction fromSupplier( final ThrowingSupplier supplier ) + public static ThrowingFunction fromSupplier( ThrowingSupplier supplier ) { - return new ThrowingFunction() - { - @Override - public T apply( Void t ) throws E - { - return supplier.get(); - } - }; + return t -> supplier.get(); } } diff --git a/community/common/src/main/java/org/neo4j/function/UncaughtCheckedException.java b/community/common/src/main/java/org/neo4j/function/UncaughtCheckedException.java new file mode 100644 index 0000000000000..cd76013e82074 --- /dev/null +++ b/community/common/src/main/java/org/neo4j/function/UncaughtCheckedException.java @@ -0,0 +1,49 @@ +package org.neo4j.function; + +import java.util.Optional; + +/** + * Wrapper around checked exceptions for rethrowing them as runtime exceotions when the signature of the containing method + * cannot be changed to declare them. + * + * Thrown by {@link ThrowingFunction#catchThrown(Class, ThrowingFunction)} + */ +public class UncaughtCheckedException extends RuntimeException +{ + private final Object source; + + public UncaughtCheckedException( Object source, Throwable cause ) + { + super( "Uncaught checked exception", cause ); + if ( cause == null ) + { + throw new IllegalArgumentException( "Expected non-null cause" ); + } + this.source = source; + } + + /** + * Check the that the cause has the given type and if succesful, return it. + * + * @param clazz class object for the desired type of the cause + * @param the desired type of the cause + * @return the underlying cause of this exception but only if it is of desired type E, nothing otherwise + */ + public Optional getCauseIfOfType( Class clazz ) + { + Throwable cause = getCause(); + if ( clazz.isInstance( cause ) ) + { + return Optional.of( clazz.cast( cause ) ); + } + else + { + return Optional.empty(); + } + } + + public Object source() + { + return source; + } +} diff --git a/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java b/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java index 13db867b8601d..fefd507209d04 100644 --- a/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java +++ b/community/common/src/main/java/org/neo4j/kernel/api/exceptions/Status.java @@ -404,7 +404,6 @@ public Code code() enum Security implements Status // TODO: rework by the Security Team before these are updated { // client - InvalidArguments( ClientError, "The request contained fields that were empty or are not allowed." ), CredentialsExpired( ClientError, "The credentials have expired and need to be updated." ), Unauthorized( ClientError, "The client is unauthorized due to authentication failure." ), AuthenticationRateLimit( ClientError, "The client has provided incorrect authentication details too many times in a row." ), @@ -429,6 +428,7 @@ public Code code() enum General implements Status { // client errors + InvalidArguments( ClientError, "The request contained fields that were empty or are not allowed." ), ForbiddenOnReadOnlyDatabase( ClientError, "This is a read only database, writing or modifying the database is not allowed." ), diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/security/exception/InvalidArgumentsException.java b/community/kernel/src/main/java/org/neo4j/kernel/api/exceptions/InvalidArgumentsException.java similarity index 81% rename from community/kernel/src/main/java/org/neo4j/kernel/api/security/exception/InvalidArgumentsException.java rename to community/kernel/src/main/java/org/neo4j/kernel/api/exceptions/InvalidArgumentsException.java index 62eed61dc2287..cb0db8435ecaf 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/security/exception/InvalidArgumentsException.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/exceptions/InvalidArgumentsException.java @@ -17,9 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.kernel.api.security.exception; - -import org.neo4j.kernel.api.exceptions.Status; +package org.neo4j.kernel.api.exceptions; public class InvalidArgumentsException extends Exception implements Status.HasStatus { @@ -27,8 +25,13 @@ public class InvalidArgumentsException extends Exception implements Status.HasSt public InvalidArgumentsException( String message ) { - super(message); - this.status = Status.Security.InvalidArguments; + this( message, null ); + } + + public InvalidArgumentsException( String message, Throwable cause ) + { + super( message, cause ); + this.status = Status.General.InvalidArguments; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/security/AuthSubject.java b/community/kernel/src/main/java/org/neo4j/kernel/api/security/AuthSubject.java index 8c199f974a48c..eeb9cf0295cb8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/security/AuthSubject.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/security/AuthSubject.java @@ -22,7 +22,7 @@ import java.io.IOException; import org.neo4j.graphdb.security.AuthorizationViolationException; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; public interface AuthSubject extends AccessMode { diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/AbstractUserRepository.java b/community/security/src/main/java/org/neo4j/server/security/auth/AbstractUserRepository.java index 064947b559a91..cac2f7cc7b707 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/AbstractUserRepository.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/AbstractUserRepository.java @@ -29,7 +29,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.lifecycle.LifecycleAdapter; import org.neo4j.server.security.auth.exception.ConcurrentModificationException; diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/AuthProcedures.java b/community/security/src/main/java/org/neo4j/server/security/auth/AuthProcedures.java index 717fecb6c23e3..8d4084a1757cf 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/AuthProcedures.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/AuthProcedures.java @@ -26,7 +26,7 @@ import java.util.stream.Stream; import org.neo4j.kernel.api.security.AuthSubject; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java index abfe75df5af0a..72823bad36547 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthManager.java @@ -29,7 +29,7 @@ import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthToken; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import org.neo4j.server.security.auth.exception.ConcurrentModificationException; diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthSubject.java b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthSubject.java index dd58f6015d7fc..ca441fcb4ddb3 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthSubject.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/BasicAuthSubject.java @@ -25,7 +25,7 @@ import org.neo4j.kernel.api.security.AccessMode; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import static org.neo4j.kernel.api.security.AuthenticationResult.FAILURE; import static org.neo4j.kernel.api.security.AuthenticationResult.PASSWORD_CHANGE_REQUIRED; diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/BasicPasswordPolicy.java b/community/security/src/main/java/org/neo4j/server/security/auth/BasicPasswordPolicy.java index a1ed018b5db26..ac7b7e5002b49 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/BasicPasswordPolicy.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/BasicPasswordPolicy.java @@ -19,7 +19,7 @@ */ package org.neo4j.server.security.auth; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; public class BasicPasswordPolicy implements PasswordPolicy { diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/PasswordPolicy.java b/community/security/src/main/java/org/neo4j/server/security/auth/PasswordPolicy.java index 6da65945bc685..2cfd22e872447 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/PasswordPolicy.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/PasswordPolicy.java @@ -19,7 +19,7 @@ */ package org.neo4j.server.security.auth; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; public interface PasswordPolicy { diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/UserManager.java b/community/security/src/main/java/org/neo4j/server/security/auth/UserManager.java index 1ad2b531b82d6..dbc4cf52e3961 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/UserManager.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/UserManager.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.Set; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; public interface UserManager { diff --git a/community/security/src/main/java/org/neo4j/server/security/auth/UserRepository.java b/community/security/src/main/java/org/neo4j/server/security/auth/UserRepository.java index 44ab611741d5d..5f60c4e8f8d50 100644 --- a/community/security/src/main/java/org/neo4j/server/security/auth/UserRepository.java +++ b/community/security/src/main/java/org/neo4j/server/security/auth/UserRepository.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.Set; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.server.security.auth.exception.ConcurrentModificationException; diff --git a/community/security/src/test/java/org/neo4j/commandline/admin/security/CommandTestBase.java b/community/security/src/test/java/org/neo4j/commandline/admin/security/CommandTestBase.java index e52d768271925..a855785c29226 100644 --- a/community/security/src/test/java/org/neo4j/commandline/admin/security/CommandTestBase.java +++ b/community/security/src/test/java/org/neo4j/commandline/admin/security/CommandTestBase.java @@ -30,7 +30,7 @@ import org.neo4j.commandline.admin.OutsideWorld; import org.neo4j.io.fs.DelegateFileSystemAbstraction; import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.logging.NullLogProvider; import org.neo4j.server.security.auth.Credential; import org.neo4j.server.security.auth.FileUserRepository; diff --git a/community/security/src/test/java/org/neo4j/server/security/auth/AuthProceduresIT.java b/community/security/src/test/java/org/neo4j/server/security/auth/AuthProceduresIT.java index 96b8590cc1c98..dcd83dc17216b 100644 --- a/community/security/src/test/java/org/neo4j/server/security/auth/AuthProceduresIT.java +++ b/community/security/src/test/java/org/neo4j/server/security/auth/AuthProceduresIT.java @@ -43,7 +43,7 @@ import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.test.TestGraphDatabaseBuilder; diff --git a/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java b/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java index a0f6c4698ceb7..3162ebe9aa7e8 100644 --- a/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java +++ b/community/security/src/test/java/org/neo4j/server/security/auth/BasicAuthManagerTest.java @@ -29,7 +29,7 @@ import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import static org.hamcrest.Matchers.containsString; diff --git a/community/server/src/main/java/org/neo4j/server/rest/dbms/UserService.java b/community/server/src/main/java/org/neo4j/server/rest/dbms/UserService.java index 3e7dbb1a6787d..cd686f6c315b9 100644 --- a/community/server/src/main/java/org/neo4j/server/rest/dbms/UserService.java +++ b/community/server/src/main/java/org/neo4j/server/rest/dbms/UserService.java @@ -32,7 +32,7 @@ import org.neo4j.kernel.api.security.AuthManager; import org.neo4j.kernel.api.exceptions.Status; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.server.rest.repr.AuthorizationRepresentation; import org.neo4j.server.rest.repr.BadInputException; import org.neo4j.server.rest.repr.ExceptionRepresentation; diff --git a/community/server/src/test/java/org/neo4j/server/rest/dbms/UserServiceTest.java b/community/server/src/test/java/org/neo4j/server/rest/dbms/UserServiceTest.java index 6260a2a525f79..b5dd702dee51e 100644 --- a/community/server/src/test/java/org/neo4j/server/rest/dbms/UserServiceTest.java +++ b/community/server/src/test/java/org/neo4j/server/rest/dbms/UserServiceTest.java @@ -33,7 +33,7 @@ import javax.ws.rs.core.Response; import org.neo4j.kernel.api.security.AuthManager; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.server.rest.repr.OutputFormat; import org.neo4j.server.rest.repr.formats.JsonFormat; import org.neo4j.server.security.auth.AuthenticationStrategy; diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java index 945271c7b5c4a..0c3a39fdf8b54 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/api/security/EnterpriseAuthSubject.java @@ -24,7 +24,7 @@ import org.neo4j.graphdb.security.AuthorizationViolationException; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; /** * A logged in user. diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/BuiltInProcedures.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/BuiltInProcedures.java index 823b4da6189a3..478e4689c65b1 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/BuiltInProcedures.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/BuiltInProcedures.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.neo4j.function.UncaughtCheckedException; import org.neo4j.graphdb.DependencyResolver; import org.neo4j.graphdb.security.AuthorizationViolationException; import org.neo4j.helpers.collection.Pair; @@ -41,7 +42,7 @@ import org.neo4j.kernel.api.bolt.ManagedBoltStateMachine; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.security.AuthSubject; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.enterprise.api.security.EnterpriseAuthSubject; import org.neo4j.kernel.impl.api.KernelTransactions; import org.neo4j.kernel.internal.GraphDatabaseAPI; @@ -56,6 +57,8 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.neo4j.function.ThrowingFunction.catchThrown; +import static org.neo4j.function.ThrowingFunction.throwIfPresent; import static org.neo4j.graphdb.security.AuthorizationViolationException.PERMISSION_DENIED; import static org.neo4j.kernel.enterprise.builtinprocs.QueryId.parseQueryId; import static org.neo4j.kernel.enterprise.builtinprocs.QueryId.queryId; @@ -129,12 +132,20 @@ public Stream terminateConnectionsForUser( @Name( "username" ) @Procedure( name = "dbms.listQueries", mode = DBMS ) public Stream listQueries() throws InvalidArgumentsException, IOException { - return getKernelTransactions() - .activeTransactions() - .stream() - .flatMap( KernelTransactionHandle::executingQueries ) - .filter( ( query ) -> isAdminEnterpriseAuthSubject() || authSubject.hasUsername( query.username() ) ) - .map( this::queryStatusResult ); + try + { + return getKernelTransactions() + .activeTransactions() + .stream() + .flatMap( KernelTransactionHandle::executingQueries ) + .filter( ( query ) -> isAdminEnterpriseAuthSubject() || authSubject.hasUsername( query.username() ) ) + .map( catchThrown( InvalidArgumentsException.class, this::queryStatusResult ) ); + } + catch ( UncaughtCheckedException uncaught ) + { + throwIfPresent( uncaught.getCauseIfOfType( InvalidArgumentsException.class ) ); + throw uncaught; + } } @Description( "Kill all transactions executing the query with the given query id." ) @@ -142,14 +153,22 @@ public Stream listQueries() throws InvalidArgumentsException, public Stream killQuery( @Name( "id" ) String idText ) throws InvalidArgumentsException, IOException { - long queryId = parseQueryId( idText ).kernelQueryId(); + try + { + long queryId = parseQueryId( idText ).kernelQueryId(); - Set> executingQueries = - getKernelTransactions().activeTransactions( tx -> executingQueriesWithId( queryId, tx ) ); + Set> executingQueries = + getKernelTransactions().activeTransactions( tx -> executingQueriesWithId( queryId, tx ) ); - return executingQueries - .stream() - .map(this::killQueryTransaction); + return executingQueries + .stream() + .map( catchThrown( InvalidArgumentsException.class, this::killQueryTransaction ) ); + } + catch ( UncaughtCheckedException uncaught ) + { + throwIfPresent( uncaught.getCauseIfOfType( InvalidArgumentsException.class ) ); + throw uncaught; + } } @Description( "Kill all transactions executing a query with any of the given query ids." ) @@ -157,18 +176,26 @@ public Stream killQuery( @Name( "id" ) String idText ) public Stream killQueries( @Name( "ids" ) List idTexts ) throws InvalidArgumentsException, IOException { - Set queryIds = - idTexts.stream() - .map( QueryId::parseQueryId ) - .map( QueryId::kernelQueryId ) - .collect( Collectors.toSet() ); + try + { + Set queryIds = idTexts + .stream() + .map( catchThrown( InvalidArgumentsException.class, QueryId::parseQueryId ) ) + .map( catchThrown( InvalidArgumentsException.class, QueryId::kernelQueryId ) ) + .collect( Collectors.toSet() ); - Set> executingQueries = + Set> executingQueries = getKernelTransactions().activeTransactions( tx -> executingQueriesWithIds( queryIds, tx ) ); - return executingQueries + return executingQueries .stream() - .map(this::killQueryTransaction); + .map( catchThrown( InvalidArgumentsException.class, this::killQueryTransaction ) ); + } + catch ( UncaughtCheckedException uncaught ) + { + throwIfPresent( uncaught.getCauseIfOfType( InvalidArgumentsException.class ) ); + throw uncaught; + } } private Stream executingQueriesWithIds( Set ids, KernelTransactionHandle txHandle ) @@ -182,6 +209,7 @@ private Stream executingQueriesWithId( long id, KernelTransactio } private QueryTerminationResult killQueryTransaction( Pair pair ) + throws InvalidArgumentsException { ExecutingQuery query = pair.other(); if ( isAdminEnterpriseAuthSubject() || authSubject.hasUsername( query.username() ) ) @@ -297,7 +325,7 @@ private EnterpriseAuthSubject ensureSelfOrAdminEnterpriseAuthSubject( String use throw new AuthorizationViolationException( PERMISSION_DENIED ); } - private QueryStatusResult queryStatusResult( ExecutingQuery q ) + private QueryStatusResult queryStatusResult( ExecutingQuery q ) throws InvalidArgumentsException { return new QueryStatusResult( queryId( q.kernelQueryId() ), diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/QueryId.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/QueryId.java index 0b82eb022c535..42c73bc428e26 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/QueryId.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/QueryId.java @@ -19,17 +19,19 @@ */ package org.neo4j.kernel.enterprise.builtinprocs; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; + public final class QueryId { public static final String QUERY_ID_PREFIX = "query-"; private final long kernelQueryId; - public static QueryId queryId( long queryId ) + public static QueryId queryId( long queryId ) throws InvalidArgumentsException { return new QueryId( queryId ); } - public static QueryId parseQueryId( String queryIdText ) + public static QueryId parseQueryId( String queryIdText ) throws InvalidArgumentsException { try { @@ -40,17 +42,17 @@ public static QueryId parseQueryId( String queryIdText ) } catch ( NumberFormatException e ) { - throw new IllegalArgumentException( e ); + throw new InvalidArgumentsException( "Could not parse query id (expected format: query-1234)", e ); } - throw new IllegalArgumentException( "Could not parse query id" ); + throw new InvalidArgumentsException( "Could not parse query id (expected format: query-1234)" ); } - private QueryId( long kernelQueryId ) + private QueryId( long kernelQueryId ) throws InvalidArgumentsException { if ( kernelQueryId <= 0 ) { - throw new IllegalArgumentException( "Negative query ids are not supported" ); + throw new InvalidArgumentsException( "Negative query ids are not supported (expected format: query-1234)" ); } this.kernelQueryId = kernelQueryId; } diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/QueryIdTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/QueryIdTest.java index 41d604e14c3f2..696ea8356f1f5 100644 --- a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/QueryIdTest.java +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/QueryIdTest.java @@ -23,6 +23,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; + import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.neo4j.kernel.enterprise.builtinprocs.QueryId.parseQueryId; @@ -34,49 +36,49 @@ public class QueryIdTest public ExpectedException thrown = ExpectedException.none(); @Test - public void printsQueryIds() + public void printsQueryIds() throws InvalidArgumentsException { assertThat( queryId( 12L ).toString(), equalTo( "query-12" ) ); } @Test - public void doesNotConstructNegativeQueryIds() + public void doesNotConstructNegativeQueryIds() throws InvalidArgumentsException { - thrown.expect( IllegalArgumentException.class ); + thrown.expect( InvalidArgumentsException.class ); queryId( -15L ); } @Test - public void parsesQueryIds() + public void parsesQueryIds() throws InvalidArgumentsException { assertThat( parseQueryId( "query-14" ), equalTo( queryId( 14L ) ) ); } @Test - public void doesNotParseNegativeQueryIds() + public void doesNotParseNegativeQueryIds() throws InvalidArgumentsException { - thrown.expect( IllegalArgumentException.class ); + thrown.expect( InvalidArgumentsException.class ); parseQueryId( "query--12" ); } @Test - public void doesNotParseRandomText() + public void doesNotParseRandomText() throws InvalidArgumentsException { - thrown.expect( IllegalArgumentException.class ); + thrown.expect( InvalidArgumentsException.class ); parseQueryId( "blarglbarf" ); } @Test - public void doesNotParseTrailingRandomText() + public void doesNotParseTrailingRandomText() throws InvalidArgumentsException { - thrown.expect( IllegalArgumentException.class ); + thrown.expect( InvalidArgumentsException.class ); parseQueryId( "query-12 " ); } @Test - public void doesNotParseEmptyText() + public void doesNotParseEmptyText() throws InvalidArgumentsException { - thrown.expect( IllegalArgumentException.class ); + thrown.expect( InvalidArgumentsException.class ); parseQueryId( "" ); } } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AbstractRoleRepository.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AbstractRoleRepository.java index 100ef2a2b27c3..22aa8ae014d6e 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AbstractRoleRepository.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AbstractRoleRepository.java @@ -32,7 +32,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.lifecycle.LifecycleAdapter; import org.neo4j.server.security.auth.ListSnapshot; import org.neo4j.server.security.auth.exception.ConcurrentModificationException; diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java index a1890493d1196..0a43f8c539578 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java @@ -32,7 +32,7 @@ import org.neo4j.kernel.api.bolt.ManagedBoltStateMachine; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.security.AuthSubject; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.impl.api.KernelTransactions; import org.neo4j.kernel.impl.enterprise.SecurityLog; import org.neo4j.kernel.internal.GraphDatabaseAPI; diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java index b0dd68d812491..8bfa013485281 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseUserManager.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.Set; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.server.security.auth.UserManager; public interface EnterpriseUserManager extends UserManager diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java index 6279dcb7560c2..610a5e93b9797 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/InternalFlatFileRealm.java @@ -50,7 +50,7 @@ import org.neo4j.kernel.api.security.AuthToken; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import org.neo4j.kernel.impl.util.JobScheduler; import org.neo4j.server.security.auth.AuthenticationStrategy; diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java index a4a049e19a85a..4255c19fe1031 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java @@ -24,7 +24,7 @@ import java.util.Set; import java.util.stream.Collectors; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.server.security.auth.ListSnapshot; import org.neo4j.server.security.auth.User; diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/StandardEnterpriseAuthSubject.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/StandardEnterpriseAuthSubject.java index 98334272fe02c..5ed5a569324cd 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/StandardEnterpriseAuthSubject.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/StandardEnterpriseAuthSubject.java @@ -27,7 +27,7 @@ import org.neo4j.kernel.api.security.AccessMode; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.enterprise.api.security.EnterpriseAuthSubject; import static java.util.stream.Collectors.toSet; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresInteractionTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresInteractionTestBase.java index c50ce1a89fb6e..787239e15b200 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresInteractionTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresInteractionTestBase.java @@ -26,7 +26,7 @@ import java.util.stream.Stream; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.test.rule.concurrent.ThreadingRule; import static java.lang.String.format; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/EmbeddedBuiltInProceduresInteractionTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/EmbeddedBuiltInProceduresInteractionTest.java index 6028db822e1ae..9572e4fcf21be 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/EmbeddedBuiltInProceduresInteractionTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/EmbeddedBuiltInProceduresInteractionTest.java @@ -33,7 +33,7 @@ import org.neo4j.kernel.api.security.AccessMode; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.enterprise.api.security.EnterpriseAuthSubject; import org.neo4j.kernel.impl.coreapi.InternalTransaction; import org.neo4j.kernel.impl.factory.GraphDatabaseFacade; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/MultiRealmAuthManagerTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/MultiRealmAuthManagerTest.java index adaeb99b62bd7..84ee7099b6746 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/MultiRealmAuthManagerTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/MultiRealmAuthManagerTest.java @@ -26,10 +26,10 @@ import java.util.Collections; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.api.security.AuthSubject; import org.neo4j.kernel.api.security.AuthToken; import org.neo4j.kernel.api.security.AuthenticationResult; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; import org.neo4j.kernel.api.security.exception.InvalidAuthTokenException; import org.neo4j.kernel.impl.enterprise.SecurityLog; import org.neo4j.kernel.impl.util.JobScheduler; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java index e92cc4c2ef46a..b5d4fb7e6abad 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java @@ -46,7 +46,7 @@ import org.neo4j.graphdb.config.Setting; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.helpers.HostnamePort; -import org.neo4j.kernel.api.security.exception.InvalidArgumentsException; +import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.logging.Log; import org.neo4j.procedure.Context; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java index b57cd0d0a049e..b201e0ad1518a 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java @@ -248,7 +248,7 @@ public void shouldFailWhenTerminatingConnectionsForNonExistentUser() throws Thro pullAll() ) ); // Then - assertThat( admin, eventuallyReceives( msgFailure( Status.Security.InvalidArguments, + assertThat( admin, eventuallyReceives( msgFailure( Status.General.InvalidArguments, "User 'NonExistentUser' does not exist." ) ) ); }