Search in sources :

Example 1 with PermissionBackendException

use of com.google.gerrit.server.permissions.PermissionBackendException in project gerrit by GerritCodeReview.

the class PostReview method apply.

public Response<ReviewResult> apply(BatchUpdate.Factory updateFactory, RevisionResource revision, ReviewInput input, Timestamp ts) throws RestApiException, UpdateException, OrmException, IOException, PermissionBackendException {
    // Respect timestamp, but truncate at change created-on time.
    ts = Ordering.natural().max(ts, revision.getChange().getCreatedOn());
    if (revision.getEdit().isPresent()) {
        throw new ResourceConflictException("cannot post review on edit");
    }
    if (input.onBehalfOf != null) {
        revision = onBehalfOf(revision, input);
    } else if (input.drafts == null) {
        input.drafts = DraftHandling.DELETE;
    }
    if (input.labels != null) {
        checkLabels(revision, input.strictLabels, input.labels);
    }
    if (input.comments != null) {
        cleanUpComments(input.comments);
        checkComments(revision, input.comments);
    }
    if (input.robotComments != null) {
        if (!migration.readChanges()) {
            throw new MethodNotAllowedException("robot comments not supported");
        }
        checkRobotComments(revision, input.robotComments);
    }
    if (input.notify == null) {
        log.warn("notify = null; assuming notify = NONE");
        input.notify = NotifyHandling.NONE;
    }
    ListMultimap<RecipientType, Account.Id> accountsToNotify = notifyUtil.resolveAccounts(input.notifyDetails);
    Map<String, AddReviewerResult> reviewerJsonResults = null;
    List<PostReviewers.Addition> reviewerResults = Lists.newArrayList();
    boolean hasError = false;
    boolean confirm = false;
    if (input.reviewers != null) {
        reviewerJsonResults = Maps.newHashMap();
        for (AddReviewerInput reviewerInput : input.reviewers) {
            // Prevent notifications because setting reviewers is batched.
            reviewerInput.notify = NotifyHandling.NONE;
            PostReviewers.Addition result = postReviewers.prepareApplication(revision.getChangeResource(), reviewerInput, true);
            reviewerJsonResults.put(reviewerInput.reviewer, result.result);
            if (result.result.error != null) {
                hasError = true;
                continue;
            }
            if (result.result.confirm != null) {
                confirm = true;
                continue;
            }
            reviewerResults.add(result);
        }
    }
    ReviewResult output = new ReviewResult();
    output.reviewers = reviewerJsonResults;
    if (hasError || confirm) {
        return Response.withStatusCode(SC_BAD_REQUEST, output);
    }
    output.labels = input.labels;
    try (BatchUpdate bu = updateFactory.create(db.get(), revision.getChange().getProject(), revision.getUser(), ts)) {
        Account.Id id = revision.getUser().getAccountId();
        boolean ccOrReviewer = false;
        if (input.labels != null && !input.labels.isEmpty()) {
            ccOrReviewer = input.labels.values().stream().filter(v -> v != 0).findFirst().isPresent();
        }
        if (!ccOrReviewer) {
            // Check if user was already CCed or reviewing prior to this review.
            ReviewerSet currentReviewers = approvalsUtil.getReviewers(db.get(), revision.getChangeResource().getNotes());
            ccOrReviewer = currentReviewers.all().contains(id);
        }
        // themselves as a reviewer or to the CC list.
        for (PostReviewers.Addition reviewerResult : reviewerResults) {
            bu.addOp(revision.getChange().getId(), reviewerResult.op);
            if (!ccOrReviewer && reviewerResult.result.reviewers != null) {
                for (ReviewerInfo reviewerInfo : reviewerResult.result.reviewers) {
                    if (Objects.equals(id.get(), reviewerInfo._accountId)) {
                        ccOrReviewer = true;
                        break;
                    }
                }
            }
            if (!ccOrReviewer && reviewerResult.result.ccs != null) {
                for (AccountInfo accountInfo : reviewerResult.result.ccs) {
                    if (Objects.equals(id.get(), accountInfo._accountId)) {
                        ccOrReviewer = true;
                        break;
                    }
                }
            }
        }
        if (!ccOrReviewer) {
            // User posting this review isn't currently in the reviewer or CC list,
            // isn't being explicitly added, and isn't voting on any label.
            // Automatically CC them on this change so they receive replies.
            PostReviewers.Addition selfAddition = postReviewers.ccCurrentUser(revision.getUser(), revision);
            bu.addOp(revision.getChange().getId(), selfAddition.op);
        }
        bu.addOp(revision.getChange().getId(), new Op(revision.getPatchSet().getId(), input, accountsToNotify));
        bu.execute();
        for (PostReviewers.Addition reviewerResult : reviewerResults) {
            reviewerResult.gatherResults();
        }
        emailReviewers(revision.getChange(), reviewerResults, input.notify, accountsToNotify);
    }
    return Response.ok(output);
}
Also used : ON_BEHALF_OF(com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF) ListMultimap(com.google.common.collect.ListMultimap) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) PatchSetApproval(com.google.gerrit.reviewdb.client.PatchSetApproval) ReviewerSet(com.google.gerrit.server.ReviewerSet) Config(org.eclipse.jgit.lib.Config) Map(java.util.Map) RetryHelper(com.google.gerrit.server.update.RetryHelper) DraftHandling(com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling) Side(com.google.gerrit.extensions.client.Side) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) ChangeMessage(com.google.gerrit.reviewdb.client.ChangeMessage) Set(java.util.Set) Collectors.joining(java.util.stream.Collectors.joining) StandardCharsets(java.nio.charset.StandardCharsets) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) CommentAdded(com.google.gerrit.server.extensions.events.CommentAdded) AutoValue(com.google.auto.value.AutoValue) LabelId(com.google.gerrit.reviewdb.client.LabelId) NotesMigration(com.google.gerrit.server.notedb.NotesMigration) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) ReviewDb(com.google.gerrit.reviewdb.server.ReviewDb) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) Change(com.google.gerrit.reviewdb.client.Change) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) CommentsUtil(com.google.gerrit.server.CommentsUtil) Response(com.google.gerrit.extensions.restapi.Response) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) Lists(com.google.common.collect.Lists) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) REVIEWER(com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER) HashCode(com.google.common.hash.HashCode) PatchListCache(com.google.gerrit.server.patch.PatchListCache) TimeUtil(com.google.gerrit.common.TimeUtil) MoreObjects(com.google.common.base.MoreObjects) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) CommentsUtil.setCommentRevId(com.google.gerrit.server.CommentsUtil.setCommentRevId) RobotCommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) ReviewInput(com.google.gerrit.extensions.api.changes.ReviewInput) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) LabelVote(com.google.gerrit.server.util.LabelVote) SC_BAD_REQUEST(javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST) ChangeControl(com.google.gerrit.server.project.ChangeControl) AddReviewerResult(com.google.gerrit.extensions.api.changes.AddReviewerResult) OrmException(com.google.gwtorm.server.OrmException) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) UpdateException(com.google.gerrit.server.update.UpdateException) Comment(com.google.gerrit.reviewdb.client.Comment) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) AccountInfo(com.google.gerrit.extensions.common.AccountInfo) Gson(com.google.gson.Gson) AuthException(com.google.gerrit.extensions.restapi.AuthException) Context(com.google.gerrit.server.update.Context) RetryingRestModifyView(com.google.gerrit.server.update.RetryingRestModifyView) Collectors.toSet(java.util.stream.Collectors.toSet) ReviewerInfo(com.google.gerrit.extensions.api.changes.ReviewerInfo) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) LabelType(com.google.gerrit.common.data.LabelType) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Status(com.google.gerrit.reviewdb.client.PatchLineComment.Status) AccountsCollection(com.google.gerrit.server.account.AccountsCollection) LabelTypes(com.google.gerrit.common.data.LabelTypes) AddReviewerInput(com.google.gerrit.extensions.api.changes.AddReviewerInput) FixSuggestionInfo(com.google.gerrit.extensions.common.FixSuggestionInfo) Url(com.google.gerrit.extensions.restapi.Url) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) RobotComment(com.google.gerrit.reviewdb.client.RobotComment) LabelPermission(com.google.gerrit.server.permissions.LabelPermission) FixSuggestion(com.google.gerrit.reviewdb.client.FixSuggestion) ChangePermission(com.google.gerrit.server.permissions.ChangePermission) Hashing(com.google.common.hash.Hashing) ReviewerState(com.google.gerrit.extensions.client.ReviewerState) Patch(com.google.gerrit.reviewdb.client.Patch) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) HashSet(java.util.HashSet) CommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput) Range(com.google.gerrit.extensions.client.Comment.Range) Account(com.google.gerrit.reviewdb.client.Account) ChangeUtil(com.google.gerrit.server.ChangeUtil) OutputFormat(com.google.gerrit.server.OutputFormat) ChangeContext(com.google.gerrit.server.update.ChangeContext) FixReplacementInfo(com.google.gerrit.extensions.common.FixReplacementInfo) CurrentUser(com.google.gerrit.server.CurrentUser) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) UTF_8(java.nio.charset.StandardCharsets.UTF_8) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) FixReplacement(com.google.gerrit.reviewdb.client.FixReplacement) Maps(com.google.common.collect.Maps) ApprovalsUtil(com.google.gerrit.server.ApprovalsUtil) Collectors.toList(java.util.stream.Collectors.toList) Address(com.google.gerrit.server.mail.Address) Provider(com.google.inject.Provider) Ordering(com.google.common.collect.Ordering) RecipientType(com.google.gerrit.extensions.api.changes.RecipientType) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PatchSetUtil(com.google.gerrit.server.PatchSetUtil) Collections(java.util.Collections) Account(com.google.gerrit.reviewdb.client.Account) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) RecipientType(com.google.gerrit.extensions.api.changes.RecipientType) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) AddReviewerResult(com.google.gerrit.extensions.api.changes.AddReviewerResult) ReviewerSet(com.google.gerrit.server.ReviewerSet) LabelId(com.google.gerrit.reviewdb.client.LabelId) CommentsUtil.setCommentRevId(com.google.gerrit.server.CommentsUtil.setCommentRevId) AccountInfo(com.google.gerrit.extensions.common.AccountInfo) AddReviewerInput(com.google.gerrit.extensions.api.changes.AddReviewerInput) ReviewerInfo(com.google.gerrit.extensions.api.changes.ReviewerInfo)

Example 2 with PermissionBackendException

use of com.google.gerrit.server.permissions.PermissionBackendException in project gerrit by GerritCodeReview.

the class ReceiveCommits method parseCommands.

private void parseCommands(Collection<ReceiveCommand> commands) throws PermissionBackendException {
    List<String> optionList = rp.getPushOptions();
    if (optionList != null) {
        for (String option : optionList) {
            int e = option.indexOf('=');
            if (e > 0) {
                pushOptions.put(option.substring(0, e), option.substring(e + 1));
            } else {
                pushOptions.put(option, "");
            }
        }
    }
    logDebug("Parsing {} commands", commands.size());
    for (ReceiveCommand cmd : commands) {
        if (cmd.getResult() != NOT_ATTEMPTED) {
            // Already rejected by the core receive process.
            logDebug("Already processed by core: {} {}", cmd.getResult(), cmd);
            continue;
        }
        if (!Repository.isValidRefName(cmd.getRefName()) || cmd.getRefName().contains("//")) {
            reject(cmd, "not valid ref");
            continue;
        }
        if (MagicBranch.isMagicBranch(cmd.getRefName())) {
            parseMagicBranch(cmd);
            continue;
        }
        if (projectControl.getProjectState().isAllUsers() && RefNames.REFS_USERS_SELF.equals(cmd.getRefName())) {
            String newName = RefNames.refsUsers(user.getAccountId());
            logDebug("Swapping out command for {} to {}", RefNames.REFS_USERS_SELF, newName);
            final ReceiveCommand orgCmd = cmd;
            cmd = new ReceiveCommand(cmd.getOldId(), cmd.getNewId(), newName, 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());
        if (m.matches()) {
            // The referenced change must exist and must still be open.
            //
            Change.Id changeId = Change.Id.parse(m.group(1));
            parseReplaceCommand(cmd, changeId);
            continue;
        }
        switch(cmd.getType()) {
            case CREATE:
                parseCreate(cmd);
                break;
            case UPDATE:
                parseUpdate(cmd);
                break;
            case DELETE:
                parseDelete(cmd);
                break;
            case UPDATE_NONFASTFORWARD:
                parseRewind(cmd);
                break;
            default:
                reject(cmd, "prohibited by Gerrit: unknown command type " + cmd.getType());
                continue;
        }
        if (cmd.getResult() != NOT_ATTEMPTED) {
            continue;
        }
        if (isConfig(cmd)) {
            logDebug("Processing {} command", cmd.getRefName());
            if (!projectControl.isOwner()) {
                reject(cmd, "not project owner");
                continue;
            }
            switch(cmd.getType()) {
                case CREATE:
                case UPDATE:
                case UPDATE_NONFASTFORWARD:
                    try {
                        ProjectConfig cfg = new ProjectConfig(project.getNameKey());
                        cfg.load(rp.getRevWalk(), cmd.getNewId());
                        if (!cfg.getValidationErrors().isEmpty()) {
                            addError("Invalid project configuration:");
                            for (ValidationError err : cfg.getValidationErrors()) {
                                addError("  " + err.getMessage());
                            }
                            reject(cmd, "invalid project configuration");
                            logError("User " + user.getUserName() + " tried to push invalid project configuration " + cmd.getNewId().name() + " for " + project.getName());
                            continue;
                        }
                        Project.NameKey newParent = cfg.getProject().getParent(allProjectsName);
                        Project.NameKey oldParent = project.getParent(allProjectsName);
                        if (oldParent == null) {
                            // update of the 'All-Projects' project
                            if (newParent != null) {
                                reject(cmd, "invalid project configuration: root project cannot have parent");
                                continue;
                            }
                        } else {
                            if (!oldParent.equals(newParent)) {
                                try {
                                    permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
                                } catch (AuthException e) {
                                    reject(cmd, "invalid project configuration: only Gerrit admin can set parent");
                                    continue;
                                }
                            }
                            if (projectCache.get(newParent) == null) {
                                reject(cmd, "invalid project configuration: parent does not exist");
                                continue;
                            }
                        }
                        for (Entry<ProjectConfigEntry> e : pluginConfigEntries) {
                            PluginConfig pluginCfg = cfg.getPluginConfig(e.getPluginName());
                            ProjectConfigEntry configEntry = e.getProvider().get();
                            String value = pluginCfg.getString(e.getExportName());
                            String oldValue = projectControl.getProjectState().getConfig().getPluginConfig(e.getPluginName()).getString(e.getExportName());
                            if (configEntry.getType() == ProjectConfigEntryType.ARRAY) {
                                oldValue = Arrays.stream(projectControl.getProjectState().getConfig().getPluginConfig(e.getPluginName()).getStringList(e.getExportName())).collect(joining("\n"));
                            }
                            if ((value == null ? oldValue != null : !value.equals(oldValue)) && !configEntry.isEditable(projectControl.getProjectState())) {
                                reject(cmd, String.format("invalid project configuration: Not allowed to set parameter" + " '%s' of plugin '%s' on project '%s'.", e.getExportName(), e.getPluginName(), project.getName()));
                                continue;
                            }
                            if (ProjectConfigEntryType.LIST.equals(configEntry.getType()) && value != null && !configEntry.getPermittedValues().contains(value)) {
                                reject(cmd, String.format("invalid project configuration: The value '%s' is " + "not permitted for parameter '%s' of plugin '%s'.", value, e.getExportName(), e.getPluginName()));
                            }
                        }
                    } catch (Exception e) {
                        reject(cmd, "invalid project configuration");
                        logError("User " + user.getUserName() + " tried to push invalid project configuration " + cmd.getNewId().name() + " for " + project.getName(), e);
                        continue;
                    }
                    break;
                case DELETE:
                    break;
                default:
                    reject(cmd, "prohibited by Gerrit: don't know how to handle config update of type " + cmd.getType());
                    continue;
            }
        }
    }
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) Matcher(java.util.regex.Matcher) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) RefOperationValidationException(com.google.gerrit.server.git.validators.RefOperationValidationException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) OrmException(com.google.gwtorm.server.OrmException) MissingObjectException(org.eclipse.jgit.errors.MissingObjectException) UpdateException(com.google.gerrit.server.update.UpdateException) AuthException(com.google.gerrit.extensions.restapi.AuthException) CmdLineException(org.kohsuke.args4j.CmdLineException) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) CommitValidationException(com.google.gerrit.server.git.validators.CommitValidationException) ServiceMayNotContinueException(org.eclipse.jgit.transport.ServiceMayNotContinueException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Result(org.eclipse.jgit.transport.ReceiveCommand.Result) PluginConfig(com.google.gerrit.server.config.PluginConfig) Project(com.google.gerrit.reviewdb.client.Project) ProjectConfigEntry(com.google.gerrit.server.config.ProjectConfigEntry)

Example 3 with PermissionBackendException

use of com.google.gerrit.server.permissions.PermissionBackendException in project gerrit by GerritCodeReview.

the class ProjectControlHandler method parseArguments.

@Override
public final int parseArguments(final Parameters params) throws CmdLineException {
    String projectName = params.getParameter(0);
    while (projectName.endsWith("/")) {
        projectName = projectName.substring(0, projectName.length() - 1);
    }
    while (projectName.startsWith("/")) {
        // Be nice and drop the leading "/" if supplied by an absolute path.
        // We don't have a file system hierarchy, just a flat namespace in
        // the database's Project entities. We never encode these with a
        // leading '/' but users might accidentally include them in Git URLs.
        //
        projectName = projectName.substring(1);
    }
    String nameWithoutSuffix = ProjectUtil.stripGitSuffix(projectName);
    Project.NameKey nameKey = new Project.NameKey(nameWithoutSuffix);
    ProjectControl control;
    try {
        control = projectControlFactory.controlFor(nameKey, user.get());
        permissionBackend.user(user).project(nameKey).check(ProjectPermission.ACCESS);
    } catch (AuthException e) {
        throw new CmdLineException(owner, new NoSuchProjectException(nameKey).getMessage());
    } catch (NoSuchProjectException e) {
        throw new CmdLineException(owner, e.getMessage());
    } catch (PermissionBackendException | IOException e) {
        log.warn("Cannot load project " + nameWithoutSuffix, e);
        throw new CmdLineException(owner, new NoSuchProjectException(nameKey).getMessage());
    }
    setter.addValue(control);
    return 1;
}
Also used : Project(com.google.gerrit.reviewdb.client.Project) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) AuthException(com.google.gerrit.extensions.restapi.AuthException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) IOException(java.io.IOException) ProjectControl(com.google.gerrit.server.project.ProjectControl) CmdLineException(org.kohsuke.args4j.CmdLineException)

Example 4 with PermissionBackendException

use of com.google.gerrit.server.permissions.PermissionBackendException in project gerrit by GerritCodeReview.

the class ChangeJson method format.

private ChangeInfo format(ChangeData cd, Optional<PatchSet.Id> limitToPsId, boolean fillAccountLoader) throws OrmException {
    try {
        if (fillAccountLoader) {
            accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS));
            ChangeInfo res = toChangeInfo(cd, limitToPsId);
            accountLoader.fill();
            return res;
        }
        return toChangeInfo(cd, limitToPsId);
    } catch (PatchListNotAvailableException | GpgException | OrmException | IOException | PermissionBackendException | RuntimeException e) {
        if (!has(CHECK)) {
            Throwables.throwIfInstanceOf(e, OrmException.class);
            throw new OrmException(e);
        }
        return checkOnly(cd);
    }
}
Also used : GpgException(com.google.gerrit.server.GpgException) ChangeInfo(com.google.gerrit.extensions.common.ChangeInfo) OrmException(com.google.gwtorm.server.OrmException) PatchListNotAvailableException(com.google.gerrit.server.patch.PatchListNotAvailableException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) IOException(java.io.IOException)

Example 5 with PermissionBackendException

use of com.google.gerrit.server.permissions.PermissionBackendException in project gerrit by GerritCodeReview.

the class AdminSetParent method run.

@Override
protected void run() throws Failure {
    if (oldParent == null && children.isEmpty()) {
        throw die("child projects have to be specified as " + "arguments or the --children-of option has to be set");
    }
    if (oldParent == null && !excludedChildren.isEmpty()) {
        throw die("--exclude can only be used together with --children-of");
    }
    final StringBuilder err = new StringBuilder();
    final Set<Project.NameKey> grandParents = new HashSet<>();
    grandParents.add(allProjectsName);
    if (newParent != null) {
        newParentKey = newParent.getProject().getNameKey();
        // Catalog all grandparents of the "parent", we want to
        // catch a cycle in the parent pointers before it occurs.
        //
        Project.NameKey gp = newParent.getProject().getParent();
        while (gp != null && grandParents.add(gp)) {
            final ProjectState s = projectCache.get(gp);
            if (s != null) {
                gp = s.getProject().getParent();
            } else {
                break;
            }
        }
    }
    final List<Project.NameKey> childProjects = new ArrayList<>();
    for (final ProjectControl pc : children) {
        childProjects.add(pc.getProject().getNameKey());
    }
    if (oldParent != null) {
        try {
            childProjects.addAll(getChildrenForReparenting(oldParent));
        } catch (PermissionBackendException e) {
            throw new Failure(1, "permissions unavailable", e);
        }
    }
    for (final Project.NameKey nameKey : childProjects) {
        final String name = nameKey.get();
        if (allProjectsName.equals(nameKey)) {
            // Don't allow the wild card project to have a parent.
            //
            err.append("error: Cannot set parent of '").append(name).append("'\n");
            continue;
        }
        if (grandParents.contains(nameKey) || nameKey.equals(newParentKey)) {
            // Try to avoid creating a cycle in the parent pointers.
            //
            err.append("error: Cycle exists between '").append(name).append("' and '").append(newParentKey != null ? newParentKey.get() : allProjectsName.get()).append("'\n");
            continue;
        }
        try (MetaDataUpdate md = metaDataUpdateFactory.create(nameKey)) {
            ProjectConfig config = ProjectConfig.read(md);
            config.getProject().setParentName(newParentKey);
            md.setMessage("Inherit access from " + (newParentKey != null ? newParentKey.get() : allProjectsName.get()) + "\n");
            config.commit(md);
        } catch (RepositoryNotFoundException notFound) {
            err.append("error: Project ").append(name).append(" not found\n");
        } catch (IOException | ConfigInvalidException e) {
            final String msg = "Cannot update project " + name;
            log.error(msg, e);
            err.append("error: ").append(msg).append("\n");
        }
        projectCache.evict(nameKey);
    }
    if (err.length() > 0) {
        while (err.charAt(err.length() - 1) == '\n') {
            err.setLength(err.length() - 1);
        }
        throw die(err.toString());
    }
}
Also used : ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) ArrayList(java.util.ArrayList) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) RepositoryNotFoundException(org.eclipse.jgit.errors.RepositoryNotFoundException) IOException(java.io.IOException) ProjectControl(com.google.gerrit.server.project.ProjectControl) ProjectConfig(com.google.gerrit.server.git.ProjectConfig) Project(com.google.gerrit.reviewdb.client.Project) ProjectState(com.google.gerrit.server.project.ProjectState) HashSet(java.util.HashSet) MetaDataUpdate(com.google.gerrit.server.git.MetaDataUpdate)

Aggregations

PermissionBackendException (com.google.gerrit.server.permissions.PermissionBackendException)23 IOException (java.io.IOException)13 AuthException (com.google.gerrit.extensions.restapi.AuthException)12 OrmException (com.google.gwtorm.server.OrmException)12 Project (com.google.gerrit.reviewdb.client.Project)10 CurrentUser (com.google.gerrit.server.CurrentUser)7 ChangeData (com.google.gerrit.server.query.change.ChangeData)7 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)6 RestApiException (com.google.gerrit.extensions.restapi.RestApiException)6 Change (com.google.gerrit.reviewdb.client.Change)6 ArrayList (java.util.ArrayList)6 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)5 HashSet (java.util.HashSet)5 MoreObjects (com.google.common.base.MoreObjects)4 Strings (com.google.common.base.Strings)4 ReviewDb (com.google.gerrit.reviewdb.server.ReviewDb)4 ChangeNotes (com.google.gerrit.server.notedb.ChangeNotes)4 PermissionBackend (com.google.gerrit.server.permissions.PermissionBackend)4 Inject (com.google.inject.Inject)4 Provider (com.google.inject.Provider)4