Search in sources :

Example 1 with Capable

use of com.google.gerrit.common.data.Capable in project gerrit by GerritCodeReview.

the class ProjectAccessHandler method call.

@Override
public final T call() throws NoSuchProjectException, IOException, ConfigInvalidException, InvalidNameException, NoSuchGroupException, OrmException, UpdateParentFailedException, PermissionDeniedException, PermissionBackendException {
    final ProjectControl projectControl = projectControlFactory.controlFor(projectName);
    Capable r = projectControl.canPushToAtLeastOneRef();
    if (r != Capable.OK) {
        throw new PermissionDeniedException(r.getMessage());
    }
    try (MetaDataUpdate md = metaDataUpdateFactory.create(projectName)) {
        ProjectConfig config = ProjectConfig.read(md, base);
        Set<String> toDelete = scanSectionNames(config);
        for (AccessSection section : mergeSections(sectionList)) {
            String name = section.getName();
            if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
                if (checkIfOwner && !projectControl.isOwner()) {
                    continue;
                }
                replace(config, toDelete, section);
            } else if (AccessSection.isValid(name)) {
                if (checkIfOwner && !projectControl.controlForRef(name).isOwner()) {
                    continue;
                }
                RefPattern.validate(name);
                replace(config, toDelete, section);
            }
        }
        for (String name : toDelete) {
            if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
                if (!checkIfOwner || projectControl.isOwner()) {
                    config.remove(config.getAccessSection(name));
                }
            } else if (!checkIfOwner || projectControl.controlForRef(name).isOwner()) {
                config.remove(config.getAccessSection(name));
            }
        }
        boolean parentProjectUpdate = false;
        if (!config.getProject().getNameKey().equals(allProjects) && !config.getProject().getParent(allProjects).equals(parentProjectName)) {
            parentProjectUpdate = true;
            try {
                setParent.get().validateParentUpdate(projectControl, MoreObjects.firstNonNull(parentProjectName, allProjects).get(), checkIfOwner);
            } catch (AuthException e) {
                throw new UpdateParentFailedException("You are not allowed to change the parent project since you are " + "not an administrator. You may save the modifications for review " + "so that an administrator can approve them.", e);
            } catch (ResourceConflictException | UnprocessableEntityException e) {
                throw new UpdateParentFailedException(e.getMessage(), e);
            }
            config.getProject().setParentName(parentProjectName);
        }
        if (message != null && !message.isEmpty()) {
            if (!message.endsWith("\n")) {
                message += "\n";
            }
            md.setMessage(message);
        } else {
            md.setMessage("Modify access rules\n");
        }
        return updateProjectConfig(projectControl, config, md, parentProjectUpdate);
    } catch (RepositoryNotFoundException notFound) {
        throw new NoSuchProjectException(projectName);
    }
}
Also used : UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) UpdateParentFailedException(com.google.gerrit.common.errors.UpdateParentFailedException) AuthException(com.google.gerrit.extensions.restapi.AuthException) RepositoryNotFoundException(org.eclipse.jgit.errors.RepositoryNotFoundException) ProjectControl(com.google.gerrit.server.project.ProjectControl) AccessSection(com.google.gerrit.common.data.AccessSection) ProjectConfig(com.google.gerrit.server.git.ProjectConfig) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Capable(com.google.gerrit.common.data.Capable) PermissionDeniedException(com.google.gerrit.common.errors.PermissionDeniedException) MetaDataUpdate(com.google.gerrit.server.git.MetaDataUpdate)

Example 2 with Capable

use of com.google.gerrit.common.data.Capable in project gerrit by GerritCodeReview.

the class CherryPickCommit method applyImpl.

@Override
public ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, CommitResource rsrc, CherryPickInput input) throws OrmException, IOException, UpdateException, RestApiException {
    RevCommit commit = rsrc.getCommit();
    String message = Strings.nullToEmpty(input.message).trim();
    input.message = message.isEmpty() ? commit.getFullMessage() : message;
    String destination = Strings.nullToEmpty(input.destination).trim();
    input.parent = input.parent == null ? 1 : input.parent;
    if (destination.isEmpty()) {
        throw new BadRequestException("destination must be non-empty");
    }
    ProjectControl projectControl = rsrc.getProject();
    Capable capable = projectControl.canPushToAtLeastOneRef();
    if (capable != Capable.OK) {
        throw new AuthException(capable.getMessage());
    }
    String refName = RefNames.fullName(destination);
    RefControl refControl = projectControl.controlForRef(refName);
    if (!refControl.canUpload()) {
        throw new AuthException("Not allowed to cherry pick " + commit + " to " + destination);
    }
    Project.NameKey project = projectControl.getProject().getNameKey();
    try {
        Change.Id cherryPickedChangeId = cherryPickChange.cherryPick(updateFactory, null, null, null, null, project, commit, input, refName, refControl);
        return json.noOptions().format(project, cherryPickedChangeId);
    } catch (InvalidChangeOperationException e) {
        throw new BadRequestException(e.getMessage());
    } catch (IntegrationException e) {
        throw new ResourceConflictException(e.getMessage());
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) IntegrationException(com.google.gerrit.server.git.IntegrationException) RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) ProjectControl(com.google.gerrit.server.project.ProjectControl) Project(com.google.gerrit.reviewdb.client.Project) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Capable(com.google.gerrit.common.data.Capable) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 3 with Capable

use of com.google.gerrit.common.data.Capable in project gerrit by GerritCodeReview.

the class CreateChange method applyImpl.

@Override
protected Response<ChangeInfo> applyImpl(BatchUpdate.Factory updateFactory, TopLevelResource parent, ChangeInput input) throws OrmException, IOException, InvalidChangeOperationException, RestApiException, UpdateException, PermissionBackendException {
    if (Strings.isNullOrEmpty(input.project)) {
        throw new BadRequestException("project must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.branch)) {
        throw new BadRequestException("branch must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.subject)) {
        throw new BadRequestException("commit message must be non-empty");
    }
    if (input.status != null) {
        if (input.status != ChangeStatus.NEW && input.status != ChangeStatus.DRAFT) {
            throw new BadRequestException("unsupported change status");
        }
        if (!allowDrafts && input.status == ChangeStatus.DRAFT) {
            throw new MethodNotAllowedException("draft workflow is disabled");
        }
    }
    String refName = RefNames.fullName(input.branch);
    ProjectResource rsrc = projectsCollection.parse(input.project);
    Capable r = rsrc.getControl().canPushToAtLeastOneRef();
    if (r != Capable.OK) {
        throw new AuthException(r.getMessage());
    }
    RefControl refControl = rsrc.getControl().controlForRef(refName);
    if (!refControl.canUpload() || !refControl.isVisible()) {
        throw new AuthException("cannot upload review");
    }
    Project.NameKey project = rsrc.getNameKey();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        ObjectId parentCommit;
        List<String> groups;
        if (input.baseChange != null) {
            List<ChangeControl> ctls = changeFinder.find(input.baseChange, rsrc.getControl().getUser());
            if (ctls.size() != 1) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            ChangeControl ctl = Iterables.getOnlyElement(ctls);
            if (!ctl.isVisible(db.get())) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
            parentCommit = ObjectId.fromString(ps.getRevision().get());
            groups = ps.getGroups();
        } else {
            Ref destRef = git.getRefDatabase().exactRef(refName);
            if (destRef != null) {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    throw new ResourceConflictException(String.format("Branch %s already exists.", refName));
                }
                parentCommit = destRef.getObjectId();
            } else {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    parentCommit = null;
                } else {
                    throw new UnprocessableEntityException(String.format("Branch %s does not exist.", refName));
                }
            }
            groups = Collections.emptyList();
        }
        RevCommit mergeTip = parentCommit == null ? null : rw.parseCommit(parentCommit);
        Timestamp now = TimeUtil.nowTs();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = me.newCommitterIdent(now, serverTimeZone);
        AccountState account = accountCache.get(me.getAccountId());
        GeneralPreferencesInfo info = account.getAccount().getGeneralPreferencesInfo();
        ObjectId treeId = mergeTip == null ? emptyTreeId(oi) : mergeTip.getTree();
        ObjectId id = ChangeIdUtil.computeChangeId(treeId, mergeTip, author, author, input.subject);
        String commitMessage = ChangeIdUtil.insertId(input.subject, id);
        if (Boolean.TRUE.equals(info.signedOffBy)) {
            commitMessage += String.format("%s%s", SIGNED_OFF_BY_TAG, account.getAccount().getNameEmail(anonymousCowardName));
        }
        RevCommit c;
        if (input.merge != null) {
            // create a merge commit
            if (!(submitType.equals(SubmitType.MERGE_ALWAYS) || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
                throw new BadRequestException("Submit type: " + submitType + " is not supported");
            }
            c = newMergeCommit(git, oi, rw, rsrc.getControl(), mergeTip, input.merge, author, commitMessage);
        } else {
            // create an empty commit
            c = newCommit(oi, rw, author, mergeTip, commitMessage);
        }
        Change.Id changeId = new Change.Id(seq.nextChangeId());
        ChangeInserter ins = changeInserterFactory.create(changeId, c, refName);
        ins.setMessage(String.format("Uploaded patch set %s.", ins.getPatchSetId().get()));
        String topic = input.topic;
        if (topic != null) {
            topic = Strings.emptyToNull(topic.trim());
        }
        ins.setTopic(topic);
        ins.setDraft(input.status == ChangeStatus.DRAFT);
        ins.setPrivate(input.isPrivate != null && input.isPrivate);
        ins.setWorkInProgress(input.workInProgress != null && input.workInProgress);
        ins.setGroups(groups);
        ins.setNotify(input.notify);
        ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
        try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.insertChange(ins);
            bu.execute();
        }
        ChangeJson json = jsonFactory.noOptions();
        return Response.created(json.format(ins.getChange()));
    } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Capable(com.google.gerrit.common.data.Capable) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ChangeControl(com.google.gerrit.server.project.ChangeControl) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) AccountState(com.google.gerrit.server.account.AccountState) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) GeneralPreferencesInfo(com.google.gerrit.extensions.client.GeneralPreferencesInfo) ProjectResource(com.google.gerrit.server.project.ProjectResource) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 4 with Capable

use of com.google.gerrit.common.data.Capable in project gerrit by GerritCodeReview.

the class MagicBranch method checkMagicBranchRef.

private static Capable checkMagicBranchRef(String branchName, Repository repo, Project project) {
    List<Ref> blockingFors;
    try {
        blockingFors = repo.getRefDatabase().getRefsByPrefix(branchName);
    } catch (IOException err) {
        String projName = project.getName();
        logger.atWarning().withCause(err).log("Cannot scan refs in '%s'", projName);
        return new Capable("Server process cannot read '" + projName + "'");
    }
    if (!blockingFors.isEmpty()) {
        String projName = project.getName();
        logger.atSevere().log("Repository '%s' needs the following refs removed to receive changes: %s", projName, blockingFors);
        return new Capable("One or more " + branchName + " names blocks change upload");
    }
    return Capable.OK;
}
Also used : Ref(org.eclipse.jgit.lib.Ref) Capable(com.google.gerrit.common.data.Capable) IOException(java.io.IOException)

Example 5 with Capable

use of com.google.gerrit.common.data.Capable in project gerrit by GerritCodeReview.

the class CherryPick method applyImpl.

@Override
protected ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, RevisionResource revision, CherryPickInput input) throws OrmException, IOException, UpdateException, RestApiException {
    final ChangeControl control = revision.getControl();
    input.parent = input.parent == null ? 1 : input.parent;
    if (input.message == null || input.message.trim().isEmpty()) {
        throw new BadRequestException("message must be non-empty");
    } else if (input.destination == null || input.destination.trim().isEmpty()) {
        throw new BadRequestException("destination must be non-empty");
    }
    if (!control.isVisible(dbProvider.get())) {
        throw new AuthException("Cherry pick not permitted");
    }
    ProjectControl projectControl = control.getProjectControl();
    Capable capable = projectControl.canPushToAtLeastOneRef();
    if (capable != Capable.OK) {
        throw new AuthException(capable.getMessage());
    }
    String refName = RefNames.fullName(input.destination);
    RefControl refControl = projectControl.controlForRef(refName);
    if (!refControl.canUpload()) {
        throw new AuthException("Not allowed to cherry pick " + revision.getChange().getId().toString() + " to " + input.destination);
    }
    try {
        Change.Id cherryPickedChangeId = cherryPickChange.cherryPick(updateFactory, revision.getChange(), revision.getPatchSet(), input, refName, refControl);
        return json.noOptions().format(revision.getProject(), cherryPickedChangeId);
    } catch (InvalidChangeOperationException e) {
        throw new BadRequestException(e.getMessage());
    } catch (IntegrationException | NoSuchChangeException e) {
        throw new ResourceConflictException(e.getMessage());
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) IntegrationException(com.google.gerrit.server.git.IntegrationException) RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) ProjectControl(com.google.gerrit.server.project.ProjectControl) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Capable(com.google.gerrit.common.data.Capable) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) ChangeControl(com.google.gerrit.server.project.ChangeControl) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException)

Aggregations

Capable (com.google.gerrit.common.data.Capable)9 AuthException (com.google.gerrit.extensions.restapi.AuthException)6 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)5 Change (com.google.gerrit.reviewdb.client.Change)4 ProjectControl (com.google.gerrit.server.project.ProjectControl)4 RefControl (com.google.gerrit.server.project.RefControl)4 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)3 UnprocessableEntityException (com.google.gerrit.extensions.restapi.UnprocessableEntityException)2 Project (com.google.gerrit.reviewdb.client.Project)2 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)2 IntegrationException (com.google.gerrit.server.git.IntegrationException)2 ChangeControl (com.google.gerrit.server.project.ChangeControl)2 InvalidChangeOperationException (com.google.gerrit.server.project.InvalidChangeOperationException)2 IOException (java.io.IOException)2 Ref (org.eclipse.jgit.lib.Ref)2 RevCommit (org.eclipse.jgit.revwalk.RevCommit)2 AccessSection (com.google.gerrit.common.data.AccessSection)1 ContributorAgreement (com.google.gerrit.common.data.ContributorAgreement)1 PermissionRule (com.google.gerrit.common.data.PermissionRule)1 PermissionDeniedException (com.google.gerrit.common.errors.PermissionDeniedException)1