package org.dcache.gplazma.plugins;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dcache.auth.FQAN;
import org.dcache.gplazma.util.NameRolePair;
import org.dcache.util.Glob;
/**
* Parser for vorolemap files ("<DN>" "<FQAN>" "<USERNAME>") mapping
* dn/fqan pairs to a username.
*
* @author karsten
*/
class VOMapLineParser
implements LineParser<VOMapLineParser.DNFQANPredicate, String>
{
private static final Logger _log = LoggerFactory.getLogger(VOMapLineParser.class);
private static final String SOME_WS = "\\s+";
private static final String DN_WILDCARD = "\\*";
private static final String QUOTED_TERM = "\"[^\"]*\"";
private static final String UNQUOTED_DN = "(?:/[\\w\\d\\s,;:@\\-\\*\\.=]+)+";
private static final String DN = DN_WILDCARD +"|(?:"+ UNQUOTED_DN +")|(?:"+ QUOTED_TERM + ")";
private static final String UNQUOTED_FQAN = "(?:/[\\w\\d,;:@\\-\\*\\.]+)+(?:/[\\w\\d\\s,;:@\\-\\*=]+)*";
private static final String FQAN = "(?:" + UNQUOTED_FQAN +")|(?:"+ QUOTED_TERM + ")";
private static final String USERNAME = "[\\w.][\\w.\\-]*";
private static final String COMMENT = "#.*";
private static final Pattern ROLE_MAP_FILE_LINE_PATTERN =
Pattern.compile("(?:"+SOME_WS+")?" + "("+ DN +")"+ "(?:" + SOME_WS +
"("+ FQAN +"))?" + SOME_WS + "("+ USERNAME +")" +
"(?:"+SOME_WS+")?" + "(?:" + COMMENT + ")?");
private static final int RM_DN_GROUP = 1;
private static final int RM_FQAN_GROUP = 2;
private static final int RM_KEY_GROUP = 3;
@Override
public Map.Entry<DNFQANPredicate, String> accept(String line) {
if (Strings.isNullOrEmpty(line.trim()) || line.startsWith("#")) {
return null;
}
Matcher matcher = ROLE_MAP_FILE_LINE_PATTERN.matcher(line);
if (matcher.matches()) {
String dn = matcher.group(RM_DN_GROUP).replace("\"", "");
String vorole =
Strings.nullToEmpty(matcher.group(RM_FQAN_GROUP));
FQAN fqan = new FQAN(vorole.replace("\"", ""));
return new DNFQANStringEntry(new DNFQANPredicate(dn, fqan),
matcher.group(RM_KEY_GROUP));
}
_log.warn("Ignored malformed line in VORoleMap-File: '{}'", line);
return null;
}
static class DNFQANPredicate implements MapPredicate<NameRolePair>
{
private final Pattern _dnPattern;
private final FQAN _fqan;
public DNFQANPredicate(String dnGlob, FQAN fqan) {
_dnPattern = Glob.parseGlobToPattern(dnGlob);
_fqan = fqan;
}
@Override
public boolean matches(NameRolePair dnfqan) {
String dn = Strings.nullToEmpty(dnfqan.getName());
FQAN fqan = new FQAN(Strings.nullToEmpty(dnfqan.getRole()));
return _dnPattern.matcher(dn).matches() &&
(_fqan.toString().isEmpty() || _fqan.equals(fqan));
}
}
private static final class DNFQANStringEntry
implements Map.Entry<DNFQANPredicate, String>
{
private final DNFQANPredicate _key;
private String _value;
public DNFQANStringEntry(DNFQANPredicate key, String value) {
_key = key;
_value = value;
}
@Override
public DNFQANPredicate getKey() {
return _key;
}
@Override
public String getValue() {
return _value;
}
@Override
public String setValue(String value) {
return _value = value;
}
}
}