package org.apache.archiva.redback.rest.services.interceptors;
/*
 * 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.
 */


import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.InvalidTokenException;
import org.apache.archiva.redback.authentication.TokenData;
import org.apache.archiva.redback.authentication.TokenManager;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.configuration.UserConfigurationKeys;
import org.apache.archiva.redback.integration.filter.authentication.basic.HttpBasicAuthentication;
import org.apache.archiva.redback.users.User;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Martin Stockhammer on 19.01.17.
 * <p>
 * This interceptor tries to check if requests come from a valid origin and
 * are not generated by another site on behalf of the real client.
 * <p>
 * We are using some of the techniques mentioned in
 * https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
 * <p>
 * Try to find Origin and Referer of the request.
 * Match them to the target address, that may be either statically configured or is determined
 * by the Host/X-Forwarded-For Header.
 */
@Provider
@Service( "requestValidationInterceptor#rest" )
@Priority( Priorities.PRECHECK )
public class RequestValidationInterceptor
    extends AbstractInterceptor
    implements ContainerRequestFilter, ContainerResponseFilter
{


    private static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";

    private static final String X_FORWARDED_HOST = "X-Forwarded-Host";

    private static final String X_XSRF_TOKEN = "X-XSRF-TOKEN";

    private static final String ORIGIN = "Origin";

    private static final String REFERER = "Referer";

    private static final int DEFAULT_HTTP = 80;

    private static final int DEFAULT_HTTPS = 443;

    private final Logger log = LoggerFactory.getLogger( getClass() );

    private boolean enabled = true;

    private boolean checkToken = true;

    private boolean useStaticUrl = false;

    private boolean denyAbsentHeaders = true;

    private List<URL> baseUrl = new ArrayList<URL>();

    private HttpServletRequest httpRequest = null;

    @Inject
    @Named( value = "httpAuthenticator#basic" )
    private HttpBasicAuthentication httpAuthenticator;

    @Inject
    @Named( value = "tokenManager#default" )
    TokenManager tokenManager;

    @Context
    private ResourceInfo resourceInfo;

    private UserConfiguration config;

    @Override
    public void filter( ContainerRequestContext requestContext, ContainerResponseContext responseContext ) throws IOException
    {
        responseContext.getHeaders().add(
            "Access-Control-Allow-Origin", "http://localhost:4200");
        responseContext.getHeaders().add(
            "Access-Control-Allow-Credentials", "true");
        responseContext.getHeaders().add(
            "Access-Control-Allow-Headers",
            "origin, content-type, accept, authorization");
        responseContext.getHeaders().add(
            "Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH");
    }

    private class HeaderValidationInfo
    {

        final static int UNKNOWN = -1;

        final static int OK = 0;

        final static int F_REFERER_HOST = 1;

        final static int F_REFERER_PORT = 2;

        final static int F_ORIGIN_HOST = 8;

        final static int F_ORIGIN_PORT = 16;

        final static int F_ORIGIN_PROTOCOL = 32;

        boolean headerFound = false;

        URL targetUrl;

        URL originUrl;

        URL refererUrl;

        String targetHost;

        String originHost;

        String refererHost;

        int targetPort;

        int originPort;

        int refererPort;

        int status = UNKNOWN;

        public HeaderValidationInfo( URL targetUrl )
        {
            setTargetUrl( targetUrl );
        }

        public URL getTargetUrl()
        {
            return targetUrl;
        }

        public void setTargetUrl( URL targetUrl )
        {
            this.targetUrl = targetUrl;
            this.targetHost = getHost( targetUrl );
            this.targetPort = getPort( targetUrl );
        }

        public URL getOriginUrl()
        {
            return originUrl;
        }

        public void setOriginUrl( URL originUrl )
        {
            this.originUrl = originUrl;
            this.originHost = getHost( originUrl );
            this.originPort = getPort( originUrl );
            checkOrigin();
            this.headerFound = true;
        }

        public URL getRefererUrl()
        {
            return refererUrl;
        }

        public void setRefererUrl( URL refererUrl )
        {
            this.refererUrl = refererUrl;
            this.refererHost = getHost( refererUrl );
            this.refererPort = getPort( refererUrl );
            checkReferer();
            this.headerFound = true;
        }

        public String getTargetHost()
        {
            return targetHost;
        }

        public void setTargetHost( String targetHost )
        {
            this.targetHost = targetHost;
        }

        public String getOriginHost()
        {
            return originHost;
        }

        public void setOriginHost( String originHost )
        {
            this.originHost = originHost;
        }

        public String getRefererHost()
        {
            return refererHost;
        }

        public void setRefererHost( String refererHost )
        {
            this.refererHost = refererHost;
        }

        public int getTargetPort()
        {
            return targetPort;
        }

        public void setTargetPort( int targetPort )
        {
            this.targetPort = targetPort;
        }

        public int getOriginPort()
        {
            return originPort;
        }

        public void setOriginPort( int originPort )
        {
            this.originPort = originPort;
        }

        public int getRefererPort()
        {
            return refererPort;
        }

        public void setRefererPort( int refererPort )
        {
            this.refererPort = refererPort;
        }

        public void setStatus( int status )
        {
            this.status |= status;
        }

        public int getStatus()
        {
            return this.status;
        }

        // Origin check for Protocol, Host, Port
        public void checkOrigin()
        {
            if ( this.getStatus() == UNKNOWN )
            {
                this.status = OK;
            }
            if ( !targetUrl.getProtocol().equals( originUrl.getProtocol() ) )
            {
                setStatus( F_ORIGIN_PROTOCOL );
            }
            if ( !targetHost.equals( originHost ) )
            {
                setStatus( F_ORIGIN_HOST );
            }
            if ( targetPort != originPort )
            {
                setStatus( F_ORIGIN_PORT );
            }
        }

        // Referer check only for Host, Port
        public void checkReferer()
        {
            if ( this.getStatus() == UNKNOWN )
            {
                this.status = OK;
            }
            if ( !targetHost.equals( refererHost ) )
            {
                setStatus( F_REFERER_HOST );
            }
            if ( targetPort != refererPort )
            {
                setStatus( F_REFERER_PORT );
            }
        }

        public boolean hasOriginError()
        {
            return ( status & ( F_ORIGIN_PROTOCOL | F_ORIGIN_HOST | F_ORIGIN_PORT ) ) > 0;
        }

        public boolean hasRefererError()
        {
            return ( status & ( F_REFERER_HOST | F_REFERER_PORT ) ) > 0;
        }

        @Override
        public String toString()
        {
            return "Stat=" + status + ", target=" + targetUrl + ", origin=" + originUrl + ", referer=" + refererUrl;
        }
    }

    @Inject
    public RequestValidationInterceptor( @Named( value = "userConfiguration#default" ) UserConfiguration config )
    {
        this.config = config;
    }

    @PostConstruct
    public void init()
    {
        List<String> baseUrlList = config.getList( UserConfigurationKeys.REST_BASE_URL );
        if ( baseUrlList != null )
        {
            for ( String baseUrlStr : baseUrlList )
            {
                if ( !"".equals( baseUrlStr.trim() ) )
                {
                    try
                    {
                        baseUrl.add( new URL( baseUrlStr ) );
                        useStaticUrl = true;
                    }
                    catch ( MalformedURLException ex )
                    {
                        log.error( "Configured baseUrl (rest.baseUrl={}) is invalid. Message: {}", baseUrlStr,
                            ex.getMessage() );
                    }
                }
            }
        }
        denyAbsentHeaders = config.getBoolean( UserConfigurationKeys.REST_CSRF_ABSENTORIGIN_DENY, true );
        enabled = config.getBoolean( UserConfigurationKeys.REST_CSRF_ENABLED, true );
        if ( !enabled )
        {
            log.info( "CSRF Filter is disabled by configuration" );
        }
        else
        {
            log.info( "CSRF Filter is enable" );
        }
        checkToken = !config.getBoolean( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, false );
        if ( !checkToken )
        {
            log.info( "CSRF Token validation is disabled by configuration" );
        }
        else
        {
            log.info( "CSRF Token validation is enable" );
        }
    }

    @Override
    public void filter( ContainerRequestContext containerRequestContext )
        throws IOException
    {

        if ( enabled )
        {

            final String requestPath = containerRequestContext.getUriInfo( ).getPath( );
            if (ignoreAuth( requestPath )) {
                return;
            }

            HttpServletRequest request = getRequest();
            List<URL> targetUrls = getTargetUrl( request );
            if ( targetUrls == null )
            {
                log.error( "Could not verify target URL." );
                containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                return;
            }
            List<HeaderValidationInfo> validationInfos = new ArrayList<HeaderValidationInfo>();
            boolean targetMatch = false;
            boolean noHeader = true;
            for ( URL targetUrl : targetUrls )
            {
                log.trace( "Checking against target URL: {}", targetUrl );
                HeaderValidationInfo info = checkSourceRequestHeader( new HeaderValidationInfo( targetUrl ), request );
                // We need only one match
                noHeader = noHeader && info.getStatus() == info.UNKNOWN;
                if ( info.getStatus() == info.OK )
                {
                    targetMatch = true;
                    break;
                }
                else
                {
                    validationInfos.add( info );
                }
            }
            if ( noHeader && denyAbsentHeaders )
            {
                log.warn( "Request denied. No Origin or Referer header found and {}=true",
                    UserConfigurationKeys.REST_CSRF_ABSENTORIGIN_DENY );
                containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                return;
            }
            if ( !targetMatch )
            {
                log.warn( "HTTP Header check failed. Assuming CSRF attack." );
                for ( HeaderValidationInfo info : validationInfos )
                {
                    if ( info.hasOriginError() )
                    {
                        log.warn(
                            "Origin Header does not match: originUrl={}, targetUrl={}. Matches: Host={}, Port={}, Protocol={}",
                            info.originUrl, info.targetUrl, ( info.getStatus() & info.F_ORIGIN_HOST ) == 0,
                            ( info.getStatus() & info.F_ORIGIN_PORT ) == 0,
                            ( info.getStatus() & info.F_ORIGIN_PROTOCOL ) == 0 );
                    }
                    if ( info.hasRefererError() )
                    {
                        log.warn(
                            "Referer Header does not match: refererUrl={}, targetUrl={}. Matches: Host={}, Port={}",
                            info.refererUrl, info.targetUrl, ( info.getStatus() & info.F_REFERER_HOST ) == 0,
                            ( info.getStatus() & info.F_REFERER_PORT ) == 0 );
                    }
                }
                containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                return;
            }
            if ( checkToken )
            {
                checkValidationToken( containerRequestContext, request );
            }
        }
    }

    /**
     * Checks the request for a validation token header. It takes the encrypted token, decrypts it
     * and compares the user information from the token to the logged in user.
     *
     * @param containerRequestContext
     * @param request
     */
    private void checkValidationToken( ContainerRequestContext containerRequestContext, HttpServletRequest request )
    {
        RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo );
        // We check only services that are restricted
        if ( !redbackAuthorization.noRestriction() )
        {
            String tokenString = request.getHeader( X_XSRF_TOKEN );
            if ( tokenString == null || tokenString.length() == 0 )
            {
                log.warn( "No validation token header found: {}", X_XSRF_TOKEN );
                containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                return;
            }

            try
            {
                TokenData td = tokenManager.decryptToken( tokenString );
                AuthenticationResult auth = getAuthenticationResult( containerRequestContext, httpAuthenticator, request );
                if ( auth == null )
                {
                    log.error( "Not authentication data found" );
                    containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                    return;
                }
                User loggedIn = auth.getUser();
                if ( loggedIn == null )
                {
                    log.error( "User not logged in" );
                    containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                    return;
                }
                String username = loggedIn.getUsername();
                if ( !td.isValid() || !td.getUser().equals( username ) )
                {
                    log.error( "Invalid data in validation token header {} for user {}: isValid={}, username={}",
                        X_XSRF_TOKEN, username, td.isValid(), td.getUser() );
                    containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                }
            }
            catch ( InvalidTokenException e )
            {
                log.error( "Token validation failed {}", e.getMessage() );
                containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
            }
        }
        log.debug( "Token validated" );
    }

    private HttpServletRequest getRequest()
    {
        if ( httpRequest != null )
        {
            return httpRequest;
        }
        else
        {
            return getHttpServletRequest( );
        }
    }

    private List<URL> getTargetUrl( HttpServletRequest request )
    {
        if ( useStaticUrl )
        {
            return baseUrl;
        }
        else
        {
            List<URL> urls = new ArrayList<URL>();
            URL requestUrl;
            try
            {
                requestUrl = new URL( request.getRequestURL().toString() );
                urls.add( requestUrl );
            }
            catch ( MalformedURLException ex )
            {
                log.error( "Bad Request URL {}, Message: {}", request.getRequestURL(), ex.getMessage() );
                return null;
            }
            String xforwarded = request.getHeader( X_FORWARDED_HOST );
            String xforwardedProto = request.getHeader( X_FORWARDED_PROTO );
            if ( xforwardedProto == null )
            {
                xforwardedProto = requestUrl.getProtocol();
            }

            if ( xforwarded != null && !StringUtils.isEmpty( xforwarded ) )
            {
                // X-Forwarded-Host header may contain multiple hosts if there is
                // more than one proxy between the client and the server
                String[] forwardedList = xforwarded.split( "\\s*,\\s*" );
                for ( String hostname : forwardedList )
                {
                    try
                    {
                        urls.add( new URL( xforwardedProto + "://" + hostname ) );
                    }
                    catch ( MalformedURLException ex )
                    {
                        log.warn( "X-Forwarded-Host Header is malformed: {}", ex.getMessage() );
                    }
                }
            }
            return urls;
        }
    }

    private int getPort( final URL url )
    {
        return url.getPort() > 0
            ? url.getPort()
            : ( "https".equals( url.getProtocol() ) ? DEFAULT_HTTPS : DEFAULT_HTTP );
    }

    private String getHost( final URL url )
    {
        return url.getHost().trim().toLowerCase();
    }

    /**
     * Checks the validation headers. First the Origin header is checked, if this fails
     * or is absent, the referer header is checked.
     *
     * @param info    The info object that must be populated with the targetURL
     * @param request The HTTP request object
     * @return A info object with updated status information
     */
    private HeaderValidationInfo checkSourceRequestHeader( final HeaderValidationInfo info,
                                                           final HttpServletRequest request )
    {
        String origin = request.getHeader( ORIGIN );
        if ( origin != null )
        {
            try
            {
                info.setOriginUrl( new URL( origin ) );
            }
            catch ( MalformedURLException e )
            {
                log.warn( "Bad origin header found: {}", origin );
            }
        }
        // Check referer if Origin header dos not match or is not available
        if ( info.getStatus() != info.OK )
        {
            String referer = request.getHeader( REFERER );
            if ( referer != null )
            {
                try
                {
                    info.setRefererUrl( new URL( referer ) );
                }
                catch ( MalformedURLException ex )
                {
                    log.warn( "Bad URL in Referer HTTP-Header: {}, Message: {}", referer, ex.getMessage() );
                }
            }
        }
        return info;
    }

    public void setHttpRequest( HttpServletRequest request )
    {
        this.httpRequest = request;
    }

}
