James Moger
2012-02-03 b7403152813c7fee783e3c999c7f7ae9fbaacce0
Block pushes to a repository with a working copy (issue-49)
11 files modified
124 ■■■■■ changed files
docs/00_index.mkd 5 ●●●● patch | view | raw | blame | history
docs/04_releases.mkd 1 ●●●● patch | view | raw | blame | history
src/com/gitblit/AccessRestrictionFilter.java 17 ●●●●● patch | view | raw | blame | history
src/com/gitblit/DownloadZipFilter.java 12 ●●●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java 1 ●●●● patch | view | raw | blame | history
src/com/gitblit/GitFilter.java 23 ●●●●● patch | view | raw | blame | history
src/com/gitblit/PagesFilter.java 12 ●●●●● patch | view | raw | blame | history
src/com/gitblit/SyndicationFilter.java 12 ●●●●● patch | view | raw | blame | history
src/com/gitblit/models/RepositoryModel.java 6 ●●●● patch | view | raw | blame | history
test-gitblit.properties 2 ●●● patch | view | raw | blame | history
tests/com/gitblit/tests/GitServletTest.java 33 ●●●●● patch | view | raw | blame | history
docs/00_index.mkd
@@ -30,10 +30,7 @@
Gitblit is an open-source, pure Java stack for managing, viewing, and serving [Git][git] repositories.  
It's designed primarily as a tool for small workgroups who want to host centralized repositories.
You can browse a live demo [here](http://demo-gitblit.rhcloud.com) hosted on [RedHat's OpenShift][rhcloud] cloud service.
**NOTE:**
The demo is a bit unstable due to a bug in JBossAS7/Tomcat when running in LOW_MEMORY mode which OpenShift mandates.  RedHat engineers hope to have this issue resolved soon.
You can browse a live demo [here](https://demo-gitblit.rhcloud.com) hosted on [RedHat's OpenShift][rhcloud] cloud service.
### GO: Single-Stack Solution
docs/04_releases.mkd
@@ -6,6 +6,7 @@
#### changes
- block pushes to a repository with a working copy (i.e. non-bare repository) (issue-49)
- web.datetimestampLongFormat from *EEEE, MMMM d, yyyy h:mm a z* to *EEEE, MMMM d, yyyy HH:mm Z* (issue 50)
#### additions
src/com/gitblit/AccessRestrictionFilter.java
@@ -62,6 +62,15 @@
    protected abstract String getUrlRequestAction(String url);
    /**
     * Determine if the action may be executed on the repository.
     *
     * @param repository
     * @param action
     * @return true if the action may be performed
     */
    protected abstract boolean isActionAllowed(RepositoryModel repository, String action);
    /**
     * Determine if the repository requires authentication.
     * 
     * @param repository
@@ -110,6 +119,14 @@
            httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        // Confirm that the action may be executed on the repository
        if (!isActionAllowed(model, urlRequestType)) {
            logger.info(MessageFormat.format("ARF: action {0} on {1} forbidden ({2})",
                    urlRequestType, model, HttpServletResponse.SC_FORBIDDEN));
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        // Wrap the HttpServletRequest with the AccessRestrictionRequest which
        // overrides the servlet container user principal methods.
src/com/gitblit/DownloadZipFilter.java
@@ -57,6 +57,18 @@
    }
    /**
     * Determine if the action may be executed on the repository.
     *
     * @param repository
     * @param action
     * @return true if the action may be performed
     */
    @Override
    protected boolean isActionAllowed(RepositoryModel repository, String action) {
        return true;
    }
    /**
     * Determine if the repository requires authentication.
     * 
     * @param repository
src/com/gitblit/GitBlit.java
@@ -760,6 +760,7 @@
        model.name = repositoryName;
        model.hasCommits = JGitUtils.hasCommits(r);
        model.lastChange = JGitUtils.getLastChange(r, null);
        model.isBare = r.isBare();
        StoredConfig config = JGitUtils.readConfig(r);
        if (config != null) {
            model.description = getConfig(config, "description", "");
src/com/gitblit/GitFilter.java
@@ -81,6 +81,25 @@
        }
        return null;
    }
    /**
     * Determine if the repository can receive pushes.
     *
     * @param repository
     * @param action
     * @return true if the action may be performed
     */
    @Override
    protected boolean isActionAllowed(RepositoryModel repository, String action) {
        if (action.equals(gitReceivePack)) {
            // Push request
            if (!repository.isBare) {
                logger.warn("Gitblit does not allow pushes to repositories with a working copy");
                return false;
            }
        }
        return true;
    }
    /**
     * Determine if the repository requires authentication.
@@ -107,8 +126,8 @@
        if (!GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
            // Git Servlet disabled
            return false;
        }
        boolean readOnly = repository.isFrozen;
        }
        boolean readOnly = repository.isFrozen;
        if (readOnly || repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) {
            boolean authorizedUser = user.canAccessRepository(repository);
            if (action.equals(gitReceivePack)) {
src/com/gitblit/PagesFilter.java
@@ -77,6 +77,18 @@
    }
    /**
     * Determine if the action may be executed on the repository.
     *
     * @param repository
     * @param action
     * @return true if the action may be performed
     */
    @Override
    protected boolean isActionAllowed(RepositoryModel repository, String action) {
        return true;
    }
    /**
     * Determine if the repository requires authentication.
     * 
     * @param repository
src/com/gitblit/SyndicationFilter.java
@@ -55,6 +55,18 @@
    }
    /**
     * Determine if the action may be executed on the repository.
     *
     * @param repository
     * @param action
     * @return true if the action may be performed
     */
    @Override
    protected boolean isActionAllowed(RepositoryModel repository, String action) {
        return true;
    }
    /**
     * Determine if the repository requires authentication.
     * 
     * @param repository
src/com/gitblit/models/RepositoryModel.java
@@ -53,14 +53,14 @@
    public boolean skipSizeCalculation;
    public boolean skipSummaryMetrics;
    public String frequency;
    public boolean isBare;
    public String origin;
    public String HEAD;
    public List<String> availableRefs;
    public String size;
    public List<String> preReceiveScripts;
    public List<String> postReceiveScripts;
    public List<String> mailingLists;
    public String HEAD;
    public List<String> availableRefs;
    private String displayName;
    
    public RepositoryModel() {
test-gitblit.properties
@@ -7,7 +7,7 @@
git.enableGitServlet = true
groovy.scriptsFolder = groovy
groovy.preReceiveScripts = blockpush
groovy.postReceiveScripts = sendmail jenkins
groovy.postReceiveScripts = sendmail
web.authenticateViewPages = false
web.authenticateAdminPages = true
web.allowCookieAuthentication = true
tests/com/gitblit/tests/GitServletTest.java
@@ -30,6 +30,8 @@
    static File ticgit2Folder = new File(GitBlitSuite.REPOSITORIES, "working/ticgit2");
    static File jgitFolder = new File(GitBlitSuite.REPOSITORIES, "working/jgit");
    static File jgit2Folder = new File(GitBlitSuite.REPOSITORIES, "working/jgit2");
    String url = GitBlitSuite.url;
    String account = GitBlitSuite.account;
@@ -60,6 +62,9 @@
        }
        if (jgitFolder.exists()) {
            FileUtils.delete(jgitFolder, FileUtils.RECURSIVE);
        }
        if (jgit2Folder.exists()) {
            FileUtils.delete(jgit2Folder, FileUtils.RECURSIVE);
        }
    }
@@ -141,6 +146,34 @@
        close(git);
    }
    
    @Test
    public void testPushToNonBareRepository() throws Exception {
        CloneCommand clone = Git.cloneRepository();
        clone.setURI(MessageFormat.format("{0}/git/working/jgit", url));
        clone.setDirectory(jgit2Folder);
        clone.setBare(false);
        clone.setCloneAllBranches(true);
        clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
        close(clone.call());
        assertTrue(true);
        Git git = Git.open(jgit2Folder);
        File file = new File(jgit2Folder, "NONBARE");
        OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true));
        BufferedWriter w = new BufferedWriter(os);
        w.write("// " + new Date().toString() + "\n");
        w.close();
        git.add().addFilepattern(file.getName()).call();
        git.commit().setMessage("test commit followed by push to non-bare repository").call();
        try {
            git.push().setPushAll().call();
            assertTrue(false);
        } catch (Exception e) {
            assertTrue(e.getCause().getMessage().contains("git-receive-pack not permitted"));
        }
        close(git);
    }
    private void close(Git git) {
        // really close the repository
        // decrement the use counter to 0