Repository: Mailu/Mailu

Issue:
Certdump: Make acme.json as a variable - enhancement
## Environment & Version

### Environment

- [x] docker-compose
- [ ] kubernetes
- [ ] docker swarm

### Version

- Version: `1.9`

## Description
I am using Traefik as reverse proxy and Traefik can handle multiple domain names for one host. For this reason i setup Traefik to store for each domain the certificates in different files, e. g. `acme-<domain>.json`
Certdumps script has a hardcoded point to acme.json in a specific folder. I mounted the volume of Traefik which contains the acme files.
Without editing the script in the running Certdump container i can't get the updated certificate that is done by Traefik

## Replication Steps
Store cert in a separate file.
traefik.yml:
```
certificatesResolvers:
  letsencrypt-<domain>:
    acme:
      email: certificate@example.com
      storage: /data/acme-<domain>.json
      tlsChallenge: {}
```
Using the cert resolver for Mailu.
Mailu docker-compose:
```
traefik.http.routers.mailu.tls.certresolver=letsencrypt-<domain>
```
Mount the acme.json folder to certdump
Mailu docker-compose:
```
certdumper:
    image: ${DOCKER_REGISTRY}/${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}traefik-certdumper:${MAILU_VERSION:-1.9}
    container_name: mailu_certdump-1.9
    restart: always
    environment:
      - DOMAIN=mail.<fqdn>
      - TRAEFIK_VERSION=${TRAEFIK_VERSION}
    volumes:
      - /etc/localtime:/etc/localtime:ro
      # Folder, which contains the acme.json
      - "traefik_data:/traefik:ro"
      # Folder, where cert.pem and key.pem will be written
      - "certdumper-data-1.9:/output"
```
## Observed behaviour
In the Traefik folder is still an old acme.json file with expired certificates. Certdump always takes acme.json until I change it manually in `run.sh` script. Of course this works only until the container will be deployed again.
## Expected behaviour
Certdump should not take hardcoded acme.json
## Logs
Not necessary.



Discussion:

Resolving patch:
diff --git a/core/admin/mailu/internal/views/auth.py b/core/admin/mailu/internal/views/auth.py
--- a/core/admin/mailu/internal/views/auth.py
+++ b/core/admin/mailu/internal/views/auth.py
@@ -28,8 +28,6 @@ def nginx_authentication():
         response = flask.Response()
         response.headers['Auth-Status'] = status
         response.headers['Auth-Error-Code'] = code
-        if int(flask.request.headers['Auth-Login-Attempt']) < 10:
-            response.headers['Auth-Wait'] = '3'
         return response
     raw_password = urllib.parse.unquote(headers['Auth-Pass']) if 'Auth-Pass' in headers else ''
     headers = nginx.handle_authentication(flask.request.headers)
@@ -45,8 +43,6 @@ def nginx_authentication():
             response = flask.Response()
             response.headers['Auth-Status'] = status
             response.headers['Auth-Error-Code'] = code
-            if int(flask.request.headers['Auth-Login-Attempt']) < 10:
-                response.headers['Auth-Wait'] = '3'
             return response
         is_valid_user = True
     if headers.get("Auth-Status") == "OK":
diff --git a/core/nginx/letsencrypt.py b/core/nginx/letsencrypt.py
--- a/core/nginx/letsencrypt.py
+++ b/core/nginx/letsencrypt.py
@@ -1,9 +1,15 @@
 #!/usr/bin/env python3
 
+import logging as log
 import os
-import time
+import requests
+import sys
 import subprocess
+import time
+from threading import Thread
+from http.server import HTTPServer, SimpleHTTPRequestHandler
 
+log.basicConfig(stream=sys.stderr, level="WARNING")
 hostnames = ','.join(set(host.strip() for host in os.environ['HOSTNAMES'].split(',')))
 
 command = [
@@ -39,8 +45,34 @@
 # Wait for nginx to start
 time.sleep(5)
 
+class MyRequestHandler(SimpleHTTPRequestHandler):
+    def do_GET(self):
+        if self.path == '/testing':
+            self.send_response(204)
+        else:
+            self.send_response(404)
+        self.send_header('Content-Type', 'text/plain')
+        self.end_headers()
+
+def serve_one_request():
+    with HTTPServer(("0.0.0.0", 8008), MyRequestHandler) as server:
+        server.handle_request()
+
 # Run certbot every day
 while True:
+    while True:
+        hostname = os.environ['HOSTNAMES'].split(' ')[0]
+        target = f'http://{hostname}/.well-known/acme-challenge/testing'
+        thread = Thread(target=serve_one_request)
+        thread.start()
+        r = requests.get(target)
+        if r.status_code != 204:
+            log.error(f"Can't reach {target}!, please ensure it's fixed or change the TLS_FLAVOR.")
+            time.sleep(5)
+        else:
+            break
+        thread.join()
+
     subprocess.call(command)
     subprocess.call(command2)
     time.sleep(86400)


Test patch: