Skip to content

Commit

Permalink
Add unit tests for ShiroAuthenticationInfo merge
Browse files Browse the repository at this point in the history
- Rename ShiroRealmLifeCycle to RealmLifeCycle
  • Loading branch information
henriknyman committed Jun 27, 2016
1 parent e4df4f0 commit 8b0d232
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 12 deletions.
Expand Up @@ -62,7 +62,7 @@
/**
* Shiro realm wrapping FileUserRepository and FileRoleRepository
*/
public class InternalFlatFileRealm extends AuthorizingRealm implements ShiroRealmLifecycle, EnterpriseUserManager
public class InternalFlatFileRealm extends AuthorizingRealm implements RealmLifecycle, EnterpriseUserManager
{
/**
* This flag is used in the same way as User.PASSWORD_CHANGE_REQUIRED, but it's
Expand Down
Expand Up @@ -19,6 +19,8 @@
*/
package org.neo4j.server.security.enterprise.auth;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
Expand All @@ -32,7 +34,9 @@
import java.util.Collection;
import java.util.Collections;
import javax.naming.NamingException;
import javax.naming.ldap.LdapContext;

import org.neo4j.kernel.api.security.AuthenticationResult;
import org.neo4j.kernel.configuration.Config;

/**
Expand All @@ -45,7 +49,6 @@ public LdapRealm( Config config )
super();
setRolePermissionResolver( rolePermissionResolver );
configureRealm( config );
// TODO: Set NeoSubjectFactory on the SecurityManager
}

@Override
Expand All @@ -56,6 +59,15 @@ protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection princi
return new SimpleAuthorizationInfo( Collections.singleton( PredefinedRolesBuilder.READER ) );
}

@Override
protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, Object ldapPrincipal,
Object ldapCredentials, LdapContext ldapContext)
throws NamingException {
// NOTE: This will be called only if authentication with the ldap context was successful
return new ShiroAuthenticationInfo( token.getPrincipal(), token.getCredentials(), getName(),
AuthenticationResult.SUCCESS );
}

private final RolePermissionResolver rolePermissionResolver = new RolePermissionResolver()
{
@Override
Expand Down
Expand Up @@ -21,7 +21,6 @@

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.cache.ehcache.EhCacheManager;
Expand Down Expand Up @@ -102,9 +101,9 @@ public void init() throws Throwable
{
((CachingRealm) realm).setCacheManager( cacheManager );
}
if ( realm instanceof ShiroRealmLifecycle )
if ( realm instanceof RealmLifecycle )
{
((ShiroRealmLifecycle) realm).initialize();
((RealmLifecycle) realm).initialize();
}
}
}
Expand All @@ -114,9 +113,9 @@ public void start() throws Throwable
{
for ( Realm realm : realms )
{
if ( realm instanceof ShiroRealmLifecycle )
if ( realm instanceof RealmLifecycle )
{
((ShiroRealmLifecycle) realm).start();
((RealmLifecycle) realm).start();
}
}
}
Expand All @@ -126,9 +125,9 @@ public void stop() throws Throwable
{
for ( Realm realm : realms )
{
if ( realm instanceof ShiroRealmLifecycle )
if ( realm instanceof RealmLifecycle )
{
((ShiroRealmLifecycle) realm).stop();
((RealmLifecycle) realm).stop();
}
}
}
Expand All @@ -142,9 +141,9 @@ public void shutdown() throws Throwable
{
((CachingRealm) realm).setCacheManager( null );
}
if ( realm instanceof ShiroRealmLifecycle )
if ( realm instanceof RealmLifecycle )
{
((ShiroRealmLifecycle) realm).shutdown();
((RealmLifecycle) realm).shutdown();
}
}
cacheManager.destroy();
Expand Down
Expand Up @@ -19,7 +19,7 @@
*/
package org.neo4j.server.security.enterprise.auth;

public interface ShiroRealmLifecycle
public interface RealmLifecycle
{
void initialize() throws Throwable;
void start() throws Throwable;
Expand Down
@@ -0,0 +1,122 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.server.security.enterprise.auth;

import org.junit.Test;

import org.neo4j.kernel.api.security.AuthenticationResult;

import static org.junit.Assert.assertEquals;
import static org.neo4j.kernel.api.security.AuthenticationResult.*;

public class ShiroAuthenticationInfoTest
{
private ShiroAuthenticationInfo successInfo = new ShiroAuthenticationInfo( "user", "password", "realm", SUCCESS );
private ShiroAuthenticationInfo failureInfo = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
private ShiroAuthenticationInfo tooManyAttemptsInfo = new ShiroAuthenticationInfo( "user", "password", "realm", TOO_MANY_ATTEMPTS );
private ShiroAuthenticationInfo pwChangeRequiredInfo = new ShiroAuthenticationInfo( "user", "password", "realm", PASSWORD_CHANGE_REQUIRED );

// These tests are here to remind you that you need to update the ShiroAuthenticationInfo.mergeMatrix[][]
// whenever you add/remove/move values in the AuthenticationResult enum

@Test
public void shouldChangeMergeMatrixIfAuthenticationResultEnumChanges()
{
// These are the assumptions made for ShiroAuthenticationInfo.mergeMatrix[][]
// which have to stay in sync with the enum
assertEquals( AuthenticationResult.SUCCESS.ordinal(), 0 );
assertEquals( AuthenticationResult.FAILURE.ordinal(), 1 );
assertEquals( AuthenticationResult.TOO_MANY_ATTEMPTS.ordinal(), 2 );
assertEquals( AuthenticationResult.PASSWORD_CHANGE_REQUIRED.ordinal(), 3 );
assertEquals( AuthenticationResult.values().length, 4 );
}

@Test
public void shouldMergeTwoSuccessToSameValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", SUCCESS );
info.merge( successInfo );

assertEquals( info.getAuthenticationResult(), SUCCESS );
}

@Test
public void shouldMergeTwoFailureToSameValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
info.merge( failureInfo );

assertEquals( info.getAuthenticationResult(), FAILURE );
}

@Test
public void shouldMergeTwoTooManyAttemptsToSameValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", TOO_MANY_ATTEMPTS );
info.merge( tooManyAttemptsInfo );

assertEquals( info.getAuthenticationResult(), TOO_MANY_ATTEMPTS );
}

@Test
public void shouldMergeTwoPasswordChangeRequiredToSameValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", PASSWORD_CHANGE_REQUIRED );
info.merge( pwChangeRequiredInfo );

assertEquals( info.getAuthenticationResult(), PASSWORD_CHANGE_REQUIRED );
}

@Test
public void shouldMergeFailureWithSuccessToNewValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
info.merge( successInfo );

assertEquals( info.getAuthenticationResult(), SUCCESS );
}

@Test
public void shouldMergeFailureWithTooManyAttemptsToNewValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
info.merge( tooManyAttemptsInfo );

assertEquals( info.getAuthenticationResult(), TOO_MANY_ATTEMPTS );
}

@Test
public void shouldMergeFailureWithPasswordChangeRequiredToNewValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
info.merge( pwChangeRequiredInfo );

assertEquals( info.getAuthenticationResult(), PASSWORD_CHANGE_REQUIRED );
}

@Test
public void shouldMergeToNewValue()
{
ShiroAuthenticationInfo info = new ShiroAuthenticationInfo( "user", "password", "realm", FAILURE );
info.merge( pwChangeRequiredInfo );

assertEquals( info.getAuthenticationResult(), PASSWORD_CHANGE_REQUIRED );
}
}

0 comments on commit 8b0d232

Please sign in to comment.