/*
 * 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.catalina.filters;

import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;

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 javax.servlet.http.HttpSession;

/**
 * Provides basic CSRF protection for REST APIs. The filter assumes that the
 * clients have adapted the transfer of the nonce through the 'X-CSRF-Token'
 * header.
 *
 * <pre>
 * Positive scenario:
 *           Client                            Server
 *              |                                 |
 *              | GET Fetch Request              \| JSESSIONID
 *              |---------------------------------| X-CSRF-Token
 *              |                                /| pair generation
 *              |/Response to Fetch Request       |
 *              |---------------------------------|
 * JSESSIONID   |\                                |
 * X-CSRF-Token |                                 |
 * pair cached  | POST Request with valid nonce  \| JSESSIONID
 *              |---------------------------------| X-CSRF-Token
 *              |                                /| pair validation
 *              |/ Response to POST Request       |
 *              |---------------------------------|
 *              |\                                |
 *
 * Negative scenario:
 *           Client                            Server
 *              |                                 |
 *              | POST Request without nonce     \| JSESSIONID
 *              |---------------------------------| X-CSRF-Token
 *              |                                /| pair validation
 *              |/Request is rejected             |
 *              |---------------------------------|
 *              |\                                |
 *
 *           Client                            Server
 *              |                                 |
 *              | POST Request with invalid nonce\| JSESSIONID
 *              |---------------------------------| X-CSRF-Token
 *              |                                /| pair validation
 *              |/Request is rejected             |
 *              |---------------------------------|
 *              |\                                |
 * </pre>
 */
public class RestCsrfPreventionFilter extends CsrfPreventionFilterBase {
    private enum MethodType {
        NON_MODIFYING_METHOD, MODIFYING_METHOD
    }

    private static final Pattern NON_MODIFYING_METHODS_PATTERN = Pattern
            .compile("GET|HEAD|OPTIONS");

    private Set<String> pathsAcceptingParams = new HashSet<>();

    private String pathsDelimiter = ",";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            MethodType mType = MethodType.MODIFYING_METHOD;
            String method = ((HttpServletRequest) request).getMethod();
            if (method != null && NON_MODIFYING_METHODS_PATTERN.matcher(method).matches()) {
                mType = MethodType.NON_MODIFYING_METHOD;
            }

            RestCsrfPreventionStrategy strategy;
            switch (mType) {
            case NON_MODIFYING_METHOD:
                strategy = new FetchRequest();
                break;
            default:
                strategy = new StateChangingRequest();
                break;
            }

            if (!strategy.apply((HttpServletRequest) request, (HttpServletResponse) response)) {
                return;
            }
        }
        chain.doFilter(request, response);
    }

    private abstract static class RestCsrfPreventionStrategy {

        abstract boolean apply(HttpServletRequest request, HttpServletResponse response)
                throws IOException;

        protected String extractNonceFromRequestHeader(HttpServletRequest request, String key) {
            return request.getHeader(key);
        }

        protected String[] extractNonceFromRequestParams(HttpServletRequest request, String key) {
            return request.getParameterValues(key);
        }

        protected void storeNonceToResponse(HttpServletResponse response, String key, String value) {
            response.setHeader(key, value);
        }

        protected String extractNonceFromSession(HttpSession session, String key) {
            return session == null ? null : (String) session.getAttribute(key);
        }

        protected void storeNonceToSession(HttpSession session, String key, Object value) {
            session.setAttribute(key, value);
        }
    }

    private class StateChangingRequest extends RestCsrfPreventionStrategy {

        @Override
        public boolean apply(HttpServletRequest request, HttpServletResponse response)
                throws IOException {
            if (isValidStateChangingRequest(
                    extractNonceFromRequest(request),
                    extractNonceFromSession(request.getSession(false),
                            Constants.CSRF_REST_NONCE_SESSION_ATTR_NAME))) {
                return true;
            }

            storeNonceToResponse(response, Constants.CSRF_REST_NONCE_HEADER_NAME,
                    Constants.CSRF_REST_NONCE_HEADER_REQUIRED_VALUE);
            response.sendError(getDenyStatus(),
                    sm.getString("restCsrfPreventionFilter.invalidNonce"));
            return false;
        }

        private boolean isValidStateChangingRequest(String reqNonce, String sessionNonce) {
            return reqNonce != null && sessionNonce != null
                    && Objects.equals(reqNonce, sessionNonce);
        }

        private String extractNonceFromRequest(HttpServletRequest request) {
            String nonceFromRequest = extractNonceFromRequestHeader(request,
                    Constants.CSRF_REST_NONCE_HEADER_NAME);
            if ((nonceFromRequest == null || Objects.equals("", nonceFromRequest))
                    && !getPathsAcceptingParams().isEmpty()
                    && getPathsAcceptingParams().contains(getRequestedPath(request))) {
                nonceFromRequest = extractNonceFromRequestParams(request);
            }
            return nonceFromRequest;
        }

        private String extractNonceFromRequestParams(HttpServletRequest request) {
            String[] params = extractNonceFromRequestParams(request,
                    Constants.CSRF_REST_NONCE_HEADER_NAME);
            if (params != null && params.length > 0) {
                String nonce = params[0];
                for (String param : params) {
                    if (!Objects.equals(param, nonce)) {
                        return null;
                    }
                }
                return nonce;
            }
            return null;
        }
    }

    private class FetchRequest extends RestCsrfPreventionStrategy {

        @Override
        public boolean apply(HttpServletRequest request, HttpServletResponse response) {
            if (Constants.CSRF_REST_NONCE_HEADER_FETCH_VALUE
                    .equalsIgnoreCase(extractNonceFromRequestHeader(request,
                            Constants.CSRF_REST_NONCE_HEADER_NAME))) {
                String nonceFromSessionStr = extractNonceFromSession(request.getSession(false),
                        Constants.CSRF_REST_NONCE_SESSION_ATTR_NAME);
                if (nonceFromSessionStr == null) {
                    nonceFromSessionStr = generateNonce();
                    storeNonceToSession(Objects.requireNonNull(request.getSession(true)),
                            Constants.CSRF_REST_NONCE_SESSION_ATTR_NAME, nonceFromSessionStr);
                }
                storeNonceToResponse(response, Constants.CSRF_REST_NONCE_HEADER_NAME,
                        nonceFromSessionStr);
            }
            return true;
        }

    }

    /**
     * A comma separated list of URLs that can accept nonces via request
     * parameter 'X-CSRF-Token'. For use cases when a nonce information cannot
     * be provided via header, one can provide it via request parameters. If
     * there is a X-CSRF-Token header, it will be taken with preference over any
     * parameter with the same name in the request. Request parameters cannot be
     * used to fetch new nonce, only header.
     *
     * @param pathsList
     *            Comma separated list of URLs to be configured as paths
     *            accepting request parameters with nonce information.
     */
    public void setPathsAcceptingParams(String pathsList) {
        if (pathsList != null) {
            for (String element : pathsList.split(pathsDelimiter)) {
                    pathsAcceptingParams.add(element.trim());
            }
        }
    }

    public Set<String> getPathsAcceptingParams() {
        return pathsAcceptingParams;
    }
}
