package org.dcache.gplazma.plugins; import org.globus.gsi.gssapi.jaas.GlobusPrincipal; import javax.security.auth.kerberos.KerberosPrincipal; import java.security.Principal; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Collection; import java.util.Map; import java.util.Properties; import java.util.Set; import org.dcache.auth.LoginNamePrincipal; import org.dcache.auth.UserNamePrincipal; import org.dcache.gplazma.AuthenticationException; import org.dcache.gplazma.util.GridMapFile; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Predicates.instanceOf; import static com.google.common.collect.Iterables.*; import static org.dcache.gplazma.util.Preconditions.checkAuthentication; /** * Maps GlobusPrincipal and KerberosPrincipal to UserNamePrincipal * using a classic grid-mapfile. * * The plugin is silently skipped if principals already contains a * user name principal. */ public class GridMapFilePlugin implements GPlazmaMappingPlugin { private final GridMapFile _gridMapFile; private static final String GRIDMAP = "gplazma.gridmap.file"; public GridMapFilePlugin(Properties properties) { String path = properties.getProperty(GRIDMAP); checkArgument(path != null, "Undefined property: " + GRIDMAP); _gridMapFile = new GridMapFile(path); } private Map.Entry<Principal,String> getMappingFor(Set<Principal> principals) { Principal loginName = find(principals, instanceOf(LoginNamePrincipal.class), null); for (Principal principal: principals) { if (principal instanceof GlobusPrincipal || principal instanceof KerberosPrincipal) { Collection<String> names = _gridMapFile.getMappedUsernames(principal.getName()); if (!names.isEmpty()) { String name; if (loginName == null) { name = get(names, 0); } else if (names.contains(loginName.getName())) { name = loginName.getName(); } else { continue; } return new SimpleImmutableEntry<>(principal, name); } } } return null; } @Override public void map(Set<Principal> principals) throws AuthenticationException { if (any(principals, instanceOf(UserNamePrincipal.class))) { return; } _gridMapFile.refresh(); Map.Entry<Principal,String> entry = getMappingFor(principals); checkAuthentication(entry != null, "no mapping"); principals.add(new UserNamePrincipal(entry.getValue())); } }