From ad4c4de05f232bda1b1becfb2625e8f6454b3a1b Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Wed, 21 Apr 2021 21:43:05 +0300
Subject: [PATCH] First draft.

Depends on my fork of flask-simpleldap.
---
 .dockerignore    |  2 ++
 Dockerfile       | 17 +++++++++------
 README.md        |  7 ++++++
 app.py           | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 requirements.txt |  4 ++++
 5 files changed, 80 insertions(+), 6 deletions(-)
 create mode 100644 app.py
 create mode 100644 requirements.txt

diff --git a/.dockerignore b/.dockerignore
index 72e8ffc..6ca01de 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1 +1,3 @@
 *
+!app.py
+!requirements.txt
diff --git a/Dockerfile b/Dockerfile
index 6a5e2bf..8163793 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,11 +3,13 @@ FROM registry.hub.docker.com/library/python:3.9-slim-buster as wheels
 RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get install -y \
         build-essential \
+        git \
         libldap2-dev \
         libsasl2-dev \
     ;
 WORKDIR /wheels
 RUN python3 -m pip wheel https://github.com/python-ldap/python-ldap/releases/download/python-ldap-3.3.1/python-ldap-3.3.1.tar.gz
+RUN python3 -m pip wheel git+https://github.com/adarnimrod/flask-simpleldap.git@ldapi-support#egg=flask-simpleldap
 
 FROM registry.hub.docker.com/library/python:3.9-slim-buster
 # hadolint ignore=DL3008
@@ -19,9 +21,12 @@ RUN apt-get update && \
     rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*
 COPY --from=wheels /wheels/*.whl /wheels/
 RUN pip install /wheels/*.whl
-# hadolint ignore=DL3013
-RUN pip install --no-cache-dir \
-        flask \
-        flask-ldap \
-        gunicorn \
-    ;
+WORKDIR /app
+COPY requirements.txt ./
+RUN pip install --no-cache-dir -r requirements.txt
+COPY * ./
+USER nobody
+EXPOSE 8080
+ENV FORWARDED_ALLOW_IPS "*"
+HEALTHCHECK CMD wget --spider --quiet http://localhost:8080/ping --user-agent 'Docker Healthcheck' || exit 1
+CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--log-file", "-", "--workers", "2", "app:app"]
diff --git a/README.md b/README.md
index 9dafa16..99ea348 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,13 @@
 
 LDAP authentication webserver to use with Nginx' auth\_request.
 
+## Configuration
+
+All of the configuration is done with environment variables. For the
+complete list see <https://flask-simpleldap.readthedocs.io/en/latest/#configuration>
+and
+<https://flask.palletsprojects.com/en/1.1.x/config/#configuring-from-environment-variables>.
+
 ## License
 
 This software is licensed under the MIT license (see `LICENSE.txt`).
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..ba058c4
--- /dev/null
+++ b/app.py
@@ -0,0 +1,56 @@
+"""LDAP authentication webserver to use with Nginx' auth_request."""
+# pylint: disable=import-error
+
+import os
+from flask import Flask
+from flask_simpleldap import LDAP
+
+app = Flask(__name__)
+app.config["SECRET_KEY"] = os.getenv("SECRET_KEY", os.urandom(16))
+app.config["LDAP_SCHEMA"] = os.getenv("LDAP_SCHEMA", "ldapi")
+app.config["LDAP_HOST"] = os.getenv("LDAP_HOST", "localhost")
+app.config["LDAP_PORT"] = int(os.getenv("LDAP_PORT", "389"))
+app.config["LDAP_USERNAME"] = os.getenv("LDAP_USERNAME")
+app.config["LDAP_PASSWORD"] = os.getenv("LDAP_PASSWORD")
+app.config["LDAP_USE_TLS"] = (
+    os.getenv("LDAP_USE_TLS", "false").lower() == "true"
+)
+app.config["LDAP_REQUIRE_CERT"] = (
+    os.getenv("LDAP_REQUIRE_CERT", "false").lower() == "true"
+)
+app.config["LDAP_BASE_DN"] = os.getenv("LDAP_BASE_DN")
+app.config["LDAP_REALM_NAME"] = os.getenv(
+    "LDAP_REALM_NAME", "LDAP authentication"
+)
+app.config["LDAP_OPENLDAP"] = (
+    os.getenv("LDAP_OPENLDAP", "false").lower() == "true"
+)
+app.config["LDAP_OBJECTS_DN"] = os.getenv(
+    "LDAP_OBJECTS_DN", "distinguishedName"
+)
+app.config["LDAP_USER_OBJECT_FILTER"] = os.getenv(
+    "LDAP_USER_OBJECT_FILTER", "(&(objectclass=Person)(userPrincipalName=%s))"
+)
+
+ldap = LDAP(app)
+
+
+@app.route("/ping")
+def ping():
+    """Healthcheck."""
+    return "pong"
+
+
+@app.route("/")
+def index():
+    return
+
+
+@app.route("/login")
+@ldap.basic_auth_required
+def login():
+    return "OK"
+
+
+if __name__ == "__main__":
+    app.run()
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..d15a68a
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+flask
+flask-simpleldap
+gunicorn
+python-ldap
-- 
GitLab