@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(); }
@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 ); }
@GET @Path( "/{username}" ) public Response getUser( @PathParam( "username" ) String username, @Context HttpServletRequest req ) { Principal principal = req.getUserPrincipal(); if ( principal == null || !principal.getName().equals( username ) ) { return output.notFound(); } LoginContext loginContext = getLoginContextFromUserPrincipal( principal ); UserManager userManager = userManagerSupplier.getUserManager( loginContext.subject(), false ); try { User user = userManager.getUser( username ); return output.ok( new AuthorizationRepresentation( user ) ); } catch ( InvalidArgumentsException e ) { return output.notFound(); } }
@Description( "Create a new user." ) @Procedure( name = "dbms.security.createUser", mode = DBMS ) public void createUser( @Name( "username" ) String username, @Name( "password" ) String password, @Name( value = "requirePasswordChange", defaultValue = "true" ) boolean requirePasswordChange ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] securityContext.assertCredentialsNotExpired(); userManager.newUser( username, password != null ? UTF8.encode( password ) : null, requirePasswordChange ); }
private UserResult userResultForName( String username ) { User user = userManager.silentlyGetUser( username ); Iterable<String> flags = user == null ? emptyList() : user.getFlags(); return new UserResult( username, flags ); }
@Description( "List all native users." ) @Procedure( name = "dbms.security.listUsers", mode = DBMS ) public Stream<UserResult> listUsers() { securityContext.assertCredentialsNotExpired(); Set<String> usernames = userManager.getAllUsernames(); if ( usernames.isEmpty() ) { return showCurrentUser(); } else { return usernames.stream().map( this::userResultForName ); } }
@Description( "Create a new user." ) @Procedure( name = "dbms.security.createUser", mode = DBMS ) public void createUser( @Name( "username" ) String username, @Name( "password" ) String password, @Name( value = "requirePasswordChange", defaultValue = "true" ) boolean requirePasswordChange ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] securityContext.assertCredentialsNotExpired(); userManager.newUser( username, password != null ? UTF8.encode( password ) : null, requirePasswordChange ); }
private UserResult userResultForName( String username ) { User user = userManager.silentlyGetUser( username ); Iterable<String> flags = user == null ? emptyList() : user.getFlags(); return new UserResult( username, flags ); }
@Description( "List all native users." ) @Procedure( name = "dbms.security.listUsers", mode = DBMS ) public Stream<UserResult> listUsers() { securityContext.assertCredentialsNotExpired(); Set<String> usernames = userManager.getAllUsernames(); if ( usernames.isEmpty() ) { return showCurrentUser(); } else { return usernames.stream().map( this::userResultForName ); } }
userManager.setUserPassword( username, UTF8.encode( newPassword ), false );
@Test public void shouldReturn404WhenRequestingUserIfUnknownUser() throws Exception { // Given HttpServletRequest req = mock( HttpServletRequest.class ); when( req.getUserPrincipal() ).thenReturn( neo4jPrinciple ); userManagerSupplier.getUserManager().deleteUser( "neo4j" ); OutputFormat outputFormat = new EntityOutputFormat( new JsonFormat(), new URI( "http://www.example.com" ), null ); UserService userService = new UserService( userManagerSupplier, new JsonFormat(), outputFormat ); // When Response response = userService.getUser( "neo4j", req ); // Then assertThat( response.getStatus(), equalTo( 404 ) ); }
@Test public void shouldChangePasswordAndReturnSuccess() throws Exception { // Given HttpServletRequest req = mock( HttpServletRequest.class ); when( req.getUserPrincipal() ).thenReturn( neo4jPrinciple ); OutputFormat outputFormat = new EntityOutputFormat( new JsonFormat(), new URI( "http://www.example.com" ), null ); UserService userService = new UserService( userManagerSupplier, new JsonFormat(), outputFormat ); // When Response response = userService.setPassword( "neo4j", req, "{ \"password\" : \"test\" }" ); // Then assertThat( response.getStatus(), equalTo( 200 ) ); userManagerSupplier.getUserManager().getUser( "neo4j" ).credentials().matchesPassword( "test" ); }
String username = AuthToken.safeCast( PRINCIPAL, authToken ); userManagerSupplier.getUserManager( loginContext.subject(), false ) .setUserPassword( username, newPassword, false ); // NOTE: This will overwrite newPassword with zeroes loginContext.subject().setPasswordChangeNoLongerRequired(); break;
@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 ); }
@GET @Path( "/{username}" ) public Response getUser( @PathParam( "username" ) String username, @Context HttpServletRequest req ) { Principal principal = req.getUserPrincipal(); if ( principal == null || !principal.getName().equals( username ) ) { return output.notFound(); } LoginContext loginContext = getLoginContextFromUserPrincipal( principal ); UserManager userManager = userManagerSupplier.getUserManager( loginContext.subject(), false ); try { User user = userManager.getUser( username ); return output.ok( new AuthorizationRepresentation( user ) ); } catch ( InvalidArgumentsException e ) { return output.notFound(); } }
@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(); }
userManager.setUserPassword( username, UTF8.encode( newPassword ), false );
String username = AuthToken.safeCast( PRINCIPAL, authToken ); userManagerSupplier.getUserManager( loginContext.subject(), false ) .setUserPassword( username, newPassword, false ); // NOTE: This will overwrite newPassword with zeroes loginContext.subject().setPasswordChangeNoLongerRequired(); break;