Make project and ref for each PermissionRule available to RefControl
This information is important to be able to allow ALLOW rules to override BLOCK rules if they are defined on the same project. This will be implemented in a follow-up change. Change-Id: If22c1f0f8e13735e2e1e6e868e82b0d3617ef616 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com> Signed-off-by: Sasa Zivkov <sasa.zivkov@sap.com>
This commit is contained in:
@@ -16,10 +16,13 @@ package com.google.gerrit.server.project;
|
||||
|
||||
import static com.google.gerrit.server.project.RefControl.isRE;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
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.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@@ -73,7 +76,7 @@ public class PermissionCollection {
|
||||
}
|
||||
|
||||
boolean perUser = false;
|
||||
List<AccessSection> sections = new ArrayList<AccessSection>();
|
||||
Map<AccessSection, Project.NameKey> sectionToProject = Maps.newLinkedHashMap();
|
||||
for (SectionMatcher matcher : matcherList) {
|
||||
// If the matcher has to expand parameters and its prefix matches the
|
||||
// reference there is a very good chance the reference is actually user
|
||||
@@ -93,9 +96,10 @@ public class PermissionCollection {
|
||||
}
|
||||
|
||||
if (matcher.match(ref, username)) {
|
||||
sections.add(matcher.section);
|
||||
sectionToProject.put(matcher.section, matcher.project);
|
||||
}
|
||||
}
|
||||
List<AccessSection> sections = Lists.newArrayList(sectionToProject.keySet());
|
||||
sorter.sort(ref, sections);
|
||||
|
||||
Set<SeenRule> seen = new HashSet<SeenRule>();
|
||||
@@ -104,7 +108,9 @@ public class PermissionCollection {
|
||||
|
||||
HashMap<String, List<PermissionRule>> permissions =
|
||||
new HashMap<String, List<PermissionRule>>();
|
||||
Map<PermissionRule, ProjectRef> ruleProps = Maps.newIdentityHashMap();
|
||||
for (AccessSection section : sections) {
|
||||
Project.NameKey project = sectionToProject.get(section);
|
||||
for (Permission permission : section.getPermissions()) {
|
||||
boolean exclusivePermissionExists =
|
||||
exclusiveGroupPermissions.contains(permission.getName());
|
||||
@@ -124,6 +130,7 @@ public class PermissionCollection {
|
||||
permissions.put(permission.getName(), r);
|
||||
}
|
||||
r.add(rule);
|
||||
ruleProps.put(rule, new ProjectRef(project, section.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,16 +140,20 @@ public class PermissionCollection {
|
||||
}
|
||||
}
|
||||
|
||||
return new PermissionCollection(permissions, perUser ? username : null);
|
||||
return new PermissionCollection(permissions, ruleProps,
|
||||
perUser ? username : null);
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, List<PermissionRule>> rules;
|
||||
private final Map<PermissionRule, ProjectRef> ruleProps;
|
||||
private final String username;
|
||||
|
||||
private PermissionCollection(Map<String, List<PermissionRule>> rules,
|
||||
Map<PermissionRule, ProjectRef> ruleProps,
|
||||
String username) {
|
||||
this.rules = rules;
|
||||
this.ruleProps = ruleProps;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@@ -167,6 +178,10 @@ public class PermissionCollection {
|
||||
return r != null ? r : Collections.<PermissionRule> emptyList();
|
||||
}
|
||||
|
||||
ProjectRef getRuleProps(PermissionRule rule) {
|
||||
return ruleProps.get(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain all declared permission rules that match the reference.
|
||||
*
|
||||
|
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
|
||||
class ProjectRef {
|
||||
|
||||
final Project.NameKey project;
|
||||
final String ref;
|
||||
|
||||
ProjectRef(Project.NameKey project, String ref) {
|
||||
this.project = project;
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof ProjectRef
|
||||
&& project.equals(((ProjectRef) other).project)
|
||||
&& ref.equals(((ProjectRef) other).ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return project.hashCode() * 31 + ref.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return project + ", " + ref;
|
||||
}
|
||||
}
|
@@ -212,7 +212,8 @@ public class ProjectState {
|
||||
section.setPermissions(copy);
|
||||
}
|
||||
|
||||
SectionMatcher matcher = SectionMatcher.wrap(section);
|
||||
SectionMatcher matcher = SectionMatcher.wrap(getProject().getNameKey(),
|
||||
section);
|
||||
if (matcher != null) {
|
||||
sm.add(matcher);
|
||||
}
|
||||
@@ -350,4 +351,4 @@ public class ProjectState {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ import static com.google.gerrit.server.project.RefControl.isRE;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.ParameterizedString;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
|
||||
import dk.brics.automaton.Automaton;
|
||||
|
||||
@@ -31,33 +32,37 @@ import java.util.regex.Pattern;
|
||||
* faster selection of which sections are relevant to any given input reference.
|
||||
*/
|
||||
abstract class SectionMatcher {
|
||||
static SectionMatcher wrap(AccessSection section) {
|
||||
static SectionMatcher wrap(Project.NameKey project, AccessSection section) {
|
||||
String ref = section.getName();
|
||||
if (AccessSection.isValid(ref)) {
|
||||
return wrap(ref, section);
|
||||
return wrap(project, ref, section);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static SectionMatcher wrap(String pattern, AccessSection section) {
|
||||
static SectionMatcher wrap(Project.NameKey project, String pattern,
|
||||
AccessSection section) {
|
||||
if (pattern.contains("${")) {
|
||||
return new ExpandParameters(pattern, section);
|
||||
return new ExpandParameters(project, pattern, section);
|
||||
|
||||
} else if (isRE(pattern)) {
|
||||
return new Regexp(pattern, section);
|
||||
return new Regexp(project, pattern, section);
|
||||
|
||||
} else if (pattern.endsWith("/*")) {
|
||||
return new Prefix(pattern.substring(0, pattern.length() - 1), section);
|
||||
return new Prefix(project, pattern.substring(0, pattern.length() - 1),
|
||||
section);
|
||||
|
||||
} else {
|
||||
return new Exact(pattern, section);
|
||||
return new Exact(project, pattern, section);
|
||||
}
|
||||
}
|
||||
|
||||
final Project.NameKey project;
|
||||
final AccessSection section;
|
||||
|
||||
SectionMatcher(AccessSection section) {
|
||||
SectionMatcher(Project.NameKey project, AccessSection section) {
|
||||
this.project = project;
|
||||
this.section = section;
|
||||
}
|
||||
|
||||
@@ -66,8 +71,8 @@ abstract class SectionMatcher {
|
||||
private static class Exact extends SectionMatcher {
|
||||
private final String expect;
|
||||
|
||||
Exact(String name, AccessSection section) {
|
||||
super(section);
|
||||
Exact(Project.NameKey project, String name, AccessSection section) {
|
||||
super(project, section);
|
||||
expect = name;
|
||||
}
|
||||
|
||||
@@ -80,8 +85,8 @@ abstract class SectionMatcher {
|
||||
private static class Prefix extends SectionMatcher {
|
||||
private final String prefix;
|
||||
|
||||
Prefix(String pfx, AccessSection section) {
|
||||
super(section);
|
||||
Prefix(Project.NameKey project, String pfx, AccessSection section) {
|
||||
super(project, section);
|
||||
prefix = pfx;
|
||||
}
|
||||
|
||||
@@ -94,8 +99,8 @@ abstract class SectionMatcher {
|
||||
private static class Regexp extends SectionMatcher {
|
||||
private final Pattern pattern;
|
||||
|
||||
Regexp(String re, AccessSection section) {
|
||||
super(section);
|
||||
Regexp(Project.NameKey project, String re, AccessSection section) {
|
||||
super(project, section);
|
||||
pattern = Pattern.compile(re);
|
||||
}
|
||||
|
||||
@@ -109,8 +114,9 @@ abstract class SectionMatcher {
|
||||
private final ParameterizedString template;
|
||||
private final String prefix;
|
||||
|
||||
ExpandParameters(String pattern, AccessSection section) {
|
||||
super(section);
|
||||
ExpandParameters(Project.NameKey project, String pattern,
|
||||
AccessSection section) {
|
||||
super(project, section);
|
||||
template = new ParameterizedString(pattern);
|
||||
|
||||
if (isRE(pattern)) {
|
||||
@@ -141,7 +147,7 @@ abstract class SectionMatcher {
|
||||
u = username;
|
||||
}
|
||||
|
||||
SectionMatcher next = wrap(
|
||||
SectionMatcher next = wrap(project,
|
||||
template.replace(Collections.singletonMap("username", u)),
|
||||
section);
|
||||
return next != null ? next.match(ref, username) : false;
|
||||
|
Reference in New Issue
Block a user