From 01d24773fb088229aa6a4015dde92b554fe36917 Mon Sep 17 00:00:00 2001
From: Thorge Petersen <petersen@rz.uni-kiel.de>
Date: Mon, 17 Jun 2024 15:24:59 +0200
Subject: [PATCH] Added /user/auth subroute for basic auth

---
 CHANGELOG.md               |  4 ++++
 ckanext/odsh/plugin.py     |  2 ++
 ckanext/odsh/views/user.py | 26 +++++++++++++++++++++++++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ebf7f34..02867b9d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Added
+
+- Added `/user/auth` Subroute: This new endpoint serves as an internal authentication endpoint to validate CKAN users against the CKAN user database. It supports HTTP Basic Authentication, allowing Nginx to forward authentication requests to CKAN.
+
 ### Fixed
 
 - Resolved display issues of the resource view and share icons.
diff --git a/ckanext/odsh/plugin.py b/ckanext/odsh/plugin.py
index 2078ae16..76bb10a4 100644
--- a/ckanext/odsh/plugin.py
+++ b/ckanext/odsh/plugin.py
@@ -73,6 +73,8 @@ class OdshPlugin(p.SingletonPlugin, DefaultTranslation, tk.DefaultDatasetForm):
         bp_user = user.blueprint
         bp_user.add_url_rule(u'/user', endpoint='user_index',
                              view_func=user.index, strict_slashes=False)
+        bp_user.add_url_rule(u'/user/auth', endpoint='user_auth',
+                             view_func=user.auth, strict_slashes=False)
         # bp_user.add_url_rule(u'/user/register', view_func=user.register)
 
         # Dashboard
diff --git a/ckanext/odsh/views/user.py b/ckanext/odsh/views/user.py
index 7963a52e..308ca820 100644
--- a/ckanext/odsh/views/user.py
+++ b/ckanext/odsh/views/user.py
@@ -1,7 +1,8 @@
 import ckan.plugins.toolkit as toolkit
 import ckan.authz as authz
 from ckan.common import g
-from flask import Blueprint
+import ckan.lib.authenticator as authenticator
+from flask import Blueprint, request, Response                                                                                                                           
 import ckan.views.user as ckan_user_view
 import logging
 
@@ -33,3 +34,26 @@ def read(id=None):
     if not g.user:
         return ckan_user_view.login()
     return ckan_user_view.read(id)
+
+
+def auth():
+    auth = request.authorization
+    if not auth:
+        return Response('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
+
+    username = auth.username
+    password = auth.password
+
+    if _authenticate(username, password):
+        return Response('Authorized', 200)
+    else:
+        return Response('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
+
+
+def _authenticate(username, password):
+    identity = {'login': username, 'password': password}
+    user = authenticator.ckan_authenticator(identity)
+
+    if user:
+        return user
+    return None
-- 
GitLab