From 0e1b78d88bdd252df3531cff1a86166cedec7919 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Fri, 24 May 2024 13:24:24 +0200 Subject: [PATCH] Merge pull request from GHSA-2crp-q9pc-457j * ensure API login only works if mfa is not required * add migration to log out users * add migration to clear users --- src/backend/InvenTree/users/api.py | 21 +++++++++++++-- .../migrations/0011_auto_20240523_1640.py | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py diff --git a/src/backend/InvenTree/users/api.py b/src/backend/InvenTree/users/api.py index 43fe8ad521..6ff708dbca 100644 --- a/src/backend/InvenTree/users/api.py +++ b/src/backend/InvenTree/users/api.py @@ -3,11 +3,12 @@ import datetime import logging -from django.contrib.auth import get_user, login +from django.contrib.auth import get_user, login, logout from django.contrib.auth.models import Group, User from django.urls import include, path, re_path from django.views.generic.base import RedirectView +from allauth.account.adapter import get_adapter from dj_rest_auth.views import LoginView, LogoutView from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_view from rest_framework import exceptions, permissions @@ -17,6 +18,7 @@ from rest_framework.response import Response from rest_framework.views import APIView import InvenTree.helpers +from common.models import InvenTreeSetting from InvenTree.filters import SEARCH_ORDER_FILTER from InvenTree.mixins import ( ListAPI, @@ -216,7 +218,22 @@ class GroupList(ListCreateAPI): class Login(LoginView): """API view for logging in via API.""" - ... + def process_login(self): + """Process the login request, ensure that MFA is enforced if required.""" + # Normal login process + ret = super().process_login() + + # Now check if MFA is enforced + user = self.request.user + adapter = get_adapter(self.request) + + # User requires 2FA or MFA is enforced globally - no logins via API + if adapter.has_2fa_enabled(user) or InvenTreeSetting.get_setting( + 'LOGIN_ENFORCE_MFA' + ): + logout(self.request) + raise exceptions.PermissionDenied('MFA required for this user') + return ret @extend_schema_view( diff --git a/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py b/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py new file mode 100644 index 0000000000..1673fcc899 --- /dev/null +++ b/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.12 on 2024-05-23 16:40 + +from importlib import import_module + +from django.conf import settings +from django.db import migrations + + +def clear_sessions(apps, schema_editor): + """Clear all user sessions.""" + + engine = import_module(settings.SESSION_ENGINE) + engine.SessionStore.clear_expired() + print('Cleared all user sessions to deal with GHSA-2crp-q9pc-457j') + +class Migration(migrations.Migration): + + dependencies = [ + ("users", "0010_alter_apitoken_key"), + ] + + operations = [ + migrations.RunPython( + clear_sessions, reverse_code=migrations.RunPython.noop, + ) + ]