RefPatternMatcher: Pass in CurrentUser instead of username
This will allow us to expand more user-specific parameters then just
${username}, e.g. we may want to expand ${userid} to the sharded
account ID so that we can assign each user permissions on its own user
branch in the All-Users repository.
Change-Id: I003d5d3b247f3fb2f4613e368cd37f1afb7616e5
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
@@ -413,7 +413,7 @@ public class ChangeControl {
|
||||
|
||||
private boolean match(String destBranch, String refPattern) {
|
||||
return RefPatternMatcher.getMatcher(refPattern).match(destBranch,
|
||||
getUser().getUserName());
|
||||
getUser());
|
||||
}
|
||||
|
||||
private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) {
|
||||
|
||||
@@ -26,12 +26,11 @@ import com.google.gerrit.common.data.Permission;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -65,22 +64,21 @@ public class PermissionCollection {
|
||||
* priority order (project specific definitions must appear before
|
||||
* inherited ones).
|
||||
* @param ref reference being accessed.
|
||||
* @param usernameProvider if the reference is a per-user reference, access
|
||||
* sections using the parameter variable "${username}" will first
|
||||
* have each of {@code usernames} inserted into them before seeing if
|
||||
* they apply to the reference named by {@code ref}.
|
||||
* @param user if the reference is a per-user reference, e.g. access
|
||||
* sections using the parameter variable "${username}" will have
|
||||
* each username inserted into them to see if they apply to the
|
||||
* reference named by {@code ref}.
|
||||
* @return map of permissions that apply to this reference, keyed by
|
||||
* permission name.
|
||||
*/
|
||||
PermissionCollection filter(Iterable<SectionMatcher> matcherList,
|
||||
String ref, Provider<? extends Collection<String>> usernameProvider) {
|
||||
String ref, CurrentUser user) {
|
||||
if (isRE(ref)) {
|
||||
ref = RefControl.shortestExample(ref);
|
||||
} else if (ref.endsWith("/*")) {
|
||||
ref = ref.substring(0, ref.length() - 1);
|
||||
}
|
||||
|
||||
Collection<String> usernames = null;
|
||||
boolean perUser = false;
|
||||
Map<AccessSection, Project.NameKey> sectionToProject = new LinkedHashMap<>();
|
||||
for (SectionMatcher sm : matcherList) {
|
||||
@@ -101,14 +99,9 @@ public class PermissionCollection {
|
||||
continue;
|
||||
}
|
||||
perUser = true;
|
||||
if (usernames == null) {
|
||||
usernames = usernameProvider.get();
|
||||
}
|
||||
for (String username : usernames) {
|
||||
if (sm.match(ref, username)) {
|
||||
sectionToProject.put(sm.section, sm.project);
|
||||
break;
|
||||
}
|
||||
if (sm.match(ref, user)) {
|
||||
sectionToProject.put(sm.section, sm.project);
|
||||
break;
|
||||
}
|
||||
} else if (sm.match(ref, null)) {
|
||||
sectionToProject.put(sm.section, sm.project);
|
||||
|
||||
@@ -227,25 +227,8 @@ public class ProjectControl {
|
||||
}
|
||||
RefControl ctl = refControls.get(refName);
|
||||
if (ctl == null) {
|
||||
Provider<List<String>> usernames = new Provider<List<String>>() {
|
||||
@Override
|
||||
public List<String> get() {
|
||||
List<String> r;
|
||||
if (user.isIdentifiedUser()) {
|
||||
Set<String> emails = user.asIdentifiedUser().getEmailAddresses();
|
||||
r = new ArrayList<>(emails.size() + 1);
|
||||
r.addAll(emails);
|
||||
} else {
|
||||
r = new ArrayList<>(1);
|
||||
}
|
||||
if (user.getUserName() != null) {
|
||||
r.add(user.getUserName());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
};
|
||||
PermissionCollection relevant =
|
||||
permissionFilter.filter(access(), refName, usernames);
|
||||
permissionFilter.filter(access(), refName, user);
|
||||
ctl = new RefControl(this, refName, relevant);
|
||||
refControls.put(refName, ctl);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,15 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import static com.google.gerrit.server.project.RefControl.isRE;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gerrit.common.data.ParameterizedString;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
|
||||
import dk.brics.automaton.Automaton;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class RefPatternMatcher {
|
||||
@@ -36,7 +40,7 @@ public abstract class RefPatternMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean match(String ref, String username);
|
||||
public abstract boolean match(String ref, CurrentUser user);
|
||||
|
||||
private static class Exact extends RefPatternMatcher {
|
||||
private final String expect;
|
||||
@@ -46,7 +50,7 @@ public abstract class RefPatternMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String ref, String username) {
|
||||
public boolean match(String ref, CurrentUser user) {
|
||||
return expect.equals(ref);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +63,7 @@ public abstract class RefPatternMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String ref, String username) {
|
||||
public boolean match(String ref, CurrentUser user) {
|
||||
return ref.startsWith(prefix);
|
||||
}
|
||||
}
|
||||
@@ -72,7 +76,7 @@ public abstract class RefPatternMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String ref, String username) {
|
||||
public boolean match(String ref, CurrentUser user) {
|
||||
return pattern.matcher(ref).matches();
|
||||
}
|
||||
}
|
||||
@@ -101,20 +105,41 @@ public abstract class RefPatternMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String ref, String username) {
|
||||
if (!ref.startsWith(prefix) || username == null) {
|
||||
public boolean match(String ref, CurrentUser user) {
|
||||
if (!ref.startsWith(prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String u;
|
||||
if (isRE(template.getPattern())) {
|
||||
u = Pattern.quote(username);
|
||||
} else {
|
||||
u = username;
|
||||
}
|
||||
for (String username : getUsernames(user)) {
|
||||
String u;
|
||||
if (isRE(template.getPattern())) {
|
||||
u = Pattern.quote(username);
|
||||
} else {
|
||||
u = username;
|
||||
}
|
||||
|
||||
RefPatternMatcher next = getMatcher(expand(template, u));
|
||||
return next != null ? next.match(expand(ref, u), username) : false;
|
||||
RefPatternMatcher next = getMatcher(expand(template, u));
|
||||
if (next != null && next.match(expand(ref, u), user)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Iterable<String> getUsernames(CurrentUser user) {
|
||||
if (user.isIdentifiedUser()) {
|
||||
Set<String> emails = user.asIdentifiedUser().getEmailAddresses();
|
||||
if (user.getUserName() == null) {
|
||||
return emails;
|
||||
} else if (emails.isEmpty()) {
|
||||
return ImmutableSet.of(user.getUserName());
|
||||
}
|
||||
Iterables.concat(emails, ImmutableSet.of(user.getUserName()));
|
||||
}
|
||||
if (user.getUserName() != null) {
|
||||
return ImmutableSet.of(user.getUserName());
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
boolean matchPrefix(String ref) {
|
||||
|
||||
@@ -16,6 +16,7 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
|
||||
/**
|
||||
* Matches an AccessSection against a reference name.
|
||||
@@ -45,7 +46,7 @@ class SectionMatcher extends RefPatternMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String ref, String username) {
|
||||
return this.matcher.match(ref, username);
|
||||
public boolean match(String ref, CurrentUser user) {
|
||||
return this.matcher.match(ref, user);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user