@Override public String username() { return user.name(); }
@Mapping( "password_change" ) public ValueRepresentation passwordChange() { return ValueRepresentation.uri( format( "/user/%s/password", user.name() ) ); } }
@Mapping( "username" ) public ValueRepresentation user() { return ValueRepresentation.string( user.name() ); }
@Override public void create( User user ) throws InvalidArgumentsException, IOException { assertValidUsername( user.name() ); synchronized ( this ) { // Check for existing user for ( User other : users ) { if ( other.name().equals( user.name() ) ) { throw new InvalidArgumentsException( "The specified user '" + user.name() + "' already exists." ); } } users.add( user ); usersByName.put( user.name(), user ); persistUsers(); } }
@Override public synchronized boolean delete( User user ) throws IOException { boolean foundUser = false; // Copy-on-write for the users list List<User> newUsers = new ArrayList<>(); for ( User other : users ) { if ( other.name().equals( user.name() ) ) { foundUser = true; } else { newUsers.add( other ); } } if ( foundUser ) { users = newUsers; usersByName.remove( user.name() ); persistUsers(); } return foundUser; }
if ( !existingUser.name().equals( updatedUser.name() ) ) throw new IllegalArgumentException( "The attempt to update the role from '" + existingUser.name() + "' to '" + updatedUser.name() + "' failed. Changing a roles name is not allowed." ); usersByName.put( updatedUser.name(), updatedUser ); persistUsers();
@Override protected String serialize( User user ) { return String.join( userSeparator, user.name(), // Only used by FileRepository (InternalFlatFileRealm) so we can assume LegacyCredential here serialize( (LegacyCredential) user.credentials() ), String.join( ",", user.getFlags() ) ); }
@Override public void setUsers( ListSnapshot<User> usersSnapshot ) throws InvalidArgumentsException { for ( User user : usersSnapshot.values() ) { assertValidUsername( user.name() ); } synchronized ( this ) { users.clear(); this.users.addAll( usersSnapshot.values() ); this.lastLoaded.set( usersSnapshot.timestamp() ); trimToList( usersByName, users, User::name ); for ( User user : users ) { usersByName.put( user.name(), user ); } } }
@Override public AuthenticationResult authenticate( User user, byte[] password ) { AuthenticationMetadata authMetadata = authMetadataFor( user.name() ); if ( !authMetadata.authenticationPermitted() ) { return AuthenticationResult.TOO_MANY_ATTEMPTS; } if ( user.credentials().matchesPassword( password ) ) { authMetadata.authSuccess(); return AuthenticationResult.SUCCESS; } else { authMetadata.authFailed(); return AuthenticationResult.FAILURE; } }
private boolean realUsersExist( Config config ) { boolean result = false; File authFile = CommunitySecurityModule.getUserRepositoryFile( config ); if ( outsideWorld.fileSystem().fileExists( authFile ) ) { result = true; // Check if it only contains the default neo4j user FileUserRepository userRepository = new FileUserRepository( outsideWorld.fileSystem(), authFile, NullLogProvider.getInstance() ); try ( Lifespan life = new Lifespan( userRepository ) ) { ListSnapshot<User> users = userRepository.getPersistedSnapshot(); if ( users.values().size() == 1 ) { User user = users.values().get( 0 ); if ( INITIAL_USER_NAME.equals( user.name() ) && user.credentials().matchesPassword( INITIAL_PASSWORD ) ) { // We allow overwriting an unmodified default neo4j user result = false; } } } catch ( IOException e ) { // Do not allow overwriting if we had a problem reading the file } } return result; }
@Test public void shouldStoreAndRetrieveUsersByName() throws Exception { // Given FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); users.create( user ); // When User result = users.getUserByName( user.name() ); // Then assertThat( result, equalTo( user ) ); }
@Test public void shouldNotFindUserAfterDelete() throws Throwable { // Given FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); users.create( user ); // When users.delete( user ); // Then assertThat( users.getUserByName( user.name() ), nullValue() ); }
@Test public void shouldPersistUsers() throws Throwable { // Given FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); users.create( user ); users = new FileUserRepository( fs, authFile, logProvider ); users.start(); // When User resultByName = users.getUserByName( user.name() ); // Then assertThat( resultByName, equalTo( user ) ); }
@Test public void shouldThrowIfUpdateChangesName() throws Throwable { // Given FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); users.create( user ); // When User updatedUser = new User.Builder( "john", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ) .build(); try { users.update( user, updatedUser ); fail( "expected exception not thrown" ); } catch ( IllegalArgumentException e ) { // Then continue } assertThat( users.getUserByName( user.name() ), equalTo( user ) ); }
@Override public String username() { return user.name(); }
@Mapping( "username" ) public ValueRepresentation user() { return ValueRepresentation.string( user.name() ); }
@Mapping( "password_change" ) public ValueRepresentation passwordChange() { return ValueRepresentation.uri( format( "/user/%s/password", user.name() ) ); } }
@Override public void create( User user ) throws InvalidArgumentsException, IOException { assertValidUsername( user.name() ); synchronized ( this ) { // Check for existing user for ( User other : users ) { if ( other.name().equals( user.name() ) ) { throw new InvalidArgumentsException( "The specified user '" + user.name() + "' already exists." ); } } users.add( user ); usersByName.put( user.name(), user ); persistUsers(); } }
@Override protected String serialize( User user ) { return String.join( userSeparator, user.name(), // Only used by FileRepository (InternalFlatFileRealm) so we can assume LegacyCredential here serialize( (LegacyCredential) user.credentials() ), String.join( ",", user.getFlags() ) ); }
@Override public void setUsers( ListSnapshot<User> usersSnapshot ) throws InvalidArgumentsException { for ( User user : usersSnapshot.values() ) { assertValidUsername( user.name() ); } synchronized ( this ) { users.clear(); this.users.addAll( usersSnapshot.values() ); this.lastLoaded.set( usersSnapshot.timestamp() ); trimToList( usersByName, users, User::name ); for ( User user : users ) { usersByName.put( user.name(), user ); } } }