package org.dcache.gplazma.plugins;
import org.globus.gsi.gssapi.jaas.GlobusPrincipal;
import javax.security.auth.kerberos.KerberosPrincipal;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Principal;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.dcache.auth.FQANPrincipal;
import org.dcache.auth.LoginNamePrincipal;
import org.dcache.auth.UserNamePrincipal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.filter;
/**
* A {@link GPlazmaMappingPlugin} that maps a one principal type to an other one.
* This is required to convert equivalent principals into principals provided by
* {@code org.dcache.auth} package.
* NOTICE, this plugin modifies the original set of principals.
*/
public class MutatorPlugin implements GPlazmaMappingPlugin {
private final ClassLoader classLoader = ClassLoader.getSystemClassLoader();
static final String IN_OPTION = "gplazma.mutator.accept";
static final String OUT_OPTION = "gplazma.mutator.produce";
private final Class<? extends Principal> inPrincipal;
private final Class<? extends Principal> outPrincipal;
private Constructor<? extends Principal> outConstructor;
public MutatorPlugin(Properties properties) throws ClassNotFoundException, NoSuchMethodException {
String inClass = properties.getProperty(IN_OPTION);
String outClass = properties.getProperty(OUT_OPTION);
checkArgument(inClass != null, "Undefined property: " + IN_OPTION);
checkArgument(outClass != null, "Undefined property: " + OUT_OPTION);
Class<?> principal = classLoader.loadClass(inClass);
checkArgument(Principal.class.isAssignableFrom(principal), inClass + " is not a Principal");
inPrincipal = (Class<? extends Principal>) principal;
outPrincipal = classOf(outClass);
outConstructor = outPrincipal.getConstructor(String.class);
}
@Override
public void map(Set<Principal> principals) {
Set<Principal> mutated = new HashSet<>();
for (Principal p : filter(principals, inPrincipal)) {
try {
Principal out = outConstructor.newInstance(p.getName());
mutated.add(out);
} catch (IllegalAccessException | IllegalArgumentException |
InstantiationException | InvocationTargetException ignored) {
}
}
principals.addAll(mutated);
}
public static Class<? extends Principal> classOf(String type) {
switch (type) {
case "dn":
return GlobusPrincipal.class;
case "kerberos":
return KerberosPrincipal.class;
case "fqan":
return FQANPrincipal.class;
case "name":
return LoginNamePrincipal.class;
case "username":
return UserNamePrincipal.class;
default:
throw new IllegalArgumentException("unknown type: " + type);
}
}
}