/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.qpid.server.management.plugin.filter;

import java.io.IOException;
import java.security.AccessControlException;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
import org.apache.qpid.server.management.plugin.HttpManagementUtil;
import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.security.auth.ManagementConnectionPrincipal;
import org.apache.qpid.server.util.ConnectionScopedRuntimeException;

public class AuthenticationCheckFilter implements Filter
{
    public static final String INIT_PARAM_ALLOWED = "allowed";
    private String _allowed = null;

    private Broker _broker;
    private HttpManagementConfiguration _managementConfiguration;

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException
    {
        String allowed = filterConfig.getInitParameter(INIT_PARAM_ALLOWED);
        if (allowed != null && !"".equals(allowed))
        {
            _allowed = allowed;
        }
        ServletContext servletContext = filterConfig.getServletContext();
        _broker = HttpManagementUtil.getBroker(servletContext);
        _managementConfiguration = HttpManagementUtil.getManagementConfiguration(servletContext);
    }

    @Override
    public void destroy()
    {

    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException
    {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        boolean isPreemptiveAuthentication = false;

        try
        {
            Subject subject = HttpManagementUtil.getAuthorisedSubject(httpRequest);

            if (subject == null)
            {
                if (_allowed != null && httpRequest.getServletPath().startsWith(_allowed))
                {
                    subject = new Subject(true,
                                          Collections.<Principal>singleton(new ServletConnectionPrincipal(httpRequest)),
                                          Collections.emptySet(),
                                          Collections.emptySet());
                }
                else
                {
                    subject = tryPreemptiveAuthentication(httpRequest);
                    isPreemptiveAuthentication = true;
                }
            }
            else
            {
                Set<Principal> principals = subject.getPrincipals();
                Set<Principal> newPrincipals = new LinkedHashSet<>();
                for (Principal principal : principals)
                {
                    if (!(principal instanceof ManagementConnectionPrincipal))
                    {
                        newPrincipals.add(principal);
                    }
                }
                subject = new Subject(false,
                                      principals, subject.getPublicCredentials(), subject.getPrivateCredentials());
                ServletConnectionPrincipal principal = new ServletConnectionPrincipal(httpRequest);
                subject.getPrincipals().add(principal);
                subject.setReadOnly();
            }

            doFilterChainAs(request, response, chain, subject);
        }
        catch (AccessControlException e)
        {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            invalidateSession(httpRequest);
            return;
        }
        catch (SecurityException e)
        {
            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            invalidateSession(httpRequest);
            return;
        }
        finally
        {
            if (isPreemptiveAuthentication)
            {
                invalidateSession(httpRequest);
            }
        }
    }

    private void doFilterChainAs(final ServletRequest request,
                                 final ServletResponse response,
                                 final FilterChain chain,
                                 final Subject subject) throws IOException, ServletException
    {
        try
        {
            Subject.doAs(subject, new PrivilegedExceptionAction<Void>()
            {
                @Override
                public Void run() throws IOException, ServletException
                {
                    chain.doFilter(request, response);
                    return null;
                }
            });
        }
        catch (PrivilegedActionException e)
        {
            Throwable cause = e.getCause();

            if (cause instanceof IOException)
            {
                throw (IOException) cause;
            }
            else if (cause instanceof ServletException)
            {
                throw (ServletException) cause;
            }
            else if (cause instanceof Error)
            {
                throw (Error) cause;
            }
            else if (cause instanceof RuntimeException)
            {
                throw (RuntimeException) cause;
            }

            throw new ConnectionScopedRuntimeException(e.getCause());
        }
    }

    private Subject tryPreemptiveAuthentication(final HttpServletRequest httpRequest)
    {
        Subject subject = HttpManagementUtil.tryToAuthenticate(httpRequest, _managementConfiguration);
        if (subject == null)
        {
            throw new SecurityException("Only authenticated users can access the management interface");
        }

        subject = HttpManagementUtil.createServletConnectionSubject(httpRequest, subject);

        HttpManagementUtil.assertManagementAccess(_broker, subject);

        return subject;
    }

    private void invalidateSession(final HttpServletRequest httpRequest)
    {
        HttpSession session = httpRequest.getSession(false);
        if (session != null)
        {
            session.invalidate();
        }
    }
}
