Improved modify_user for backend plugins

This commit is contained in:
Ferdinand Thiessen 2020-10-24 20:09:45 +02:00
parent d3a2b40834
commit dc6b30e4e7
5 changed files with 33 additions and 30 deletions

View File

@ -46,7 +46,7 @@ class AuthPlugin(Plugin):
Args: Args:
user: User object user: User object
password: Password (some backends need the current password for changes) password: Password (some backends need the current password for changes) if None force edit (admin)
new_password: If set a password change is requested new_password: If set a password change is requested
Raises: Raises:
NotImplemented: If backend does not support this feature (or no password change) NotImplemented: If backend does not support this feature (or no password change)

View File

@ -8,6 +8,7 @@ from werkzeug.exceptions import BadRequest
from flaschengeist.modules import AuthPlugin from flaschengeist.modules import AuthPlugin
from flaschengeist.system.models.user import User from flaschengeist.system.models.user import User
import flaschengeist.system.controller.userController as userController
class AuthLDAP(AuthPlugin): class AuthLDAP(AuthPlugin):
@ -33,6 +34,8 @@ class AuthLDAP(AuthPlugin):
app.config["LDAP_SECRET"] = (config["SECRET"],) app.config["LDAP_SECRET"] = (config["SECRET"],)
self.ldap = LDAPConn(app) self.ldap = LDAPConn(app)
self.dn = config["BASEDN"] self.dn = config["BASEDN"]
self.admin_dn = config["ADMIN_DN"]
self.admin_secret = config["ADMIN_SECRET"]
def login(self, user, password): def login(self, user, password):
if not user: if not user:
@ -55,8 +58,7 @@ class AuthLDAP(AuthPlugin):
user.mail = r["mail"][0] user.mail = r["mail"][0]
if "displayName" in r: if "displayName" in r:
user.display_name = r["displayName"][0] user.display_name = r["displayName"][0]
for group in self._get_groups(user.userid): userController.set_roles(user, self._get_groups(user.userid))
user.add_role(group)
def _get_groups(self, uid): def _get_groups(self, uid):
groups = [] groups = []
@ -84,7 +86,10 @@ class AuthLDAP(AuthPlugin):
def modify_user(self, user: User, password, new_password=None): def modify_user(self, user: User, password, new_password=None):
try: try:
dn = user.attributes["DN"].value dn = user.attributes["DN"].value
ldap_conn = self.ldap.connect(dn, password) if password:
ldap_conn = self.ldap.connect(dn, password)
else:
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
modifier = {} modifier = {}
for name, ldap_name in [ for name, ldap_name in [
("firstname", "givenName"), ("firstname", "givenName"),
@ -92,7 +97,7 @@ class AuthLDAP(AuthPlugin):
("mail", "mail"), ("mail", "mail"),
("display_name", "displayName"), ("display_name", "displayName"),
]: ]:
if getattr(user, name): if hasattr(user, name):
modifier[ldap_name] = [(MODIFY_REPLACE, [getattr(user, name)])] modifier[ldap_name] = [(MODIFY_REPLACE, [getattr(user, name)])]
if new_password: if new_password:
salted_password = hashed(HASHED_SALTED_SHA512, new_password) salted_password = hashed(HASHED_SALTED_SHA512, new_password)

View File

@ -2,6 +2,8 @@ import binascii
import hashlib import hashlib
import os import os
from werkzeug.exceptions import BadRequest
from flaschengeist.modules import AuthPlugin from flaschengeist.modules import AuthPlugin
from flaschengeist.system.models.user import User from flaschengeist.system.models.user import User
@ -23,9 +25,12 @@ def _verify_password(stored_password, provided_password):
class AuthPlain(AuthPlugin): class AuthPlain(AuthPlugin):
def login(self, user: User, password: str): def login(self, user: User, password: str):
if user and "password" in user.attributes: if user.has_attribute("password"):
return _verify_password(user.attributes["password"].value, password) return _verify_password(user.get_attributes("password"), password)
return False return False
def modify_user(self, user, password, new_password=None): def modify_user(self, user, password, new_password=None):
pass if password is not None and not self.login(user, password):
raise BadRequest
if new_password:
user.attributes["password"].value = _hash_password(new_password)

View File

@ -1,5 +1,5 @@
from flask import current_app from flask import current_app
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound, BadRequest
from flaschengeist.system.models.user import User, Role from flaschengeist.system.models.user import User, Role
from flaschengeist.system.database import db from flaschengeist.system.database import db
@ -25,15 +25,21 @@ def update_user(user):
db.session.commit() db.session.commit()
def set_roles(user: User, roles: [str]):
user.roles.clear()
for role_name in roles:
role = Role.query.filter(Role.name == role_name).one_or_one()
if not role:
raise BadRequest("Role not found >{}<".format(role_name))
user.roles.append(role)
def modify_user(user, password, new_password=None): def modify_user(user, password, new_password=None):
"""Modify given user on the backend """Modify given user on the backend
Args: Args:
user: User object to sync with backend user: User object to sync with backend
password: Cu db.session.commit() password: Current password (most backends are needing this)
# TODO: is this needed?
def user_has_rorrent password (most backends are needing this)
new_password (optional): New password, if password should be changed new_password (optional): New password, if password should be changed
Raises: Raises:

View File

@ -70,24 +70,11 @@ class User(db.Model, ModelSerializeMixin):
else: else:
self._attributes[name] = _UserAttribute(name=name, value=value) self._attributes[name] = _UserAttribute(name=name, value=value)
def add_role(self, name): def has_attribute(self, name):
r = Role.query.filter_by(name=name).first() return name in self._attributes
if not r:
r = Role(name=name)
self.roles.append(r)
def update_data(self, data): def get_attribute(self, name):
logger.debug("update data of user") return self._attributes[name].value
if "userid" in data:
self.userid = data["userid"]
if "firstname" in data:
self.firstname = data["firstname"]
if "lastname" in data:
self.lastname = data["lastname"]
if "mail" in data:
self.mail = data["mail"]
if "display_name" in data:
self.display_name = data["display_name"]
def get_permissions(self): def get_permissions(self):
return ["user"] + [permission.name for role in self.roles for permission in role.permissions] return ["user"] + [permission.name for role in self.roles for permission in role.permissions]