diff --git a/backend/root/custom_classes/middlewares.py b/backend/root/custom_classes/middlewares.py index 08fbdedd5..206c114db 100644 --- a/backend/root/custom_classes/middlewares.py +++ b/backend/root/custom_classes/middlewares.py @@ -4,6 +4,8 @@ from django.http import HttpRequest, HttpResponse + + LOG = logging.getLogger(__name__) # This token can be imported anywhere to retrieve the values. @@ -49,5 +51,19 @@ def __init__(self, get_response) -> None: # type: ignore # noqa: ANN001 # Uknow self.get_response = get_response def __call__(self, request: HttpRequest) -> HttpResponse: - print("YEEEET DUDE") - return self.get_response(request) + + try: + impersonate = request.get_signed_cookie('impersonated_user_id', default=None) + if impersonate is not None: + from samfundet.models import User + request.user = User.objects.get(id=int(impersonate)) + print("EYOO DUDE YOURE NOT YOURSELF") + except: + pass + + response = self.get_response(request) + + if hasattr(response, 'requested_impersonate_user'): + response.set_signed_cookie('impersonated_user_id', request.user.id) + + return response diff --git a/backend/root/utils/routes.py b/backend/root/utils/routes.py index 97fca8328..75c9a4398 100644 --- a/backend/root/utils/routes.py +++ b/backend/root/utils/routes.py @@ -5,7 +5,7 @@ DO NOT WRITE IN THIS FILE, AS IT WILL BE OVERWRITTEN ON NEXT UPDATE. THIS FILE WAS GENERATED BY: root.management.commands.generate_routes -LAST UPDATE: 2023-08-29 08:57:57.685488+00:00 +LAST UPDATE: 2023-09-14 19:45:16.057665+00:00 """ ############################################################ @@ -424,6 +424,7 @@ samfundet__user = 'samfundet:user' samfundet__groups = 'samfundet:groups' samfundet__users = 'samfundet:users' +samfundet__impersonate = 'samfundet:impersonate' samfundet__eventsperday = 'samfundet:eventsperday' samfundet__eventsupcomming = 'samfundet:eventsupcomming' samfundet__isclosed = 'samfundet:isclosed' diff --git a/backend/samfundet/urls.py b/backend/samfundet/urls.py index a84a4dadd..7bca7b513 100644 --- a/backend/samfundet/urls.py +++ b/backend/samfundet/urls.py @@ -48,6 +48,7 @@ path('user/', views.UserView.as_view(), name='user'), path('groups/', views.AllGroupsView.as_view(), name='groups'), path('users/', views.AllUsersView.as_view(), name='users'), + path('impersonate/', views.ImpersonateView.as_view(), name='impersonate'), path('events-per-day/', views.EventPerDayView.as_view(), name='eventsperday'), path('events-upcomming/', views.EventsUpcomingView.as_view(), name='eventsupcomming'), path('isclosed/', views.IsClosedView().as_view(), name='isclosed'), diff --git a/backend/samfundet/views.py b/backend/samfundet/views.py index ebfe45080..2a38b8069 100644 --- a/backend/samfundet/views.py +++ b/backend/samfundet/views.py @@ -344,6 +344,16 @@ class AllUsersView(ListAPIView): queryset = User.objects.all() +class ImpersonateView(APIView): + permission_classes = [IsAuthenticated] # TODO authentication check + + def post(self, request: Request) -> Response: + user_id = int(request.data.get('user_id')) if hasattr(request, 'user_id') else None + response = Response(status=200) + response.requested_impersonate_user = user_id + return response + + class AllGroupsView(ListAPIView): permission_classes = [IsAuthenticated] serializer_class = GroupSerializer diff --git a/frontend/src/PagesAdmin/ImpersonateUserAdminPage/ImpersonateUserAdminPage.tsx b/frontend/src/PagesAdmin/ImpersonateUserAdminPage/ImpersonateUserAdminPage.tsx index bbd174ff3..d35ca9ddb 100644 --- a/frontend/src/PagesAdmin/ImpersonateUserAdminPage/ImpersonateUserAdminPage.tsx +++ b/frontend/src/PagesAdmin/ImpersonateUserAdminPage/ImpersonateUserAdminPage.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { EventDto, UserDto } from '~/dto'; -import { getUser, getUsers } from '~/api'; +import { getUser, getUsers, impersonateUser } from '~/api'; import styles from './ImpersonateUserAdminPage.module.scss'; import { Table } from '~/Components/Table'; import secretAgent from '~/assets/memes/secret-service.gif'; @@ -11,6 +11,7 @@ import bondmusic from '~/assets/memes/jamesbond.mp3'; import { Icon } from '@iconify/react'; import { InputField } from '~/Components'; import { queryDto } from '~/utils'; +import { useAuthContext } from '~/AuthContext'; export function ImpersonateUserAdminPage() { const [query, setQuery] = useState(''); @@ -39,6 +40,22 @@ export function ImpersonateUserAdminPage() { return `${user.first_name} ${user.last_name}`; } + const auth = useAuthContext(); + function impersonate(user: UserDto) { + impersonateUser(user) + .then((ok) => { + if (ok) { + getUser() + .then((user) => auth.setUser(user)) + .catch(console.error); + alert('nice, middleware is good, TODO proper handling in frontend'); + } + }) + .catch((err) => { + alert(JSON.stringify(err)); + }); + } + return ( <>
@@ -55,10 +72,10 @@ export function ImpersonateUserAdminPage() { inputClassName={styles.inputClass} placeholder={'Search...'} onChange={setQuery} />
{displayUsers.map((u) => ( -
+
+ ))}
diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 2f99c0550..9cd8c7a21 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -78,6 +78,12 @@ export async function getUser(): Promise { return response.data; } +export async function impersonateUser(user: UserDto): Promise { + const url = BACKEND_DOMAIN + ROUTES.backend.samfundet__impersonate; + const response = await axios.post(url, { user_id: user.id }, { withCredentials: true }); + return response.status == 200; +} + export async function getUsers(): Promise { const url = BACKEND_DOMAIN + ROUTES.backend.samfundet__users; const response = await axios.get(url, { withCredentials: true }); diff --git a/frontend/src/routes/backend.ts b/frontend/src/routes/backend.ts index 89aad7ff3..4dc53bb27 100644 --- a/frontend/src/routes/backend.ts +++ b/frontend/src/routes/backend.ts @@ -4,7 +4,7 @@ THIS FILE IS AUTOGENERATED. DO NOT WRITE IN THIS FILE, AS IT WILL BE OVERWRITTEN ON NEXT UPDATE. THIS FILE WAS GENERATED BY: root.management.commands.generate_routes -LAST UPDATE: 2023-08-29 08:57:57.685488+00:00 +LAST UPDATE: 2023-09-14 19:45:16.057665+00:00 """ */ // ############################################################ @@ -423,6 +423,7 @@ export const ROUTES_BACKEND = { samfundet__user: '/user/', samfundet__groups: '/groups/', samfundet__users: '/users/', + samfundet__impersonate: '/impersonate/', samfundet__eventsperday: '/events-per-day/', samfundet__eventsupcomming: '/events-upcomming/', samfundet__isclosed: '/isclosed/', @@ -432,4 +433,4 @@ export const ROUTES_BACKEND = { samfundet__active_recruitment_positions: '/active-recruitment-positions/', static__path: '/static/:path', media__path: '/media/:path', -} as const; +} as const; \ No newline at end of file