#Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
#Copyright (C) 2024 HTWKalender support@htwkalender.de

#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU Affero General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU Affero General Public License for more details.

#You should have received a copy of the GNU Affero General Public License
#along with this program.  If not, see <https://www.gnu.org/licenses/>.

worker_processes  4;

error_log  /opt/bitnami/nginx/logs/error.log;
pid        /opt/bitnami/nginx/tmp/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # Cloudflare IP Ranges (https://www.cloudflare.com/ips/)
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 2400:cb00::/32;
    set_real_ip_from 2606:4700::/32;
    set_real_ip_from 2803:f800::/32;
    set_real_ip_from 2405:b500::/32;
    set_real_ip_from 2405:8100::/32;
    set_real_ip_from 2a06:98c0::/29;
    set_real_ip_from 2c0f:f248::/32;

    # Docker IP Ranges (https://docs.docker.com/network/iptables/)
    set_real_ip_from 172.16.0.0/12;
    set_real_ip_from 141.57.0.0/16;

    real_ip_header CF-Connecting-IP;

    access_log  /opt/bitnami/nginx/logs/proxy_access.log;
    error_log   /opt/bitnami/nginx/logs/proxy_error.log;

    sendfile        on;
    keepalive_timeout  180s;
    send_timeout 180s;

    map $request_method $cache_bypass {
        default 0;
        POST 1;
        PUT 1;
        DELETE 1;
    }

    client_body_temp_path /opt/bitnami/nginx/tmp/client_temp;
    proxy_temp_path       /opt/bitnami/nginx/tmp/proxy_temp_path;
    fastcgi_temp_path     /opt/bitnami/nginx/tmp/fastcgi_temp;
    uwsgi_temp_path       /opt/bitnami/nginx/tmp/uwsgi_temp;
    scgi_temp_path        /opt/bitnami/nginx/tmp/scgi_temp;

    proxy_cache_path /dev/shm levels=1:2 keys_zone=mcache:16m inactive=600s max_size=512m;
    proxy_cache_methods GET HEAD;
    proxy_cache_min_uses 1;
    proxy_cache_key "$request_method$host$request_uri";
    proxy_cache_use_stale timeout updating;
    proxy_ignore_headers Cache-Control Expires Set-Cookie;

    proxy_buffering on;
    proxy_buffers 8 16k;
    proxy_buffer_size 16k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_max_temp_file_size 1024m;

    proxy_set_header    X-Forwarded-Host   $host;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto  $scheme;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    Host               $host;

    geo $admin {
        default 1;
        10.0.0.0/8 0;     # Private Network
        127.0.0.0/8 0;    # Localhost Network
        192.168.0.0/16 0; # Localhost Network
        141.57.0.0/16 0;  # HTWK Leipzig Network
        172.16.0.0/12 0;  # Private Network
    }

    map $admin $limit_key {
        0 "";
        1 $binary_remote_addr;
    }

    # Different rate limits for different request methods
    map $request_method $ratelimit_key {
        POST     $binary_remote_addr;
        default  "";
    }

    limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/m;

    # Limit the number of requests per IP
    limit_req_zone $limit_key zone=feed:20m rate=20r/m;
    limit_req_zone $limit_key zone=modules:10m rate=30r/m;

    server {
        listen              80;
        listen              [::]:80;
        http2               on;
        server_name         dev.htwkalender.de;
        return 301 https://$host$request_uri;
    }

    server {
        listen              443 ssl;
        listen              [::]:443 ssl;
        http2               on;
        server_name         dev.htwkalender.de;
        ssl_certificate     dev_htwkalender_de.pem;
        ssl_certificate_key dev_htwkalender_de.key.pem;

        location /api/feed {
            limit_req zone=createFeed nodelay;
            limit_req zone=feed burst=10 nodelay;
            proxy_pass http://htwkalender-ical:8091;
            client_max_body_size 2m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
            limit_req_status 429;
        }

        location /api {
            proxy_pass http://htwkalender-data-manager:8090;
            client_max_body_size 20m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
        }

        # Cache only specific URI
        location /api/modules {
            proxy_pass http://htwkalender-data-manager:8090;
            client_max_body_size 20m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
            proxy_cache_bypass 0;
            proxy_no_cache     0;
            proxy_cache        mcache; # mcache=RAM
            proxy_cache_valid 200 301 302  10m;
            proxy_cache_valid 403 404      5m;
            proxy_cache_lock   on;
            proxy_cache_use_stale timeout updating;
            add_header X-Proxy-Cache $upstream_cache_status;
            limit_req zone=modules burst=5 nodelay;
        }

        location /api/rooms {
            proxy_pass http://htwkalender-data-manager:8090;
            client_max_body_size 20m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
            proxy_cache_bypass 0;
            proxy_no_cache     0;
            proxy_cache        mcache; # mcache=RAM
            proxy_cache_valid 200 301 302  10m;
            proxy_cache_valid 403 404      5m;
            proxy_cache_lock   on;
            proxy_cache_use_stale timeout updating;
            add_header X-Proxy-Cache $upstream_cache_status;
            limit_req zone=modules burst=5 nodelay;
        }

        location /api/schedule {
            proxy_pass http://htwkalender-data-manager:8090;
            client_max_body_size 20m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
            proxy_cache_bypass 0;
            proxy_no_cache     0;
            proxy_cache        mcache; # mcache=RAM
            proxy_cache_valid 200 301 302  10m;
            proxy_cache_valid 403 404      5m;
            proxy_cache_lock   on;
            proxy_cache_use_stale timeout updating;
            add_header X-Proxy-Cache $upstream_cache_status;
            limit_req zone=modules burst=30 nodelay;
        }

        location /api/courses {
            proxy_pass http://htwkalender-data-manager:8090;
            client_max_body_size 20m;
            proxy_connect_timeout 600s;
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout 600s;
            proxy_cache_bypass 0;
            proxy_no_cache     0;
            proxy_cache        mcache; # mcache=RAM
            proxy_cache_valid 200 301 302  10m;
            proxy_cache_valid 403 404      5m;
            proxy_cache_lock   on;
            proxy_cache_use_stale timeout updating;
            add_header X-Proxy-Cache $upstream_cache_status;
            limit_req zone=modules burst=5 nodelay;
        }

        location /_ {
            proxy_pass http://htwkalender-data-manager:8090;
            # if user is not 0 in admin list, return 404
            if ($admin) {
                return 404 "Not Found";
            }
            # Increase upload file size
            client_max_body_size 100m;
        }

        location / {
            proxy_pass http://htwkalender-frontend:8000;
        }
    }
}
