Search in sources :

Example 1 with ReceiveHook

use of com.gitblit.extensions.ReceiveHook in project gitblit by gitblit.

the class GitblitReceivePack method onPostReceive.

/**
	 * Instrumentation point where the incoming push has been applied to the
	 * repository. This is the point where we would trigger a Jenkins build
	 * or send an email.
	 */
@Override
public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {
    if (commands.size() == 0) {
        LOGGER.debug("skipping post-receive processing, no refs created, updated, or removed");
        return;
    }
    logRefChange(commands);
    updateIncrementalPushTags(commands);
    updateGitblitRefLog(commands);
    // if the BranchTicketService is active it will reindex, as appropriate
    for (ReceiveCommand cmd : commands) {
        if (Result.OK.equals(cmd.getResult()) && BranchTicketService.BRANCH.equals(cmd.getRefName())) {
            rp.getRepository().fireEvent(new ReceiveCommandEvent(repository, cmd));
        }
    }
    // call post-receive plugins
    for (ReceiveHook hook : gitblit.getExtensions(ReceiveHook.class)) {
        try {
            hook.onPostReceive(this, commands);
        } catch (Exception e) {
            LOGGER.error("Failed to execute extension", e);
        }
    }
    // run Groovy hook scripts
    Set<String> scripts = new LinkedHashSet<String>();
    scripts.addAll(gitblit.getPostReceiveScriptsInherited(repository));
    if (!ArrayUtils.isEmpty(repository.postReceiveScripts)) {
        scripts.addAll(repository.postReceiveScripts);
    }
    runGroovy(commands, scripts);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) ReceiveHook(com.gitblit.extensions.ReceiveHook) PostReceiveHook(org.eclipse.jgit.transport.PostReceiveHook) PreReceiveHook(org.eclipse.jgit.transport.PreReceiveHook) IOException(java.io.IOException)

Example 2 with ReceiveHook

use of com.gitblit.extensions.ReceiveHook in project gitblit by gitblit.

the class GitblitReceivePack method onPreReceive.

/**
	 * Instrumentation point where the incoming push event has been parsed,
	 * validated, objects created BUT refs have not been updated. You might
	 * use this to enforce a branch-write permissions model.
	 */
@Override
public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {
    if (commands.size() == 0) {
        // no receive commands to process
        // this can happen if receive pack subclasses intercept and filter
        // the commands
        LOGGER.debug("skipping pre-receive processing, no refs created, updated, or removed");
        return;
    }
    if (repository.isMirror) {
        // repository is a mirror
        for (ReceiveCommand cmd : commands) {
            sendRejection(cmd, "Gitblit does not allow pushes to \"{0}\" because it is a mirror!", repository.name);
        }
        return;
    }
    if (repository.isFrozen) {
        // repository is frozen/readonly
        for (ReceiveCommand cmd : commands) {
            sendRejection(cmd, "Gitblit does not allow pushes to \"{0}\" because it is frozen!", repository.name);
        }
        return;
    }
    if (!repository.isBare) {
        // repository has a working copy
        for (ReceiveCommand cmd : commands) {
            sendRejection(cmd, "Gitblit does not allow pushes to \"{0}\" because it has a working copy!", repository.name);
        }
        return;
    }
    if (!canPush(commands)) {
        // user does not have push permissions
        for (ReceiveCommand cmd : commands) {
            sendRejection(cmd, "User \"{0}\" does not have push permissions for \"{1}\"!", user.username, repository.name);
        }
        return;
    }
    if (repository.accessRestriction.atLeast(AccessRestrictionType.PUSH) && repository.verifyCommitter) {
        // enforce committer verification
        if (StringUtils.isEmpty(user.emailAddress)) {
            // reject the push because the pushing account does not have an email address
            for (ReceiveCommand cmd : commands) {
                sendRejection(cmd, "Sorry, the account \"{0}\" does not have an email address set for committer verification!", user.username);
            }
            return;
        }
        // Optionally enforce that the committer of first parent chain
        // match the account being used to push the commits.
        //
        // This requires all merge commits are executed with the "--no-ff"
        // option to force a merge commit even if fast-forward is possible.
        // This ensures that the chain first parents has the commit
        // identity of the merging user.
        boolean allRejected = false;
        for (ReceiveCommand cmd : commands) {
            String firstParent = null;
            try {
                List<RevCommit> commits = JGitUtils.getRevLog(rp.getRepository(), cmd.getOldId().name(), cmd.getNewId().name());
                for (RevCommit commit : commits) {
                    if (firstParent != null) {
                        if (!commit.getName().equals(firstParent)) {
                            // ignore: commit is right-descendant of a merge
                            continue;
                        }
                    }
                    // update expected next commit id
                    if (commit.getParentCount() == 0) {
                        firstParent = null;
                    } else {
                        firstParent = commit.getParents()[0].getId().getName();
                    }
                    PersonIdent committer = commit.getCommitterIdent();
                    if (!user.is(committer.getName(), committer.getEmailAddress())) {
                        // verification failed
                        String reason = MessageFormat.format("{0} by {1} <{2}> was not committed by {3} ({4}) <{5}>", commit.getId().name(), committer.getName(), StringUtils.isEmpty(committer.getEmailAddress()) ? "?" : committer.getEmailAddress(), user.getDisplayName(), user.username, user.emailAddress);
                        LOGGER.warn(reason);
                        cmd.setResult(Result.REJECTED_OTHER_REASON, reason);
                        allRejected &= true;
                        break;
                    } else {
                        allRejected = false;
                    }
                }
            } catch (Exception e) {
                LOGGER.error("Failed to verify commits were made by pushing user", e);
            }
        }
        if (allRejected) {
            // all ref updates rejected, abort
            return;
        }
    }
    for (ReceiveCommand cmd : commands) {
        String ref = cmd.getRefName();
        if (ref.startsWith(Constants.R_HEADS)) {
            switch(cmd.getType()) {
                case UPDATE_NONFASTFORWARD:
                case DELETE:
                    // reset branch commit cache on REWIND and DELETE
                    CommitCache.instance().clear(repository.name, ref);
                    break;
                default:
                    break;
            }
        } else if (ref.equals(BranchTicketService.BRANCH)) {
            // ensure pushing user is an administrator OR an owner
            // i.e. prevent ticket tampering
            boolean permitted = user.canAdmin() || repository.isOwner(user.username);
            if (!permitted) {
                sendRejection(cmd, "{0} is not permitted to push to {1}", user.username, ref);
            }
        } else if (ref.startsWith(Constants.R_FOR)) {
            // prevent accidental push to refs/for
            sendRejection(cmd, "{0} is not configured to receive patchsets", repository.name);
        }
    }
    // call pre-receive plugins
    for (ReceiveHook hook : gitblit.getExtensions(ReceiveHook.class)) {
        try {
            hook.onPreReceive(this, commands);
        } catch (Exception e) {
            LOGGER.error("Failed to execute extension", e);
        }
    }
    Set<String> scripts = new LinkedHashSet<String>();
    scripts.addAll(gitblit.getPreReceiveScriptsInherited(repository));
    if (!ArrayUtils.isEmpty(repository.preReceiveScripts)) {
        scripts.addAll(repository.preReceiveScripts);
    }
    runGroovy(commands, scripts);
    for (ReceiveCommand cmd : commands) {
        if (!Result.NOT_ATTEMPTED.equals(cmd.getResult())) {
            LOGGER.warn(MessageFormat.format("{0} {1} because \"{2}\"", cmd.getNewId().getName(), cmd.getResult(), cmd.getMessage()));
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) ReceiveHook(com.gitblit.extensions.ReceiveHook) PostReceiveHook(org.eclipse.jgit.transport.PostReceiveHook) PreReceiveHook(org.eclipse.jgit.transport.PreReceiveHook) PersonIdent(org.eclipse.jgit.lib.PersonIdent) IOException(java.io.IOException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

ReceiveHook (com.gitblit.extensions.ReceiveHook)2 IOException (java.io.IOException)2 LinkedHashSet (java.util.LinkedHashSet)2 PostReceiveHook (org.eclipse.jgit.transport.PostReceiveHook)2 PreReceiveHook (org.eclipse.jgit.transport.PreReceiveHook)2 ReceiveCommand (org.eclipse.jgit.transport.ReceiveCommand)2 PersonIdent (org.eclipse.jgit.lib.PersonIdent)1 RevCommit (org.eclipse.jgit.revwalk.RevCommit)1