From 4a6be8f75e8b85fcfed3c2b607e24dcf1b0da68e Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 25 Oct 2023 10:43:17 +0000 Subject: [PATCH] check if user has finance perm --- fet2020/authentications/authentications.py | 108 +++++++++++++++++++-- fet2020/authentications/forms.py | 17 +++- fet2020/fet2020/middleware.py | 6 -- 3 files changed, 116 insertions(+), 15 deletions(-) diff --git a/fet2020/authentications/authentications.py b/fet2020/authentications/authentications.py index fd9a591f..031576db 100644 --- a/fet2020/authentications/authentications.py +++ b/fet2020/authentications/authentications.py @@ -4,6 +4,8 @@ from ldap3 import HASHED_SALTED_SHA, MODIFY_REPLACE, Connection, Server from ldap3.core.exceptions import LDAPBindError from ldap3.utils.hashed import hashed +from members.models import Member + logger = logging.getLogger(__name__) host = "ldap://juri.fet.htu.tuwien.ac.at" port = 389 @@ -17,18 +19,110 @@ def authentication(username, password): server = Server(host, port=port) userdn = f"uid={username},ou=user,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at" + finance_perm = None + + firstname = "" + surname = "" + mail = "" + try: c = Connection(server, user=userdn, password=password, auto_bind=True) - if c.extend.standard.who_am_i(): - return username + + if not c.extend.standard.who_am_i(): + logger.info(f"Username '{username}' is not in the list.") + return None + + # get member infos from ldap + c.search( + search_base=userdn, + search_filter=f"(uid={username})", + search_scope="SUBTREE", + attributes=["givenName", "sn", "mail"], + ) + + firstname = c.response[0]["attributes"]["givenName"][0] + surname = c.response[0]["attributes"]["sn"][0] + mail = c.response[0]["attributes"]["mail"][0] + + # check if member has finance permission + c.search( + search_base="CN=finance,OU=Groups,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at", + search_filter="(objectClass=posixGroup)", + search_scope="SUBTREE", + attributes=["memberUid"], + ) + + if username in c.response[0]["attributes"]["memberUid"]: + finance_perm = True except LDAPBindError as e: - logger.info(f"LDAP Bind error. Error: {e}") - except Exception as e: - logger.info(f"Auth exception. Error: {e}") + logger.info(f"LDAP Bind error from username '{username}'. Error: {e}") + return None - logger.info(f"This username has been typed: '{username}'") - return None + except Exception as e: + logger.info(f"Auth exception from username '{username}'. Error: {e}") + return None + + # get member or if not then create a new member + try: + member = Member.objects.get(mailaccount=mail) + except Member.DoesNotExist: + member = Member() + member.firstname = firstname + member.surname = surname + member.username = username + member.mailaccount = mail + logger.info(f"Member '{username}' created.") + member.save() + + # set username if not exists + if not member.username: + member.username = username + logger.info(f"User '{username}' saved.") + member.save() + + logger.info(f"User '{username}' logged in.") + return username + + +def get_finance_perm(username, password): + # no empty passwords + if password is None or password.strip() == "": + return None + + server = Server(host, port=port) + userdn = f"uid={username},ou=user,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at" + + finance_perm = None + + try: + c = Connection(server, user=userdn, password=password, auto_bind=True) + + if not c.extend.standard.who_am_i(): + logger.info(f"Username '{username}' is not in the list.") + return None + + # check if member has finance permission + c.search( + search_base="CN=finance,OU=Groups,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at", + search_filter="(objectClass=posixGroup)", + search_scope="SUBTREE", + attributes=["memberUid"], + ) + + if username in c.response[0]["attributes"]["memberUid"]: + logger.info(f"User '{username}' has finance permission.") + finance_perm = True + + except LDAPBindError as e: + logger.info(f"LDAP Bind error from username '{username}'. Error: {e}") + return None + + except Exception as e: + logger.info(f"Auth exception from username '{username}'. Error: {e}") + return None + + return finance_perm def change_password(username, old_password, new_password): diff --git a/fet2020/authentications/forms.py b/fet2020/authentications/forms.py index 539dfa7b..2fb3743e 100644 --- a/fet2020/authentications/forms.py +++ b/fet2020/authentications/forms.py @@ -1,8 +1,12 @@ +import logging + from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm -from django.contrib.auth.models import User +from django.contrib.auth.models import Group, User from django.core.exceptions import ValidationError -from .authentications import authentication, change_password +from .authentications import authentication, change_password, get_finance_perm + +logger = logging.getLogger(__name__) class LoginForm(AuthenticationForm): @@ -25,6 +29,15 @@ class LoginForm(AuthenticationForm): finally: self.confirm_login_allowed(self.user_cache) + # add user to all groups + for elem in Group.objects.all(): + elem.user_set.add(self.user_cache) + + # delete finance group if no permission + if not get_finance_perm(username, password): + finance_group = Group.objects.get(name="finance") + finance_group.user_set.remove(self.user_cache) + return self.cleaned_data diff --git a/fet2020/fet2020/middleware.py b/fet2020/fet2020/middleware.py index 93d8f6d6..ab43b7f6 100644 --- a/fet2020/fet2020/middleware.py +++ b/fet2020/fet2020/middleware.py @@ -12,10 +12,4 @@ class FETHeaderMiddleware(RemoteUserMiddleware): super().process_request(request) if request.user.is_authenticated: - from django.contrib.auth.models import Group - - groups = Group.objects.all() - [request.user.groups.add(group.pk) for group in groups] - - # request.user.is_superuser = True request.user.is_staff = True