package diskCacheV111.util;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dcache.util.Glob;
public class VOInfo implements Serializable
{
private static final long serialVersionUID = -8014669884189610627L;
private static final Pattern p1 = Pattern.compile( "(.*)/Role=(.*)");
private static final Pattern p2 = Pattern.compile( "(.*)()");
private final String voGroup;
private final String voRole;
public VOInfo(String pattern) {
Matcher m = getMatcher(pattern);
voGroup = m.group(1);
voRole = mapRoleToGlob( m.group(2));
}
/**
* Map a role-part of a user-supplied pattern to a Glob.
* <p>
* If the user supplied a pattern without a role part (e.g., <tt>/ops</tt>)
* then we treat this as if the user supplied a pattern with a wildcard
* role (e.g., <tt>/ops/Role=*</tt>)
* <p>
* This should not be needed as <tt>voms-proxy-init</tt> will always
* returns all subgroups a user is a member of.
* <p>
* In an ideal world, this method would be an identity transform, as it is
* with the group-part of the user-supplied pattern.
* <p>
* In fact, this method is needed to hide a bug in gPlazma's
* getFQANSfromVOMSAttributes method in X509Utils. This method is to
* be reviewed (and removed) once this bug is fixed.
*/
private String mapRoleToGlob( String roleInFqan) {
return roleInFqan.isEmpty() ? "*" : roleInFqan;
}
private Matcher getMatcher( String pattern) {
Matcher m = p1.matcher( pattern);
if( m.matches()) {
return m;
}
m = p2.matcher( pattern);
if( m.matches()) {
return m;
}
throw new RuntimeException("Failed to find a matcher for FQAN pattern: " + pattern);
}
public VOInfo(String voGroup,String voRole) {
this.voGroup = voGroup;
this.voRole = voRole;
}
@Override
public String toString(){
return voGroup + ':' + voRole;
}
@Nullable
public String getVoGroup() {
return voGroup;
}
@Nullable
public String getVoRole() {
return voRole;
}
@Override
public int hashCode(){
return Objects.hashCode(voGroup) ^ Objects.hashCode(voRole);
}
@Override
public boolean equals(Object o) {
if(o == null || !(o instanceof VOInfo )){
return false;
}
VOInfo voinfo = (VOInfo) o;
return Objects.equals(voGroup, voinfo.voGroup) && Objects.equals(voRole, voinfo.voRole);
}
public boolean match(final String group, final String role)
{
if (voGroup == null) {
return false;
}
boolean roleMatches;
if( voRole != null) {
Glob rolePattern = new Glob(voRole);
roleMatches = rolePattern.matches(role==null ? "null" : role);
} else {
roleMatches = true;
}
Glob groupPattern = new Glob(voGroup);
return groupPattern.matches(group==null ? "null" : group) && roleMatches;
}
}