package org.cloudfoundry.identity.uaa.authentication.manager;
import org.cloudfoundry.identity.uaa.authentication.AccountNotVerifiedException;
import org.cloudfoundry.identity.uaa.authentication.AuthenticationPolicyRejectionException;
import org.cloudfoundry.identity.uaa.constants.OriginKeys;
import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.scim.ScimGroupExternalMembershipManager;
import org.cloudfoundry.identity.uaa.scim.ScimGroupProvisioning;
import org.cloudfoundry.identity.uaa.provider.IdentityProvider;
import org.cloudfoundry.identity.uaa.provider.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.cloudfoundry.identity.uaa.zone.MultitenancyFixture;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ProviderNotFoundException;
import org.springframework.security.core.Authentication;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class DynamicZoneAwareAuthenticationManagerTest {
public static final IdentityZone ZONE = MultitenancyFixture.identityZone("test", "test");
DynamicZoneAwareAuthenticationManager manager;
IdentityProviderProvisioning providerProvisioning = mock(IdentityProviderProvisioning.class);
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = LdapIdentityProviderDefinition.searchAndBindMapGroupToScopes(
"ldap://localhost:38889/",
"cn=admin,ou=Users,dc=test,dc=com",
"adminsecret",
"dc=test,dc=com",
"cn={0}",
"ou=scopes,dc=test,dc=com",
"member={0}",
"mail",
null,
false,
true,
true,
100,
true);
AuthenticationManager uaaAuthenticationMgr = mock(AuthenticationManager.class);
ScimGroupExternalMembershipManager scimGroupExternalMembershipManager = mock(ScimGroupExternalMembershipManager.class);
ScimGroupProvisioning scimGroupProvisioning = mock(ScimGroupProvisioning.class);
LdapLoginAuthenticationManager ldapLoginAuthenticationManager = mock(LdapLoginAuthenticationManager.class);
Authentication success = mock(Authentication.class);
IdentityProvider uaaActive = mock(IdentityProvider.class);
IdentityProvider uaaInactive = mock(IdentityProvider.class);
IdentityProvider ldapActive = mock(IdentityProvider.class);
IdentityProvider ldapInactive = mock(IdentityProvider.class);
@Before
@After
public void beforeAndAfter() throws Exception {
when(success.isAuthenticated()).thenReturn(true);
when(uaaActive.isActive()).thenReturn(true);
when(uaaActive.getOriginKey()).thenReturn(OriginKeys.UAA);
when(uaaInactive.isActive()).thenReturn(false);
when(uaaInactive.getOriginKey()).thenReturn(OriginKeys.UAA);
when(ldapActive.isActive()).thenReturn(true);
when(ldapActive.getOriginKey()).thenReturn(OriginKeys.LDAP);
when(ldapInactive.isActive()).thenReturn(false);
when(ldapInactive.getOriginKey()).thenReturn(OriginKeys.LDAP);
when(ldapActive.getConfig()).thenReturn(ldapIdentityProviderDefinition);
when(ldapActive.getConfig()).thenReturn(ldapIdentityProviderDefinition);
IdentityZoneHolder.clear();
}
@Test
public void testAuthenticateInUaaZone() throws Exception {
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager();
Authentication result = manager.authenticate(null);
assertNull(result);
verifyZeroInteractions(uaaAuthenticationMgr);
}
@Test
public void testNonUAAZoneUaaNotActive() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaInactive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
when(mockManager.authenticate(any(Authentication.class))).thenReturn(success);
when(mockManager.getDefinition()).thenReturn(ldapIdentityProviderDefinition);
Authentication result = manager.authenticate(success);
assertSame(success, result);
verifyZeroInteractions(uaaAuthenticationMgr);
}
@Test
public void testNonUAAZoneUaaActiveAccountNotVerified() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaActive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
when(uaaAuthenticationMgr.authenticate(any(Authentication.class))).thenThrow(new AccountNotVerifiedException("mock"));
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
try {
manager.authenticate(success);
fail("Expected AccountNotVerifiedException ");
} catch (AccountNotVerifiedException x) {
//expected
}
verify(mockManager, times(0)).authenticate(any(Authentication.class));
}
@Test
public void testNonUAAZoneUaaActiveAccountLocked() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaActive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
when(uaaAuthenticationMgr.authenticate(any(Authentication.class))).thenThrow(new AuthenticationPolicyRejectionException("mock"));
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
try {
manager.authenticate(success);
fail("Expected AuthenticationPolicyRejectionException ");
} catch (AuthenticationPolicyRejectionException x) {
//expected
}
verify(mockManager, times(0)).authenticate(any(Authentication.class));
}
@Test
public void testNonUAAZoneUaaActiveUaaAuthenticationSucccess() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaActive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
when(uaaAuthenticationMgr.authenticate(any(Authentication.class))).thenReturn(success);
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
assertSame(success, manager.authenticate(success));
verify(mockManager, times(0)).authenticate(any(Authentication.class));
}
@Test
public void testNonUAAZoneUaaActiveUaaAuthenticationFailure() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaActive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
when(uaaAuthenticationMgr.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException("mock"));
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
when(mockManager.authenticate(any(Authentication.class))).thenReturn(success);
assertSame(success, manager.authenticate(success));
}
@Test
public void testAuthenticateInNoneUaaZoneWithLdapProvider() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapActive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaInactive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
when(mockManager.authenticate(any(Authentication.class))).thenReturn(success);
when(mockManager.getDefinition()).thenReturn(ldapIdentityProviderDefinition);
Authentication result = manager.authenticate(success);
assertSame(success, result);
verifyZeroInteractions(uaaAuthenticationMgr);
}
@Test
public void testAuthenticateInNoneUaaZoneWithInactiveProviders() throws Exception {
IdentityZoneHolder.set(ZONE);
when(providerProvisioning.retrieveByOrigin(OriginKeys.LDAP, ZONE.getId())).thenReturn(ldapInactive);
when(providerProvisioning.retrieveByOrigin(OriginKeys.UAA, ZONE.getId())).thenReturn(uaaInactive);
DynamicZoneAwareAuthenticationManager manager = getDynamicZoneAwareAuthenticationManager(true);
DynamicLdapAuthenticationManager mockManager = manager.getLdapAuthenticationManager(null, null);
when(mockManager.authenticate(any(Authentication.class))).thenReturn(success);
when(mockManager.getDefinition()).thenReturn(ldapIdentityProviderDefinition);
try {
manager.authenticate(success);
fail("Was expecting a "+ProviderNotFoundException.class);
} catch (ProviderNotFoundException x) {
//expected
}
verifyZeroInteractions(uaaAuthenticationMgr);
verifyZeroInteractions(mockManager);
}
protected DynamicZoneAwareAuthenticationManager getDynamicZoneAwareAuthenticationManager() {
return getDynamicZoneAwareAuthenticationManager(false);
}
protected DynamicZoneAwareAuthenticationManager getDynamicZoneAwareAuthenticationManager(boolean mock) {
if (mock) {
final DynamicLdapAuthenticationManager mockLdapManager = mock(DynamicLdapAuthenticationManager.class);
return new DynamicZoneAwareAuthenticationManager(
providerProvisioning,
uaaAuthenticationMgr,
scimGroupExternalMembershipManager,
scimGroupProvisioning,
ldapLoginAuthenticationManager
) {
@Override
public DynamicLdapAuthenticationManager getLdapAuthenticationManager(IdentityZone zone, IdentityProvider provider) {
when(mockLdapManager.getDefinition()).thenReturn(ldapIdentityProviderDefinition);
return mockLdapManager;
}
};
} else {
return new DynamicZoneAwareAuthenticationManager(
providerProvisioning,
uaaAuthenticationMgr,
scimGroupExternalMembershipManager,
scimGroupProvisioning,
ldapLoginAuthenticationManager
);
}
}
}