% 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.

-module(chttpd_cors).


-export([
    maybe_handle_preflight_request/1,
    maybe_handle_preflight_request/2,
    headers/2,
    headers/4
]).
-export([
    is_cors_enabled/1,
    get_cors_config/1
]).


-include_lib("couch/include/couch_db.hrl").
-include_lib("chttpd/include/chttpd_cors.hrl").


%% http://www.w3.org/TR/cors/#resource-preflight-requests

maybe_handle_preflight_request(#httpd{method=Method}) when Method /= 'OPTIONS' ->
    not_preflight;
maybe_handle_preflight_request(Req) ->
    case maybe_handle_preflight_request(Req, get_cors_config(Req)) of
        not_preflight ->
            not_preflight;
        {ok, PreflightHeaders} ->
            chttpd:send_response_no_cors(Req, 204, PreflightHeaders, <<>>)
    end.


maybe_handle_preflight_request(#httpd{}=Req, Config) ->
    case is_cors_enabled(Config) of
        true ->
            case preflight_request(Req, Config) of
                {ok, PreflightHeaders} ->
                    {ok, PreflightHeaders};
                not_preflight ->
                    not_preflight;
                UnknownError ->
                    couch_log:error(
                        "Unknown response of chttpd_cors:preflight_request(~p): ~p",
                        [Req, UnknownError]
                    ),
                    not_preflight
            end;
        false ->
            not_preflight
    end.


preflight_request(Req, Config) ->
    case get_origin(Req) of
        undefined ->
            %% If the Origin header is not present terminate this set of
            %% steps. The request is outside the scope of this specification.
            %% http://www.w3.org/TR/cors/#resource-preflight-requests
            not_preflight;
        Origin ->
            AcceptedOrigins = get_accepted_origins(Req, Config),
            AcceptAll = lists:member(<<"*">>, AcceptedOrigins),

            HandlerFun = fun() ->
                handle_preflight_request(Req, Config, Origin)
            end,

            %% We either need to accept all origins or have it listed
            %% in our origins. Origin can only contain a single origin
            %% as the user agent will not follow redirects [1]. If the
            %% value of the Origin header is not a case-sensitive
            %% match for any of the values in list of origins do not
            %% set any additional headers and terminate this set
            %% of steps [1].
            %%
            %% [1]: http://www.w3.org/TR/cors/#resource-preflight-requests
            %%
            %% TODO: Square against multi origin Security Considerations and the
            %% Vary header
            %%
            case AcceptAll orelse lists:member(Origin, AcceptedOrigins) of
                true -> HandlerFun();
                false -> not_preflight
            end
    end.


handle_preflight_request(Req, Config, Origin) ->
    case chttpd:header_value(Req, "Access-Control-Request-Method") of
    undefined ->
        %% If there is no Access-Control-Request-Method header
        %% or if parsing failed, do not set any additional headers
        %% and terminate this set of steps. The request is outside
        %% the scope of this specification.
        %% http://www.w3.org/TR/cors/#resource-preflight-requests
        not_preflight;
    Method ->
        SupportedMethods = get_origin_config(Config, Origin,
                <<"allow_methods">>, ?SUPPORTED_METHODS),

        SupportedHeaders = get_origin_config(Config, Origin,
                <<"allow_headers">>, ?SUPPORTED_HEADERS),


        %% get max age
        MaxAge = couch_util:get_value(<<"max_age">>, Config,
            ?CORS_DEFAULT_MAX_AGE),

        PreflightHeaders0 = maybe_add_credentials(Config, Origin, [
            {"Access-Control-Allow-Origin", binary_to_list(Origin)},
            {"Access-Control-Max-Age", MaxAge},
            {"Access-Control-Allow-Methods",
                string:join(SupportedMethods, ", ")}]),

        case lists:member(Method, SupportedMethods) of
            true ->
                %% method ok , check headers
                AccessHeaders = chttpd:header_value(Req,
                    "Access-Control-Request-Headers"),
                {FinalReqHeaders, ReqHeaders} = case AccessHeaders of
                    undefined -> {"", []};
                    "" -> {"", []};
                    Headers ->
                        %% transform header list in something we
                        %% could check. make sure everything is a
                        %% list
                        RH = [to_lower(H)
                              || H <- split_headers(Headers)],
                        {Headers, RH}
                end,
                %% check if headers are supported
                case ReqHeaders -- SupportedHeaders of
                [] ->
                    PreflightHeaders = PreflightHeaders0 ++
                                       [{"Access-Control-Allow-Headers",
                                         FinalReqHeaders}],
                    {ok, PreflightHeaders};
                _ ->
                    not_preflight
                end;
            false ->
            %% If method is not a case-sensitive match for any of
            %% the values in list of methods do not set any additional
            %% headers and terminate this set of steps.
            %% http://www.w3.org/TR/cors/#resource-preflight-requests
            not_preflight
        end
    end.


headers(Req, RequestHeaders) ->
    case get_origin(Req) of
        undefined ->
            %% If the Origin header is not present terminate
            %% this set of steps. The request is outside the scope
            %% of this specification.
            %% http://www.w3.org/TR/cors/#resource-processing-model
            RequestHeaders;
        Origin ->
            headers(Req, RequestHeaders, Origin, get_cors_config(Req))
    end.


headers(_Req, RequestHeaders, undefined, _Config) ->
    RequestHeaders;
headers(Req, RequestHeaders, Origin, Config) when is_list(Origin) ->
    headers(Req, RequestHeaders, ?l2b(string:to_lower(Origin)), Config);
headers(Req, RequestHeaders, Origin, Config) ->
    case is_cors_enabled(Config) of
        true ->
            AcceptedOrigins = get_accepted_origins(Req, Config),
            CorsHeaders = handle_headers(Config, Origin, AcceptedOrigins),
            ExposedCouchHeaders = couch_util:get_value(
                <<"exposed_headers">>, Config, ?COUCH_HEADERS),
            maybe_apply_headers(CorsHeaders, RequestHeaders, ExposedCouchHeaders);
        false ->
            RequestHeaders
    end.


maybe_apply_headers([], RequestHeaders, _ExposedCouchHeaders) ->
    RequestHeaders;
maybe_apply_headers(CorsHeaders, RequestHeaders, ExposedCouchHeaders) ->
    %% Find all non ?SIMPLE_HEADERS and and non ?SIMPLE_CONTENT_TYPE_VALUES,
    %% expose those through Access-Control-Expose-Headers, allowing
    %% the client to access them in the browser. Also append in
    %% ?COUCH_HEADERS, as further headers may be added later that
    %% need to be exposed.
    %% return: RequestHeaders ++ CorsHeaders ++ ACEH

    ExposedHeaders0 = simple_headers([K || {K,_V} <- RequestHeaders]),

    %% If Content-Type is not in ExposedHeaders, and the Content-Type
    %% is not a member of ?SIMPLE_CONTENT_TYPE_VALUES, then add it
    %% into the list of ExposedHeaders
    ContentType = proplists:get_value("content-type", ExposedHeaders0),
    IncludeContentType = case ContentType of
        undefined ->
            false;
        _ ->
            lists:member(string:to_lower(ContentType), ?SIMPLE_CONTENT_TYPE_VALUES)
        end,
    ExposedHeaders = case IncludeContentType of
        false ->
            ["content-type" | lists:delete("content-type", ExposedHeaders0)];
        true ->
            ExposedHeaders0
        end,

    %% ExposedCouchHeaders may get added later, so expose them by default
    ACEH = [{"Access-Control-Expose-Headers",
        string:join(ExposedHeaders ++ ExposedCouchHeaders, ", ")}],
    CorsHeaders ++ RequestHeaders ++ ACEH.


simple_headers(Headers) ->
    LCHeaders = [to_lower(H) || H <- Headers],
    lists:filter(fun(H) -> lists:member(H, ?SIMPLE_HEADERS) end, LCHeaders).


to_lower(String) when is_binary(String) ->
    to_lower(?b2l(String));
to_lower(String) ->
    string:to_lower(String).


handle_headers(_Config, _Origin, []) ->
    [];
handle_headers(Config, Origin, AcceptedOrigins) ->
    AcceptAll = lists:member(<<"*">>, AcceptedOrigins),
    case AcceptAll orelse lists:member(Origin, AcceptedOrigins) of
    true ->
        make_cors_header(Config, Origin);
    false ->
        %% If the value of the Origin header is not a
        %% case-sensitive match for any of the values
        %% in list of origins, do not set any additional
        %% headers and terminate this set of steps.
        %% http://www.w3.org/TR/cors/#resource-requests
        []
    end.


make_cors_header(Config, Origin) ->
    Headers = [{"Access-Control-Allow-Origin", binary_to_list(Origin)}],
    maybe_add_credentials(Config, Origin, Headers).


%% util


maybe_add_credentials(Config, Origin, Headers) ->
    case allow_credentials(Config, Origin) of
        false ->
            Headers;
        true ->
            Headers ++ [{"Access-Control-Allow-Credentials", "true"}]
    end.


allow_credentials(_Config, <<"*">>) ->
    false;
allow_credentials(Config, Origin) ->
    get_origin_config(Config, Origin, <<"allow_credentials">>,
        ?CORS_DEFAULT_ALLOW_CREDENTIALS).


get_cors_config(#httpd{cors_config = undefined, mochi_req = MochiReq}) ->
    Host = couch_httpd_vhost:host(MochiReq),

    EnableCors = config:get("httpd", "enable_cors", "false") =:= "true",
    AllowCredentials = cors_config(Host, "credentials", "false") =:= "true",

    AllowHeaders = case cors_config(Host, "headers", undefined) of
        undefined ->
            ?SUPPORTED_HEADERS;
        AllowHeaders0 ->
            [to_lower(H) || H <- split_list(AllowHeaders0)]
    end,
    AllowMethods = case cors_config(Host, "methods", undefined) of
        undefined ->
            ?SUPPORTED_METHODS;
        AllowMethods0 ->
            split_list(AllowMethods0)
    end,
    ExposedHeaders = case cors_config(Host, "exposed_headers", undefined) of
        undefined ->
            ?COUCH_HEADERS;
        ExposedHeaders0 ->
            [to_lower(H) || H <- split_list(ExposedHeaders0)]
    end,
    MaxAge = cors_config(Host, "max_age", ?CORS_DEFAULT_MAX_AGE),
    Origins0 = binary_split_list(cors_config(Host, "origins", [])),
    Origins = [{O, {[]}} || O <- Origins0],
    [
        {<<"enable_cors">>, EnableCors},
        {<<"allow_credentials">>, AllowCredentials},
        {<<"allow_methods">>, AllowMethods},
        {<<"allow_headers">>, AllowHeaders},
        {<<"exposed_headers">>, ExposedHeaders},
        {<<"max_age">>, MaxAge},
        {<<"origins">>, {Origins}}
    ];
get_cors_config(#httpd{cors_config = Config}) ->
    Config.


cors_config(Host, Key, Default) ->
    config:get(cors_section(Host), Key,
        config:get("cors", Key, Default)).


cors_section(HostValue) ->
    HostPort = maybe_strip_scheme(HostValue),
    Host = hd(string:tokens(HostPort, ":")),
    "cors:" ++ Host.


maybe_strip_scheme(Host) ->
    case string:str(Host, "://") of
        0 -> Host;
        N -> string:substr(Host, N + 3)
    end.


is_cors_enabled(Config) ->
    case get(disable_couch_httpd_cors) of
        undefined ->
            put(disable_couch_httpd_cors, true);
        _ ->
            ok
    end,
    couch_util:get_value(<<"enable_cors">>, Config, false).


%% Get a list of {Origin, OriginConfig} tuples
%% ie: get_origin_configs(Config) ->
%% [
%%     {<<"http://foo.com">>,
%%         {
%%             [
%%                 {<<"allow_credentials">>, true},
%%                 {<<"allow_methods">>, [<<"POST">>]}
%%             ]
%%         }
%%     },
%%     {<<"http://baz.com">>, {[]}}
%% ]
get_origin_configs(Config) ->
    {Origins} = couch_util:get_value(<<"origins">>, Config, {[]}),
    Origins.


%% Get config for an individual Origin
%% ie: get_origin_config(Config, <<"http://foo.com">>) ->
%% [
%%     {<<"allow_credentials">>, true},
%%     {<<"allow_methods">>, [<<"POST">>]}
%% ]
get_origin_config(Config, Origin) ->
    OriginConfigs = get_origin_configs(Config),
    {OriginConfig} = couch_util:get_value(Origin, OriginConfigs, {[]}),
    OriginConfig.


%% Get config of a single key for an individual Origin
%% ie: get_origin_config(Config, <<"http://foo.com">>, <<"allow_methods">>, [])
%% [<<"POST">>]
get_origin_config(Config, Origin, Key, Default) ->
    OriginConfig = get_origin_config(Config, Origin),
    couch_util:get_value(Key, OriginConfig,
        couch_util:get_value(Key, Config, Default)).


get_origin(Req) ->
    case chttpd:header_value(Req, "Origin") of
        undefined ->
            undefined;
        Origin ->
            ?l2b(Origin)
    end.


get_accepted_origins(_Req, Config) ->
    lists:map(fun({K,_V}) -> K end, get_origin_configs(Config)).


split_list(S) ->
    re:split(S, "\\s*,\\s*", [trim, {return, list}]).


binary_split_list(S) ->
    [list_to_binary(E) || E <- split_list(S)].


split_headers(H) ->
    re:split(H, ",\\s*", [{return,list}, trim]).
