Support refs/users/self for the GET branch rest endpoint

A user may fetch the magic branch refs/users/self and this branch is
resolved to the user branch of the calling user
> git fetch origin refs/users/self

This change adds support for this magic ref to the GET Branch rest
endpoint. This only works if the repository is All-Users.

Change-Id: I2d56a8896e0b701351e10e22ba6012ed28d53117
This commit is contained in:
Youssef Elghareeb
2020-10-26 19:02:39 +01:00
parent b7dadde0bf
commit a5639fcef6
6 changed files with 26 additions and 7 deletions

View File

@@ -1702,7 +1702,9 @@ List all branches that match regex `t.*1`:
'GET /projects/link:#project-name[\{project-name\}]/branches/link:#branch-id[\{branch-id\}]' 'GET /projects/link:#project-name[\{project-name\}]/branches/link:#branch-id[\{branch-id\}]'
-- --
Retrieves a branch of a project. Retrieves a branch of a project. For the "All-Users" repository, the magic
branch "refs/users/self" is automatically resolved to the user branch of the
calling user.
.Request .Request
---- ----

View File

@@ -255,6 +255,10 @@ public class RefNames {
return ref.startsWith(REFS_USERS); return ref.startsWith(REFS_USERS);
} }
public static boolean isRefsUsersSelf(String ref, boolean isAllUsers) {
return isAllUsers && REFS_USERS_SELF.equals(ref);
}
/** /**
* Whether the ref is a group branch that stores NoteDb data of a group. Returns {@code true} for * Whether the ref is a group branch that stores NoteDb data of a group. Returns {@code true} for
* all refs that start with {@code refs/groups/}. * all refs that start with {@code refs/groups/}.

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.api.projects;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException; import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.projects.BranchApi; import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.api.projects.BranchInfo; import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.api.projects.BranchInput;
@@ -126,6 +127,10 @@ public class BranchApiImpl implements BranchApi {
private BranchResource resource() private BranchResource resource()
throws RestApiException, IOException, PermissionBackendException { throws RestApiException, IOException, PermissionBackendException {
return branches.parse(project, IdString.fromDecoded(ref)); String refName = ref;
if (RefNames.isRefsUsersSelf(ref, project.getProjectState().isAllUsers())) {
refName = RefNames.refsUsers(project.getUser().getAccountId());
}
return branches.parse(project, IdString.fromDecoded(refName));
} }
} }

View File

@@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.flogger.LazyArgs.lazy; import static com.google.common.flogger.LazyArgs.lazy;
import static com.google.gerrit.entities.RefNames.REFS_CHANGES; import static com.google.gerrit.entities.RefNames.REFS_CHANGES;
import static com.google.gerrit.entities.RefNames.isConfigRef; import static com.google.gerrit.entities.RefNames.isConfigRef;
import static com.google.gerrit.entities.RefNames.isRefsUsersSelf;
import static com.google.gerrit.git.ObjectIds.abbreviateName; import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.server.change.HashtagsUtil.cleanupHashtag; import static com.google.gerrit.server.change.HashtagsUtil.cleanupHashtag;
import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN; import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN;
@@ -1080,7 +1081,7 @@ class ReceiveCommits {
private ReceiveCommand wrapReceiveCommand(ReceiveCommand cmd, Task progress) { private ReceiveCommand wrapReceiveCommand(ReceiveCommand cmd, Task progress) {
String refname = cmd.getRefName(); String refname = cmd.getRefName();
if (projectState.isAllUsers() && RefNames.REFS_USERS_SELF.equals(cmd.getRefName())) { if (isRefsUsersSelf(cmd.getRefName(), projectState.isAllUsers())) {
refname = RefNames.refsUsers(user.getAccountId()); refname = RefNames.refsUsers(user.getAccountId());
logger.atFine().log("Swapping out command for %s to %s", RefNames.REFS_USERS_SELF, refname); logger.atFine().log("Swapping out command for %s to %s", RefNames.REFS_USERS_SELF, refname);
} }

View File

@@ -143,7 +143,11 @@ public class ListBranches implements RestReadView<ProjectResource> {
BranchInfo toBranchInfo(BranchResource rsrc) BranchInfo toBranchInfo(BranchResource rsrc)
throws IOException, ResourceNotFoundException, PermissionBackendException { throws IOException, ResourceNotFoundException, PermissionBackendException {
try (Repository db = repoManager.openRepository(rsrc.getNameKey())) { try (Repository db = repoManager.openRepository(rsrc.getNameKey())) {
Ref r = db.exactRef(rsrc.getRef()); String refName = rsrc.getRef();
if (RefNames.isRefsUsersSelf(refName, rsrc.getProjectState().isAllUsers())) {
refName = RefNames.refsUsers(rsrc.getUser().getAccountId());
}
Ref r = db.exactRef(refName);
if (r == null) { if (r == null) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }

View File

@@ -262,9 +262,12 @@ public class GetBranchIT extends AbstractDaemonTest {
requestScopeOperations.setApiUser(user.id()); requestScopeOperations.setApiUser(user.id());
assertBranchFound(allUsers, RefNames.refsUsers(user.id())); assertBranchFound(allUsers, RefNames.refsUsers(user.id()));
// TODO: every user can see the own user ref via the magic ref/users/self ref // every user can see the own user ref via the magic ref/users/self ref. For this special case,
// requestScopeOperations.setApiUser(user.id()); // the branch in the request is refs/users/self, but the response contains the actual
// assertBranchFound(allUsers, RefNames.REFS_USERS_SELF); // refs/users/$sharded_id/$id
BranchInfo branchInfo =
gApi.projects().name(allUsers.get()).branch(RefNames.REFS_USERS_SELF).get();
assertThat(branchInfo.ref).isEqualTo(RefNames.refsUsers(user.id()));
} }
@Test @Test