# nginx.vh.default.conf  --  docker-openresty
#
# This file is installed to:
#   `/etc/nginx/conf.d/`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#

# cache for JWT verification results
lua_shared_dict introspection 10m;

server
{
	listen 443 ssl;

	# Cookie idletime in seconds. If a cookie is not used for this time, the session becomes invalid. By default this is set to 0 seconds, meaning it is disabled.
	set $session_cookie_idletime 1800;
	
	# needed to reuse a session, made in another tab
	set $session_cookie_samesite None;

	# adjust the values of this block for your system and the "proxy_pass" directive below
	# you can create "certificate.pem" und "private-key.pem" via:
	# openssl genrsa -out private-key.pem
	# openssl req -new -x509 -key private-key.pem -out certificate.pem
	set $tenant_id      '00000000-0000-0000-0000-000000000000';
	set $client_id      '00000000-0000-0000-0000-000000000000';
	set $client_secret  '000000000000000000000000000000000000';
	ssl_certificate     /etc/nginx/conf.d/certificate.pem;
	ssl_certificate_key /etc/nginx/conf.d/private-key.pem;

	location /
	{
		resolver 8.8.8.8;

		proxy_pass http://enaio-gateway:8083;
		proxy_set_header X-forwarded-host $host;
		proxy_buffering off;

		access_by_lua_block
		{
			local opts =
			{
				discovery = "https://login.microsoftonline.com/" .. ngx.var.tenant_id .. "/v2.0/.well-known/openid-configuration",
				client_id = ngx.var.client_id,
				client_secret = ngx.var.client_secret,
				redirect_uri_scheme = ngx.var.scheme,
				ssl_verify = "no",
				scope = "openid profile " .. ngx.var.client_id .. "/.default",
				redirect_uri_path = "/oauth2",
				post_logout_redirect_uri = ngx.var.scheme .. "://" .. ngx.var.host .. ":" .. ngx.var.server_port .. "/",
				logout_path = "/restylogout",
				session_contents = {user=true, id_token=true, enc_id_token=true},
			}

			local user = nil
			
			if
				ngx.req.get_headers().authorization == nil or
				string.find(ngx.req.get_headers().authorization,"Bearer") == nil
			then
				-- Anmeldung per Browser (grant_type=authorization_code)
				
				local res, err, url, session = require("resty.openidc").authenticate(opts)
				user = not(err) and session.data.id_token.preferred_username or nil
			else
				-- Anmeldung per Token
				-- im Benutzerkontext (grant_type=password) enthält "json.unique_name" den UPN, welcher ein "@"-Zeichen enthält
				-- im Service-Kontext (grant_type=client_credentials) ist "json.unique_name" leer, weswegen die Azure Object-ID benutzt wird
				
				local json, err, access_token = require("resty.openidc").bearer_jwt_verify(opts)
				user = not(err) and (json.unique_name ~= nil and json.unique_name or json.oid) or nil
				
				if err then
					ngx.status = ngx.HTTP_UNAUTHORIZED
					ngx.say(err)
					ngx.exit(ngx.HTTP_UNAUTHORIZED)
				end
			end
			
			-- optional den UPN verkürzen ("someone@sometenant.onmicrosoft.com" -> "someone")
			local shortname = ""
			
			for i = 1, #user do
				local c = user:sub(i,i)
				
				if c == "@" then break end
				
				shortname = shortname .. c
			end
			
			ngx.log(ngx.INFO, "#### Azure User " .. tostring(shortname) .. " ####")
			ngx.req.set_header("X-User", shortname)
		}
	}
}