diff --git a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java index a150d48c1c3fe..9678e9cb9257a 100644 --- a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java +++ b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java @@ -499,8 +499,8 @@ private static String defaultPageCacheMemory() pathSetting( "unsupported.dbms.security.auth_store.location", NO_DEFAULT ); @Internal - public static final Setting group_store = // TODO: Move this to enterprise - pathSetting( "unsupported.dbms.security.group_store.location", NO_DEFAULT ); + public static final Setting role_store = // TODO: Move this to enterprise + pathSetting( "unsupported.dbms.security.role_store.location", NO_DEFAULT ); @Internal public static final Setting auth_manager = setting( "unsupported.dbms.security.auth_manager", STRING, "" ); diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManager.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManager.java index 2eb002ee020f3..b0ea5f856ad21 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManager.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManager.java @@ -26,9 +26,10 @@ public class EnterpriseAuthManager extends ShiroAuthManager { - public EnterpriseAuthManager( UserRepository users, GroupRepository groups, PasswordPolicy passwordPolicy, Clock clock, boolean authEnabled ) + public EnterpriseAuthManager( UserRepository userRepository, RoleRepository roleRepository, + PasswordPolicy passwordPolicy, Clock clock, boolean authEnabled ) { - super( users, groups, passwordPolicy, clock, authEnabled ); + super( userRepository, roleRepository, passwordPolicy, clock, authEnabled ); } @Override diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManagerFactory.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManagerFactory.java index 1013b5612cfd0..099e4c4af55af 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManagerFactory.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/EnterpriseAuthManagerFactory.java @@ -48,12 +48,12 @@ public AuthManager newInstance( Config config, LogProvider logProvider ) final UserRepository userRepository = new FileUserRepository( config.get( GraphDatabaseSettings.auth_store ).toPath(), logProvider ); - final GroupRepository grouoRepository = - new FileGroupRepository( config.get( GraphDatabaseSettings.group_store ).toPath(), logProvider ); + final RoleRepository roleRepository = + new FileRoleRepository( config.get( GraphDatabaseSettings.role_store ).toPath(), logProvider ); final PasswordPolicy passwordPolicy = new BasicPasswordPolicy(); - return new EnterpriseAuthManager( userRepository, grouoRepository, passwordPolicy, systemUTC(), + return new EnterpriseAuthManager( userRepository, roleRepository, passwordPolicy, systemUTC(), config.get( GraphDatabaseSettings.auth_enabled ) ); } } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileGroupRepository.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileGroupRepository.java deleted file mode 100644 index 6385da857db87..0000000000000 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileGroupRepository.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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.security.enterprise.auth; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; - -import org.neo4j.kernel.api.security.exception.IllegalCredentialsException; -import org.neo4j.kernel.lifecycle.LifecycleAdapter; -import org.neo4j.logging.Log; -import org.neo4j.logging.LogProvider; -//import org.neo4j.server.security.auth.UserRepository; -import org.neo4j.server.security.auth.exception.ConcurrentModificationException; - -import static java.nio.file.StandardCopyOption.ATOMIC_MOVE; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; - -/** - * Stores group data. In memory, but backed by persistent storage so changes to this repository will survive - * JVM restarts and crashes. - */ -// TODO: Extract shared code with FileUserRepository -public class FileGroupRepository extends LifecycleAdapter implements GroupRepository -{ - private final Path groupFile; - - /** Quick lookup of groups by name */ - private final Map groupsByName = new ConcurrentHashMap<>(); - private final Map> groupsByUsername = new ConcurrentHashMap<>(); - - private final Log log; - - /** Master list of groups */ - private volatile List groups = new ArrayList<>(); - - private final GroupSerialization serialization = new GroupSerialization(); - - public FileGroupRepository( Path file, LogProvider logProvider ) - { - this.groupFile = file.toAbsolutePath(); - this.log = logProvider.getLog( getClass() ); - } - - @Override - public GroupRecord findByName( String name ) - { - return groupsByName.get( name ); - } - - @Override - public Set findByUsername( String username ) - { - return groupsByUsername.get( username ); - } - - @Override - public void start() throws Throwable - { - if ( Files.exists( groupFile ) ) - { - loadGroupsFromFile(); - } - } - - @Override - public void create( GroupRecord group ) throws IllegalCredentialsException, IOException - { - if ( !isValidName( group.name() ) ) - { - throw new IllegalCredentialsException( "'" + group.name() + "' is not a valid group name." ); - } - - synchronized (this) - { - // Check for existing group - for ( GroupRecord other : groups ) - { - if ( other.name().equals( group.name() ) ) - { - throw new IllegalCredentialsException( "The specified group already exists" ); - } - } - - groups.add( group ); - - saveGroupsToFile(); - - groupsByName.put( group.name(), group ); - - populateUserMap( group ); - } - } - - @Override - public void update( GroupRecord existingGroup, GroupRecord updatedGroup ) throws ConcurrentModificationException, IOException - { - // Assert input is ok - if ( !existingGroup.name().equals( updatedGroup.name() ) ) - { - throw new IllegalArgumentException( "updatedGroup has a different name" ); - } - - synchronized (this) - { - // Copy-on-write for the groups list - List newGroups = new ArrayList<>(); - boolean foundGroup = false; - for ( GroupRecord other : groups ) - { - if ( other.equals( existingGroup ) ) - { - foundGroup = true; - newGroups.add( updatedGroup ); - } else - { - newGroups.add( other ); - } - } - - if ( !foundGroup ) - { - throw new ConcurrentModificationException(); - } - - groups = newGroups; - - saveGroupsToFile(); - - groupsByName.put( updatedGroup.name(), updatedGroup ); - - removeFromUserMap( existingGroup ); - populateUserMap( updatedGroup ); - } - } - - @Override - public boolean delete( GroupRecord group ) throws IOException - { - boolean foundGroup = false; - synchronized (this) - { - // Copy-on-write for the groups list - List newGroups = new ArrayList<>(); - for ( GroupRecord other : groups ) - { - if ( other.name().equals( group.name() ) ) - { - foundGroup = true; - } else - { - newGroups.add( other ); - } - } - - if ( foundGroup ) - { - groups = newGroups; - - saveGroupsToFile(); - - groupsByName.remove( group.name() ); - } - - removeFromUserMap( group ); - } - return foundGroup; - } - - @Override - public int numberOfGroups() - { - return groups.size(); - } - - @Override - public boolean isValidName( String name ) - { - return name.matches( "^[a-zA-Z0-9_]+$" ); - } - - private void saveGroupsToFile() throws IOException - { - Path directory = groupFile.getParent(); - if ( !Files.exists( directory ) ) - { - Files.createDirectories( directory ); - } - - Path tempFile = Files.createTempFile( directory, groupFile.getFileName().toString() + "-", ".tmp" ); - try - { - Files.write( tempFile, serialization.serialize( groups ) ); - Files.move( tempFile, groupFile, ATOMIC_MOVE, REPLACE_EXISTING ); - } catch ( Throwable e ) - { - Files.delete( tempFile ); - throw e; - } - } - - private void loadGroupsFromFile() throws IOException - { - byte[] fileBytes = Files.readAllBytes( groupFile ); - List loadedGroups; - try - { - loadedGroups = serialization.deserializeGroups( fileBytes ); - } catch ( GroupSerialization.FormatException e ) - { - log.error( "Ignoring group file \"%s\" (%s)", groupFile.toAbsolutePath(), e.getMessage() ); - throw new IllegalStateException( "Failed to read group file: " + groupFile ); - } - - groups = loadedGroups; - for ( GroupRecord group : groups ) - { - groupsByName.put( group.name(), group ); - - populateUserMap( group ); - } - } - - private void populateUserMap( GroupRecord group ) - { - for ( String username : group.users() ) - { - SortedSet memberOfGroups = groupsByUsername.get( username ); - if ( memberOfGroups == null ) - { - memberOfGroups = new ConcurrentSkipListSet<>(); - groupsByUsername.put( username, memberOfGroups ); - } - memberOfGroups.add( group.name() ); - } - } - - private void removeFromUserMap( GroupRecord group ) - { - for ( String username : group.users() ) - { - SortedSet memberOfGroups = groupsByUsername.get( username ); - if ( memberOfGroups != null ) - { - memberOfGroups.remove( group.name() ); - } - } - } -} diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileRoleRepository.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileRoleRepository.java new file mode 100644 index 0000000000000..20d8269d05903 --- /dev/null +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileRoleRepository.java @@ -0,0 +1,273 @@ +/* + * 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.security.enterprise.auth; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.neo4j.kernel.api.security.exception.IllegalCredentialsException; +import org.neo4j.kernel.lifecycle.LifecycleAdapter; +import org.neo4j.logging.Log; +import org.neo4j.logging.LogProvider; +//import org.neo4j.server.security.auth.UserRepository; +import org.neo4j.server.security.auth.exception.ConcurrentModificationException; + +import static java.nio.file.StandardCopyOption.ATOMIC_MOVE; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + +/** + * Stores role data. In memory, but backed by persistent storage so changes to this repository will survive + * JVM restarts and crashes. + */ +// TODO: Extract shared code with FileUserRepository +public class FileRoleRepository extends LifecycleAdapter implements RoleRepository +{ + private final Path roleFile; + + /** Quick lookup of roles by name */ + private final Map rolesByName = new ConcurrentHashMap<>(); + private final Map> rolesByUsername = new ConcurrentHashMap<>(); + + private final Log log; + + /** Master list of roles */ + private volatile List roles = new ArrayList<>(); + + private final RoleSerialization serialization = new RoleSerialization(); + + public FileRoleRepository( Path file, LogProvider logProvider ) + { + this.roleFile = file.toAbsolutePath(); + this.log = logProvider.getLog( getClass() ); + } + + @Override + public RoleRecord findByName( String name ) + { + return rolesByName.get( name ); + } + + @Override + public Set findByUsername( String username ) + { + return rolesByUsername.get( username ); + } + + @Override + public void start() throws Throwable + { + if ( Files.exists( roleFile ) ) + { + loadRolesFromFile(); + } + } + + @Override + public void create( RoleRecord role ) throws IllegalCredentialsException, IOException + { + if ( !isValidName( role.name() ) ) + { + throw new IllegalCredentialsException( "'" + role.name() + "' is not a valid role name." ); + } + + synchronized (this) + { + // Check for existing role + for ( RoleRecord other : roles ) + { + if ( other.name().equals( role.name() ) ) + { + throw new IllegalCredentialsException( "The specified role already exists" ); + } + } + + roles.add( role ); + + saveRolesToFile(); + + rolesByName.put( role.name(), role ); + + populateUserMap( role ); + } + } + + @Override + public void update( RoleRecord existingRole, RoleRecord updatedRole ) throws ConcurrentModificationException, IOException + { + // Assert input is ok + if ( !existingRole.name().equals( updatedRole.name() ) ) + { + throw new IllegalArgumentException( "updatedRole has a different name" ); + } + + synchronized (this) + { + // Copy-on-write for the roles list + List newRoles = new ArrayList<>(); + boolean foundRole = false; + for ( RoleRecord other : roles ) + { + if ( other.equals( existingRole ) ) + { + foundRole = true; + newRoles.add( updatedRole ); + } else + { + newRoles.add( other ); + } + } + + if ( !foundRole ) + { + throw new ConcurrentModificationException(); + } + + roles = newRoles; + + saveRolesToFile(); + + rolesByName.put( updatedRole.name(), updatedRole ); + + removeFromUserMap( existingRole ); + populateUserMap( updatedRole ); + } + } + + @Override + public boolean delete( RoleRecord role ) throws IOException + { + boolean foundRole = false; + synchronized (this) + { + // Copy-on-write for the roles list + List newRoles = new ArrayList<>(); + for ( RoleRecord other : roles ) + { + if ( other.name().equals( role.name() ) ) + { + foundRole = true; + } else + { + newRoles.add( other ); + } + } + + if ( foundRole ) + { + roles = newRoles; + + saveRolesToFile(); + + rolesByName.remove( role.name() ); + } + + removeFromUserMap( role ); + } + return foundRole; + } + + @Override + public int numberOfRoles() + { + return roles.size(); + } + + @Override + public boolean isValidName( String name ) + { + return name.matches( "^[a-zA-Z0-9_]+$" ); + } + + private void saveRolesToFile() throws IOException + { + Path directory = roleFile.getParent(); + if ( !Files.exists( directory ) ) + { + Files.createDirectories( directory ); + } + + Path tempFile = Files.createTempFile( directory, roleFile.getFileName().toString() + "-", ".tmp" ); + try + { + Files.write( tempFile, serialization.serialize( roles ) ); + Files.move( tempFile, roleFile, ATOMIC_MOVE, REPLACE_EXISTING ); + } catch ( Throwable e ) + { + Files.delete( tempFile ); + throw e; + } + } + + private void loadRolesFromFile() throws IOException + { + byte[] fileBytes = Files.readAllBytes( roleFile ); + List loadedRoles; + try + { + loadedRoles = serialization.deserializeRoles( fileBytes ); + } catch ( RoleSerialization.FormatException e ) + { + log.error( "Ignoring role file \"%s\" (%s)", roleFile.toAbsolutePath(), e.getMessage() ); + throw new IllegalStateException( "Failed to read role file: " + roleFile ); + } + + roles = loadedRoles; + for ( RoleRecord role : roles ) + { + rolesByName.put( role.name(), role ); + + populateUserMap( role ); + } + } + + private void populateUserMap( RoleRecord role ) + { + for ( String username : role.users() ) + { + SortedSet memberOfRoles = rolesByUsername.get( username ); + if ( memberOfRoles == null ) + { + memberOfRoles = new ConcurrentSkipListSet<>(); + rolesByUsername.put( username, memberOfRoles ); + } + memberOfRoles.add( role.name() ); + } + } + + private void removeFromUserMap( RoleRecord role ) + { + for ( String username : role.users() ) + { + SortedSet memberOfRoles = rolesByUsername.get( username ); + if ( memberOfRoles != null ) + { + memberOfRoles.remove( role.name() ); + } + } + } +} diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileUserRealm.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileUserRealm.java index 7de877693261a..040ca905b9720 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileUserRealm.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/FileUserRealm.java @@ -55,7 +55,7 @@ public class FileUserRealm extends AuthorizingRealm { private final UserRepository userRepository; - private final GroupRepository groupRepository; + private final RoleRepository roleRepository; private final CredentialsMatcher credentialsMatcher = ( AuthenticationToken token, AuthenticationInfo info ) -> @@ -90,12 +90,12 @@ public Collection resolvePermissionsInRole( String roleString ) private final Map roles; - public FileUserRealm( UserRepository userRepository, GroupRepository groupRepository ) + public FileUserRealm( UserRepository userRepository, RoleRepository roleRepository ) { super(); this.userRepository = userRepository; - this.groupRepository = groupRepository; + this.roleRepository = roleRepository; setCredentialsMatcher( credentialsMatcher ); setRolePermissionResolver( rolePermissionResolver ); @@ -107,7 +107,7 @@ protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principa { User user = userRepository.findByName( (String) principals.getPrimaryPrincipal() ); - Set roles = groupRepository.findByUsername( user.name() ); + Set roles = roleRepository.findByUsername( user.name() ); return new SimpleAuthorizationInfo( roles ); } @@ -154,31 +154,31 @@ User newUser( String username, String initialPassword, boolean requirePasswordCh return user; } - GroupRecord newGroup( String groupName, String... users ) throws + RoleRecord newRole( String roleName, String... users ) throws IOException, IllegalCredentialsException, ConcurrentModificationException { - assertValidName( groupName ); + assertValidName( roleName ); SortedSet userSet = new TreeSet( Arrays.asList( users ) ); - GroupRecord group = new GroupRecord.Builder().withName( groupName ).withUsers( userSet ).build(); - groupRepository.create( group ); + RoleRecord role = new RoleRecord.Builder().withName( roleName ).withUsers( userSet ).build(); + roleRepository.create( role ); - return group; + return role; } - private void addUserToGroup( User user, String groupName ) + private void addUserToRole( User user, String roleName ) throws IOException, IllegalCredentialsException, ConcurrentModificationException { - GroupRecord group = groupRepository.findByName( groupName ); - if ( group == null ) + RoleRecord role = roleRepository.findByName( roleName ); + if ( role == null ) { - GroupRecord newGroup = new GroupRecord( groupName, user.name() ); - groupRepository.create( newGroup ); + RoleRecord newRole = new RoleRecord( roleName, user.name() ); + roleRepository.create( newRole ); } else { - GroupRecord newGroup = group.augment().withUser( user.name() ).build(); - groupRepository.update( group, newGroup ); + RoleRecord newRole = role.augment().withUser( user.name() ).build(); + roleRepository.update( role, newRole ); } } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRecord.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRecord.java similarity index 83% rename from enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRecord.java rename to enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRecord.java index 8800ef1b0b6d0..d7083f9388000 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRecord.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRecord.java @@ -25,26 +25,26 @@ /** * Controls authorization and authentication for a set of users. */ -public class GroupRecord +public class RoleRecord { /* Design note: These instances are shared across threads doing disparate things with them, and there are no access locks. Correctness depends on write-time assertions and this class remaining immutable. Please do not introduce mutable fields here. */ - /** Group name */ + /** Role name */ private final String name; /** Member users */ private final SortedSet users; - public GroupRecord( String name, SortedSet users ) + public RoleRecord( String name, SortedSet users ) { this.name = name; this.users = users; } - public GroupRecord( String name, String... users ) + public RoleRecord( String name, String... users ) { this.name = name; this.users = new TreeSet(); @@ -62,7 +62,7 @@ public String name() public SortedSet users() { return users; } - /** Use this group as a base for a new group object */ + /** Use this role as a base for a new role object */ public Builder augment() { return new Builder(this); } @Override @@ -77,13 +77,13 @@ public boolean equals( Object o ) return false; } - GroupRecord group = (GroupRecord) o; + RoleRecord role = (RoleRecord) o; - if ( name != null ? !name.equals( group.name ) : group.name != null ) + if ( name != null ? !name.equals( role.name ) : role.name != null ) { return false; } - if ( users != null ? !users.equals( group.users ) : group.users != null ) + if ( users != null ? !users.equals( role.users ) : role.users != null ) { return false; } @@ -102,7 +102,7 @@ public int hashCode() @Override public String toString() { - return "Group{" + + return "Role{" + "name='" + name + '\'' + ", users='" + users + '\'' + '}'; @@ -115,7 +115,7 @@ public static class Builder public Builder() { } - public Builder( GroupRecord base ) + public Builder( RoleRecord base ) { name = base.name; users = base.users; @@ -125,9 +125,9 @@ public Builder( GroupRecord base ) public Builder withUsers( SortedSet users ) { this.users = users; return this; } public Builder withUser( String user ) { this.users.add( user ); return this; } - public GroupRecord build() + public RoleRecord build() { - return new GroupRecord( name, users ); + return new RoleRecord( name, users ); } } } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRepository.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java similarity index 54% rename from enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRepository.java rename to enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java index d0b19b9a3d00b..9e1971b1fa2b4 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupRepository.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleRepository.java @@ -27,38 +27,38 @@ import org.neo4j.server.security.auth.exception.ConcurrentModificationException; /** - * A component that can store and retrieve groups. Implementations must be thread safe. + * A component that can store and retrieve roles. Implementations must be thread safe. */ -public interface GroupRepository extends Lifecycle +public interface RoleRepository extends Lifecycle { - GroupRecord findByName( String name ); + RoleRecord findByName( String name ); Set findByUsername( String username ); /** - * Create a group, given that the groups token is unique. - * @param group the new group object - * @throws IllegalCredentialsException if the group name is not valid + * Create a role, given that the roles token is unique. + * @param role the new role object + * @throws IllegalCredentialsException if the role name is not valid */ - void create( GroupRecord group ) throws IllegalCredentialsException, IOException; + void create( RoleRecord role ) throws IllegalCredentialsException, IOException; /** - * Update a group, given that the group token is unique. - * @param existingGroup the existing group object, which must match the current state in this repository - * @param updatedGroup the updated group object - * @throws ConcurrentModificationException if the existingGroup does not match the current state in the repository + * Update a role, given that the role token is unique. + * @param existingRole the existing role object, which must match the current state in this repository + * @param updatedRole the updated role object + * @throws ConcurrentModificationException if the existingRole does not match the current state in the repository */ - void update( GroupRecord existingGroup, GroupRecord updatedGroup ) throws ConcurrentModificationException, IOException; + void update( RoleRecord existingRole, RoleRecord updatedRole ) throws ConcurrentModificationException, IOException; /** - * Deletes a group. - * @param group the group to delete - * @return true if the group was found and deleted + * Deletes a role. + * @param role the role to delete + * @return true if the role was found and deleted */ - boolean delete( GroupRecord group ) throws IOException; + boolean delete( RoleRecord role ) throws IOException; - int numberOfGroups(); + int numberOfRoles(); - /** Utility for API consumers to tell if #create() will accept a given group name */ + /** Utility for API consumers to tell if #create() will accept a given role name */ boolean isValidName( String name ); } diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupSerialization.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleSerialization.java similarity index 78% rename from enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupSerialization.java rename to enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleSerialization.java index 288bfcdff691f..e29769ed80c71 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/GroupSerialization.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/RoleSerialization.java @@ -30,9 +30,9 @@ import static java.lang.String.format; /** - * Serializes group authorization and authentication data to a format similar to unix passwd files. + * Serializes role authorization and authentication data to a format similar to unix passwd files. */ -public class GroupSerialization +public class RoleSerialization { public class FormatException extends Exception { @@ -42,47 +42,47 @@ public class FormatException extends Exception } } - private static final String groupSeparator = ":"; + private static final String roleSeparator = ":"; private static final String userSeparator = ","; - public byte[] serialize(Collection groups) + public byte[] serialize(Collection roles) { StringBuilder sb = new StringBuilder(); - for ( GroupRecord group : groups ) + for ( RoleRecord role : roles ) { - sb.append( serialize(group) ).append( "\n" ); + sb.append( serialize(role) ).append( "\n" ); } return UTF8.encode( sb.toString() ); } - public List deserializeGroups( byte[] bytes ) throws FormatException + public List deserializeRoles( byte[] bytes ) throws FormatException { - List out = new ArrayList<>(); + List out = new ArrayList<>(); int lineNumber = 1; for ( String line : UTF8.decode( bytes ).split( "\n" ) ) { if (line.trim().length() > 0) { - out.add( deserializeGroup( line, lineNumber ) ); + out.add( deserializeRole( line, lineNumber ) ); } lineNumber++; } return out; } - private String serialize( GroupRecord group ) + private String serialize( RoleRecord role ) { - return join( groupSeparator, group.name(), serialize( group.users() ) ); + return join( roleSeparator, role.name(), serialize( role.users() ) ); } - private GroupRecord deserializeGroup( String line, int lineNumber ) throws FormatException + private RoleRecord deserializeRole( String line, int lineNumber ) throws FormatException { - String[] parts = line.split( groupSeparator, -1 ); + String[] parts = line.split( roleSeparator, -1 ); if ( parts.length != 2 ) { throw new FormatException( format( "wrong number of line fields [line %d]", lineNumber ) ); } - return new GroupRecord.Builder() + return new RoleRecord.Builder() .withName( parts[0] ) .withUsers( deserializeUsers( parts[1], lineNumber ) ) .build(); diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManager.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManager.java index d937a9d64752c..7385ca521d85c 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManager.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManager.java @@ -48,26 +48,28 @@ public class ShiroAuthManager extends BasicAuthManager private final EhCacheManager cacheManager; private final FileUserRealm realm; - public ShiroAuthManager( UserRepository userRepository, GroupRepository groupRepository, + public ShiroAuthManager( UserRepository userRepository, RoleRepository roleRepository, PasswordPolicy passwordPolicy, AuthenticationStrategy authStrategy, boolean authEnabled ) { super( userRepository, passwordPolicy, authStrategy, authEnabled ); - realm = new FileUserRealm( userRepository, groupRepository ); + realm = new FileUserRealm( userRepository, roleRepository ); // TODO: Maybe MemoryConstrainedCacheManager is good enough if we do not need timeToLiveSeconds? It would be one less dependency. // Or we could try to reuse Hazelcast which is already a dependency, but we would need to write some glue code. cacheManager = new EhCacheManager(); securityManager = new DefaultSecurityManager( realm ); } - public ShiroAuthManager( UserRepository users, GroupRepository groups, PasswordPolicy passwordPolicy, AuthenticationStrategy authStrategy ) + public ShiroAuthManager( UserRepository userRepository, RoleRepository roleRepository, PasswordPolicy passwordPolicy, + AuthenticationStrategy authStrategy ) { - this( users, groups, passwordPolicy, authStrategy, true ); + this( userRepository, roleRepository, passwordPolicy, authStrategy, true ); } - public ShiroAuthManager( UserRepository users, GroupRepository groups, PasswordPolicy passwordPolicy, Clock clock, boolean authEnabled ) + public ShiroAuthManager( UserRepository userRepository, RoleRepository roleRepository, PasswordPolicy passwordPolicy, + Clock clock, boolean authEnabled ) { - this( users, groups, passwordPolicy, new RateLimitedAuthenticationStrategy( clock, 3 ), authEnabled ); + this( userRepository, roleRepository, passwordPolicy, new RateLimitedAuthenticationStrategy( clock, 3 ), authEnabled ); } @Override @@ -118,13 +120,13 @@ public User newUser( String username, String initialPassword, boolean requirePas } } - public GroupRecord newGroup( String groupName, String... users ) throws IOException, IllegalCredentialsException + public RoleRecord newRole( String roleName, String... users ) throws IOException, IllegalCredentialsException { assertAuthEnabled(); try { - return realm.newGroup( groupName, users ); + return realm.newRole( roleName, users ); } catch ( ConcurrentModificationException e ) diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileGroupRepositoryTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileRoleRepositoryTest.java similarity index 60% rename from enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileGroupRepositoryTest.java rename to enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileRoleRepositoryTest.java index 74a2223519b36..0a8ddd0f05b88 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileGroupRepositoryTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/FileRoleRepositoryTest.java @@ -54,7 +54,7 @@ import static org.junit.Assert.fail; @RunWith(Parameterized.class) -public class FileGroupRepositoryTest +public class FileRoleRepositoryTest { private final FileSystem fs; private Path authFile; @@ -72,75 +72,75 @@ public static Collection data() @Rule public ExpectedException thrown = ExpectedException.none(); - public FileGroupRepositoryTest( Configuration fsConfig, String fsType ) + public FileRoleRepositoryTest( Configuration fsConfig, String fsType ) { fs = Jimfs.newFileSystem( fsConfig ); authFile = fs.getPath( "dbms", "auth.db" ); } @Test - public void shouldStoreAndRetriveGroupsByName() throws Exception + public void shouldStoreAndRetriveRolesByName() throws Exception { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - GroupRecord group = new GroupRecord( "admin", "petra", "olivia" ); - groups.create( group ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + RoleRecord role = new RoleRecord( "admin", "petra", "olivia" ); + roleRepository.create( role ); // When - GroupRecord result = groups.findByName( group.name() ); + RoleRecord result = roleRepository.findByName( role.name() ); // Then - assertThat( result, equalTo( group ) ); + assertThat( result, equalTo( role ) ); } @Test - public void shouldPersistGroups() throws Throwable + public void shouldPersistRoles() throws Throwable { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - GroupRecord group = new GroupRecord( "admin", "craig", "karl" ); - groups.create( group ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + RoleRecord role = new RoleRecord( "admin", "craig", "karl" ); + roleRepository.create( role ); - groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - groups.start(); + roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + roleRepository.start(); // When - GroupRecord resultByName = groups.findByName( group.name() ); + RoleRecord resultByName = roleRepository.findByName( role.name() ); // Then - assertThat( resultByName, equalTo( group ) ); + assertThat( resultByName, equalTo( role ) ); } @Test - public void shouldNotFindGroupAfterDelete() throws Throwable + public void shouldNotFindRoleAfterDelete() throws Throwable { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - GroupRecord group = new GroupRecord( "jake", "admin" ); - groups.create( group ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + RoleRecord role = new RoleRecord( "jake", "admin" ); + roleRepository.create( role ); // When - groups.delete( group ); + roleRepository.delete( role ); // Then - assertThat( groups.findByName( group.name() ), nullValue() ); + assertThat( roleRepository.findByName( role.name() ), nullValue() ); } @Test public void shouldNotAllowComplexNames() throws Exception { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); // When - assertTrue( groups.isValidName( "neo4j" ) ); - assertTrue( groups.isValidName( "johnosbourne" ) ); - assertTrue( groups.isValidName( "john_osbourne" ) ); - - assertFalse( groups.isValidName( ":" ) ); - assertFalse( groups.isValidName( "" ) ); - assertFalse( groups.isValidName( "john osbourne" ) ); - assertFalse( groups.isValidName( "john:osbourne" ) ); + assertTrue( roleRepository.isValidName( "neo4j" ) ); + assertTrue( roleRepository.isValidName( "johnosbourne" ) ); + assertTrue( roleRepository.isValidName( "john_osbourne" ) ); + + assertFalse( roleRepository.isValidName( ":" ) ); + assertFalse( roleRepository.isValidName( "" ) ); + assertFalse( roleRepository.isValidName( "john osbourne" ) ); + assertFalse( roleRepository.isValidName( "john:osbourne" ) ); } @Test @@ -170,14 +170,14 @@ public void move( Path source, Path target, CopyOption... options ) throws IOExc Path authFile = moveFailingFileSystem.getPath( "dbms", "auth.db" ); - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - groups.start(); - GroupRecord group = new GroupRecord( "admin", "jake" ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + roleRepository.start(); + RoleRecord role = new RoleRecord( "admin", "jake" ); // When try { - groups.create( group ); + roleRepository.create( role ); fail( "Expected an IOException" ); } catch ( IOException e ) { @@ -193,38 +193,38 @@ public void move( Path source, Path target, CopyOption... options ) throws IOExc public void shouldThrowIfUpdateChangesName() throws Throwable { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - GroupRecord group = new GroupRecord( "admin", "steve", "bob" ); - groups.create( group ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + RoleRecord role = new RoleRecord( "admin", "steve", "bob" ); + roleRepository.create( role ); // When - GroupRecord updatedGroup = new GroupRecord( "admins", "steve", "bob" ); + RoleRecord updatedRole = new RoleRecord( "admins", "steve", "bob" ); try { - groups.update( group, updatedGroup ); + roleRepository.update( role, updatedRole ); fail( "expected exception not thrown" ); } catch ( IllegalArgumentException e ) { // Then continue } - assertThat( groups.findByName( group.name() ), equalTo( group ) ); + assertThat( roleRepository.findByName( role.name() ), equalTo( role ) ); } @Test - public void shouldThrowIfExistingGroupDoesNotMatch() throws Throwable + public void shouldThrowIfExistingRoleDoesNotMatch() throws Throwable { // Given - FileGroupRepository groups = new FileGroupRepository( authFile, NullLogProvider.getInstance() ); - GroupRecord group = new GroupRecord( "admin", "jake" ); - groups.create( group ); - GroupRecord modifiedGroup = new GroupRecord( "admin", "jake", "john" ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, NullLogProvider.getInstance() ); + RoleRecord role = new RoleRecord( "admin", "jake" ); + roleRepository.create( role ); + RoleRecord modifiedRole = new RoleRecord( "admin", "jake", "john" ); // When - GroupRecord updatedGroup = new GroupRecord( "admin", "john" ); + RoleRecord updatedRole = new RoleRecord( "admin", "john" ); try { - groups.update( modifiedGroup, updatedGroup ); + roleRepository.update( modifiedRole, updatedRole ); fail( "expected exception not thrown" ); } catch ( ConcurrentModificationException e ) { @@ -243,16 +243,16 @@ public void shouldIgnoreInvalidEntries() throws Throwable "admin:admin:\n" ) ); // When - FileGroupRepository groups = new FileGroupRepository( authFile, logProvider ); + FileRoleRepository roleRepository = new FileRoleRepository( authFile, logProvider ); thrown.expect( IllegalStateException.class ); - thrown.expectMessage( startsWith( "Failed to read group file: " ) ); - groups.start(); + thrown.expectMessage( startsWith( "Failed to read role file: " ) ); + roleRepository.start(); // Then - assertThat( groups.numberOfGroups(), equalTo( 1 ) ); + assertThat( roleRepository.numberOfRoles(), equalTo( 1 ) ); logProvider.assertExactly( - AssertableLogProvider.inLog( FileGroupRepository.class ).error( - "Ignoring group file \"%s\" (%s)", authFile.toAbsolutePath(), "wrong number of line fields [line 1]" + AssertableLogProvider.inLog( FileRoleRepository.class ).error( + "Ignoring role file \"%s\" (%s)", authFile.toAbsolutePath(), "wrong number of line fields [line 1]" ) ); } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryGroupRepository.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryGroupRepository.java deleted file mode 100644 index e148fd7458ec5..0000000000000 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryGroupRepository.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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.security.enterprise.auth; - -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; - -import org.neo4j.kernel.api.security.exception.IllegalCredentialsException; -import org.neo4j.kernel.lifecycle.LifecycleAdapter; -import org.neo4j.server.security.auth.exception.ConcurrentModificationException; - -/** A group repository implementation that just stores groups in memory */ -public class InMemoryGroupRepository extends LifecycleAdapter implements GroupRepository -{ - private final ConcurrentHashMap groups = new ConcurrentHashMap<>(); - private final Map> groupsByUsername = new ConcurrentHashMap<>(); - - @Override - public GroupRecord findByName( String name ) - { - return groups.get( name ); - } - - @Override - public Set findByUsername( String username ) - { - return groupsByUsername.get( username ); - } - - @Override - public void create( GroupRecord group ) throws IllegalCredentialsException - { - synchronized (this) - { - // Check for existing group or token - for ( GroupRecord other : groups.values() ) - { - if ( other.name().equals( group.name() ) ) - { - throw new IllegalCredentialsException( "The specified group already exists" ); - } - } - - groups.put( group.name(), group ); - - populateUserMap( group ); - } - } - - @Override - public void update( GroupRecord existingGroup, GroupRecord updatedGroup ) throws ConcurrentModificationException - { - // Assert input is ok - if ( !existingGroup.name().equals( updatedGroup.name() ) ) - { - throw new IllegalArgumentException( "updatedGroup has a different name" ); - } - - synchronized (this) - { - boolean foundGroup = false; - for ( GroupRecord other : groups.values() ) - { - if ( other.equals( existingGroup ) ) - { - foundGroup = true; - } - } - - if ( !foundGroup ) - { - throw new ConcurrentModificationException(); - } - - groups.put( updatedGroup.name(), updatedGroup ); - - removeFromUserMap( existingGroup ); - populateUserMap( updatedGroup ); - } - } - - @Override - public boolean delete( GroupRecord group ) - { - synchronized (this) - { - boolean removedGroup = groups.remove( group.name() ) != null; - - if ( removedGroup ) - { - removeFromUserMap( group ); - } - - return removedGroup; - } - } - - @Override - public int numberOfGroups() - { - return groups.size(); - } - - @Override - public boolean isValidName( String name ) - { - // This repo can store any name - return true; - } - - private void populateUserMap( GroupRecord group ) - { - for ( String username : group.users() ) - { - SortedSet memberOfGroups = groupsByUsername.get( username ); - if ( memberOfGroups == null ) - { - memberOfGroups = new ConcurrentSkipListSet<>(); - groupsByUsername.put( username, memberOfGroups ); - } - memberOfGroups.add( group.name() ); - } - } - - private void removeFromUserMap( GroupRecord group ) - { - for ( String username : group.users() ) - { - SortedSet memberOfGroups = groupsByUsername.get( username ); - if ( memberOfGroups != null ) - { - memberOfGroups.remove( group.name() ); - } - } - } - -} diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryRoleRepository.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryRoleRepository.java new file mode 100644 index 0000000000000..f6c4f9862357d --- /dev/null +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/InMemoryRoleRepository.java @@ -0,0 +1,157 @@ +/* + * 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.security.enterprise.auth; + +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.neo4j.kernel.api.security.exception.IllegalCredentialsException; +import org.neo4j.kernel.lifecycle.LifecycleAdapter; +import org.neo4j.server.security.auth.exception.ConcurrentModificationException; + +/** A role repository implementation that just stores roles in memory */ +public class InMemoryRoleRepository extends LifecycleAdapter implements RoleRepository +{ + private final ConcurrentHashMap roles = new ConcurrentHashMap<>(); + private final Map> rolesByUsername = new ConcurrentHashMap<>(); + + @Override + public RoleRecord findByName( String name ) + { + return roles.get( name ); + } + + @Override + public Set findByUsername( String username ) + { + return rolesByUsername.get( username ); + } + + @Override + public void create( RoleRecord role ) throws IllegalCredentialsException + { + synchronized (this) + { + // Check for existing role or token + for ( RoleRecord other : roles.values() ) + { + if ( other.name().equals( role.name() ) ) + { + throw new IllegalCredentialsException( "The specified role already exists" ); + } + } + + roles.put( role.name(), role ); + + populateUserMap( role ); + } + } + + @Override + public void update( RoleRecord existingRole, RoleRecord updatedRole ) throws ConcurrentModificationException + { + // Assert input is ok + if ( !existingRole.name().equals( updatedRole.name() ) ) + { + throw new IllegalArgumentException( "updated role has a different name" ); + } + + synchronized (this) + { + boolean foundRole = false; + for ( RoleRecord other : roles.values() ) + { + if ( other.equals( existingRole ) ) + { + foundRole = true; + } + } + + if ( !foundRole ) + { + throw new ConcurrentModificationException(); + } + + roles.put( updatedRole.name(), updatedRole ); + + removeFromUserMap( existingRole ); + populateUserMap( updatedRole ); + } + } + + @Override + public boolean delete( RoleRecord role ) + { + synchronized (this) + { + boolean removedRole = roles.remove( role.name() ) != null; + + if ( removedRole ) + { + removeFromUserMap( role ); + } + + return removedRole; + } + } + + @Override + public int numberOfRoles() + { + return roles.size(); + } + + @Override + public boolean isValidName( String name ) + { + // This repo can store any name + return true; + } + + private void populateUserMap( RoleRecord role ) + { + for ( String username : role.users() ) + { + SortedSet membersOfRole = rolesByUsername.get( username ); + if ( membersOfRole == null ) + { + membersOfRole = new ConcurrentSkipListSet<>(); + rolesByUsername.put( username, membersOfRole ); + } + membersOfRole.add( role.name() ); + } + } + + private void removeFromUserMap( RoleRecord role ) + { + for ( String username : role.users() ) + { + SortedSet membersOfRole = rolesByUsername.get( username ); + if ( membersOfRole != null ) + { + membersOfRole.remove( role.name() ); + } + } + } + +} diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/GroupSerializationTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/RoleSerializationTest.java similarity index 75% rename from enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/GroupSerializationTest.java rename to enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/RoleSerializationTest.java index ce3a55cd09dfb..320f8840e696f 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/GroupSerializationTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/RoleSerializationTest.java @@ -32,7 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -public class GroupSerializationTest +public class RoleSerializationTest { private SortedSet steveBob; @@ -54,17 +54,17 @@ public void setUp() public void shouldSerializeAndDeserialize() throws Exception { // Given - GroupSerialization serialization = new GroupSerialization(); + RoleSerialization serialization = new RoleSerialization(); - List groups = asList( - new GroupRecord( "admin", steveBob ), - new GroupRecord( "publisher", kellyMarie ) ); + List roles = asList( + new RoleRecord( "admin", steveBob ), + new RoleRecord( "publisher", kellyMarie ) ); // When - byte[] serialized = serialization.serialize( groups ); + byte[] serialized = serialization.serialize( roles ); // Then - assertThat( serialization.deserializeGroups( serialized ), equalTo( groups ) ); + assertThat( serialization.deserializeRoles( serialized ), equalTo( roles ) ); } /** @@ -75,16 +75,16 @@ public void shouldSerializeAndDeserialize() throws Exception public void shouldReadV1SerializationFormat() throws Exception { // Given - GroupSerialization serialization = new GroupSerialization(); + RoleSerialization serialization = new RoleSerialization(); // When - List deserialized = serialization.deserializeGroups( UTF8.encode( + List deserialized = serialization.deserializeRoles( UTF8.encode( ("admin:Bob,Steve\n" + "publisher:Kelly,Marie\n") ) ); // Then assertThat( deserialized, equalTo( asList( - new GroupRecord( "admin", steveBob ), - new GroupRecord( "publisher", kellyMarie ) ) ) ); + new RoleRecord( "admin", steveBob ), + new RoleRecord( "publisher", kellyMarie ) ) ) ); } } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManagerTest.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManagerTest.java index 9fa08873d0738..66068ad52bc61 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManagerTest.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ShiroAuthManagerTest.java @@ -47,7 +47,7 @@ public class ShiroAuthManagerTest { private InMemoryUserRepository users; - private InMemoryGroupRepository groups; + private InMemoryRoleRepository roles; private AuthenticationStrategy authStrategy; private PasswordPolicy passwordPolicy; private ShiroAuthManager manager; @@ -56,10 +56,10 @@ public class ShiroAuthManagerTest public void setUp() throws Throwable { users = new InMemoryUserRepository(); - groups = new InMemoryGroupRepository(); + roles = new InMemoryRoleRepository(); authStrategy = mock( AuthenticationStrategy.class ); passwordPolicy = mock( PasswordPolicy.class ); - manager = new ShiroAuthManager( users, groups, passwordPolicy, authStrategy, true ); + manager = new ShiroAuthManager( users, roles, passwordPolicy, authStrategy, true ); manager.init(); } @@ -235,20 +235,20 @@ public void shouldReturnNullWhenSettingPasswordForUnknownUser() throws Throwable private void createTestUsers() throws Throwable { manager.newUser( "morpheus", "abc123", false ); - manager.newGroup( "admin", "morpheus" ); + manager.newRole( "admin", "morpheus" ); manager.newUser( "trinity", "abc123", false ); - manager.newGroup( "architect", "trinity" ); + manager.newRole( "architect", "trinity" ); manager.newUser( "tank", "abc123", false ); - manager.newGroup( "publisher", "tank" ); + manager.newRole( "publisher", "tank" ); manager.newUser( "neo", "abc123", false ); - manager.newGroup( "reader", "neo" ); + manager.newRole( "reader", "neo" ); manager.newUser( "smith", "abc123", false ); - manager.newGroup( "agent", "smith" ); + manager.newRole( "agent", "smith" ); when( authStrategy.isAuthenticationPermitted( anyString() ) ).thenReturn( true ); } @Test - public void userWithAdminGroupShouldHaveCorrectPermissions() throws Throwable + public void userWithAdminRoleShouldHaveCorrectPermissions() throws Throwable { // Given createTestUsers(); @@ -264,7 +264,7 @@ public void userWithAdminGroupShouldHaveCorrectPermissions() throws Throwable } @Test - public void userWithArchitectGroupShouldHaveCorrectPermissions() throws Throwable + public void userWithArchitectRoleShouldHaveCorrectPermissions() throws Throwable { // Given createTestUsers(); @@ -280,7 +280,7 @@ public void userWithArchitectGroupShouldHaveCorrectPermissions() throws Throwabl } @Test - public void userWithPublisherGroupShouldHaveCorrectPermissions() throws Throwable + public void userWithPublisherRoleShouldHaveCorrectPermissions() throws Throwable { // Given createTestUsers(); @@ -296,7 +296,7 @@ public void userWithPublisherGroupShouldHaveCorrectPermissions() throws Throwabl } @Test - public void userWithReaderGroupShouldHaveCorrectPermissions() throws Throwable + public void userWithReaderRoleShouldHaveCorrectPermissions() throws Throwable { // Given createTestUsers(); @@ -312,7 +312,7 @@ public void userWithReaderGroupShouldHaveCorrectPermissions() throws Throwable } @Test - public void userWithNonPredefinedGroupShouldHaveNoPermissions() throws Throwable + public void userWithNonPredefinedRoleShouldHaveNoPermissions() throws Throwable { // Given createTestUsers(); @@ -354,7 +354,7 @@ public void shouldThrowWhenAuthIsDisabled() throws Throwable // Restart with auth disabled manager.stop(); manager.shutdown(); - manager = new ShiroAuthManager( users, groups, passwordPolicy, authStrategy, false ); + manager = new ShiroAuthManager( users, roles, passwordPolicy, authStrategy, false ); manager.start(); try