add ldap auth

This commit is contained in:
weeman 2021-07-11 12:16:41 +02:00
parent cd2a7853dd
commit bbf8719fc9
Signed by untrusted user: weeman
GPG Key ID: 34F0524D4DA694A1
7 changed files with 108 additions and 17 deletions

View File

@ -16,6 +16,7 @@ sqlalchemy = "~=1.4.18"
waitress = "~=2.0.0"
pyyaml = "~=5.4.1"
flask-cors = "~=3.0.10"
ldap3 = "*"
[dev-packages]
flake8 = "~=3.9.2"

37
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "128a3b90d2e3d5876c5942fb256dba2d5e3d0b3a545cae6d51aeda6925a0f593"
"sha256": "0974e530bf219a5408b754c526f3699f2caf1620ea63cc991377574b5eeb1709"
},
"pipfile-spec": 6,
"requires": {
@ -135,6 +135,17 @@
"markers": "python_version >= '3.6'",
"version": "==3.0.1"
},
"ldap3": {
"hashes": [
"sha256:18c3ee656a6775b9b0d60f7c6c5b094d878d1d90fc03d56731039f0a4b546a91",
"sha256:4139c91f0eef9782df7b77c8cbc6243086affcb6a8a249b768a9658438e5da59",
"sha256:8c949edbad2be8a03e719ba48bd6779f327ec156929562814b3e84ab56889c8c",
"sha256:afc6fc0d01f02af82cd7bfabd3bbfd5dc96a6ae91e97db0a2dab8a0f1b436056",
"sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57"
],
"index": "pypi",
"version": "==2.9"
},
"mako": {
"hashes": [
"sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab",
@ -183,6 +194,24 @@
"markers": "python_version >= '3.6'",
"version": "==2.0.1"
},
"pyasn1": {
"hashes": [
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf",
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00",
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776",
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba",
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2",
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
],
"version": "==0.4.8"
},
"python-dateutil": {
"hashes": [
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
@ -374,11 +403,11 @@
},
"identify": {
"hashes": [
"sha256:18d0c531ee3dbc112fa6181f34faa179de3f57ea57ae2899754f16a7e0ff6421",
"sha256:5b41f71471bc738e7b586308c3fca172f78940195cb3bf6734c1e66fdac49306"
"sha256:7abaecbb414e385752e8ce02d8c494f4fbc780c975074b46172598a28f1ab839",
"sha256:a0e700637abcbd1caae58e0463861250095dfe330a8371733a471af706a4a29a"
],
"markers": "python_full_version >= '3.6.1'",
"version": "==2.2.10"
"version": "==2.2.11"
},
"idna": {
"hashes": [

View File

@ -68,9 +68,18 @@ flake8
### Testbenutzer
#### Lokal ohne LDAP
Für ein Login ohne LDAP werden die Benutzer aus der [`auth.yml`](./data/auth.yml) benutzt.
#### Lokal mit LDAP
Einen LDAP Server aufsetzen. Z.B. https://directory.apache.org/apacheds/
In der `.env` die LDAP Dinge ausfüllen (siehe [`env.dev`](./env.dev)).
### Beispiel-Requests
Beispiele brauchen curl und jq.

19
app.py
View File

@ -8,25 +8,36 @@ import os
from dotenv import load_dotenv, find_dotenv
from flask import Flask
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from flask.logging import default_handler
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from ldap3.utils.log import logger as ldap3_logger
from ldap3.utils.log import set_library_log_detail_level, BASIC
load_dotenv(find_dotenv())
app = Flask(__name__)
loglevel = os.getenv("KI_LOGLEVEL", logging.WARNING)
loglevel = int(loglevel)
app.logger.setLevel(loglevel)
logging.basicConfig(level=loglevel)
logging.debug("Hello from KI")
app = Flask(__name__)
set_library_log_detail_level(BASIC)
ldap3_logger.addHandler(default_handler)
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("SQLALCHEMY_DATABASE_URI")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["KI_DATA_DIR"] = os.path.dirname(__file__) + "/data"
app.config["KI_AUTH"] = os.getenv("KI_AUTH")
app.config["CORS_ORIGINS"] = os.getenv("CORS_ORIGINS", "*")
app.config["KI_AUTH"] = os.getenv("KI_AUTH")
app.config["KI_LDAP_URL"] = os.getenv("KI_LDAP_URL")
app.config["KI_LDAP_ROOT_DN"] = os.getenv("KI_LDAP_ROOT_DN")
CORS(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
logging.debug("Hello from KI")
from ki import module # noqa

View File

@ -9,7 +9,12 @@ CORS_ORIGINS=*
FLASK_APP=app.py
FLASK_ENV=development
# auth method: file or ldap
KI_AUTH=file
# ldap auth only
KI_LDAP_URL=ldap://localhost:10389
KI_LDAP_ROOT_DN=dc=example,dc=com
# 10 = debug
KI_LOGLEVEL=10

View File

@ -5,11 +5,28 @@
import uuid
import yaml
from ldap3 import Server, Connection, ALL
from app import app, db
from ki.models import User, Token
def auth(username, password):
def create_user_token(username):
user = User.query.filter(User.auth_id.__eq__(username)).first()
if user is None:
user = User(auth_id=username)
db.session.add(user)
token = Token(token=str(uuid.uuid4()), user=user)
db.session.add(token)
db.session.commit()
return token
def file_auth(username, password):
app.logger.debug("performing file authentication")
auth_file_path = app.config["KI_DATA_DIR"] + "/auth.yml"
with open(auth_file_path, "r") as auth_file_stream:
@ -23,14 +40,32 @@ def auth(username, password):
if auth_user["password"] != password:
return None
user = User.query.filter(User.auth_id.__eq__(username)).first()
return create_user_token(username)
if user is None:
user = User(auth_id=username)
db.session.add(user)
token = Token(token=str(uuid.uuid4()), user=user)
db.session.add(token)
db.session.commit()
def ldap_auth(username, password):
app.logger.debug("performing LDAP authentication")
return token
server = Server(app.config['KI_LDAP_URL'], get_info=ALL)
root_dn = app.config['KI_LDAP_ROOT_DN']
ldap_user = f"cn={username},{root_dn}"
app.logger.debug(f"server: {server}")
connection = Connection(server, user=ldap_user, password=password)
if connection.bind():
connection.unbind()
return create_user_token(username)
connection.unbind()
return None
def auth(username, password):
if app.config['KI_AUTH'] == 'file':
return file_auth(username, password)
if app.config['KI_AUTH'] == 'ldap':
return ldap_auth(username, password)
raise RuntimeError('unknown auth method')

View File

@ -17,6 +17,7 @@ class ApiTest(unittest.TestCase):
app.debug = True
app.config["TESTING"] = True
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
self.client = app.test_client()
with app.app_context():