Merge changes from topic 'refs-users-self'
* changes: RefPatternMatcher: Pass in CurrentUser instead of username Support push to refs/users/self in All-Users repository Support fetch of refs/users/self from All-Users repository
This commit is contained in:
@@ -17,6 +17,7 @@ package com.google.gerrit.acceptance.api.accounts;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assert_;
|
import static com.google.common.truth.Truth.assert_;
|
||||||
|
import static com.google.gerrit.acceptance.GitUtil.fetch;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
|
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
||||||
import static com.google.gerrit.gpg.testutil.TestKeys.allValidKeys;
|
import static com.google.gerrit.gpg.testutil.TestKeys.allValidKeys;
|
||||||
@@ -36,9 +37,11 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
|
|||||||
import com.google.gerrit.acceptance.AccountCreator;
|
import com.google.gerrit.acceptance.AccountCreator;
|
||||||
import com.google.gerrit.acceptance.PushOneCommit;
|
import com.google.gerrit.acceptance.PushOneCommit;
|
||||||
import com.google.gerrit.acceptance.TestAccount;
|
import com.google.gerrit.acceptance.TestAccount;
|
||||||
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.extensions.api.accounts.EmailInput;
|
import com.google.gerrit.extensions.api.accounts.EmailInput;
|
||||||
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
||||||
import com.google.gerrit.extensions.api.changes.StarsInput;
|
import com.google.gerrit.extensions.api.changes.StarsInput;
|
||||||
|
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
|
||||||
import com.google.gerrit.extensions.common.AccountInfo;
|
import com.google.gerrit.extensions.common.AccountInfo;
|
||||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||||
import com.google.gerrit.extensions.common.GpgKeyInfo;
|
import com.google.gerrit.extensions.common.GpgKeyInfo;
|
||||||
@@ -53,7 +56,10 @@ import com.google.gerrit.gpg.server.GpgKeys;
|
|||||||
import com.google.gerrit.gpg.testutil.TestKey;
|
import com.google.gerrit.gpg.testutil.TestKey;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
|
import com.google.gerrit.reviewdb.client.RefNames;
|
||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
|
import com.google.gerrit.server.util.MagicBranch;
|
||||||
import com.google.gerrit.testutil.ConfigSuite;
|
import com.google.gerrit.testutil.ConfigSuite;
|
||||||
import com.google.gerrit.testutil.FakeEmailSender.Message;
|
import com.google.gerrit.testutil.FakeEmailSender.Message;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@@ -62,6 +68,8 @@ import com.google.inject.Provider;
|
|||||||
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||||
|
import org.eclipse.jgit.junit.TestRepository;
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.RefUpdate;
|
import org.eclipse.jgit.lib.RefUpdate;
|
||||||
@@ -354,6 +362,84 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
gApi.accounts().self().addEmail(input);
|
gApi.accounts().self().addEmail(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchUserBranch() throws Exception {
|
||||||
|
// change something in the user preferences to ensure that the user branch
|
||||||
|
// is created
|
||||||
|
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
|
||||||
|
input.changesPerPage =
|
||||||
|
GeneralPreferencesInfo.defaults().changesPerPage + 10;
|
||||||
|
gApi.accounts().self().setPreferences(input);
|
||||||
|
|
||||||
|
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
|
||||||
|
fetch(allUsersRepo, RefNames.refsUsers(admin.id) + ":userRef");
|
||||||
|
Ref userRef = allUsersRepo.getRepository().exactRef("userRef");
|
||||||
|
assertThat(userRef).isNotNull();
|
||||||
|
|
||||||
|
fetch(allUsersRepo, RefNames.REFS_USERS_SELF + ":userSelfRef");
|
||||||
|
Ref userSelfRef =
|
||||||
|
allUsersRepo.getRepository().getRefDatabase().exactRef("userSelfRef");
|
||||||
|
assertThat(userSelfRef).isNotNull();
|
||||||
|
assertThat(userSelfRef.getObjectId()).isEqualTo(userRef.getObjectId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pushToUserBranch() throws Exception {
|
||||||
|
// change something in the user preferences to ensure that the user branch
|
||||||
|
// is created
|
||||||
|
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
|
||||||
|
input.changesPerPage =
|
||||||
|
GeneralPreferencesInfo.defaults().changesPerPage + 10;
|
||||||
|
gApi.accounts().self().setPreferences(input);
|
||||||
|
|
||||||
|
removeExclusiveReadPermissionOnAllUsers();
|
||||||
|
String userRefName = RefNames.refsUsers(admin.id);
|
||||||
|
grant(Permission.PUSH, allUsers, userRefName);
|
||||||
|
|
||||||
|
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
|
||||||
|
fetch(allUsersRepo, RefNames.refsUsers(admin.id) + ":userRef");
|
||||||
|
allUsersRepo.reset("userRef");
|
||||||
|
PushOneCommit push = pushFactory.create(db, admin.getIdent(), allUsersRepo);
|
||||||
|
push.to(userRefName).assertOkStatus();
|
||||||
|
|
||||||
|
push = pushFactory.create(db, admin.getIdent(), allUsersRepo);
|
||||||
|
push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pushToUserBranchForReview() throws Exception {
|
||||||
|
// change something in the user preferences to ensure that the user branch
|
||||||
|
// is created
|
||||||
|
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
|
||||||
|
input.changesPerPage =
|
||||||
|
GeneralPreferencesInfo.defaults().changesPerPage + 10;
|
||||||
|
gApi.accounts().self().setPreferences(input);
|
||||||
|
|
||||||
|
removeExclusiveReadPermissionOnAllUsers();
|
||||||
|
String userRefName = RefNames.refsUsers(admin.id);
|
||||||
|
grant(Permission.PUSH, allUsers, MagicBranch.NEW_CHANGE + userRefName);
|
||||||
|
|
||||||
|
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
|
||||||
|
fetch(allUsersRepo, RefNames.refsUsers(admin.id) + ":userRef");
|
||||||
|
allUsersRepo.reset("userRef");
|
||||||
|
PushOneCommit push = pushFactory.create(db, admin.getIdent(), allUsersRepo);
|
||||||
|
PushOneCommit.Result r = push.to(MagicBranch.NEW_CHANGE + userRefName);
|
||||||
|
r.assertOkStatus();
|
||||||
|
assertThat(r.getChange().change().getDest().get()).isEqualTo(userRefName);
|
||||||
|
|
||||||
|
push = pushFactory.create(db, admin.getIdent(), allUsersRepo);
|
||||||
|
r = push.to(MagicBranch.NEW_CHANGE + RefNames.REFS_USERS_SELF);
|
||||||
|
r.assertOkStatus();
|
||||||
|
assertThat(r.getChange().change().getDest().get()).isEqualTo(userRefName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeExclusiveReadPermissionOnAllUsers() throws Exception {
|
||||||
|
ProjectConfig cfg = projectCache.checkedGet(allUsers).getConfig();
|
||||||
|
cfg.getAccessSection(RefNames.REFS_USERS + "*", true)
|
||||||
|
.remove(new Permission(Permission.READ));
|
||||||
|
saveProjectConfig(allUsers, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addGpgKey() throws Exception {
|
public void addGpgKey() throws Exception {
|
||||||
TestKey key = validKeyWithoutExpiration();
|
TestKey key = validKeyWithoutExpiration();
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class RefNames {
|
|||||||
/** Preference settings for a user {@code refs/users} */
|
/** Preference settings for a user {@code refs/users} */
|
||||||
public static final String REFS_USERS = "refs/users/";
|
public static final String REFS_USERS = "refs/users/";
|
||||||
|
|
||||||
|
/** Magic user branch in All-Users {@code refs/users/self} */
|
||||||
|
public static final String REFS_USERS_SELF = "refs/users/self";
|
||||||
|
|
||||||
/** Default user preference settings */
|
/** Default user preference settings */
|
||||||
public static final String REFS_USERS_DEFAULT = RefNames.REFS_USERS + "default";
|
public static final String REFS_USERS_DEFAULT = RefNames.REFS_USERS + "default";
|
||||||
|
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ public class ReceiveCommits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<Branch.NameKey> branches = new HashSet<>();
|
Set<Branch.NameKey> branches = new HashSet<>();
|
||||||
for (ReceiveCommand c : commands) {
|
for (ReceiveCommand c : batch.getCommands()) {
|
||||||
if (c.getResult() == OK) {
|
if (c.getResult() == OK) {
|
||||||
if (c.getType() == ReceiveCommand.Type.UPDATE) { // aka fast-forward
|
if (c.getType() == ReceiveCommand.Type.UPDATE) { // aka fast-forward
|
||||||
tagCache.updateFastForward(project.getNameKey(),
|
tagCache.updateFastForward(project.getNameKey(),
|
||||||
@@ -890,6 +890,19 @@ public class ReceiveCommits {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (projectControl.getProjectState().isAllUsers()
|
||||||
|
&& RefNames.REFS_USERS_SELF.equals(cmd.getRefName())) {
|
||||||
|
final ReceiveCommand orgCmd = cmd;
|
||||||
|
cmd = new ReceiveCommand(cmd.getOldId(), cmd.getNewId(),
|
||||||
|
RefNames.refsUsers(user.getAccountId()), cmd.getType()) {
|
||||||
|
@Override
|
||||||
|
public void setResult(Result s, String m) {
|
||||||
|
super.setResult(s, m);
|
||||||
|
orgCmd.setResult(s, m);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Matcher m = NEW_PATCHSET.matcher(cmd.getRefName());
|
Matcher m = NEW_PATCHSET.matcher(cmd.getRefName());
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
// The referenced change must exist and must still be open.
|
// The referenced change must exist and must still be open.
|
||||||
@@ -1303,6 +1316,10 @@ public class ReceiveCommits {
|
|||||||
reject(cmd, "see help");
|
reject(cmd, "see help");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (projectControl.getProjectState().isAllUsers()
|
||||||
|
&& RefNames.REFS_USERS_SELF.equals(ref)) {
|
||||||
|
ref = RefNames.refsUsers(user.getAccountId());
|
||||||
|
}
|
||||||
if (!rp.getAdvertisedRefs().containsKey(ref) && !ref.equals(readHEAD(repo))) {
|
if (!rp.getAdvertisedRefs().containsKey(ref) && !ref.equals(readHEAD(repo))) {
|
||||||
if (ref.startsWith(Constants.R_HEADS)) {
|
if (ref.startsWith(Constants.R_HEADS)) {
|
||||||
String n = ref.substring(Constants.R_HEADS.length());
|
String n = ref.substring(Constants.R_HEADS.length());
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.eclipse.jgit.lib.Constants;
|
|||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.RefDatabase;
|
import org.eclipse.jgit.lib.RefDatabase;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.lib.SymbolicRef;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook;
|
import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook;
|
||||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||||
@@ -69,6 +70,18 @@ public class VisibleRefFilter extends AbstractAdvertiseRefsHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Ref> filter(Map<String, Ref> refs, boolean filterTagsSeparately) {
|
public Map<String, Ref> filter(Map<String, Ref> refs, boolean filterTagsSeparately) {
|
||||||
|
if (projectCtl.getProjectState().isAllUsers()
|
||||||
|
&& projectCtl.getUser().isIdentifiedUser()) {
|
||||||
|
Ref userRef =
|
||||||
|
refs.get(RefNames.refsUsers(projectCtl.getUser().getAccountId()));
|
||||||
|
if (userRef != null) {
|
||||||
|
SymbolicRef refsUsersSelf =
|
||||||
|
new SymbolicRef(RefNames.REFS_USERS_SELF, userRef);
|
||||||
|
refs = new HashMap<>(refs);
|
||||||
|
refs.put(refsUsersSelf.getName(), refsUsersSelf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (projectCtl.allRefsAreVisible(ImmutableSet.of(RefNames.REFS_CONFIG))) {
|
if (projectCtl.allRefsAreVisible(ImmutableSet.of(RefNames.REFS_CONFIG))) {
|
||||||
Map<String, Ref> r = Maps.newHashMap(refs);
|
Map<String, Ref> r = Maps.newHashMap(refs);
|
||||||
if (!projectCtl.controlForRef(RefNames.REFS_CONFIG).isVisible()) {
|
if (!projectCtl.controlForRef(RefNames.REFS_CONFIG).isVisible()) {
|
||||||
@@ -97,7 +110,8 @@ public class VisibleRefFilter extends AbstractAdvertiseRefsHook {
|
|||||||
Account.Id accountId;
|
Account.Id accountId;
|
||||||
if (ref.getName().startsWith(RefNames.REFS_CACHE_AUTOMERGE)) {
|
if (ref.getName().startsWith(RefNames.REFS_CACHE_AUTOMERGE)) {
|
||||||
continue;
|
continue;
|
||||||
} else if ((accountId = Account.Id.fromRef(ref.getName())) != null) {
|
} else if ((accountId =
|
||||||
|
Account.Id.fromRef(ref.getLeaf().getName())) != null) {
|
||||||
// Reference related to an account is visible only for the current
|
// Reference related to an account is visible only for the current
|
||||||
// account.
|
// account.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -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,15 +99,10 @@ public class PermissionCollection {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
perUser = true;
|
perUser = true;
|
||||||
if (usernames == null) {
|
if (sm.match(ref, user)) {
|
||||||
usernames = usernameProvider.get();
|
|
||||||
}
|
|
||||||
for (String username : usernames) {
|
|
||||||
if (sm.match(ref, username)) {
|
|
||||||
sectionToProject.put(sm.section, sm.project);
|
sectionToProject.put(sm.section, sm.project);
|
||||||
break;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.google.gerrit.rules.RulesCache;
|
|||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.account.CapabilityCollection;
|
import com.google.gerrit.server.account.CapabilityCollection;
|
||||||
import com.google.gerrit.server.config.AllProjectsName;
|
import com.google.gerrit.server.config.AllProjectsName;
|
||||||
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
import com.google.gerrit.server.git.BranchOrderSection;
|
import com.google.gerrit.server.git.BranchOrderSection;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
@@ -80,6 +81,7 @@ public class ProjectState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final boolean isAllProjects;
|
private final boolean isAllProjects;
|
||||||
|
private final boolean isAllUsers;
|
||||||
private final SitePaths sitePaths;
|
private final SitePaths sitePaths;
|
||||||
private final AllProjectsName allProjectsName;
|
private final AllProjectsName allProjectsName;
|
||||||
private final ProjectCache projectCache;
|
private final ProjectCache projectCache;
|
||||||
@@ -113,6 +115,7 @@ public class ProjectState {
|
|||||||
final SitePaths sitePaths,
|
final SitePaths sitePaths,
|
||||||
final ProjectCache projectCache,
|
final ProjectCache projectCache,
|
||||||
final AllProjectsName allProjectsName,
|
final AllProjectsName allProjectsName,
|
||||||
|
final AllUsersName allUsersName,
|
||||||
final ProjectControl.AssistedFactory projectControlFactory,
|
final ProjectControl.AssistedFactory projectControlFactory,
|
||||||
final PrologEnvironment.Factory envFactory,
|
final PrologEnvironment.Factory envFactory,
|
||||||
final GitRepositoryManager gitMgr,
|
final GitRepositoryManager gitMgr,
|
||||||
@@ -122,6 +125,7 @@ public class ProjectState {
|
|||||||
this.sitePaths = sitePaths;
|
this.sitePaths = sitePaths;
|
||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName);
|
this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName);
|
||||||
|
this.isAllUsers = config.getProject().getNameKey().equals(allUsersName);
|
||||||
this.allProjectsName = allProjectsName;
|
this.allProjectsName = allProjectsName;
|
||||||
this.projectControlFactory = projectControlFactory;
|
this.projectControlFactory = projectControlFactory;
|
||||||
this.envFactory = envFactory;
|
this.envFactory = envFactory;
|
||||||
@@ -362,6 +366,10 @@ public class ProjectState {
|
|||||||
return isAllProjects;
|
return isAllProjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAllUsers() {
|
||||||
|
return isAllUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUseContributorAgreements() {
|
public boolean isUseContributorAgreements() {
|
||||||
return getInheritableBoolean(new Function<Project, InheritableBoolean>() {
|
return getInheritableBoolean(new Function<Project, InheritableBoolean>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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,11 +105,12 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (String username : getUsernames(user)) {
|
||||||
String u;
|
String u;
|
||||||
if (isRE(template.getPattern())) {
|
if (isRE(template.getPattern())) {
|
||||||
u = Pattern.quote(username);
|
u = Pattern.quote(username);
|
||||||
@@ -114,7 +119,27 @@ public abstract class RefPatternMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ import com.google.gerrit.server.account.GroupMembership;
|
|||||||
import com.google.gerrit.server.account.ListGroupMembership;
|
import com.google.gerrit.server.account.ListGroupMembership;
|
||||||
import com.google.gerrit.server.config.AllProjectsName;
|
import com.google.gerrit.server.config.AllProjectsName;
|
||||||
import com.google.gerrit.server.config.AllProjectsNameProvider;
|
import com.google.gerrit.server.config.AllProjectsNameProvider;
|
||||||
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
|
import com.google.gerrit.server.config.AllUsersNameProvider;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
import com.google.gerrit.server.git.ProjectConfig;
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
import com.google.gerrit.server.schema.SchemaCreator;
|
import com.google.gerrit.server.schema.SchemaCreator;
|
||||||
@@ -218,6 +220,8 @@ public class RefControlTest {
|
|||||||
|
|
||||||
private final AllProjectsName allProjectsName =
|
private final AllProjectsName allProjectsName =
|
||||||
new AllProjectsName(AllProjectsNameProvider.DEFAULT);
|
new AllProjectsName(AllProjectsNameProvider.DEFAULT);
|
||||||
|
private final AllUsersName allUsersName =
|
||||||
|
new AllUsersName(AllUsersNameProvider.DEFAULT);
|
||||||
private final AccountGroup.UUID fixers = new AccountGroup.UUID("test.fixers");
|
private final AccountGroup.UUID fixers = new AccountGroup.UUID("test.fixers");
|
||||||
private final Map<Project.NameKey, ProjectState> all = new HashMap<>();
|
private final Map<Project.NameKey, ProjectState> all = new HashMap<>();
|
||||||
private Project.NameKey localKey = new Project.NameKey("local");
|
private Project.NameKey localKey = new Project.NameKey("local");
|
||||||
@@ -858,9 +862,10 @@ public class RefControlTest {
|
|||||||
} catch (IOException | ConfigInvalidException e) {
|
} catch (IOException | ConfigInvalidException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
all.put(pc.getName(), new ProjectState(sitePaths,
|
all.put(pc.getName(),
|
||||||
projectCache, allProjectsName, projectControlFactory, envFactory,
|
new ProjectState(sitePaths, projectCache, allProjectsName, allUsersName,
|
||||||
repoManager, rulesCache, commentLinks, pc));
|
projectControlFactory, envFactory, repoManager, rulesCache,
|
||||||
|
commentLinks, pc));
|
||||||
return repo;
|
return repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user