log_format main
    '$remote_addr - $remote_user [$time_local] "$customrequest" '
    '$status $body_bytes_sent "$customreferer" "$http_user_agent" "$sent_http_x_powered_by" '
    '$request_length $msec $request_time $upstream_addr '
    '$upstream_response_length $upstream_response_time $upstream_status';

# the Referer can be a provisioning URL, key included; mask it all when its path
# has escapes or dot segments, which could hide one
map $http_referer $customreferer {
        "~^[^?#]*(%|/\.)" "XXXXXXXX";
        "~(?i)^(.*?/+device/+provisioning/+)[^/?]*(.*)$" "$1XXXXXXXX$2";
        default $http_referer;
}

# provisioning key in a request line whose $uri normalized to another path
map $request $keymaskedrequest {
        "~(?i)^(\S+\s+(?:[a-z][a-z0-9+.-]*://[^/\s]*)?/+device/+provisioning/+)[^/?\s]*(.*)$" "$1XXXXXXXX$2";
        default $request;
}

map $keymaskedrequest $tokenmaskedrequest {
        "~^(.*)token=([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4})([a-fA-F0-9]{8})(.*)" "$1token=XXXXXXXX-XXXX-XXXX-XXXX-XXXX$3$4";
        "~^(.*)\/token\/([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4})([a-fA-F0-9]{8})(.*)" "$1/token/XXXXXXXX-XXXX-XXXX-XXXX-XXXX$3$4";
        default $keymaskedrequest;
}

# Requests rejected before their URI was parsed have an empty $uri: mask the
# whole request target, it can't be told apart from a provisioning key.
map $request $maskedtargetrequest {
        "~^(\S+\s+)\S+(.*)$" "$1XXXXXXXX$2";
        default $request;
}

# Mask the provisioning key (first segment after /device/provisioning/) on the
# normalized $uri, so an encoded request line can't escape the masking.
map $uri $customrequest {
        "~(?s)^/device/provisioning/[^/]*(.*)$" "$request_method /device/provisioning/XXXXXXXX$1$is_args$args $server_protocol";
        "" $maskedtargetrequest;
        default $tokenmaskedrequest;
}

# For the plain HTTP provisioning server of wazo-provd (generated by xivo-config):
# with http_auth_strategy url_key, the first path segment is the key.
log_format provd
    '$remote_addr - $remote_user [$time_local] "$provdrequest" '
    '$status $body_bytes_sent "-" "$http_user_agent" "$sent_http_x_powered_by" '
    '$request_length $msec $request_time $upstream_addr '
    '$upstream_response_length $upstream_response_time $upstream_status';

map $uri $provdrequest {
        "~(?s)^/[^/]*(.*)$" "$request_method /XXXXXXXX$1$is_args$args $server_protocol";
        default $maskedtargetrequest;
}

# The noauth zone is meant to be applied to ressources that are unauthenticated
# Limits are applied to each individual IP addresses. Be careful with this limit
# a single IP address could be used by many users.
limit_req_zone $binary_remote_addr zone=noauth:10m rate=25r/s;

# Entry point for internal service-to-service requests. Address-specific listeners
# take precedence over the wildcard :80 below, which still redirects to https.
server {
    listen 127.0.0.1:80;
    listen [::1]:80;  # localhost resolves to ::1 first
    server_name _;

    access_log /var/log/nginx/wazo-internal.access.log main;
    error_log /var/log/nginx/wazo-internal.error.log;

    # internal requests were sent directly to the service before: no 1m body cap
    client_max_body_size 0;

    # no wazo-no-auth-shared.conf: its zone keys on the client IP and every internal
    # client shares 127.0.0.1
    include /etc/nginx/locations/http-enabled/*;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    access_log /var/log/nginx/wazo.access.log main;
    error_log /var/log/nginx/wazo.error.log;
    root /var/www/html;

    return 301 https://$host$request_uri;
}

server {
    listen 443 default_server ssl;
    listen [::]:443 default_server ssl;
    server_name _;

    access_log /var/log/nginx/wazo.access.log main;
    error_log /var/log/nginx/wazo.error.log;
    root /var/www/html;

    include /etc/nginx/locations/https-enabled/*;

    gzip off; # gzipping SSL encripted data is a waste of time
    fastcgi_param HTTPS on;
    ssl_certificate /usr/share/wazo-certs/server.crt;
    ssl_certificate_key /usr/share/wazo-certs/server.key;
    ssl_ciphers ALL:!aNULL:!eNULL:!LOW:!EXP:!RC4:!3DES:!SEED:+HIGH:+MEDIUM;
    ssl_protocols TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=31536000";
}
