/*
 * 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.servlet;

import java.text.MessageFormat;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import javax.servlet.http.HttpServletRequest;

import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.GitBlitException;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.manager.IFederationManager;
import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;

/**
 * The GitFilter is an AccessRestrictionFilter which ensures that Git client
 * requests for push, clone, or view restricted repositories are authenticated
 * and authorized.
 *
 * @author James Moger
 *
 */
@Singleton
public class GitFilter extends AccessRestrictionFilter {

	protected static final String gitReceivePack = "/git-receive-pack";

	protected static final String gitUploadPack = "/git-upload-pack";
	
	protected static final String gitLfs = "/info/lfs";
	
	protected static final String[] suffixes = { gitReceivePack, gitUploadPack, "/info/refs", "/HEAD",
			"/objects", gitLfs };

	private IStoredSettings settings;

	private IFederationManager federationManager;

	@Inject
	public GitFilter(
			IStoredSettings settings,
			IRuntimeManager runtimeManager,
			IAuthenticationManager authenticationManager,
			IRepositoryManager repositoryManager,
			IFederationManager federationManager) {

		super(runtimeManager, authenticationManager, repositoryManager);

		this.settings = settings;
		this.federationManager = federationManager;
	}

	/**
	 * Extract the repository name from the url.
	 *
	 * @param cloneUrl
	 * @return repository name
	 */
	public static String getRepositoryName(String value) {
		String repository = value;
		// get the repository name from the url by finding a known url suffix
		for (String urlSuffix : suffixes) {
			if (repository.indexOf(urlSuffix) > -1) {
				repository = repository.substring(0, repository.indexOf(urlSuffix));
			}
		}
		return repository;
	}

	/**
	 * Extract the repository name from the url.
	 *
	 * @param url
	 * @return repository name
	 */
	@Override
	protected String extractRepositoryName(String url) {
		return GitFilter.getRepositoryName(url);
	}

	/**
	 * Analyze the url and returns the action of the request. Return values are:
	 * "/git-receive-pack", "/git-upload-pack" or "/info/lfs".
	 *
	 * @param serverUrl
	 * @return action of the request
	 */
	@Override
	protected String getUrlRequestAction(String suffix) {
		if (!StringUtils.isEmpty(suffix)) {
			if (suffix.startsWith(gitReceivePack)) {
				return gitReceivePack;
			} else if (suffix.startsWith(gitUploadPack)) {
				return gitUploadPack;
			} else if (suffix.contains("?service=git-receive-pack")) {
				return gitReceivePack;
			} else if (suffix.contains("?service=git-upload-pack")) {
				return gitUploadPack;
			} else if (suffix.startsWith(gitLfs)) {
				return gitLfs;
			} else {
				return gitUploadPack;
			}
		}
		return null;
	}

	/**
	 * Returns the user making the request, if the user has authenticated.
	 *
	 * @param httpRequest
	 * @return user
	 */
	@Override
	protected UserModel getUser(HttpServletRequest httpRequest) {
		UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());
		if (user == null) {
			user = federationManager.authenticate(httpRequest);
		}
		return user;
	}

	/**
	 * Determine if a non-existing repository can be created using this filter.
	 *
	 * @return true if the server allows repository creation on-push
	 */
	@Override
	protected boolean isCreationAllowed(String action) {
		
		//Repository must already exist before large files can be deposited
		if (action.equals(gitLfs)) {
			return false;
		}
		
		return settings.getBoolean(Keys.git.allowCreateOnPush, true);
	}

	/**
	 * 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, String method) {
		// the log here has been moved into ReceiveHook to provide clients with
		// error messages
		if (gitLfs.equals(action)) {
			if (!method.matches("GET|POST|PUT|HEAD")) {
				return false;
			}
		}
		
		return true;
	}

	@Override
	protected boolean requiresClientCertificate() {
		return settings.getBoolean(Keys.git.requiresClientCertificate, false);
	}

	/**
	 * Determine if the repository requires authentication.
	 *
	 * @param repository
	 * @param action
	 * @param method
	 * @return true if authentication required
	 */
	@Override
	protected boolean requiresAuthentication(RepositoryModel repository, String action, String method) {
		if (gitUploadPack.equals(action)) {
			// send to client
			return repository.accessRestriction.atLeast(AccessRestrictionType.CLONE);
		} else if (gitReceivePack.equals(action)) {
			// receive from client
			return repository.accessRestriction.atLeast(AccessRestrictionType.PUSH);
		} else if (gitLfs.equals(action)) {
			
			if (method.matches("GET|HEAD")) {
				return repository.accessRestriction.atLeast(AccessRestrictionType.CLONE);
			} else {
				//NOTE: Treat POST as PUT as as without reading message type cannot determine 
				return repository.accessRestriction.atLeast(AccessRestrictionType.PUSH);
			}
		}
		return false;
	}

	/**
	 * Determine if the user can access the repository and perform the specified
	 * action.
	 *
	 * @param repository
	 * @param user
	 * @param action
	 * @return true if user may execute the action on the repository
	 */
	@Override
	protected boolean canAccess(RepositoryModel repository, UserModel user, String action) {
		if (!settings.getBoolean(Keys.git.enableGitServlet, true)) {
			// Git Servlet disabled
			return false;
		}
		if (action.equals(gitReceivePack)) {
			// push permissions are enforced in the receive pack
			return true;
		} else if (action.equals(gitUploadPack)) {
			// Clone request
			if (user.canClone(repository)) {
				return true;
			} else {
				// user is unauthorized to clone this repository
				logger.warn(MessageFormat.format("user {0} is not authorized to clone {1}",
						user.username, repository));
				return false;
			}
		}
		return true;
	}

	/**
	 * An authenticated user with the CREATE role can create a repository on
	 * push.
	 *
	 * @param user
	 * @param repository
	 * @param action
	 * @return the repository model, if it is created, null otherwise
	 */
	@Override
	protected RepositoryModel createRepository(UserModel user, String repository, String action) {
		boolean isPush = !StringUtils.isEmpty(action) && gitReceivePack.equals(action);
		
		if (action.equals(gitLfs)) {
			//Repository must already exist for any filestore actions
			return null;
		}
		
		if (isPush) {
			if (user.canCreate(repository)) {
				// user is pushing to a new repository
				// validate name
				if (repository.startsWith("../")) {
					logger.error(MessageFormat.format("Illegal relative path in repository name! {0}", repository));
					return null;
				}
				if (repository.contains("/../")) {
					logger.error(MessageFormat.format("Illegal relative path in repository name! {0}", repository));
					return null;
				}

				// confirm valid characters in repository name
				Character c = StringUtils.findInvalidCharacter(repository);
				if (c != null) {
					logger.error(MessageFormat.format("Invalid character '{0}' in repository name {1}!", c, repository));
					return null;
				}

				// create repository
				RepositoryModel model = new RepositoryModel();
				model.name = repository;
				model.addOwner(user.username);
				model.projectPath = StringUtils.getFirstPathElement(repository);
				if (model.isUsersPersonalRepository(user.username)) {
					// personal repository, default to private for user
					model.authorizationControl = AuthorizationControl.NAMED;
					model.accessRestriction = AccessRestrictionType.VIEW;
				} else {
					// common repository, user default server settings
					model.authorizationControl = AuthorizationControl.fromName(settings.getString(Keys.git.defaultAuthorizationControl, ""));
					model.accessRestriction = AccessRestrictionType.fromName(settings.getString(Keys.git.defaultAccessRestriction, "PUSH"));
				}

				// create the repository
				try {
					repositoryManager.updateRepositoryModel(model.name, model, true);
					logger.info(MessageFormat.format("{0} created {1} ON-PUSH", user.username, model.name));
					return repositoryManager.getRepositoryModel(model.name);
				} catch (GitBlitException e) {
					logger.error(MessageFormat.format("{0} failed to create repository {1} ON-PUSH!", user.username, model.name), e);
				}
			} else {
				logger.warn(MessageFormat.format("{0} is not permitted to create repository {1} ON-PUSH!", user.username, repository));
			}
		}

		// repository could not be created or action was not a push
		return null;
	}
	
	/**
	 * Git lfs action uses an alternative authentication header, 
	 * dependent on the viewing method.
	 * 
	 * @param httpRequest
	 * @param action
	 * @return
	 */
	@Override
	protected String getAuthenticationHeader(HttpServletRequest httpRequest, String action) {

		if (action.equals(gitLfs)) {
			if (hasContentInRequestHeader(httpRequest, "Accept", FilestoreServlet.GIT_LFS_META_MIME)) {
				return "LFS-Authenticate";
			}
		}
		
		return super.getAuthenticationHeader(httpRequest, action);
	}
	
	/**
	 * Interrogates the request headers based on the action
	 * @param action
	 * @param request
	 * @return
	 */
	@Override
	protected boolean hasValidRequestHeader(String action,
			HttpServletRequest request) {

		if (action.equals(gitLfs) && request.getMethod().equals("POST")) {
			if ( 	!hasContentInRequestHeader(request, "Accept", FilestoreServlet.GIT_LFS_META_MIME)
				 || !hasContentInRequestHeader(request, "Content-Type", FilestoreServlet.GIT_LFS_META_MIME)) {
				return false;
			}				
		}
			
		return super.hasValidRequestHeader(action, request);
	}
}
