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) {
|
private boolean match(String destBranch, String refPattern) {
|
||||||
return RefPatternMatcher.getMatcher(refPattern).match(destBranch,
|
return RefPatternMatcher.getMatcher(refPattern).match(destBranch,
|
||||||
getUser().getUserName());
|
getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) {
|
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.common.data.PermissionRule;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -65,22 +64,21 @@ public class PermissionCollection {
|
|||||||
* priority order (project specific definitions must appear before
|
* priority order (project specific definitions must appear before
|
||||||
* inherited ones).
|
* inherited ones).
|
||||||
* @param ref reference being accessed.
|
* @param ref reference being accessed.
|
||||||
* @param usernameProvider if the reference is a per-user reference, access
|
* @param user if the reference is a per-user reference, e.g. access
|
||||||
* sections using the parameter variable "${username}" will first
|
* sections using the parameter variable "${username}" will have
|
||||||
* have each of {@code usernames} inserted into them before seeing if
|
* each username inserted into them to see if they apply to the
|
||||||
* they apply to the reference named by {@code ref}.
|
* reference named by {@code ref}.
|
||||||
* @return map of permissions that apply to this reference, keyed by
|
* @return map of permissions that apply to this reference, keyed by
|
||||||
* permission name.
|
* permission name.
|
||||||
*/
|
*/
|
||||||
PermissionCollection filter(Iterable<SectionMatcher> matcherList,
|
PermissionCollection filter(Iterable<SectionMatcher> matcherList,
|
||||||
String ref, Provider<? extends Collection<String>> usernameProvider) {
|
String ref, CurrentUser user) {
|
||||||
if (isRE(ref)) {
|
if (isRE(ref)) {
|
||||||
ref = RefControl.shortestExample(ref);
|
ref = RefControl.shortestExample(ref);
|
||||||
} else if (ref.endsWith("/*")) {
|
} else if (ref.endsWith("/*")) {
|
||||||
ref = ref.substring(0, ref.length() - 1);
|
ref = ref.substring(0, ref.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<String> usernames = null;
|
|
||||||
boolean perUser = false;
|
boolean perUser = false;
|
||||||
Map<AccessSection, Project.NameKey> sectionToProject = new LinkedHashMap<>();
|
Map<AccessSection, Project.NameKey> sectionToProject = new LinkedHashMap<>();
|
||||||
for (SectionMatcher sm : matcherList) {
|
for (SectionMatcher sm : matcherList) {
|
||||||
@@ -101,14 +99,9 @@ public class PermissionCollection {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
perUser = true;
|
perUser = true;
|
||||||
if (usernames == null) {
|
if (sm.match(ref, user)) {
|
||||||
usernames = usernameProvider.get();
|
sectionToProject.put(sm.section, sm.project);
|
||||||
}
|
break;
|
||||||
for (String username : usernames) {
|
|
||||||
if (sm.match(ref, username)) {
|
|
||||||
sectionToProject.put(sm.section, sm.project);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (sm.match(ref, null)) {
|
} else if (sm.match(ref, null)) {
|
||||||
sectionToProject.put(sm.section, sm.project);
|
sectionToProject.put(sm.section, sm.project);
|
||||||
|
|||||||
@@ -227,25 +227,8 @@ public class ProjectControl {
|
|||||||
}
|
}
|
||||||
RefControl ctl = refControls.get(refName);
|
RefControl ctl = refControls.get(refName);
|
||||||
if (ctl == null) {
|
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 =
|
PermissionCollection relevant =
|
||||||
permissionFilter.filter(access(), refName, usernames);
|
permissionFilter.filter(access(), refName, user);
|
||||||
ctl = new RefControl(this, refName, relevant);
|
ctl = new RefControl(this, refName, relevant);
|
||||||
refControls.put(refName, ctl);
|
refControls.put(refName, ctl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,15 @@ package com.google.gerrit.server.project;
|
|||||||
|
|
||||||
import static com.google.gerrit.server.project.RefControl.isRE;
|
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.common.data.ParameterizedString;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
|
||||||
import dk.brics.automaton.Automaton;
|
import dk.brics.automaton.Automaton;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public abstract class RefPatternMatcher {
|
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 static class Exact extends RefPatternMatcher {
|
||||||
private final String expect;
|
private final String expect;
|
||||||
@@ -46,7 +50,7 @@ public abstract class RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(String ref, String username) {
|
public boolean match(String ref, CurrentUser user) {
|
||||||
return expect.equals(ref);
|
return expect.equals(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +63,7 @@ public abstract class RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(String ref, String username) {
|
public boolean match(String ref, CurrentUser user) {
|
||||||
return ref.startsWith(prefix);
|
return ref.startsWith(prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +76,7 @@ public abstract class RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(String ref, String username) {
|
public boolean match(String ref, CurrentUser user) {
|
||||||
return pattern.matcher(ref).matches();
|
return pattern.matcher(ref).matches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,20 +105,41 @@ public abstract class RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(String ref, String username) {
|
public boolean match(String ref, CurrentUser user) {
|
||||||
if (!ref.startsWith(prefix) || username == null) {
|
if (!ref.startsWith(prefix)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String u;
|
for (String username : getUsernames(user)) {
|
||||||
if (isRE(template.getPattern())) {
|
String u;
|
||||||
u = Pattern.quote(username);
|
if (isRE(template.getPattern())) {
|
||||||
} else {
|
u = Pattern.quote(username);
|
||||||
u = username;
|
} else {
|
||||||
}
|
u = username;
|
||||||
|
}
|
||||||
|
|
||||||
RefPatternMatcher next = getMatcher(expand(template, u));
|
RefPatternMatcher next = getMatcher(expand(template, u));
|
||||||
return next != null ? next.match(expand(ref, u), username) : false;
|
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) {
|
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.common.data.AccessSection;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches an AccessSection against a reference name.
|
* Matches an AccessSection against a reference name.
|
||||||
@@ -45,7 +46,7 @@ class SectionMatcher extends RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(String ref, String username) {
|
public boolean match(String ref, CurrentUser user) {
|
||||||
return this.matcher.match(ref, username);
|
return this.matcher.match(ref, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user