[Plugin] Added plugin function when roles are modified
LDAP: Use same config style as the rest.
This commit is contained in:
parent
96765ee932
commit
cbcd5b39a3
|
@ -24,23 +24,23 @@ enabled = true
|
|||
|
||||
#[auth_ldap]
|
||||
# enabled = true
|
||||
# URL =
|
||||
# PORT =
|
||||
# BINDDN =
|
||||
# BASEDN =
|
||||
# SECRET =
|
||||
# USE_SSL =
|
||||
# ADMIN_DN =
|
||||
# ADMIN_SECRET =
|
||||
# gidNumber =
|
||||
# host =
|
||||
# port =
|
||||
# bind_dn =
|
||||
# base_dn =
|
||||
# secret =
|
||||
# use_ssl =
|
||||
# admin_dn =
|
||||
# admin_dn =
|
||||
# default_gid =
|
||||
|
||||
#[users]
|
||||
# allways enabled
|
||||
# always enabled
|
||||
#
|
||||
## allowed values: false, "managed", "public"
|
||||
## false: Disable registration
|
||||
## "managed": only users with matching permission are allowed to register new users
|
||||
## "public": Also unautheticated users can register an account
|
||||
## "public": Also unauthenticated users can register an account
|
||||
# registration = False
|
||||
|
||||
############################
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from flask import current_app
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from werkzeug.exceptions import BadRequest, NotFound
|
||||
|
||||
|
@ -24,7 +25,12 @@ def get_permissions():
|
|||
return Permission.query.all()
|
||||
|
||||
|
||||
def update_role(role):
|
||||
def rename(role, new_name):
|
||||
if db.session.query(db.exists().where(Role.name == new_name)).scalar():
|
||||
raise BadRequest("Name already used")
|
||||
|
||||
current_app.config["FG_AUTH_BACKEND"].modify_role(role.name, new_name)
|
||||
role.name = new_name
|
||||
db.session.commit()
|
||||
|
||||
|
||||
|
@ -62,3 +68,4 @@ def delete(role):
|
|||
except IntegrityError:
|
||||
logger.debug("IntegrityError: Role might still be in use", exc_info=True)
|
||||
raise BadRequest("Role still in use")
|
||||
current_app.config["FG_AUTH_BACKEND"].modify_role(role.name, None)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import pkg_resources
|
||||
from typing import Optional
|
||||
from werkzeug.exceptions import MethodNotAllowed
|
||||
|
||||
from flaschengeist.utils.hook import HookCall
|
||||
|
@ -67,6 +68,7 @@ class AuthPlugin(Plugin):
|
|||
|
||||
def modify_user(self, user, password, new_password=None):
|
||||
"""If backend is using (writeable) external data, then update the external database with the user provided.
|
||||
User might have roles not existing on the external database, so you might have to create those.
|
||||
|
||||
Args:
|
||||
user: User object
|
||||
|
@ -79,6 +81,16 @@ class AuthPlugin(Plugin):
|
|||
"""
|
||||
raise NotImplemented
|
||||
|
||||
def modify_role(self, old_name: str, new_name: Optional[str]):
|
||||
"""A call to this function indicated that a role was deleted (and has no users)
|
||||
Might be used if modify_user is implemented.
|
||||
|
||||
Args:
|
||||
old_name: Name of the modified role
|
||||
new_name: New role name or None if deleted
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_user(self, user, password):
|
||||
"""If backend is using (writeable) external data, then create a new user on the external database.
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ from ldap3 import SUBTREE, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, HASHED_SAL
|
|||
from ldap3.core.exceptions import LDAPPasswordIsMandatoryError, LDAPBindError
|
||||
from flask import current_app as app
|
||||
from flask_ldapconn import LDAPConn
|
||||
from werkzeug.exceptions import BadRequest
|
||||
from werkzeug.exceptions import BadRequest, InternalServerError
|
||||
|
||||
from flaschengeist import logger
|
||||
from flaschengeist.plugins import AuthPlugin
|
||||
from flaschengeist.models.user import User
|
||||
import flaschengeist.controller.userController as userController
|
||||
|
@ -17,28 +18,30 @@ class AuthLDAP(AuthPlugin):
|
|||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
|
||||
config = {"PORT": 389, "USE_SSL": False}
|
||||
config = {"port": 389, "use_ssl": False}
|
||||
config.update(cfg)
|
||||
|
||||
app.config.update(
|
||||
LDAP_SERVER=config["URL"],
|
||||
LDAP_PORT=config["PORT"],
|
||||
LDAP_BINDDN=config["BINDDN"],
|
||||
LDAP_SERVER=config["host"],
|
||||
LDAP_PORT=config["port"],
|
||||
LDAP_BINDDN=config["bind_dn"],
|
||||
LDAP_USE_TLS=False,
|
||||
LDAP_USE_SSL=config["USE_SSL"],
|
||||
LDAP_USE_SSL=config["use_ssl"],
|
||||
LDAP_TLS_VERSION=ssl.PROTOCOL_TLSv1_2,
|
||||
LDAP_REQUIRE_CERT=ssl.CERT_NONE,
|
||||
FORCE_ATTRIBUTE_VALUE_AS_LIST=True,
|
||||
)
|
||||
if "SECRET" in config:
|
||||
app.config["LDAP_SECRET"] = (config["SECRET"],)
|
||||
app.config["LDAP_SECRET"] = (config["secret"],)
|
||||
self.ldap = LDAPConn(app)
|
||||
self.dn = config["BASEDN"]
|
||||
self.gidNumber = config['gidNumber']
|
||||
self.dn = config["base_dn"]
|
||||
self.default_gid = config['default_gid']
|
||||
# TODO: might not be set if modify is called
|
||||
if "ADMIN_DN" in config:
|
||||
self.admin_dn = config["ADMIN_DN"]
|
||||
self.admin_secret = config["ADMIN_SECRET"]
|
||||
if "admin_dn" in config:
|
||||
self.admin_dn = config["admin_dn"]
|
||||
self.admin_secret = config["admin_secret"]
|
||||
else:
|
||||
self.admin_dn = None
|
||||
|
||||
def login(self, user, password):
|
||||
if not user:
|
||||
|
@ -64,6 +67,10 @@ class AuthLDAP(AuthPlugin):
|
|||
userController.set_roles(user, self._get_groups(user.userid), create=True)
|
||||
|
||||
def create_user(self, user, password):
|
||||
if self.admin_dn is None:
|
||||
logger.error("admin_dn missing in ldap config!")
|
||||
raise InternalServerError
|
||||
|
||||
try:
|
||||
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
|
||||
self.ldap.connection.search(
|
||||
|
@ -76,7 +83,7 @@ class AuthLDAP(AuthPlugin):
|
|||
attributes = {
|
||||
'sn': user.firstname,
|
||||
'givenName': user.lastname,
|
||||
'gidNumber': self.gidNumber,
|
||||
'gidNumber': self.default_gid,
|
||||
'homeDirectory': f'/home/{user.userid}',
|
||||
'loginShell': '/bin/bash',
|
||||
'uid': user.userid,
|
||||
|
@ -85,30 +92,12 @@ class AuthLDAP(AuthPlugin):
|
|||
|
||||
}
|
||||
ldap_conn.add(dn, object_class, attributes)
|
||||
self.set_roles(user)
|
||||
self._set_roles(user)
|
||||
except (LDAPPasswordIsMandatoryError, LDAPBindError):
|
||||
raise BadRequest
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def _get_groups(self, uid):
|
||||
groups = []
|
||||
|
||||
self.ldap.connection.search(
|
||||
"ou=user,{}".format(self.dn), "(uid={})".format(uid), SUBTREE, attributes=["gidNumber"]
|
||||
)
|
||||
|
||||
# Maingroup ist uninteressant
|
||||
|
||||
#main_group_number = self.ldap.connection.response[0]["attributes"]["gidNumber"]
|
||||
#if main_group_number:
|
||||
# if type(main_group_number) is list:
|
||||
# main_group_number = main_group_number[0]
|
||||
# self.ldap.connection.search(
|
||||
# "ou=group,{}".format(self.dn), "(gidNumber={})".format(main_group_number), attributes=["cn"]
|
||||
# )
|
||||
# groups.append(self.ldap.connection.response[0]["attributes"]["cn"][0])
|
||||
|
||||
self.ldap.connection.search(
|
||||
"ou=group,{}".format(self.dn), "(memberUID={})".format(uid), SUBTREE, attributes=["cn"]
|
||||
)
|
||||
|
@ -117,18 +106,18 @@ class AuthLDAP(AuthPlugin):
|
|||
groups.append(data["attributes"]["cn"][0])
|
||||
return groups
|
||||
|
||||
def set_roles(self, user: User):
|
||||
def _set_roles(self, user: User):
|
||||
try:
|
||||
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
|
||||
self.ldap.connection.search(f"ou=group,{self.dn}", "(cn=*)", SUBTREE, attributes=["cn", "gidNumber"])
|
||||
ldap_roles = self.ldap.response()
|
||||
|
||||
gidNumbers = sorted(ldap_roles, key=lambda i: i['attributes']['gidNumber'], reverse=True)
|
||||
gidNumber = gidNumbers[0]['attributes']['gidNumber'] + 1
|
||||
gid_numbers = sorted(ldap_roles, key=lambda i: i['attributes']['gidNumber'], reverse=True)
|
||||
gid_number = gid_numbers[0]['attributes']['gidNumber'] + 1
|
||||
|
||||
for user_role in user.roles:
|
||||
if user_role not in [role["attributes"]["cn"][0] for role in ldap_roles]:
|
||||
ldap_conn.add(f"cn={user_role},ou=group,{self.dn}", ["posixGroup"], attributes={"gidNumber": gidNumber})
|
||||
ldap_conn.add(f"cn={user_role},ou=group,{self.dn}", ["posixGroup"], attributes={"gidNumber": gid_number})
|
||||
|
||||
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
|
||||
self.ldap.connection.search(f"ou=group,{self.dn}", "(cn=*)", SUBTREE, attributes=["cn", "gidNumber"])
|
||||
|
@ -144,8 +133,11 @@ class AuthLDAP(AuthPlugin):
|
|||
except (LDAPPasswordIsMandatoryError, LDAPBindError):
|
||||
raise BadRequest
|
||||
|
||||
|
||||
def modify_user(self, user: User, password=None, new_password=None):
|
||||
if self.admin_dn is None:
|
||||
logger.error("admin_dn missing in ldap config!")
|
||||
raise InternalServerError
|
||||
|
||||
try:
|
||||
dn = user.get_attribute("DN")
|
||||
if password:
|
||||
|
@ -166,6 +158,6 @@ class AuthLDAP(AuthPlugin):
|
|||
salted_password = hashed(HASHED_SALTED_MD5, new_password)
|
||||
modifier["userPassword"] = [(MODIFY_REPLACE, [salted_password])]
|
||||
ldap_conn.modify(dn, modifier)
|
||||
self.set_roles(user)
|
||||
self._set_roles(user)
|
||||
except (LDAPPasswordIsMandatoryError, LDAPBindError):
|
||||
raise BadRequest
|
||||
|
|
|
@ -116,10 +116,9 @@ def edit_role(role_id, current_session):
|
|||
|
||||
data = request.get_json()
|
||||
if "name" in data:
|
||||
role.name = data["name"]
|
||||
roleController.rename(role, data["name"])
|
||||
if "permissions" in data:
|
||||
roleController.set_permissions(role, data["permissions"])
|
||||
roleController.update_role(role)
|
||||
return "", NO_CONTENT
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue