package org.mifosng.platform.infrastructure;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

/**
 *
 */
public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFilter {

	@Autowired
	private TenantDetailsService tenantDetailsService;
	
	private String tenantRequestHeader = "X-Mifos-Platform-TenantId";
	private boolean exceptionIfHeaderMissing = true;
	
	public TenantAwareBasicAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) {
		super(authenticationManager, authenticationEntryPoint);
	}
	
	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		try {
		
			if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
				// ignore to allow 'preflight' requests from AJAX applications in different domain
			} else {
			
				final String tenantId = request.getHeader(tenantRequestHeader);
		
				if (tenantId == null && exceptionIfHeaderMissing) {
					throw new InvalidTenantIdentiferException(tenantRequestHeader + " header not found in request.");
				}
				
				// check tenants database for tenantId
				MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId);
				
				ThreadLocalContextUtil.setTenant(tenant);
			}
		
			super.doFilter(req, res, chain);
		} catch (InvalidTenantIdentiferException e) {
			// deal with exception at low level
			SecurityContextHolder.getContext().setAuthentication(null);

			response.addHeader("WWW-Authenticate", "Basic realm=\"" + "Mifos Platform API" + "\"");
	        response.sendError(HttpServletResponse.SC_BAD_REQUEST, tenantRequestHeader + " header not found in request.");
		} finally {
			
		}
	}
}
@@ -1594,14 +1594,8 @@
 %09%09%09%09
-final 
 Stri
@@ -1654,163 +1654,395 @@
 ;%0A%09%09
-%0A%09%09%09%09if (tenantId == null && exceptionIfHeaderMissing) %7B%0A%09%09%09%09%09throw new InvalidTenantIdentiferException(tenantRequestHeader + %22 header not found in
+%09%09if (org.apache.commons.lang.StringUtils.isBlank(tenantId)) %7B%0A%09%09%09%09%09tenantId = request.getParameter(%22tenantIdentifier%22);%0A%09%09%09%09%7D%0A%09%09%0A%09%09%09%09if (tenantId == null && exceptionIfHeaderMissing) %7B%0A%09%09%09%09%09throw new InvalidTenantIdentiferException(%22No tenant identifier found: Add request header of '%22 + tenantRequestHeader +%0A%09%09%09%09%09%09%09%22' or add the parameter 'tenantIdentifier' to query string of
  request
 .%22);
@@ -2033,24 +2033,28 @@
 g of request
+ URL
 .%22);%0A%09%09%09%09%7D%0A%09
@@ -2590,61 +2590,22 @@
 ST, 
-tenantRequestHeader + %22 header not found in request.%22
+e.getMessage()
 );%0A%09

support passing tenant identifer through query string param to ease documentation interaction support.