package org.dcache.gplazma.plugins; import org.apache.commons.io.FileUtils; import org.dcache.auth.EmailAddressPrincipal; import org.dcache.auth.OidcSubjectPrincipal; import org.dcache.auth.UserNamePrincipal; import org.dcache.gplazma.AuthenticationException; import org.globus.gsi.gssapi.jaas.GlobusPrincipal; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.mockito.Mockito; import javax.security.auth.kerberos.KerberosPrincipal; import java.io.File; import java.io.IOException; import java.security.Principal; import java.util.HashSet; import java.util.Properties; import java.util.Set; import static org.hamcrest.Matchers.*; import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; public class GplazmaMultiMapPluginTest { @Rule public TemporaryFolder tempFolder = new TemporaryFolder(); private Set<Principal> principals; private Set<Principal> result; private Properties givenConfiguration = new Properties(); private final UserNamePrincipal testUser = new UserNamePrincipal("kermit"); @BeforeClass public static void init() throws Exception { } @Before public void setUp() throws Exception { result = new HashSet<>(); result.add(testUser); principals = new HashSet<>(); } @After public void tearDown() throws Exception { } @Test(expected = AuthenticationException.class) public void shouldFailWhenNoMappingUsingMockedMap() throws Exception { whenMapPluginCalledWith(mockedMapFileWithNoMapping(), withOidcPrincipal("googleopenidcsubject")); } @Test(expected = AuthenticationException.class) public void shouldFailWhenNoMapping() throws Exception { givenConfig(" "); whenMapPluginCalledWith( withConfig(), withOidcPrincipal("googleopenidcsubject")); } @Test public void shouldMapOidcToUsernameUsingMockedMap() throws Exception { whenMapPluginCalledWith( mockedMapFile(), withOidcPrincipal("googleopenidcsubject")); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test public void shouldMapOidcToUsername() throws Exception { givenConfig("oidc:googleopenidcsubject username:kermit"); whenMapPluginCalledWith( withConfig(), withOidcPrincipal("googleopenidcsubject")); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test public void shouldMapGlobusToUsernameUsingMockedMap() throws Exception { whenMapPluginCalledWith( mockedMapFile(), withGlobusPrincipal("/O=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test public void shouldMapGlobusToUsername() throws Exception { givenConfig("dn:\"/O=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog\" username:kermit"); whenMapPluginCalledWith( withConfig(), withGlobusPrincipal("/O=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test(expected = AuthenticationException.class) public void shouldFailGlobusToUsernameNotMapping() throws Exception { givenConfig("dn:\"/O=ES/O=Madrid/OU=upm.es/CN=Kermit The Frog\" username:kermit"); whenMapPluginCalledWith( withConfig(), withGlobusPrincipal("/O=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog") ); } @Test public void shouldMapEmailToUsernameUsingMockedMap() throws Exception { whenMapPluginCalledWith( mockedMapFile(), withEmailPrincipal("kermit.the.frog@email.com") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test public void shouldMapEmailToUsername() throws Exception { givenConfig("email:kermit.the.frog@email.com username:kermit"); whenMapPluginCalledWith( withConfig(), withEmailPrincipal("kermit.the.frog@email.com") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test(expected = AuthenticationException.class) public void shouldFailEmailToUsernameWhenSuppliedKerberos() throws Exception { givenConfig("kerberos:kermit@DESY.DE username:kermit"); whenMapPluginCalledWith( withConfig(), withEmailPrincipal("kermit.the.frog@email.com") ); } @Test public void shouldMapKerberosToUsernameUsingMockedMap() throws Exception { whenMapPluginCalledWith( mockedMapFile(), withKerberosPrincipal("kermit@DESY.DE") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test public void shouldMapKerberosToUsername() throws Exception { givenConfig("kerberos:kermit@DESY.DE username:kermit"); whenMapPluginCalledWith( withConfig(), withKerberosPrincipal("kermit@DESY.DE") ); assertThat(principals, is(not(empty()))); assertThat(principals, hasItem(testUser)); } @Test(expected = AuthenticationException.class) public void shouldFailKerberosToUsernameWhenSuppliedOidc() throws Exception { givenConfig("oidc:googlesubject username:kermit"); whenMapPluginCalledWith( withConfig(), withKerberosPrincipal("kermit@DESY.DE") ); } /*------------------------- Helpers ---------------------------*/ private void givenConfig(String map) throws IOException { final File multimapper = tempFolder.newFile("multi-mapfile"); givenConfiguration.put("gplazma.multimap.file", multimapper.getPath()); FileUtils.writeStringToFile(multimapper, map); } private void whenMapPluginCalledWith(GplazmaMultiMapFile map, Set<Principal> principals) throws AuthenticationException { GplazmaMultiMapPlugin plugin = new GplazmaMultiMapPlugin(map); plugin.map(principals); } private void whenMapPluginCalledWith(Properties properties, Set<Principal> principals) throws AuthenticationException { GplazmaMultiMapPlugin plugin = new GplazmaMultiMapPlugin(properties); plugin.map(principals); } private GplazmaMultiMapFile mockedMapFileWithNoMapping() throws AuthenticationException { GplazmaMultiMapFile map = Mockito.mock(GplazmaMultiMapFile.class); doReturn(new HashSet<>()).when(map).getMappedPrincipals(Mockito.any()); doNothing().when(map).ensureUpToDate(); return map; } private GplazmaMultiMapFile mockedMapFile() throws AuthenticationException { GplazmaMultiMapFile map = Mockito.mock(GplazmaMultiMapFile.class); doReturn(result).when(map).getMappedPrincipals(Mockito.any()); doNothing().when(map).ensureUpToDate(); return map; } private Set<Principal> withOidcPrincipal(String oidc) { principals.add(new OidcSubjectPrincipal(oidc)); return principals; } private Set<Principal> withGlobusPrincipal(String dn) { principals.add(new GlobusPrincipal(dn)); return principals; } private Set<Principal> withEmailPrincipal(String email) { principals.add(new EmailAddressPrincipal(email)); return principals; } private Set<Principal> withKerberosPrincipal(String kerberos) { principals.add(new KerberosPrincipal(kerberos)); return principals; } private Properties withConfig() { return givenConfiguration; } }