Merge branch 'stable-2.14' into stable-2.15 * stable-2.14: Upgrade bazlets to latest stable-2.14 to build with 2.14.21 API Change-Id: Icf7724472e86f97bc24eab60b9f0c4dde078bc77
diff --git a/.gitignore b/.gitignore index 72f041f..92c26ce 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,6 +1,9 @@ +# `LC_COLLATE=C sort` +/.apt_generated/ /.classpath /.primary_build_tool /.project /.settings/ /bazel-* +/bin/ /eclipse-out/
diff --git a/WORKSPACE b/WORKSPACE index 688fb8a..617504a 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -3,7 +3,7 @@ load("//:bazlets.bzl", "load_bazlets") load_bazlets( - commit = "78c35a7eb33ee5ea0980923e246c7dba37347193", + commit = "f53f51fb660552d0581aa0ba52c3836ed63d56a3", #local_path = "/home/<user>/projects/bazlets", )
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java index 17dedb6..4df4f25 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java +++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
@@ -26,6 +26,7 @@ import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.git.MetaDataUpdate; import com.google.gerrit.server.git.ProjectConfig; +import com.google.gerrit.server.group.InternalGroup; import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.RefPattern; @@ -34,6 +35,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Arrays; +import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; import org.eclipse.jgit.errors.ConfigInvalidException; @@ -143,7 +145,10 @@ private String getOwnerGroupName(ProjectState project) { Set<AccountGroup.UUID> owners = project.getAllOwners(); if (!owners.isEmpty()) { - return groupCache.get(owners.iterator().next()).getName(); + Optional<InternalGroup> owner = groupCache.get(owners.iterator().next()); + if (owner.isPresent()) { + return owner.get().getName(); + } } return String.format("no owners for project %s", project.getProject().getName()); } @@ -183,13 +188,14 @@ // this means that group is not already in the groups file, so // we need to check if group exist if if it does, get its // uuid. - AccountGroup group = groupCache.get(new AccountGroup.NameKey(rule.getGroup().getName())); + Optional<InternalGroup> group = + groupCache.get(new AccountGroup.NameKey(rule.getGroup().getName())); - if (group == null) { + if (!group.isPresent()) { log.error("Group {} not found", rule.getGroup().getName()); continue; } - rule.getGroup().setUUID(group.getGroupUUID()); + rule.getGroup().setUUID(group.get().getGroupUUID()); } perm.add(rule); }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java index 278987c..347244b 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java +++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
@@ -21,15 +21,20 @@ import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.api.groups.GroupInput; import com.google.gerrit.extensions.common.GroupInfo; +import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.TopLevelResource; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.config.AllProjectsNameProvider; import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gerrit.server.group.CreateGroup; +import com.google.gerrit.server.permissions.GlobalPermission; +import com.google.gerrit.server.permissions.PermissionBackend; +import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.project.CreateProjectArgs; import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectControl; @@ -37,8 +42,10 @@ import com.google.gerrit.server.validators.ValidationException; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; +import org.eclipse.jgit.errors.ConfigInvalidException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +66,10 @@ "Project name cannot contains spaces." + SEE_DOCUMENTATION_MSG; private static final String ROOT_PROJECT_CANNOT_CONTAINS_SLASHES_MSG = - "Root project name cannot contains slashes." + SEE_DOCUMENTATION_MSG; + "Since the \"Rights Inherit From\" field is empty, " + + "\"%s\" is considered a root project whose parent is \"%s\". " + + "Root project names cannot contain slashes." + + SEE_DOCUMENTATION_MSG; private static final String REGULAR_PROJECT_NOT_ALLOWED_AS_ROOT_MSG = "Regular projects are not allowed as root.\n\n" @@ -82,21 +92,30 @@ private final CreateGroup.Factory createGroupFactory; private final String documentationUrl; private final AllProjectsNameProvider allProjectsName; + private final Provider<CurrentUser> self; + private final PermissionBackend permissionBackend; private final PluginConfigFactory cfg; private final String pluginName; + private final ProjectControl.GenericFactory projectControlFactory; @Inject public ProjectCreationValidator( CreateGroup.Factory createGroupFactory, @PluginCanonicalWebUrl String url, AllProjectsNameProvider allProjectsName, + Provider<CurrentUser> self, + PermissionBackend permissionBackend, PluginConfigFactory cfg, - @PluginName String pluginName) { + @PluginName String pluginName, + ProjectControl.GenericFactory projectControlFactory) { this.createGroupFactory = createGroupFactory; this.documentationUrl = url + "Documentation/index.html"; this.allProjectsName = allProjectsName; + this.self = self; + this.permissionBackend = permissionBackend; this.cfg = cfg; this.pluginName = pluginName; + this.projectControlFactory = projectControlFactory; } @Override @@ -108,14 +127,30 @@ String.format(PROJECT_CANNOT_CONTAINS_SPACES_MSG, documentationUrl)); } - ProjectControl parentCtrl = args.newParent; - if (parentCtrl.getUser().getCapabilities().canAdministrateServer()) { + ProjectControl parentCtrl; + try { + parentCtrl = projectControlFactory.controlFor(args.newParent, self.get()); + } catch (NoSuchProjectException | IOException e) { + log.error( + "Failed to create project {}; Cannot retrieve info about parent project {}: {}", + name, + args.newParent.get(), + e.getMessage(), + e); + throw new ValidationException(AN_ERROR_OCCURRED_MSG); + } + + try { + permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER); + // Admins can bypass any rules to support creating projects that doesn't // comply with the new naming rules. New projects structures have to // comply but we need to be able to add new project to an existing non // compliant structure. log.debug("admin is creating project, bypassing all rules"); return; + } catch (AuthException | PermissionBackendException e) { + // continuing } if (allProjectsName.get().equals(parentCtrl.getProject().getNameKey())) { @@ -171,7 +206,7 @@ .apply(TopLevelResource.INSTANCE, new GroupInput()); } return AccountGroup.UUID.parse(groupInfo.id); - } catch (RestApiException | OrmException | IOException e) { + } catch (RestApiException | OrmException | IOException | ConfigInvalidException e) { log.error("Failed to create project {}: {}", name, e.getMessage(), e); throw new ValidationException(AN_ERROR_OCCURRED_MSG); } @@ -182,7 +217,11 @@ if (name.contains("/")) { log.debug("rejecting creation of {}: name contains slashes", name); throw new ValidationException( - String.format(ROOT_PROJECT_CANNOT_CONTAINS_SLASHES_MSG, documentationUrl)); + String.format( + ROOT_PROJECT_CANNOT_CONTAINS_SLASHES_MSG, + name, + allProjectsName.get(), + documentationUrl)); } if (!permissionOnly) { log.debug("rejecting creation of {}: missing permissions only option", name);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java index 8ea7dc6..8f53648 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java +++ b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
@@ -81,7 +81,7 @@ // Creation is rejected when root project name contains slashes RestResponse r = userRestSession.put("/projects/" + Url.encode("a/parentProject"), in); r.assertConflict(); - assertThat(r.getEntityContent()).contains("Root project name cannot contains slashes"); + assertThat(r.getEntityContent()).contains("Root project names cannot contain slashes"); } @Test @@ -162,7 +162,8 @@ ProjectState projectState = projectCache.get(new Project.NameKey(rootProject)); assertThat(projectState.getOwners().size()).isEqualTo(1); assertThat(projectState.getOwners()) - .contains(groupCache.get(new AccountGroup.NameKey(rootProject + "-admins")).getGroupUUID()); + .contains( + groupCache.get(new AccountGroup.NameKey(rootProject + "-admins")).get().getGroupUUID()); // case when <project-name>-admins group already exists rootProject = name("rootProject2"); @@ -179,7 +180,8 @@ .toString() .substring(0, 7); assertThat(projectState.getOwners()) - .contains(groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).getGroupUUID()); + .contains( + groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).get().getGroupUUID()); } @Test @@ -250,7 +252,10 @@ assertThat(projectState.getOwners().size()).isEqualTo(1); assertThat(projectState.getOwners()) .contains( - groupCache.get(new AccountGroup.NameKey(childProject + "-admins")).getGroupUUID()); + groupCache + .get(new AccountGroup.NameKey(childProject + "-admins")) + .get() + .getGroupUUID()); // case when <project-name>-admins group already exists String childProject2 = parent + "/childProject2"; @@ -267,7 +272,8 @@ .toString() .substring(0, 7); assertThat(projectState.getOwners()) - .contains(groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).getGroupUUID()); + .contains( + groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).get().getGroupUUID()); } @Test
diff --git a/tools/BUILD b/tools/BUILD new file mode 100644 index 0000000..c5ed0b7 --- /dev/null +++ b/tools/BUILD
@@ -0,0 +1 @@ +# Empty file required by Bazel
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh index be0fd7a..9cdbc95 100755 --- a/tools/eclipse/project.sh +++ b/tools/eclipse/project.sh
@@ -12,4 +12,7 @@ # 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. -`bazel query @com_googlesource_gerrit_bazlets//tools/eclipse:project --output location | sed s/BUILD:.*//`project.py -n project-group-structure -r . + +path=$(bazel query @com_googlesource_gerrit_bazlets//tools/eclipse:project \ + --output location | sed s/BUILD:.*//) +${path}project.py -n project-group-structure -r . "$@"