From d0e80bf79f5e0f98aa911f7a64686fe2ce9e8281 Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sat, 7 Sep 2019 17:53:27 +0200 Subject: [PATCH 1/6] Allow to select Python version at build With this anyone can effectively use Python 2 or 3 using --build-arg The default version is 2. --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d7226dc..980de92 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM python:2-alpine +ARG PYTHON_VERSION=2 +FROM python:${PYTHON_VERSION}-alpine COPY nginx-ldap-auth-daemon.py /usr/src/app/ From 08fb44b66d3fe13fcf0a07d0118ca5c5c4d670a8 Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sat, 7 Sep 2019 23:03:13 +0200 Subject: [PATCH 2/6] Use python instead of python2 On used docker baseimage python is already linked to python2 or python3, depending on image version --- backend-sample-app.py | 1 - nginx-ldap-auth-daemon.py | 1 - 2 files changed, 2 deletions(-) diff --git a/backend-sample-app.py b/backend-sample-app.py index 367fd54..88b4a0d 100755 --- a/backend-sample-app.py +++ b/backend-sample-app.py @@ -1,5 +1,4 @@ #!/bin/sh -''''which python2 >/dev/null && exec python2 "$0" "$@" # ''' ''''which python >/dev/null && exec python "$0" "$@" # ''' # Copyright (C) 2014-2015 Nginx, Inc. diff --git a/nginx-ldap-auth-daemon.py b/nginx-ldap-auth-daemon.py index bdfafff..55582d5 100755 --- a/nginx-ldap-auth-daemon.py +++ b/nginx-ldap-auth-daemon.py @@ -1,6 +1,5 @@ #!/bin/sh ''''[ -z $LOG ] && export LOG=/dev/stdout # ''' -''''which python2 >/dev/null && exec python2 -u "$0" "$@" >> $LOG 2>&1 # ''' ''''which python >/dev/null && exec python -u "$0" "$@" >> $LOG 2>&1 # ''' # Copyright (C) 2014-2015 Nginx, Inc. From 9f01a465d8cbcf336ac1b799819c6f0021b9baca Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sun, 8 Sep 2019 00:30:55 +0200 Subject: [PATCH 3/6] Make code compatibile with python 2 and 3 Add chcecks for version for importing and decoding bytestring. Inspired by PR #66 --- nginx-ldap-auth-daemon.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/nginx-ldap-auth-daemon.py b/nginx-ldap-auth-daemon.py index 55582d5..388364c 100755 --- a/nginx-ldap-auth-daemon.py +++ b/nginx-ldap-auth-daemon.py @@ -4,8 +4,15 @@ # Copyright (C) 2014-2015 Nginx, Inc. -import sys, os, signal, base64, ldap, Cookie, argparse -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +import sys, os, signal, base64, ldap, argparse +if sys.version_info.major == 2: + from Cookie import BaseCookie + from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +elif sys.version_info.major == 3: + from http.cookies import BaseCookie + from http.server import HTTPServer, BaseHTTPRequestHandler + +if not hasattr(__builtins__, "basestring"): basestring = (str, bytes) #Listen = ('localhost', 8888) #Listen = "/tmp/auth.sock" # Also uncomment lines in 'Requests are @@ -16,7 +23,11 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler # ----------------------------------------------------------------------------- # Requests are processed in separate thread import threading -from SocketServer import ThreadingMixIn +if sys.version_info.major == 2: + from SocketServer import ThreadingMixIn +elif sys.version_info.major == 3: + from socketserver import ThreadingMixIn + class AuthHTTPServer(ThreadingMixIn, HTTPServer): pass # ----------------------------------------------------------------------------- @@ -71,6 +82,7 @@ class AuthHandler(BaseHTTPRequestHandler): try: auth_decoded = base64.b64decode(auth_header[6:]) + if sys.version_info.major == 3: auth_decoded = auth_decoded.decode("utf-8") user, passwd = auth_decoded.split(':', 1) except: @@ -86,7 +98,7 @@ class AuthHandler(BaseHTTPRequestHandler): def get_cookie(self, name): cookies = self.headers.get('Cookie') if cookies: - authcookie = Cookie.BaseCookie(cookies).get(name) + authcookie = BaseCookie(cookies).get(name) if authcookie: return authcookie.value else: From 83e28636fb86c8d4aa5ef2e8591230ce60694315 Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sun, 8 Sep 2019 00:37:51 +0200 Subject: [PATCH 4/6] Update README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f4a6fe..79c0634 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ To install and configure the reference implementation, perform the following ste 1. On the host where the ldap-auth daemon is to run, install the following additional software. We recommend using the versions that are distributed with the operating system, instead of downloading the software from an open source repository. - - Python version 2. Version 3 is not supported. + - Python version 2 and 3 are supported. - The Python LDAP module, **python-ldap** (created by the [python-ldap.org](http://www.python-ldap.org) open source project). 1. Copy the following files from your repository clone to the indicated hosts: @@ -44,6 +44,10 @@ To install and configure the reference implementation, perform the following ste docker build -t nginx-ldap-auth-daemon . docker run nginx-ldap-auth-daemon ``` + If you desire to use a container with Python3, you can supply an appropriate build argument: + ``` + docker build -t nginx-ldap-auth-daemon --build-arg PYTHON_VERSION=3 . + ``` - **nginx-ldap-auth-daemon-ctl.sh** – Sample shell script for starting and stopping the daemon. Install on the same host as the ldap-auth daemon. From 8bd5c3ae219f986de27dca8d186d8aa744c351b5 Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sun, 8 Sep 2019 00:40:10 +0200 Subject: [PATCH 5/6] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79c0634..daee909 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ To install and configure the reference implementation, perform the following ste 1. On the host where the ldap-auth daemon is to run, install the following additional software. We recommend using the versions that are distributed with the operating system, instead of downloading the software from an open source repository. - - Python version 2 and 3 are supported. + - Python versions 2 and 3 are supported. - The Python LDAP module, **python-ldap** (created by the [python-ldap.org](http://www.python-ldap.org) open source project). 1. Copy the following files from your repository clone to the indicated hosts: From a96bbe6a5729e6e12287f8657ac46b8eaaf32d7f Mon Sep 17 00:00:00 2001 From: Robert Szulist Date: Sun, 8 Sep 2019 15:00:31 +0200 Subject: [PATCH 6/6] Add Python3 compatibility to sample app --- backend-sample-app.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/backend-sample-app.py b/backend-sample-app.py index 88b4a0d..3170d80 100755 --- a/backend-sample-app.py +++ b/backend-sample-app.py @@ -8,13 +8,29 @@ # 1) accepts GET requests on /login and responds with a login form # 2) accepts POST requests on /login, sets a cookie, and responds with redirect -import sys, os, signal, base64, Cookie, cgi, urlparse -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +import sys, os, signal, base64, cgi +if sys.version_info.major == 2: + from urlparse import urlparse + from Cookie import BaseCookie + from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +elif sys.version_info.major == 3: + from urllib.parse import urlparse + from http.cookies import BaseCookie + from http.server import HTTPServer, BaseHTTPRequestHandler Listen = ('localhost', 9000) import threading -from SocketServer import ThreadingMixIn +if sys.version_info.major == 2: + from SocketServer import ThreadingMixIn +elif sys.version_info.major == 3: + from socketserver import ThreadingMixIn + + +def ensure_bytes(data): + return data if sys.version_info.major == 2 else data.encode("utf-8") + + class AuthHTTPServer(ThreadingMixIn, HTTPServer): pass @@ -22,14 +38,14 @@ class AppHandler(BaseHTTPRequestHandler): def do_GET(self): - url = urlparse.urlparse(self.path) + url = urlparse(self.path) if url.path.startswith("/login"): return self.auth_form() self.send_response(200) self.end_headers() - self.wfile.write('Hello, world! Requested URL: ' + self.path + '\n') + self.wfile.write(ensure_bytes('Hello, world! Requested URL: ' + self.path + '\n')) # send login form html @@ -69,7 +85,7 @@ class AppHandler(BaseHTTPRequestHandler): self.send_response(200) self.end_headers() - self.wfile.write(html.replace('TARGET', target)) + self.wfile.write(ensure_bytes(html.replace('TARGET', target))) # processes posted form and sets the cookie with login/password @@ -102,8 +118,8 @@ class AppHandler(BaseHTTPRequestHandler): # and share a key with auth daemon that extracts this information # # WARNING WARNING WARNING - enc = base64.b64encode(user + ':' + passwd) - self.send_header('Set-Cookie', 'nginxauth=' + enc + '; httponly') + enc = base64.b64encode(ensure_bytes(user + ':' + passwd)) + self.send_header('Set-Cookie', b'nginxauth=' + enc + b'; httponly') self.send_header('Location', target) self.end_headers()