added LDAP authorization
This commit is contained in:
parent
e79713e094
commit
1e87406fdb
|
@ -3,13 +3,14 @@ import argparse
|
||||||
|
|
||||||
from imaginaerraum_door_admin.webapp import create_application
|
from imaginaerraum_door_admin.webapp import create_application
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--token_file", default="/etc/door_tokens", help="path to the file with door tokens and users")
|
parser.add_argument("--token_file", default="/etc/door_tokens", help="path to the file with door tokens and users")
|
||||||
parser.add_argument("--nfc_socket", default="/tmp/nfc.sock", help="socket for handling NFC reader commands")
|
parser.add_argument("--nfc_socket", default="/tmp/nfc.sock", help="socket for handling NFC reader commands")
|
||||||
parser.add_argument("--template_folder", default="templates", help="path to Flask templates folder")
|
parser.add_argument("--template_folder", default="templates", help="path to Flask templates folder")
|
||||||
parser.add_argument("--static_folder", default="static", help="path to Flask static folder")
|
parser.add_argument("--static_folder", default="static", help="path to Flask static folder")
|
||||||
parser.add_argument("--admin_file", help="Path to file for creating initial admin users")
|
parser.add_argument("--admin_file", help="Path to file for creating initial admin users")
|
||||||
|
parser.add_argument("--ldap_url", default="ldaps://do.imaginaerraum.de",
|
||||||
|
help="URL for LDAP server for alternative user authorization")
|
||||||
parser.add_argument("--mqtt_host", default="10.10.21.2", help="IP address of MQTT broker")
|
parser.add_argument("--mqtt_host", default="10.10.21.2", help="IP address of MQTT broker")
|
||||||
parser.add_argument("--port", default=80, help="Port for running the Flask server")
|
parser.add_argument("--port", default=80, help="Port for running the Flask server")
|
||||||
parser.add_argument("--mail_server", default="smtp.googlemail.com", help="email server for sending security messages")
|
parser.add_argument("--mail_server", default="smtp.googlemail.com", help="email server for sending security messages")
|
||||||
|
|
|
@ -9,8 +9,10 @@ from flask_security import Security, SQLAlchemyUserDatastore, auth_required, has
|
||||||
from flask_security.models import fsqla_v2 as fsqla
|
from flask_security.models import fsqla_v2 as fsqla
|
||||||
from flask_security.forms import LoginForm, Required, PasswordField
|
from flask_security.forms import LoginForm, Required, PasswordField
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
|
from flask_security.utils import find_user
|
||||||
from email_validator import validate_email
|
from email_validator import validate_email
|
||||||
import bleach
|
import bleach
|
||||||
|
import ldap3
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from .door_handle import DoorHandle
|
from .door_handle import DoorHandle
|
||||||
|
@ -96,10 +98,42 @@ def create_application(config):
|
||||||
class User(db.Model, fsqla.FsUserMixin):
|
class User(db.Model, fsqla.FsUserMixin):
|
||||||
username = db.Column(db.String(255))
|
username = db.Column(db.String(255))
|
||||||
|
|
||||||
|
# LDAP
|
||||||
|
ldap_server = ldap3.Server(config.ldap_url)
|
||||||
|
|
||||||
|
def validate_ldap(user, password):
|
||||||
|
# try to connect to the LDAP server
|
||||||
|
# if the connection completes successfully the given user and password is authorized
|
||||||
|
try:
|
||||||
|
con = ldap3.Connection(ldap_server, user="uid=%s,ou=Users,dc=imaginaerraum,dc=de" % (user.username,),
|
||||||
|
password=password, auto_bind=True)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
return con is not None
|
||||||
|
|
||||||
class ExtendedLoginForm(LoginForm):
|
class ExtendedLoginForm(LoginForm):
|
||||||
email = StringField('Benutzername oder E-Mail', [Required()])
|
email = StringField('Benutzername oder E-Mail', [Required()])
|
||||||
password = PasswordField('Passwort', [Required()])
|
password = PasswordField('Passwort', [Required()])
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
# authorization in LDAP uses username -> get username associated with email from the database
|
||||||
|
user = find_user(self.email.data)
|
||||||
|
# try authorizing using LDAP
|
||||||
|
response_ldap = validate_ldap(user, self.password.data)
|
||||||
|
|
||||||
|
if response_ldap:
|
||||||
|
# if LDAP authorization succeeds we update the currently stored password in the Flask user datastore
|
||||||
|
# with the one used for LDAP authorization. This way we can authorize with the LDAP password later
|
||||||
|
# even if the server is not reachable
|
||||||
|
user.password = hash_password(self.password.data)
|
||||||
|
|
||||||
|
# try authorizing using Flask security
|
||||||
|
response_orig = super(ExtendedLoginForm, self).validate()
|
||||||
|
|
||||||
|
# if any of the authorization methods is successful we authorize the user
|
||||||
|
return response_ldap or response_orig
|
||||||
|
|
||||||
|
app.config['SECURITY_MSG_USERID_NOT_PROVIDED'] = ('User ID not provided', 'error')
|
||||||
|
|
||||||
# Setup Flask-Security
|
# Setup Flask-Security
|
||||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user