/*
* Copyright (c) Members of the EGEE Collaboration. 2006-2010.
* See http://www.eu-egee.org/partners/ for details on the copyright holders.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glite.authz.pep.obligation.dfpmap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import junit.framework.TestCase;
import org.glite.authz.common.config.ConfigurationException;
import org.glite.authz.common.fqan.FQAN;
import org.glite.authz.pep.obligation.ObligationProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JUnit test case for DN/FQAN account mapping
*/
public class AccountMapperTest extends TestCase {
private Logger log = LoggerFactory.getLogger(AccountMapperTest.class);
private int N_POOL = 5;
private String[] poolAccountNamePrefixes = { "atlas", "smscg", "switch" };
private String[] fixedAccountNames = { "dteam", "robin", "batman" };
PoolAccountManager poolAccountManager = null;
File gridMapDir = null;
private File createTempGridMapDir() throws IOException {
File temp = File.createTempFile("gridmapdir", ".junit");
if (!(temp.delete())) {
throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
}
if (!(temp.mkdir())) {
throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
}
temp.deleteOnExit();
// populate with pool accounts
for (String prefix : poolAccountNamePrefixes) {
for (int i = 1; i <= N_POOL; i++) {
String pool = prefix + "00" + i;
File f = new File(temp, pool);
log.trace("create " + pool + " pool account");
f.createNewFile();
f.deleteOnExit();
}
}
// populate with fix accounts
for (String name : fixedAccountNames) {
File f = new File(temp, name);
log.trace("create " + name + " account");
f.createNewFile();
f.deleteOnExit();
}
return temp;
}
protected boolean deleteTempDir(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteTempDir(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
/**
* Returns the {@link InputStream} for the given filePath by searching in the classpath and on the file system.
*
* @param filePath Path to the file (absolute or within classpath)
* @return The file InputStream
* @throws FileNotFoundException if the filePath can't be found in classpath or on the file system
*/
protected InputStream getFileInputStream(String filePath) throws FileNotFoundException {
// first search file in classpath, then as absolute filename
log.debug("Load file from classpath: {}", filePath);
InputStream is = getClass().getResourceAsStream(filePath);
if (is == null) {
log.debug("Not in classpath, load file from file: {}", filePath);
is = new FileInputStream(filePath);
}
return is;
}
/** {@inheritDoc} */
protected void setUp() throws Exception {
super.setUp();
gridMapDir = createTempGridMapDir();
poolAccountManager = new GridMapDirPoolAccountManager(gridMapDir, true);
}
/** {@inheritDoc} */
protected void tearDown() throws Exception {
super.tearDown();
deleteTempDir(gridMapDir);
}
protected DFPM createDFPM(String filePath) throws ConfigurationException, FileNotFoundException {
DFPM dfpm = new OrderedDFPM();
InputStream is = getFileInputStream(filePath);
Reader reader = new InputStreamReader(is);
DFPMFileParser mappingFileParser = new DFPMFileParser();
mappingFileParser.parse(dfpm, reader);
return dfpm;
}
protected PosixAccount mapToPosixAccount(X500Principal subjectDN, FQAN primaryFQAN, List<FQAN> secondaryFQANs,
boolean preferDNForLoginName, boolean preferDNForPrimaryGroupName, boolean noPrimaryGroupNameIsError)
throws FileNotFoundException, ConfigurationException, ObligationProcessingException {
DFPM accountIndicatorDFPM = createDFPM("/grid-mapfile");
DFPM groupDFPM = createDFPM("/group-mapfile");
DFPMMatchStrategy<X500Principal> dnMatchStrategy = new X509MatchStrategy();
DFPMMatchStrategy<FQAN> fqanMatchStrategy = new FQANMatchStrategy();
AccountIndicatorMappingStrategy aimStrategy = new DNPrimaryFQANAccountIndicatorMappingStrategy(
accountIndicatorDFPM, dnMatchStrategy, fqanMatchStrategy, preferDNForLoginName);
GroupNameMappingStrategy gnmStrategy = new DNFQANGroupNameMappingStrategy(groupDFPM, dnMatchStrategy,
fqanMatchStrategy, preferDNForPrimaryGroupName);
AccountMapper accountMapper = new AccountMapper(aimStrategy, gnmStrategy, poolAccountManager,
noPrimaryGroupNameIsError);
PosixAccount account = accountMapper.mapToAccount(subjectDN, primaryFQAN, secondaryFQANs);
return account;
}
public void testAccountMappingDN_WithFAQNs() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Batman");
FQAN primaryFQAN = new FQAN("/dteam", "prod");
List<FQAN> secondaryFQANs = Arrays.asList(new FQAN("/atlas"), new FQAN("/switch"));
System.out.println("----------------------------------");
System.out.println("mapping (DN/FQANs) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, true, true, false);
System.out.println("mapped to POSIX account: " + account);
assertTrue("batman".equals(account.getLoginName()));
assertTrue("batman".equals(account.getPrimaryGroup()));
assertTrue(account.getSecondaryGroups().contains("dteam"));
assertTrue(account.getSecondaryGroups().contains("atlas"));
assertTrue(account.getSecondaryGroups().contains("switch"));
}
public void testAccountMappingDN_NoFQAN() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Batman");
FQAN primaryFQAN = null;
List<FQAN> secondaryFQANs = null;
System.out.println("----------------------------------");
System.out.println("mapping (DN only) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, true, true, false);
System.out.println("mapped to POSIX account: " + account);
assertTrue("batman".equals(account.getLoginName()));
assertTrue("batman".equals(account.getPrimaryGroup()));
assertTrue(account.getSecondaryGroups().isEmpty());
}
public void testAccountMappingDN_NoFQAN_NoError() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Robin");
FQAN primaryFQAN = null;
List<FQAN> secondaryFQANs = null;
System.out.println("----------------------------------");
System.out.println("mapping (DN only/No error) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, true, true, false);
System.out.println("mapped to POSIX account: " + account);
assertTrue("robin".equals(account.getLoginName()));
assertNull(account.getPrimaryGroup());
assertTrue(account.getSecondaryGroups().isEmpty());
}
public void testAccountMappingDN_NoFQAN_NoPrmaryGroupError() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Robin");
FQAN primaryFQAN = null;
List<FQAN> secondaryFQANs = null;
System.out.println("----------------------------------");
System.out.println("mapping (DN only/No primary group error) subject: " + subjectDN + " FQAN: " + primaryFQAN
+ " FQANs: " + secondaryFQANs);
try {
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, true, true, true);
fail("No primary group should failed: account=" + account);
} catch (ObligationProcessingException e) {
// expected
System.out.println("EXPECTED ERROR: " + e.getMessage());
}
}
public void testAccountMappingFQAN_dteam() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Batman");
FQAN primaryFQAN = new FQAN("/dteam", "prod");
List<FQAN> secondaryFQANs = Arrays.asList(new FQAN("/atlas"), new FQAN("/switch"));
System.out.println("----------------------------------");
System.out.println("mapping (FQAN/DN) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, false, false, false);
System.out.println("mapped to POSIX account: " + account);
assertTrue("dteam".equals(account.getLoginName()));
assertTrue("dteam".equals(account.getPrimaryGroup()));
assertTrue(account.getSecondaryGroups().contains("batman"));
assertTrue(account.getSecondaryGroups().contains("atlas"));
assertTrue(account.getSecondaryGroups().contains("switch"));
}
public void testAccountMappingFQAN_atlasPool() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Batman");
FQAN primaryFQAN = new FQAN("/atlas");
List<FQAN> secondaryFQANs = Arrays.asList(new FQAN("/dteam"), new FQAN("/switch"));
System.out.println("----------------------------------");
System.out.println("mapping (FQAN/DN) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, false, false, false);
System.out.println("mapped to POSIX account: " + account);
assertTrue(account.getLoginName().startsWith("atlas"));
assertTrue("atlas".equals(account.getPrimaryGroup()));
assertTrue(account.getSecondaryGroups().contains("batman"));
assertTrue(account.getSecondaryGroups().contains("dteam"));
assertTrue(account.getSecondaryGroups().contains("switch"));
}
public void testAccountMappingFQAN_NoPrmaryGroupError() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Robin");
FQAN primaryFQAN = new FQAN("/tata", "prod");
List<FQAN> secondaryFQANs = Arrays.asList(new FQAN("/titi"), new FQAN("/toto"));
System.out.println("----------------------------------");
System.out.println("mapping (FQAN/DN/No primary group error) subject: " + subjectDN + " FQAN: " + primaryFQAN
+ " FQANs: " + secondaryFQANs);
try {
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, false, false, true);
fail("No primary group should failed: account=" + account);
} catch (ObligationProcessingException e) {
// expected
System.out.println("EXPECTED ERROR: " + e.getMessage());
}
}
public void testAccountMappingNoDN_NoFQAN() throws Exception {
X500Principal subjectDN = null;
FQAN primaryFQAN = null;
List<FQAN> secondaryFQANs = null;
System.out.println("----------------------------------");
System.out.println("mapping (Nothing) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
try {
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, false, false, false);
fail("No subject should failed: account=" + account);
} catch (ObligationProcessingException e) {
// expected
System.out.println("EXPECTED ERROR: " + e.getMessage());
}
}
public void testAccountMappingUnknown() throws Exception {
X500Principal subjectDN = new X500Principal("OU=Grid User,CN=Unknown");
FQAN primaryFQAN = new FQAN("/tata");
List<FQAN> secondaryFQANs = Arrays.asList(new FQAN("/titi"), new FQAN("/toto"));
System.out.println("----------------------------------");
System.out.println("mapping (Unknown user) subject: " + subjectDN + " FQAN: " + primaryFQAN + " FQANs: "
+ secondaryFQANs);
try {
PosixAccount account = mapToPosixAccount(subjectDN, primaryFQAN, secondaryFQANs, false, false, false);
fail("Unknown subject/FQANs should failed: account=" + account);
} catch (ObligationProcessingException e) {
// expected
System.out.println("EXPECTED ERROR: " + e.getMessage());
}
}
}