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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 = smart_str(JSONRenderer().render(current_user.data))
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'))
return ret

View File

@ -45,7 +45,6 @@ class CompleteView(BaseRedirectView):
current_user = UserSerializer(self.request.user)
current_user = smart_str(JSONRenderer().render(current_user.data))
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'))
return response

View File

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

View File

@ -1,7 +1,7 @@
import React from 'react';
import { createMemoryHistory } from 'history';
import { act } from 'react-dom/test-utils';
import { AuthAPI, RootAPI } from 'api';
import { AuthAPI, RootAPI, MeAPI } from 'api';
import {
mountWithContexts,
waitForElement,
@ -12,7 +12,9 @@ import { getCurrentUserId } from 'util/auth';
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', () => ({
getCurrentUserId: jest.fn(),
@ -294,7 +296,7 @@ describe('<Login />', () => {
});
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({
initialEntries: ['/login'],
});
@ -316,17 +318,22 @@ describe('<Login />', () => {
},
});
});
expect(MeAPI.read).toHaveBeenCalled();
expect(window.localStorage.getItem).toHaveBeenCalledWith(SESSION_USER_ID);
expect(window.localStorage.setItem).toHaveBeenCalledWith(
SESSION_USER_ID,
'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 () => {
getCurrentUserId.mockReturnValue(42);
MeAPI.read.mockResolvedValue({ data: { results: [{ id: 42 }] } });
const history = createMemoryHistory({
initialEntries: ['/login'],
});