Removes references to current_user (#12818)

* Remove refernces to current user id in the cookie

* Removes current_user data from the cookie on api side
This commit is contained in:
Alex Corey
2022-09-27 19:15:57 -04:00
committed by GitHub
parent 42109fb45a
commit 34501fee24
4 changed files with 60 additions and 34 deletions

View File

@@ -97,7 +97,6 @@ class LoggedLoginView(auth_views.LoginView):
current_user = UserSerializer(self.request.user) current_user = UserSerializer(self.request.user)
current_user = smart_str(JSONRenderer().render(current_user.data)) current_user = smart_str(JSONRenderer().render(current_user.data))
current_user = urllib.parse.quote('%s' % current_user, '') current_user = urllib.parse.quote('%s' % current_user, '')
ret.set_cookie('current_user', current_user, secure=settings.SESSION_COOKIE_SECURE or None)
ret.setdefault('X-API-Session-Cookie-Name', getattr(settings, 'SESSION_COOKIE_NAME', 'awx_sessionid')) ret.setdefault('X-API-Session-Cookie-Name', getattr(settings, 'SESSION_COOKIE_NAME', 'awx_sessionid'))
return ret return ret

View File

@@ -45,7 +45,6 @@ class CompleteView(BaseRedirectView):
current_user = UserSerializer(self.request.user) current_user = UserSerializer(self.request.user)
current_user = smart_str(JSONRenderer().render(current_user.data)) current_user = smart_str(JSONRenderer().render(current_user.data))
current_user = urllib.parse.quote('%s' % current_user, '') current_user = urllib.parse.quote('%s' % current_user, '')
response.set_cookie('current_user', current_user, secure=settings.SESSION_COOKIE_SECURE or None)
response.setdefault('X-API-Session-Cookie-Name', getattr(settings, 'SESSION_COOKIE_NAME', 'awx_sessionid')) response.setdefault('X-API-Session-Cookie-Name', getattr(settings, 'SESSION_COOKIE_NAME', 'awx_sessionid'))
return response return response

View File

@@ -1,5 +1,5 @@
/* eslint-disable react/jsx-no-useless-fragment */ /* eslint-disable react/jsx-no-useless-fragment */
import React, { useCallback, useEffect, useRef } from 'react'; import React, { useCallback, useState, useEffect, useRef } from 'react';
import { Redirect, withRouter } from 'react-router-dom'; import { Redirect, withRouter } from 'react-router-dom';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
@@ -28,11 +28,11 @@ import {
UserCircleIcon, UserCircleIcon,
} from '@patternfly/react-icons'; } from '@patternfly/react-icons';
import useRequest, { useDismissableError } from 'hooks/useRequest'; import useRequest, { useDismissableError } from 'hooks/useRequest';
import { AuthAPI, RootAPI } from 'api'; import { AuthAPI, RootAPI, MeAPI } from 'api';
import AlertModal from 'components/AlertModal'; import AlertModal from 'components/AlertModal';
import ErrorDetail from 'components/ErrorDetail'; import ErrorDetail from 'components/ErrorDetail';
import { useSession } from 'contexts/Session'; import { useSession } from 'contexts/Session';
import { getCurrentUserId } from 'util/auth'; import LoadingSpinner from 'components/LoadingSpinner';
import { SESSION_REDIRECT_URL, SESSION_USER_ID } from '../../constants'; import { SESSION_REDIRECT_URL, SESSION_USER_ID } from '../../constants';
const loginLogoSrc = 'static/media/logo-login.svg'; const loginLogoSrc = 'static/media/logo-login.svg';
@@ -44,7 +44,8 @@ const Login = styled(PFLogin)`
`; `;
function AWXLogin({ alt, isAuthenticated }) { function AWXLogin({ alt, isAuthenticated }) {
const { authRedirectTo, isSessionExpired, setAuthRedirectTo } = useSession(); const [userId, setUserId] = useState(null);
const { authRedirectTo, isSessionExpired } = useSession();
const isNewUser = useRef(true); const isNewUser = useRef(true);
const hasVerifiedUser = useRef(false); const hasVerifiedUser = useRef(false);
@@ -107,36 +108,45 @@ function AWXLogin({ alt, isAuthenticated }) {
const { error: authError, dismissError: dismissAuthError } = const { error: authError, dismissError: dismissAuthError } =
useDismissableError(authenticationError); useDismissableError(authenticationError);
const { isLoading: isUserIdLoading, request: fetchUserId } = useRequest(
useCallback(async () => {
if (isAuthenticated(document.cookie)) {
const { data } = await MeAPI.read();
setUserId(data.results[0].id);
}
}, [isAuthenticated])
);
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
dismissAuthError(); dismissAuthError();
await authenticate(values); await authenticate(values);
setAuthRedirectTo('/home'); await fetchUserId();
}; };
if (isCustomLoginInfoLoading) { useEffect(() => {
return null; fetchUserId();
} }, [fetchUserId]);
if (isAuthenticated(document.cookie) && !hasVerifiedUser.current) { const setLocalStorageAndRedirect = useCallback(() => {
const currentUserId = getCurrentUserId(document.cookie); if (userId && !hasVerifiedUser.current) {
const verifyIsNewUser = () => { const verifyIsNewUser = () => {
const previousUserId = JSON.parse( const previousUserId = JSON.parse(
window.localStorage.getItem(SESSION_USER_ID) window.localStorage.getItem(SESSION_USER_ID)
); );
if (previousUserId === null) { if (previousUserId === null) {
return true; return true;
} }
return currentUserId.toString() !== previousUserId.toString(); return userId.toString() !== previousUserId.toString();
}; };
isNewUser.current = verifyIsNewUser(); isNewUser.current = verifyIsNewUser();
hasVerifiedUser.current = true; hasVerifiedUser.current = true;
window.localStorage.setItem(SESSION_USER_ID, JSON.stringify(currentUserId)); window.localStorage.setItem(SESSION_USER_ID, JSON.stringify(userId));
} }
}, [userId]);
if (isAuthenticated(document.cookie) && hasVerifiedUser.current) { useEffect(() => {
const redirect = isNewUser.current ? '/' : authRedirectTo; setLocalStorageAndRedirect();
return <Redirect to={redirect} />; }, [userId, setLocalStorageAndRedirect]);
}
let helperText; let helperText;
if (authError?.response?.status === 401) { if (authError?.response?.status === 401) {
@@ -162,6 +172,17 @@ function AWXLogin({ alt, isAuthenticated }) {
window.sessionStorage.setItem(SESSION_REDIRECT_URL, authRedirectTo); window.sessionStorage.setItem(SESSION_REDIRECT_URL, authRedirectTo);
}; };
if (isCustomLoginInfoLoading) {
return null;
}
if (isUserIdLoading) {
return <LoadingSpinner />;
}
if (userId && hasVerifiedUser.current) {
const redirect = isNewUser.current ? '/home' : authRedirectTo;
return <Redirect to={redirect} />;
}
return ( return (
<Login header={Header} footer={Footer}> <Login header={Header} footer={Footer}>
<LoginMainHeader <LoginMainHeader

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { AuthAPI, RootAPI } from 'api'; import { AuthAPI, RootAPI, MeAPI } from 'api';
import { import {
mountWithContexts, mountWithContexts,
waitForElement, waitForElement,
@@ -12,7 +12,9 @@ import { getCurrentUserId } from 'util/auth';
import { SESSION_USER_ID } from '../../constants'; import { SESSION_USER_ID } from '../../constants';
jest.mock('../../api'); jest.mock('../../api/models/Auth.js');
jest.mock('../../api/models/Root.js');
jest.mock('../../api/models/Me.js');
jest.mock('util/auth', () => ({ jest.mock('util/auth', () => ({
getCurrentUserId: jest.fn(), getCurrentUserId: jest.fn(),
@@ -294,7 +296,7 @@ describe('<Login />', () => {
}); });
test('render Redirect to / when already authenticated as a new user', async () => { test('render Redirect to / when already authenticated as a new user', async () => {
getCurrentUserId.mockReturnValue(1); MeAPI.read.mockResolvedValue({ data: { results: [{ id: 1 }] } });
const history = createMemoryHistory({ const history = createMemoryHistory({
initialEntries: ['/login'], initialEntries: ['/login'],
}); });
@@ -316,17 +318,22 @@ describe('<Login />', () => {
}, },
}); });
}); });
expect(MeAPI.read).toHaveBeenCalled();
expect(window.localStorage.getItem).toHaveBeenCalledWith(SESSION_USER_ID); expect(window.localStorage.getItem).toHaveBeenCalledWith(SESSION_USER_ID);
expect(window.localStorage.setItem).toHaveBeenCalledWith( expect(window.localStorage.setItem).toHaveBeenCalledWith(
SESSION_USER_ID, SESSION_USER_ID,
'1' '1'
); );
await waitForElement(wrapper, 'Redirect', (el) => el.length === 1); await waitForElement(wrapper, 'Redirect', (el) => el.length === 1);
await waitForElement(wrapper, 'Redirect', (el) => el.props().to === '/'); await waitForElement(
wrapper,
'Redirect',
(el) => el.props().to === '/home'
);
}); });
test('render redirect to authRedirectTo when authenticated as a previous user', async () => { test('render redirect to authRedirectTo when authenticated as a previous user', async () => {
getCurrentUserId.mockReturnValue(42); MeAPI.read.mockResolvedValue({ data: { results: [{ id: 42 }] } });
const history = createMemoryHistory({ const history = createMemoryHistory({
initialEntries: ['/login'], initialEntries: ['/login'],
}); });