/*
 * 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.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Constants;
import com.gitblit.dagger.DaggerFilter;
import com.gitblit.manager.IAuthenticationManager;
import com.gitblit.models.UserModel;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.StringUtils;

import dagger.ObjectGraph;

/**
 * The AuthenticationFilter is a servlet filter that preprocesses requests that
 * match its url pattern definition in the web.xml file.
 *
 * http://en.wikipedia.org/wiki/Basic_access_authentication
 *
 * @author James Moger
 *
 */
public abstract class AuthenticationFilter extends DaggerFilter {

	protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";

	protected static final String SESSION_SECURED = "com.gitblit.secured";

	protected transient Logger logger = LoggerFactory.getLogger(getClass());

	protected IAuthenticationManager authenticationManager;

	@Override
	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
		this.authenticationManager = dagger.get(IAuthenticationManager.class);
	}

	/**
	 * doFilter does the actual work of preprocessing the request to ensure that
	 * the user may proceed.
	 *
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public abstract void doFilter(final ServletRequest request, final ServletResponse response,
			final FilterChain chain) throws IOException, ServletException;

	/**
	 * Allow the filter to require a client certificate to continue processing.
	 *
	 * @return true, if a client certificate is required
	 */
	protected boolean requiresClientCertificate() {
		return false;
	}

	/**
	 * Returns the full relative url of the request.
	 *
	 * @param httpRequest
	 * @return url
	 */
	protected String getFullUrl(HttpServletRequest httpRequest) {
		String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();
		String url = httpRequest.getRequestURI().substring(servletUrl.length());
		String params = httpRequest.getQueryString();
		if (url.length() > 0 && url.charAt(0) == '/') {
			url = url.substring(1);
		}
		String fullUrl = url + (StringUtils.isEmpty(params) ? "" : ("?" + params));
		try {
			fullUrl = URLDecoder.decode(fullUrl, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			logger.warn("UTF-8 decoding of URL failed: "+fullUrl, e);
			e.printStackTrace();
		}
		return fullUrl;
	}

	/**
	 * Returns the user making the request, if the user has authenticated.
	 *
	 * @param httpRequest
	 * @return user
	 */
	protected UserModel getUser(HttpServletRequest httpRequest) {
		UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());
		return user;
	}

	/**
	 * Taken from Jetty's LoginAuthenticator.renewSessionOnAuthentication()
	 */
	protected void newSession(HttpServletRequest request, HttpServletResponse response) {
		HttpSession oldSession = request.getSession(false);
		if (oldSession != null && oldSession.getAttribute(SESSION_SECURED) == null) {
			synchronized (this) {
				Map<String, Object> attributes = new HashMap<String, Object>();
				Enumeration<String> e = oldSession.getAttributeNames();
				while (e.hasMoreElements()) {
					String name = e.nextElement();
					attributes.put(name, oldSession.getAttribute(name));
					oldSession.removeAttribute(name);
				}
				oldSession.invalidate();

				HttpSession newSession = request.getSession(true);
				newSession.setAttribute(SESSION_SECURED, Boolean.TRUE);
				for (Map.Entry<String, Object> entry : attributes.entrySet()) {
					newSession.setAttribute(entry.getKey(), entry.getValue());
				}
			}
		}
	}

	/**
	 * Wraps a standard HttpServletRequest and overrides user principal methods.
	 */
	public static class AuthenticatedRequest extends HttpServletRequestWrapper {

		private UserModel user;

		public AuthenticatedRequest(HttpServletRequest req) {
			super(req);
			user = DeepCopier.copy(UserModel.ANONYMOUS);
		}

		UserModel getUser() {
			return user;
		}

		void setUser(UserModel user) {
			this.user = user;
		}

		@Override
		public String getRemoteUser() {
			return user.username;
		}

		@Override
		public boolean isUserInRole(String role) {
			if (role.equals(Constants.ADMIN_ROLE)) {
				return user.canAdmin();
			}
			// Gitblit does not currently use actual roles in the traditional
			// servlet container sense.  That is the reason this is marked
			// deprecated, but I may want to revisit this.
			return user.hasRepositoryPermission(role);
		}

		@Override
		public Principal getUserPrincipal() {
			return user;
		}
	}
}
