diff options
author | Hugo Arès <hugo.ares@ericsson.com> | 2016-11-30 15:57:08 -0500 |
---|---|---|
committer | David Ostrovsky <david.ostrovsky@gmail.com> | 2016-12-23 05:17:33 +0000 |
commit | b21e318bc6ea811b80ae5a14795b6e8f2fbbf065 (patch) | |
tree | 6530e9b78874b01c8eab1eee6f134f5fdd07a528 | |
parent | a2a82fa11076e68af370905ec327f51c30f783ce (diff) |
Do not check visibility of parent when creating project
A project can be visible to a user but not necessarily its parent. To
be consistent, a user with create-project permission should be able to
create a project with a parent that exists even if the parent is not
visible to the user.
Here is an example when this case is happening. On a Gerrit server where
All-projects is only visible to administrators and create-project
permission is granted to non-administrators, when a non-administrator
tries to create a project with All-Projects (which is the default when
parent is not specified) as its parent, it was failing before this
change with "Not found: All-Projects".
Change-Id: Id93370ab108f377f643b55efdf781dfd2c66f220
3 files changed, 44 insertions, 5 deletions
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java index 37d350a4ba..1d659cc33a 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java @@ -274,6 +274,26 @@ public class CreateProjectIT extends AbstractDaemonTest { assertCreateFails(in, ResourceConflictException.class); } + @Test + public void testCreateProjectWithCreateProjectCapabilityAndParentNotVisible() + throws Exception { + Project parent = projectCache.get(allProjects).getProject(); + parent.setState(com.google.gerrit.extensions.client.ProjectState.HIDDEN); + allowGlobalCapabilities(SystemGroupBackend.REGISTERED_USERS, + GlobalCapability.CREATE_PROJECT); + try { + setApiUser(user); + ProjectInput in = new ProjectInput(); + in.name = name("newProject"); + ProjectInfo p = gApi.projects().create(in).get(); + assertThat(p.name).isEqualTo(in.name); + } finally { + parent.setState(com.google.gerrit.extensions.client.ProjectState.ACTIVE); + removeGlobalCapabilities(SystemGroupBackend.REGISTERED_USERS, + GlobalCapability.CREATE_PROJECT); + } + } + private AccountGroup.UUID groupUuid(String groupName) { return groupCache.get(new AccountGroup.NameKey(groupName)).getGroupUUID(); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java index 41bc288d8f..c04878f1d2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java @@ -161,7 +161,8 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn String parentName = MoreObjects.firstNonNull( Strings.emptyToNull(input.parent), allProjects.get()); - args.newParent = projectsCollection.get().parse(parentName).getControl(); + args.newParent = + projectsCollection.get().parse(parentName, false).getControl(); args.createEmptyCommit = input.createEmptyCommit; args.permissionsOnly = input.permissionsOnly; args.projectDescription = Strings.emptyToNull(input.description); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java index 0ffbe3e60f..51603fcb25 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectsCollection.java @@ -63,7 +63,7 @@ public class ProjectsCollection implements @Override public ProjectResource parse(TopLevelResource parent, IdString id) throws ResourceNotFoundException, IOException { - ProjectResource rsrc = _parse(id.get()); + ProjectResource rsrc = _parse(id.get(), true); if (rsrc == null) { throw new ResourceNotFoundException(id); } @@ -81,7 +81,24 @@ public class ProjectsCollection implements */ public ProjectResource parse(String id) throws UnprocessableEntityException, IOException { - ProjectResource rsrc = _parse(id); + return parse(id, true); + } + + /** + * Parses a project ID from a request body and returns the project. + * + * @param id ID of the project, can be a project name + * @param checkVisibility Whether to check or not that project is visible to + * the calling user + * @return the project + * @throws UnprocessableEntityException thrown if the project ID cannot be + * resolved or if the project is not visible to the calling user and + * checkVisibility is true. + * @throws IOException thrown when there is an error. + */ + public ProjectResource parse(String id, boolean checkVisibility) + throws UnprocessableEntityException, IOException { + ProjectResource rsrc = _parse(id, checkVisibility); if (rsrc == null) { throw new UnprocessableEntityException(String.format( "Project Not Found: %s", id)); @@ -89,7 +106,8 @@ public class ProjectsCollection implements return rsrc; } - private ProjectResource _parse(String id) throws IOException { + private ProjectResource _parse(String id, boolean checkVisibility) + throws IOException { if (id.endsWith(Constants.DOT_GIT_EXT)) { id = id.substring(0, id.length() - Constants.DOT_GIT_EXT.length()); } @@ -101,7 +119,7 @@ public class ProjectsCollection implements } catch (NoSuchProjectException e) { return null; } - if (!ctl.isVisible() && !ctl.isOwner()) { + if (checkVisibility && !ctl.isVisible() && !ctl.isOwner()) { return null; } return new ProjectResource(ctl); |