package org.synyx.urlaubsverwaltung.security;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.ldap.core.DirContextOperations;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
/**
* @author Aljona Murygina - murygina@synyx.de
*/
public class LdapUserMapperTest {
private static final String IDENTIFIER_ATTRIBUTE = "uid";
private static final String FIRST_NAME_ATTRIBUTE = "givenName";
private static final String LAST_NAME_ATTRIBUTE = "sn";
private static final String MAIL_ADDRESS_ATTRIBUTE = "mail";
private static final String MEMBER_OF_ATTRIBUTE = "memberOf";
private static final String MEMBER_OF_FILTER = "CN=mygroup,DC=mydomain,DC=com";
private LdapUserMapper ldapUserMapper;
@Before
public void setUp() {
ldapUserMapper = new LdapUserMapper(IDENTIFIER_ATTRIBUTE, FIRST_NAME_ATTRIBUTE, LAST_NAME_ATTRIBUTE,
MAIL_ADDRESS_ATTRIBUTE, MEMBER_OF_FILTER);
}
// Map user from attributes ----------------------------------------------------------------------------------------
@Test
public void ensureThrowsIfTryingToCreateLdapUserFromAttributesWithInvalidIdentifierAttribute()
throws NamingException {
Attributes attributes = Mockito.mock(Attributes.class);
Mockito.when(attributes.get(IDENTIFIER_ATTRIBUTE)).thenReturn(null);
try {
ldapUserMapper.mapFromAttributes(attributes);
Assert.fail("Should throw on empty username!");
} catch (InvalidSecurityConfigurationException ex) {
// Expected
}
Mockito.verify(attributes, Mockito.atLeastOnce()).get(IDENTIFIER_ATTRIBUTE);
Mockito.verify(attributes, Mockito.never()).get(FIRST_NAME_ATTRIBUTE);
Mockito.verify(attributes, Mockito.never()).get(LAST_NAME_ATTRIBUTE);
Mockito.verify(attributes, Mockito.never()).get(MAIL_ADDRESS_ATTRIBUTE);
}
@Test
public void ensureCreatesLdapUserFromAttributesWithOnlyUsernameGiven() throws NamingException {
Attributes attributes = Mockito.mock(Attributes.class);
Mockito.when(attributes.get(IDENTIFIER_ATTRIBUTE))
.thenReturn(new BasicAttribute(IDENTIFIER_ATTRIBUTE, "username"));
Mockito.when(attributes.get(FIRST_NAME_ATTRIBUTE)).thenReturn(null);
Mockito.when(attributes.get(LAST_NAME_ATTRIBUTE)).thenReturn(null);
Mockito.when(attributes.get(MAIL_ADDRESS_ATTRIBUTE)).thenReturn(null);
LdapUser ldapUser = ldapUserMapper.mapFromAttributes(attributes);
Mockito.verify(attributes).get(IDENTIFIER_ATTRIBUTE);
Mockito.verify(attributes).get(FIRST_NAME_ATTRIBUTE);
Mockito.verify(attributes).get(LAST_NAME_ATTRIBUTE);
Mockito.verify(attributes).get(MAIL_ADDRESS_ATTRIBUTE);
Assert.assertEquals("Wrong username", "username", ldapUser.getUsername());
Assert.assertFalse("First name should be empty", ldapUser.getFirstName().isPresent());
Assert.assertFalse("Last name should be empty", ldapUser.getLastName().isPresent());
Assert.assertFalse("Email should be empty", ldapUser.getEmail().isPresent());
}
@Test
public void ensureCreatesLdapUserFromAttributes() throws NamingException {
Attributes attributes = Mockito.mock(Attributes.class);
Mockito.when(attributes.get(IDENTIFIER_ATTRIBUTE))
.thenReturn(new BasicAttribute(IDENTIFIER_ATTRIBUTE, "geralt"));
Mockito.when(attributes.get(FIRST_NAME_ATTRIBUTE))
.thenReturn(new BasicAttribute(FIRST_NAME_ATTRIBUTE, "Geralt"));
Mockito.when(attributes.get(LAST_NAME_ATTRIBUTE))
.thenReturn(new BasicAttribute(LAST_NAME_ATTRIBUTE, "von Riva"));
Mockito.when(attributes.get(MAIL_ADDRESS_ATTRIBUTE))
.thenReturn(new BasicAttribute(MAIL_ADDRESS_ATTRIBUTE, "geralt@riva.de"));
LdapUser ldapUser = ldapUserMapper.mapFromAttributes(attributes);
Mockito.verify(attributes).get(IDENTIFIER_ATTRIBUTE);
Mockito.verify(attributes).get(FIRST_NAME_ATTRIBUTE);
Mockito.verify(attributes).get(LAST_NAME_ATTRIBUTE);
Mockito.verify(attributes).get(MAIL_ADDRESS_ATTRIBUTE);
Assert.assertEquals("Wrong username", "geralt", ldapUser.getUsername());
Assert.assertEquals("Wrong first name", "Geralt", ldapUser.getFirstName().get());
Assert.assertEquals("Wrong last name", "von Riva", ldapUser.getLastName().get());
Assert.assertEquals("Wrong email", "geralt@riva.de", ldapUser.getEmail().get());
}
// Map user from context -------------------------------------------------------------------------------------------
@Test
public void ensureThrowsIfTryingToCreateLdapUserFromContextWithInvalidIdentifierAttribute() throws NamingException,
UnsupportedMemberAffiliationException {
DirContextOperations ctx = Mockito.mock(DirContextOperations.class);
Mockito.when(ctx.getStringAttribute(IDENTIFIER_ATTRIBUTE)).thenReturn(null);
try {
ldapUserMapper.mapFromContext(ctx);
Assert.fail("Should throw on empty username!");
} catch (InvalidSecurityConfigurationException ex) {
// Expected
}
Mockito.verify(ctx, Mockito.atLeastOnce()).getStringAttribute(IDENTIFIER_ATTRIBUTE);
Mockito.verify(ctx, Mockito.never()).getStringAttribute(LAST_NAME_ATTRIBUTE);
Mockito.verify(ctx, Mockito.never()).getStringAttribute(FIRST_NAME_ATTRIBUTE);
Mockito.verify(ctx, Mockito.never()).getStringAttribute(MAIL_ADDRESS_ATTRIBUTE);
}
@Test
public void ensureCreatesLdapUserFromContext() throws NamingException, UnsupportedMemberAffiliationException {
DirContextOperations ctx = Mockito.mock(DirContextOperations.class);
Mockito.when(ctx.getStringAttribute(IDENTIFIER_ATTRIBUTE)).thenReturn("rick");
Mockito.when(ctx.getStringAttribute(FIRST_NAME_ATTRIBUTE)).thenReturn("Rick");
Mockito.when(ctx.getStringAttribute(LAST_NAME_ATTRIBUTE)).thenReturn("Grimes");
Mockito.when(ctx.getStringAttribute(MAIL_ADDRESS_ATTRIBUTE)).thenReturn("rick@grimes.com");
Mockito.when(ctx.getStringAttributes(MEMBER_OF_ATTRIBUTE)).thenReturn(new String[] { MEMBER_OF_FILTER });
LdapUser ldapUser = ldapUserMapper.mapFromContext(ctx);
Mockito.verify(ctx, Mockito.atLeastOnce()).getStringAttribute(IDENTIFIER_ATTRIBUTE);
Mockito.verify(ctx, Mockito.atLeastOnce()).getStringAttribute(LAST_NAME_ATTRIBUTE);
Mockito.verify(ctx, Mockito.atLeastOnce()).getStringAttribute(FIRST_NAME_ATTRIBUTE);
Mockito.verify(ctx, Mockito.atLeastOnce()).getStringAttribute(MAIL_ADDRESS_ATTRIBUTE);
Assert.assertEquals("Wrong username", "rick", ldapUser.getUsername());
Assert.assertEquals("Wrong first name", "Rick", ldapUser.getFirstName().get());
Assert.assertEquals("Wrong last name", "Grimes", ldapUser.getLastName().get());
Assert.assertEquals("Wrong email", "rick@grimes.com", ldapUser.getEmail().get());
}
@Test(expected = UnsupportedMemberAffiliationException.class)
public void ensureThrowsIfMappingUserFromContextThatIsNotMemberOfMemberFilter() throws NamingException,
UnsupportedMemberAffiliationException {
DirContextOperations ctx = Mockito.mock(DirContextOperations.class);
Mockito.when(ctx.getStringAttribute(IDENTIFIER_ATTRIBUTE)).thenReturn("rick");
Mockito.when(ctx.getStringAttribute(FIRST_NAME_ATTRIBUTE)).thenReturn("Rick");
Mockito.when(ctx.getStringAttribute(LAST_NAME_ATTRIBUTE)).thenReturn("Grimes");
Mockito.when(ctx.getStringAttribute(MAIL_ADDRESS_ATTRIBUTE)).thenReturn("rick@grimes.com");
Mockito.when(ctx.getStringAttributes(MEMBER_OF_ATTRIBUTE))
.thenReturn(new String[] { "CN=foo, DC=mydomain, DC=com" });
ldapUserMapper.mapFromContext(ctx);
}
@Test
public void ensureNoMemberOfCheckIfMemberOfFilterIsNull() throws NamingException {
ldapUserMapper = new LdapUserMapper(IDENTIFIER_ATTRIBUTE, FIRST_NAME_ATTRIBUTE, LAST_NAME_ATTRIBUTE,
MAIL_ADDRESS_ATTRIBUTE, null);
DirContextOperations ctx = Mockito.mock(DirContextOperations.class);
Mockito.when(ctx.getStringAttribute(IDENTIFIER_ATTRIBUTE)).thenReturn("rick");
Mockito.when(ctx.getStringAttribute(FIRST_NAME_ATTRIBUTE)).thenReturn("Rick");
Mockito.when(ctx.getStringAttribute(LAST_NAME_ATTRIBUTE)).thenReturn("Grimes");
Mockito.when(ctx.getStringAttribute(MAIL_ADDRESS_ATTRIBUTE)).thenReturn("rick@grimes.com");
Mockito.when(ctx.getStringAttributes(MEMBER_OF_ATTRIBUTE))
.thenReturn(new String[] { "CN=foo, DC=mydomain, DC=com" });
try {
ldapUserMapper.mapFromContext(ctx);
} catch (UnsupportedMemberAffiliationException e) {
Assert.fail("Should not throw on empty memberOf filter!");
}
Mockito.verify(ctx, Mockito.never()).getStringAttributes(MEMBER_OF_ATTRIBUTE);
}
@Test
public void ensureNoMemberOfCheckIfMemberOfFilterIsEmpty() throws NamingException {
ldapUserMapper = new LdapUserMapper(IDENTIFIER_ATTRIBUTE, FIRST_NAME_ATTRIBUTE, LAST_NAME_ATTRIBUTE,
MAIL_ADDRESS_ATTRIBUTE, "");
DirContextOperations ctx = Mockito.mock(DirContextOperations.class);
Mockito.when(ctx.getStringAttribute(IDENTIFIER_ATTRIBUTE)).thenReturn("rick");
Mockito.when(ctx.getStringAttribute(FIRST_NAME_ATTRIBUTE)).thenReturn("Rick");
Mockito.when(ctx.getStringAttribute(LAST_NAME_ATTRIBUTE)).thenReturn("Grimes");
Mockito.when(ctx.getStringAttribute(MAIL_ADDRESS_ATTRIBUTE)).thenReturn("rick@grimes.com");
Mockito.when(ctx.getStringAttributes(MEMBER_OF_ATTRIBUTE))
.thenReturn(new String[] { "CN=foo, DC=mydomain, DC=com" });
try {
ldapUserMapper.mapFromContext(ctx);
} catch (UnsupportedMemberAffiliationException e) {
Assert.fail("Should not throw on empty memberOf filter!");
}
Mockito.verify(ctx, Mockito.never()).getStringAttributes(MEMBER_OF_ATTRIBUTE);
}
}