protected String defaultString( String name ) { return String.format( "%s{ username=%s, accessMode=%s }", name, subject().username(), mode() ); }
@Override public boolean credentialsExpired() { return loginContext.subject().getAuthenticationResult() == org.neo4j.internal.kernel.api.security.AuthenticationResult.PASSWORD_CHANGE_REQUIRED; } }
@Description( "Change the current user's password." ) @Procedure( name = "dbms.security.changePassword", mode = DBMS ) public void changePassword( @Name( "password" ) String password ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] if ( securityContext.subject() == AuthSubject.ANONYMOUS ) { throw new AuthorizationViolationException( "Anonymous cannot change password" ); } userManager.setUserPassword( securityContext.subject().username(), UTF8.encode( password ), false ); securityContext.subject().setPasswordChangeNoLongerRequired(); }
switch ( loginContext.subject().getAuthenticationResult() ) userManagerSupplier.getUserManager( loginContext.subject(), false ) .setUserPassword( username, newPassword, false ); // NOTE: This will overwrite newPassword with zeroes loginContext.subject().setPasswordChangeNoLongerRequired(); break; default:
@Description( "Delete the specified user." ) @Procedure( name = "dbms.security.deleteUser", mode = DBMS ) public void deleteUser( @Name( "username" ) String username ) throws InvalidArgumentsException, IOException { securityContext.assertCredentialsNotExpired(); if ( securityContext.subject().hasUsername( username ) ) { throw new InvalidArgumentsException( "Deleting yourself (user '" + username + "') is not allowed." ); } userManager.deleteUser( username ); }
private void setUserPassword( String username, String newPassword, boolean requirePasswordChange ) throws IOException, InvalidArgumentsException { userManager.setUserPassword( username, newPassword, requirePasswordChange ); if ( securityContext.subject().hasUsername( username ) ) { securityContext.subject().setPasswordChangeNoLongerRequired(); } } }
@Before public void setup() throws InvalidAuthTokenException, IOException { fs = new EphemeralFileSystemAbstraction(); db = (GraphDatabaseAPI) createGraphDatabase( fs ); authManager = db.getDependencyResolver().resolveDependency( BasicAuthManager.class ); admin = login( "neo4j", "neo4j" ); admin.subject().setPasswordChangeNoLongerRequired(); }
switch ( loginContext.subject().getAuthenticationResult() ) userManagerSupplier.getUserManager( loginContext.subject(), false ) .setUserPassword( username, newPassword, false ); // NOTE: This will overwrite newPassword with zeroes loginContext.subject().setPasswordChangeNoLongerRequired(); break; default:
private void assertSelfOrUserManager( String username ) { if ( !subject.hasUsername( username ) ) { assertUserManager(); } }
@Override public String username() { return transaction.securityContext().subject().username(); }
public void assertCredentialsNotExpired() { if ( subject().getAuthenticationResult().equals( AuthenticationResult.PASSWORD_CHANGE_REQUIRED ) ) { throw mode().onViolation( PERMISSION_DENIED ); } }
@Description( "Change the current user's password." ) @Procedure( name = "dbms.security.changePassword", mode = DBMS ) public void changePassword( @Name( "password" ) String password ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] if ( securityContext.subject() == AuthSubject.ANONYMOUS ) { throw new AuthorizationViolationException( "Anonymous cannot change password" ); } userManager.setUserPassword( securityContext.subject().username(), UTF8.encode( password ), false ); securityContext.subject().setPasswordChangeNoLongerRequired(); }
public static Stream<TransactionTerminationResult> terminateTransactionsForValidUser( DependencyResolver dependencyResolver, String username, KernelTransaction currentTx ) { long terminatedCount = getActiveTransactions( dependencyResolver ) .stream() .filter( tx -> tx.subject().hasUsername( username ) && !tx.isUnderlyingTransaction( currentTx ) ) .map( tx -> tx.markForTermination( Status.Transaction.Terminated ) ) .filter( marked -> marked ) .count(); return Stream.of( new TransactionTerminationResult( username, terminatedCount ) ); }
final String username() { return transaction.securityContext().subject().username(); }
@Test public void shouldAuthorizeWhenPasswordChangeRequiredForWhitelistedPath() throws Exception { // Given final AuthorizationEnabledFilter filter = new AuthorizationEnabledFilter( () -> authManager, logProvider ); String credentials = Base64.encodeBase64String( "foo:bar".getBytes( StandardCharsets.UTF_8 ) ); BasicLoginContext loginContext = mock( BasicLoginContext.class ); AuthSubject authSubject = mock( AuthSubject.class ); when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/user/foo" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.PASSWORD_CHANGE_REQUIRED ); // When filter.doFilter( servletRequest, servletResponse, filterChain ); // Then verify( filterChain ).doFilter( eq( new AuthorizedRequestWrapper( BASIC_AUTH, "foo", servletRequest, AUTH_DISABLED ) ), same( servletResponse ) ); }
private boolean isAdminOrSelf( String username ) { return isAdmin() || securityContext.subject().hasUsername( username ); }
public String description() { return String.format( "user '%s' with %s", subject().username(), mode().name() ); }
@Test public void shouldAuthorizeWhenValidCredentialsSupplied() throws Exception { // Given final AuthorizationEnabledFilter filter = new AuthorizationEnabledFilter( () -> authManager, logProvider ); String credentials = Base64.encodeBase64String( "foo:bar".getBytes( StandardCharsets.UTF_8 ) ); BasicLoginContext loginContext = mock( BasicLoginContext.class ); AuthSubject authSubject = mock( AuthSubject.class ); when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/db/data" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.SUCCESS ); // When filter.doFilter( servletRequest, servletResponse, filterChain ); // Then verify( filterChain ).doFilter( eq( new AuthorizedRequestWrapper( BASIC_AUTH, "foo", servletRequest, AUTH_DISABLED ) ), same( servletResponse ) ); }
protected void terminateTransactionsForValidUser( String username ) { KernelTransaction currentTx = getCurrentTx(); getActiveTransactions() .stream() .filter( tx -> tx.subject().hasUsername( username ) && !tx.isUnderlyingTransaction( currentTx ) ).forEach( tx -> tx.markForTermination( Status.Transaction.Terminated ) ); }
@Description( "Show the current user." ) @Procedure( name = "dbms.showCurrentUser", mode = DBMS ) public Stream<UserResult> showCurrentUser() { return Stream.of( userResultForName( securityContext.subject().username() ) ); }