/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * 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.
 */
package com.gitblit.tests;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.FileUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Keys;
import com.gitblit.models.RefLogEntry;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.RefLogUtils;

public class GitServletTest extends GitblitUnitTest {

	static File ticgitFolder = new File(GitBlitSuite.REPOSITORIES, "working/ticgit");

	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.gitServletUrl;
	String account = GitBlitSuite.account;
	String password = GitBlitSuite.password;

	private static final AtomicBoolean started = new AtomicBoolean(false);

	private static UserModel getUser() {
		UserModel user = new UserModel("james");
		user.displayName = "James Moger";
		user.emailAddress = "james.moger@gmail.com";
		user.password = "james";
		return user;
	}

	private static void delete(UserModel user) {
		if (users().getUserModel(user.username) != null) {
			users().deleteUser(user.username);
		}
	}

	@BeforeClass
	public static void startGitblit() throws Exception {
		started.set(GitBlitSuite.startGitblit());

		delete(getUser());
	}

	@AfterClass
	public static void stopGitblit() throws Exception {
		if (started.get()) {
			GitBlitSuite.stopGitblit();
			deleteWorkingFolders();
		}

		delete(getUser());
	}

	public static void deleteWorkingFolders() throws Exception {
		if (ticgitFolder.exists()) {
			GitBlitSuite.close(ticgitFolder);
			FileUtils.delete(ticgitFolder, FileUtils.RECURSIVE);
		}
		if (ticgit2Folder.exists()) {
			GitBlitSuite.close(ticgit2Folder);
			FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);
		}
		if (jgitFolder.exists()) {
			GitBlitSuite.close(jgitFolder);
			FileUtils.delete(jgitFolder, FileUtils.RECURSIVE);
		}
		if (jgit2Folder.exists()) {
			GitBlitSuite.close(jgit2Folder);
			FileUtils.delete(jgit2Folder, FileUtils.RECURSIVE);
		}
	}

	@Test
	public void testClone() throws Exception {
		GitBlitSuite.close(ticgitFolder);
		if (ticgitFolder.exists()) {
			FileUtils.delete(ticgitFolder, FileUtils.RECURSIVE | FileUtils.RETRY);
		}

		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(ticgitFolder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
		GitBlitSuite.close(clone.call());
		assertTrue(true);
	}

	@Test
	public void testBogusLoginClone() throws Exception {
		// restrict repository access
		RepositoryModel model = repositories().getRepositoryModel("ticgit.git");
		model.accessRestriction = AccessRestrictionType.CLONE;
		repositories().updateRepositoryModel(model.name, model, false);

		// delete any existing working folder
		boolean cloned = false;
		try {
			CloneCommand clone = Git.cloneRepository();
			clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
			clone.setDirectory(ticgit2Folder);
			clone.setBare(false);
			clone.setCloneAllBranches(true);
			clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider("bogus", "bogus"));
			GitBlitSuite.close(clone.call());
			cloned = true;
		} catch (Exception e) {
			// swallow the exception which we expect
		}

		// restore anonymous repository access
		model.accessRestriction = AccessRestrictionType.NONE;
		repositories().updateRepositoryModel(model.name, model, false);

		assertFalse("Bogus login cloned a repository?!", cloned);
	}

	@Test
	public void testUnauthorizedLoginClone() throws Exception {
		// restrict repository access
		RepositoryModel model = repositories().getRepositoryModel("ticgit.git");
		model.accessRestriction = AccessRestrictionType.CLONE;
		model.authorizationControl = AuthorizationControl.NAMED;
		UserModel user = new UserModel("james");
		user.password = "james";
		gitblit().addUser(user);
		repositories().updateRepositoryModel(model.name, model, false);

		FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

		// delete any existing working folder
		boolean cloned = false;
		try {
			CloneCommand clone = Git.cloneRepository();
			clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
			clone.setDirectory(ticgit2Folder);
			clone.setBare(false);
			clone.setCloneAllBranches(true);
			clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(user.username, user.password));
			GitBlitSuite.close(clone.call());
			cloned = true;
		} catch (Exception e) {
			// swallow the exception which we expect
		}

		assertFalse("Unauthorized login cloned a repository?!", cloned);

		FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

		// switch to authenticated
		model.authorizationControl = AuthorizationControl.AUTHENTICATED;
		repositories().updateRepositoryModel(model.name, model, false);

		// try clone again
		cloned = false;
		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(ticgit2Folder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(user.username, user.password));
		GitBlitSuite.close(clone.call());
		cloned = true;

		assertTrue("Authenticated login could not clone!", cloned);

		FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

		// restore anonymous repository access
		model.accessRestriction = AccessRestrictionType.NONE;
		model.authorizationControl = AuthorizationControl.NAMED;
		repositories().updateRepositoryModel(model.name, model, false);

		delete(user);
	}

	@Test
	public void testAnonymousPush() throws Exception {
		GitBlitSuite.close(ticgitFolder);
		if (ticgitFolder.exists()) {
			FileUtils.delete(ticgitFolder, FileUtils.RECURSIVE | FileUtils.RETRY);
		}

		RepositoryModel model = repositories().getRepositoryModel("ticgit.git");
		model.accessRestriction = AccessRestrictionType.NONE;
		repositories().updateRepositoryModel(model.name, model, false);

		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(ticgitFolder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
		GitBlitSuite.close(clone.call());
		assertTrue(true);

		Git git = Git.open(ticgitFolder);
		File file = new File(ticgitFolder, "TODO");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// hellol中文 " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage("test commit").call();
		Iterable<PushResult> results = git.push().setPushAll().call();
		GitBlitSuite.close(git);
		for (PushResult result : results) {
			for (RemoteRefUpdate update : result.getRemoteUpdates()) {
				assertEquals(Status.OK, update.getStatus());
			}
		}
	}

	@Test
	public void testSubfolderPush() throws Exception {
		GitBlitSuite.close(jgitFolder);
		if (jgitFolder.exists()) {
			FileUtils.delete(jgitFolder, FileUtils.RECURSIVE | FileUtils.RETRY);
		}

		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/test/jgit.git", url));
		clone.setDirectory(jgitFolder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
		GitBlitSuite.close(clone.call());
		assertTrue(true);

		Git git = Git.open(jgitFolder);
		File file = new File(jgitFolder, "TODO");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage("test commit").call();
		Iterable<PushResult> results = git.push().setPushAll().setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password)).call();
		GitBlitSuite.close(git);
		for (PushResult result : results) {
			for (RemoteRefUpdate update : result.getRemoteUpdates()) {
				assertEquals(Status.OK, update.getStatus());
			}
		}
	}

	@Test
	public void testPushToFrozenRepo() throws Exception {
		GitBlitSuite.close(jgitFolder);
		if (jgitFolder.exists()) {
			FileUtils.delete(jgitFolder, FileUtils.RECURSIVE | FileUtils.RETRY);
		}

		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/test/jgit.git", url));
		clone.setDirectory(jgitFolder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
		GitBlitSuite.close(clone.call());
		assertTrue(true);

		// freeze repo
		RepositoryModel model = repositories().getRepositoryModel("test/jgit.git");
		model.isFrozen = true;
		repositories().updateRepositoryModel(model.name, model, false);

		Git git = Git.open(jgitFolder);
		File file = new File(jgitFolder, "TODO");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage("test commit").call();

		Iterable<PushResult> results = git.push().setPushAll().setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password)).call();
		for (PushResult result : results) {
			for (RemoteRefUpdate update : result.getRemoteUpdates()) {
				assertEquals(Status.REJECTED_OTHER_REASON, update.getStatus());
			}
		}

		// unfreeze repo
		model.isFrozen = false;
		repositories().updateRepositoryModel(model.name, model, false);

		results = git.push().setPushAll().setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password)).call();
		GitBlitSuite.close(git);
		for (PushResult result : results) {
			for (RemoteRefUpdate update : result.getRemoteUpdates()) {
				assertEquals(Status.OK, update.getStatus());
			}
		}
	}

	@Test
	public void testPushToNonBareRepository() throws Exception {
		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/working/jgit", url));
		clone.setDirectory(jgit2Folder);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password));
		GitBlitSuite.close(clone.call());
		assertTrue(true);

		Git git = Git.open(jgit2Folder);
		File file = new File(jgit2Folder, "NONBARE");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		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();
		Iterable<PushResult> results = git.push().setPushAll().setCredentialsProvider(new UsernamePasswordCredentialsProvider(account, password)).call();
		GitBlitSuite.close(git);
		for (PushResult result : results) {
			for (RemoteRefUpdate update : result.getRemoteUpdates()) {
				assertEquals(Status.REJECTED_OTHER_REASON, update.getStatus());
			}
		}
	}

	@Test
	public void testCommitterVerification() throws Exception {
		UserModel user = getUser();

		testCommitterVerification(user, "joe", null, false);
		testCommitterVerification(user, "joe", user.emailAddress, false);
		testCommitterVerification(user, user.username, null, false);
		testCommitterVerification(user, user.username, user.emailAddress, true);

		user.displayName = "James Moger";
		testCommitterVerification(user, user.displayName, null, false);
		testCommitterVerification(user, user.displayName, "something", false);
		testCommitterVerification(user, user.displayName, user.emailAddress, true);
	}

	private void testCommitterVerification(UserModel user, String displayName, String emailAddress, boolean expectedSuccess) throws Exception {

		delete(user);

		CredentialsProvider cp = new UsernamePasswordCredentialsProvider(user.username, user.password);

		// fork from original to a temporary bare repo
		File verification = new File(GitBlitSuite.REPOSITORIES, "refchecks/verify-committer.git");
		if (verification.exists()) {
			FileUtils.delete(verification, FileUtils.RECURSIVE);
		}
		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(verification);
		clone.setBare(true);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		GitBlitSuite.close(clone.call());

		// require push permissions and committer verification
		RepositoryModel model = repositories().getRepositoryModel("refchecks/verify-committer.git");
		model.authorizationControl = AuthorizationControl.NAMED;
		model.accessRestriction = AccessRestrictionType.PUSH;
		model.verifyCommitter = true;

		// grant user push permission
		user.setRepositoryPermission(model.name, AccessPermission.PUSH);

		gitblit().addUser(user);
		repositories().updateRepositoryModel(model.name, model, false);

		// clone temp bare repo to working copy
		File local = new File(GitBlitSuite.REPOSITORIES, "refchecks/verify-wc");
		if (local.exists()) {
			FileUtils.delete(local, FileUtils.RECURSIVE);
		}
		clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/{1}", url, model.name));
		clone.setDirectory(local);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		GitBlitSuite.close(clone.call());

		Git git = Git.open(local);

		// force an identity which may or may not match the account's identity
		git.getRepository().getConfig().setString("user", null, "name", displayName);
		git.getRepository().getConfig().setString("user", null, "email", emailAddress);
		git.getRepository().getConfig().save();

		// commit a file and push it
		File file = new File(local, "PUSHCHK");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage("push test").call();
		Iterable<PushResult> results = git.push().setCredentialsProvider(cp).setRemote("origin").call();

		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
			Status status = ref.getStatus();
			if (expectedSuccess) {
				assertTrue("Verification failed! User was NOT able to push commit! " + status.name(), Status.OK.equals(status));
			} else {
				assertTrue("Verification failed! User was able to push commit! " + status.name(), Status.REJECTED_OTHER_REASON.equals(status));
			}
		}

		GitBlitSuite.close(git);
		// close serving repository
		GitBlitSuite.close(verification);
	}

	@Test
	public void testMergeCommitterVerification() throws Exception {

		testMergeCommitterVerification(false);

		testMergeCommitterVerification(true);
	}

	private void testMergeCommitterVerification(boolean expectedSuccess) throws Exception {
		UserModel user = getUser();

		delete(user);

		CredentialsProvider cp = new UsernamePasswordCredentialsProvider(user.username, user.password);

		// fork from original to a temporary bare repo
		File verification = new File(GitBlitSuite.REPOSITORIES, "refchecks/verify-committer.git");
		if (verification.exists()) {
			FileUtils.delete(verification, FileUtils.RECURSIVE);
		}
		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(verification);
		clone.setBare(true);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		GitBlitSuite.close(clone.call());

		// require push permissions and committer verification
		RepositoryModel model = repositories().getRepositoryModel("refchecks/verify-committer.git");
		model.authorizationControl = AuthorizationControl.NAMED;
		model.accessRestriction = AccessRestrictionType.PUSH;
		model.verifyCommitter = true;

		// grant user push permission
		user.setRepositoryPermission(model.name, AccessPermission.PUSH);

		gitblit().addUser(user);
		repositories().updateRepositoryModel(model.name, model, false);

		// clone temp bare repo to working copy
		File local = new File(GitBlitSuite.REPOSITORIES, "refchecks/verify-wc");
		if (local.exists()) {
			FileUtils.delete(local, FileUtils.RECURSIVE);
		}
		clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/{1}", url, model.name));
		clone.setDirectory(local);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		GitBlitSuite.close(clone.call());

		Git git = Git.open(local);

		// checkout a mergetest branch
		git.checkout().setCreateBranch(true).setName("mergetest").call();

		// change identity
		git.getRepository().getConfig().setString("user", null, "name", "mergetest");
		git.getRepository().getConfig().setString("user", null, "email", "mergetest@merge.com");
		git.getRepository().getConfig().save();

		// commit a file
		File file = new File(local, "MERGECHK2");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		RevCommit mergeTip = git.commit().setMessage(file.getName() + " test").call();

		// return to master
		git.checkout().setName("master").call();

		// restore identity
		if (expectedSuccess) {
			git.getRepository().getConfig().setString("user", null, "name", user.username);
			git.getRepository().getConfig().setString("user", null, "email", user.emailAddress);
			git.getRepository().getConfig().save();
		}

		// commit a file
		file = new File(local, "MERGECHK1");
		os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage(file.getName() + " test").call();

		// merge the tip of the mergetest branch into master with --no-ff
		MergeResult mergeResult = git.merge().setFastForward(FastForwardMode.NO_FF).include(mergeTip.getId()).call();
		assertEquals(MergeResult.MergeStatus.MERGED, mergeResult.getMergeStatus());

		// push the merged master to the origin
		Iterable<PushResult> results = git.push().setCredentialsProvider(cp).setRemote("origin").call();

		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
			Status status = ref.getStatus();
			if (expectedSuccess) {
				assertTrue("Verification failed! User was NOT able to push commit! " + status.name(), Status.OK.equals(status));
			} else {
				assertTrue("Verification failed! User was able to push commit! " + status.name(), Status.REJECTED_OTHER_REASON.equals(status));
			}
		}

		GitBlitSuite.close(git);
		// close serving repository
		GitBlitSuite.close(verification);
	}

	@Test
	public void testBlockClone() throws Exception {
		testRefChange(AccessPermission.VIEW, null, null, null);
	}

	@Test
	public void testBlockPush() throws Exception {
		testRefChange(AccessPermission.CLONE, null, null, null);
	}

	@Test
	public void testBlockBranchCreation() throws Exception {
		testRefChange(AccessPermission.PUSH, Status.REJECTED_OTHER_REASON, null, null);
	}

	@Test
	public void testBlockBranchDeletion() throws Exception {
		testRefChange(AccessPermission.CREATE, Status.OK, Status.REJECTED_OTHER_REASON, null);
	}

	@Test
	public void testBlockBranchRewind() throws Exception {
		testRefChange(AccessPermission.DELETE, Status.OK, Status.OK, Status.REJECTED_OTHER_REASON);
	}

	@Test
	public void testBranchRewind() throws Exception {
		testRefChange(AccessPermission.REWIND, Status.OK, Status.OK, Status.OK);
	}

	private void testRefChange(AccessPermission permission, Status expectedCreate, Status expectedDelete, Status expectedRewind) throws Exception {

		final String originName = "ticgit.git";
		final String forkName = "refchecks/ticgit.git";
		final String workingCopy = "refchecks/ticgit-wc";


		// lower access restriction on origin repository
		RepositoryModel origin = repositories().getRepositoryModel(originName);
		origin.accessRestriction = AccessRestrictionType.NONE;
		repositories().updateRepositoryModel(origin.name, origin, false);

		UserModel user = getUser();
		delete(user);

		CredentialsProvider cp = new UsernamePasswordCredentialsProvider(user.username, user.password);

		// fork from original to a temporary bare repo
		File refChecks = new File(GitBlitSuite.REPOSITORIES, forkName);
		if (refChecks.exists()) {
			FileUtils.delete(refChecks, FileUtils.RECURSIVE);
		}
		CloneCommand clone = Git.cloneRepository();
		clone.setURI(url + "/" + originName);
		clone.setDirectory(refChecks);
		clone.setBare(true);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		GitBlitSuite.close(clone.call());

		// elevate repository to clone permission
		RepositoryModel model = repositories().getRepositoryModel(forkName);
		switch (permission) {
			case VIEW:
				model.accessRestriction = AccessRestrictionType.CLONE;
				break;
			case CLONE:
				model.accessRestriction = AccessRestrictionType.CLONE;
				break;
			default:
				model.accessRestriction = AccessRestrictionType.PUSH;
		}
		model.authorizationControl = AuthorizationControl.NAMED;

		// grant user specified
		user.setRepositoryPermission(model.name, permission);

		gitblit().addUser(user);
		repositories().updateRepositoryModel(model.name, model, false);

		// clone temp bare repo to working copy
		File local = new File(GitBlitSuite.REPOSITORIES, workingCopy);
		if (local.exists()) {
			FileUtils.delete(local, FileUtils.RECURSIVE);
		}
		clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/{1}", url, model.name));
		clone.setDirectory(local);
		clone.setBare(false);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);

		try {
			GitBlitSuite.close(clone.call());
		} catch (GitAPIException e) {
			if (permission.atLeast(AccessPermission.CLONE)) {
				throw e;
			} else {
				// close serving repository
				GitBlitSuite.close(refChecks);

				// user does not have clone permission
				assertTrue(e.getMessage(), e.getMessage().contains("not permitted"));
				return;
			}
		}

		Git git = Git.open(local);

		// commit a file and push it
		File file = new File(local, "PUSHCHK");
		OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		BufferedWriter w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		git.commit().setMessage("push test").call();
		Iterable<PushResult> results = null;
		try {
			results = git.push().setCredentialsProvider(cp).setRemote("origin").call();
		} catch (GitAPIException e) {
			if (permission.atLeast(AccessPermission.PUSH)) {
				throw e;
			} else {
				// close serving repository
				GitBlitSuite.close(refChecks);

				// user does not have push permission
				assertTrue(e.getMessage(), e.getMessage().contains("not permitted"));
				GitBlitSuite.close(git);
				return;
			}
		}

		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
			Status status = ref.getStatus();
			if (permission.atLeast(AccessPermission.PUSH)) {
				assertTrue("User failed to push commit?! " + status.name(), Status.OK.equals(status));
			} else {
				// close serving repository
				GitBlitSuite.close(refChecks);

				assertTrue("User was able to push commit! " + status.name(), Status.REJECTED_OTHER_REASON.equals(status));
				GitBlitSuite.close(git);
				// skip delete test
				return;
			}
		}

		// create a local branch and push the new branch back to the origin
		git.branchCreate().setName("protectme").call();
		RefSpec refSpec = new RefSpec("refs/heads/protectme:refs/heads/protectme");
		results = git.push().setCredentialsProvider(cp).setRefSpecs(refSpec).setRemote("origin").call();
		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/protectme");
			Status status = ref.getStatus();
			if (Status.OK.equals(expectedCreate)) {
				assertTrue("User failed to push creation?! " + status.name(), status.equals(expectedCreate));
			} else {
				// close serving repository
				GitBlitSuite.close(refChecks);

				assertTrue("User was able to push ref creation! " + status.name(), status.equals(expectedCreate));
				GitBlitSuite.close(git);
				// skip delete test
				return;
			}
		}

		// delete the branch locally
		git.branchDelete().setBranchNames("protectme").call();

		// push a delete ref command
		refSpec = new RefSpec(":refs/heads/protectme");
		results = git.push().setCredentialsProvider(cp).setRefSpecs(refSpec).setRemote("origin").call();
		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/protectme");
			Status status = ref.getStatus();
			if (Status.OK.equals(expectedDelete)) {
				assertTrue("User failed to push ref deletion?! " + status.name(), status.equals(Status.OK));
			} else {
				// close serving repository
				GitBlitSuite.close(refChecks);

				assertTrue("User was able to push ref deletion?! " + status.name(), status.equals(expectedDelete));
				GitBlitSuite.close(git);
				// skip rewind test
				return;
			}
		}

		// rewind master by two commits
		git.reset().setRef("HEAD~2").setMode(ResetType.HARD).call();

		// commit a change on this detached HEAD
		file = new File(local, "REWINDCHK");
		os = new OutputStreamWriter(new FileOutputStream(file, true), Constants.CHARSET);
		w = new BufferedWriter(os);
		w.write("// " + new Date().toString() + "\n");
		w.close();
		git.add().addFilepattern(file.getName()).call();
		RevCommit commit = git.commit().setMessage("rewind master and new commit").call();

		// Reset master to our new commit now we our local branch tip is no longer
		// upstream of the remote branch tip.  It is an alternate tip of the branch.
		JGitUtils.setBranchRef(git.getRepository(), "refs/heads/master", commit.getName());

		// Try pushing our new tip to the origin.
		// This requires the server to "rewind" it's master branch and update it
		// to point to our alternate tip.  This leaves the original master tip
		// unreferenced.
		results = git.push().setCredentialsProvider(cp).setRemote("origin").setForce(true).call();
		for (PushResult result : results) {
			RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
			Status status = ref.getStatus();
			if (Status.OK.equals(expectedRewind)) {
				assertTrue("User failed to rewind master?! " + status.name(), status.equals(expectedRewind));
			} else {
				assertTrue("User was able to rewind master?! " + status.name(), status.equals(expectedRewind));
			}
		}
		GitBlitSuite.close(git);

		// close serving repository
		GitBlitSuite.close(refChecks);

		delete(user);
	}

	@Test
	public void testCreateOnPush() throws Exception {
		testCreateOnPush(false, false);
		testCreateOnPush(true, false);
		testCreateOnPush(false, true);
	}

	private void testCreateOnPush(boolean canCreate, boolean canAdmin) throws Exception {

		UserModel user = new UserModel("sampleuser");
		user.password = user.username;

		delete(user);

		user.canCreate = canCreate;
		user.canAdmin = canAdmin;

		gitblit().addUser(user);

		CredentialsProvider cp = new UsernamePasswordCredentialsProvider(user.username, user.password);

		// fork from original to a temporary bare repo
		File tmpFolder = File.createTempFile("gitblit", "").getParentFile();
		File createCheck = new File(tmpFolder, "ticgit.git");
		if (createCheck.exists()) {
			FileUtils.delete(createCheck, FileUtils.RECURSIVE);
		}

		File personalRepo = new File(GitBlitSuite.REPOSITORIES, MessageFormat.format("~{0}/ticgit.git", user.username));
		GitBlitSuite.close(personalRepo);
		if (personalRepo.exists()) {
			FileUtils.delete(personalRepo, FileUtils.RECURSIVE);
		}

		File projectRepo = new File(GitBlitSuite.REPOSITORIES, "project/ticgit.git");
		GitBlitSuite.close(projectRepo);
		if (projectRepo.exists()) {
			FileUtils.delete(projectRepo, FileUtils.RECURSIVE);
		}

		CloneCommand clone = Git.cloneRepository();
		clone.setURI(MessageFormat.format("{0}/ticgit.git", url));
		clone.setDirectory(createCheck);
		clone.setBare(true);
		clone.setCloneAllBranches(true);
		clone.setCredentialsProvider(cp);
		Git git = clone.call();

		GitBlitSuite.close(personalRepo);

		// add a personal repository remote and a project remote
		git.getRepository().getConfig().setString("remote", "user", "url", MessageFormat.format("{0}/~{1}/ticgit.git", url, user.username));
		git.getRepository().getConfig().setString("remote", "project", "url", MessageFormat.format("{0}/project/ticgit.git", url));
		git.getRepository().getConfig().save();

		// push to non-existent user repository
		try {
			Iterable<PushResult> results = git.push().setRemote("user").setPushAll().setCredentialsProvider(cp).call();

			for (PushResult result : results) {
				RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
				Status status = ref.getStatus();
				assertTrue("User failed to create repository?! " + status.name(), Status.OK.equals(status));
			}

			assertTrue("User canAdmin:" + user.canAdmin + " canCreate:" + user.canCreate, user.canAdmin || user.canCreate);

			// confirm default personal repository permissions
			RepositoryModel model = repositories().getRepositoryModel(MessageFormat.format("~{0}/ticgit.git", user.username));
			user = gitblit().getUserModel(user.username);
			assertTrue("Unexpected owner", user.isOwner(model));
			assertEquals("Unexpected authorization control", AuthorizationControl.NAMED, model.authorizationControl);
			assertEquals("Unexpected access restriction", AccessRestrictionType.VIEW, model.accessRestriction);

		} catch (GitAPIException e) {
			assertTrue(e.getMessage(), e.getMessage().contains("git-receive-pack not found"));
			assertFalse("User canAdmin:" + user.canAdmin + " canCreate:" + user.canCreate, user.canAdmin || user.canCreate);
		}

		// push to non-existent project repository
		try {
			Iterable<PushResult> results = git.push().setRemote("project").setPushAll().setCredentialsProvider(cp).call();
			GitBlitSuite.close(git);

			for (PushResult result : results) {
				RemoteRefUpdate ref = result.getRemoteUpdate("refs/heads/master");
				Status status = ref.getStatus();
				assertTrue("User failed to create repository?! " + status.name(), Status.OK.equals(status));
			}

			assertTrue("User canAdmin:" + user.canAdmin, user.canAdmin);

			// confirm default project repository permissions
			RepositoryModel model = repositories().getRepositoryModel("project/ticgit.git");
			user = gitblit().getUserModel(user.username);
			assertTrue("Unexpected owner", user.isOwner(model));
			assertEquals("Unexpected authorization control", AuthorizationControl.fromName(settings().getString(Keys.git.defaultAuthorizationControl, "NAMED")), model.authorizationControl);
			assertEquals("Unexpected access restriction", AccessRestrictionType.fromName(settings().getString(Keys.git.defaultAccessRestriction, "NONE")), model.accessRestriction);

		} catch (GitAPIException e) {
			assertTrue(e.getMessage(), e.getMessage().contains("git-receive-pack not found"));
			assertFalse("User canAdmin:" + user.canAdmin, user.canAdmin);
		}

		GitBlitSuite.close(git);
		delete(user);
	}

	@Test
	public void testPushLog() throws IOException {
		String name = "refchecks/ticgit.git";
		File refChecks = new File(GitBlitSuite.REPOSITORIES, name);
		Repository repository = new FileRepositoryBuilder().setGitDir(refChecks).build();
		List<RefLogEntry> pushes = RefLogUtils.getRefLog(name, repository);
		GitBlitSuite.close(repository);
		assertTrue("Repository has an empty push log!", pushes.size() > 0);
	}
}
