Add support for ${username} in refs

Interpret a ${username} string in a ref as the name of the current
user.  This allows the refs namespace to have generic rules applied
to refs involving the user's name without having to hardcode a rule
for each user.

Bug: issue 577
Change-Id: Ib8692a13221a4581731e753e9c7cccb7aa0a96da
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Martin Fick 2010-07-15 11:36:17 -07:00 committed by Shawn O. Pearce
parent 9c89dac46b
commit f14ada51fa

View File

@ -28,6 +28,7 @@ import static com.google.gerrit.reviewdb.ApprovalCategory.PUSH_TAG_ANNOTATED;
import static com.google.gerrit.reviewdb.ApprovalCategory.PUSH_TAG_SIGNED; import static com.google.gerrit.reviewdb.ApprovalCategory.PUSH_TAG_SIGNED;
import static com.google.gerrit.reviewdb.ApprovalCategory.READ; import static com.google.gerrit.reviewdb.ApprovalCategory.READ;
import com.google.gerrit.common.data.ParamertizedString;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategory; import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.RefRight; import com.google.gerrit.reviewdb.RefRight;
@ -48,7 +49,9 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
@ -481,7 +484,7 @@ public class RefControl {
private List<RefRight> filter(Collection<RefRight> all) { private List<RefRight> filter(Collection<RefRight> all) {
List<RefRight> mine = new ArrayList<RefRight>(all.size()); List<RefRight> mine = new ArrayList<RefRight>(all.size());
for (RefRight right : all) { for (RefRight right : all) {
if (matches(getRefName(), right.getRefPattern())) { if (matches(right.getRefPattern())) {
mine.add(right); mine.add(right);
} }
} }
@ -492,20 +495,52 @@ public class RefControl {
return projectControl.getProjectState(); return projectControl.getProjectState();
} }
public static boolean matches(String refName, String refPattern) { private boolean matches(String refPattern) {
if (refPattern.startsWith(RefRight.REGEX_PREFIX)) { if (isTemplate(refPattern)) {
return Pattern.matches(refPattern, refName); ParamertizedString template = new ParamertizedString(refPattern);
HashMap<String, String> p = new HashMap<String, String>();
if (getCurrentUser() instanceof IdentifiedUser) {
p.put("username", ((IdentifiedUser) getCurrentUser()).getUserName());
} else {
// Right now we only template the username. If not available
// this rule cannot be matched at all.
//
return false;
} }
if (refPattern.endsWith("/*")) { if (isRE(refPattern)) {
for (Map.Entry<String, String> ent : p.entrySet()) {
ent.setValue(escape(ent.getValue()));
}
}
refPattern = template.replace(p);
}
if (isRE(refPattern)) {
return Pattern.matches(refPattern, getRefName());
} else if (refPattern.endsWith("/*")) {
String prefix = refPattern.substring(0, refPattern.length() - 1); String prefix = refPattern.substring(0, refPattern.length() - 1);
return refName.startsWith(prefix); return getRefName().startsWith(prefix);
} else { } else {
return refName.equals(refPattern); return getRefName().equals(refPattern);
} }
} }
private static boolean isTemplate(String refPattern) {
return 0 <= refPattern.indexOf("${");
}
private static String escape(String value) {
// Right now the only special character allowed in a
// variable value is a . in the username.
//
return value.replace(".", "\\.");
}
private static boolean isRE(String refPattern) { private static boolean isRE(String refPattern) {
return refPattern.startsWith(RefRight.REGEX_PREFIX); return refPattern.startsWith(RefRight.REGEX_PREFIX);
} }