Coverage for src/mesh/views/middleware.py: 63%

34 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-04-28 07:45 +0000

1from collections.abc import Callable 

2 

3from django.contrib import messages 

4from django.core.exceptions import ImproperlyConfigured 

5from django.http import HttpRequest, HttpResponse 

6from django.utils.translation import gettext_lazy as _ 

7 

8from mesh.model.user.user_interfaces import ImpersonateData 

9from mesh.models.user_models import User 

10 

11 

12def process_impersonate_session(request: HttpRequest) -> None: 

13 if not isinstance(request.user, User): 

14 return 

15 

16 data = ImpersonateData.from_session(request.session) 

17 if not data: 17 ↛ 18line 17 didn't jump to line 18 because the condition on line 17 was never true

18 return 

19 

20 if not data.is_valid(): 

21 ImpersonateData.clean_session(request.session) 

22 messages.warning( 

23 request, 

24 _( 

25 "Your impersonate session has expired. You can restart one using the 'Impersonate user' link from the user menu." 

26 ), 

27 ) 

28 return 

29 

30 try: 

31 # We don't check the user rights to impersonate here. This is done when 

32 # initializing the impersonate session. 

33 # There's a max. duration for the impersonate session that is sufficient to 

34 # prevent security issues. 

35 target_user = User.objects.get(pk=data.target_id) 

36 

37 # TODO: Check the source user has the right to impersonate the target user? 

38 # We don't bother doing it 

39 

40 # Replace user objects by the impersonate target 

41 request.user = target_user 

42 

43 # Corrupted impersonate data 

44 except User.DoesNotExist: 

45 ImpersonateData.clean_session(request.session) 

46 

47 

48class ImpersonateMiddleware: 

49 """ 

50 This middleware enables impersonation of users. 

51 This should be called after the SessionMiddleware and all authentication related 

52 middlewares. 

53 

54 This replaces the user object attached to the HTTP request by the targeted user. 

55 """ 

56 

57 def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]): 

58 self.get_response = get_response 

59 

60 def __call__(self, request: HttpRequest) -> HttpResponse: 

61 if not hasattr(request, "session"): 

62 raise ImproperlyConfigured( 

63 "The ImpersonateMiddleware requires session middleware to be installed." 

64 ) 

65 if not hasattr(request, "user"): 

66 raise ImproperlyConfigured( 

67 "The ImpersonateMiddleware requires authentication middleware to be installed." 

68 ) 

69 if not hasattr(request, "_messages"): 

70 raise ImproperlyConfigured( 

71 "The ImpersonateMiddleware requires the message middleware to be installed." 

72 ) 

73 

74 process_impersonate_session(request) 

75 

76 return self.get_response(request)