diff --git a/config/start.config.js b/config/start.config.js index ea807fd1..f395262a 100644 --- a/config/start.config.js +++ b/config/start.config.js @@ -15,6 +15,7 @@ module.exports = webpackBase({ DEV_PROXY: { '/api/': proxyTarget, '/assets/': proxyTarget, + '/auth/': proxyTarget, '/extensions/': proxyTarget, '/pulp/': proxyTarget, '/static/rest_framework/': proxyTarget, diff --git a/pulp-ui-config.json b/pulp-ui-config.json index 3964aba0..354e89da 100644 --- a/pulp-ui-config.json +++ b/pulp-ui-config.json @@ -1,6 +1,6 @@ { "API_BASE_PATH": "/pulp/api/v3/", "UI_BASE_PATH": "/ui/", - "UI_EXTERNAL_LOGIN_URI": null, + "UI_EXTERNAL_LOGIN_URI": "/auth/login/", "EXTRA_VERSION": "" } diff --git a/src/api/base.ts b/src/api/base.ts index 4c1bf79d..316a8853 100644 --- a/src/api/base.ts +++ b/src/api/base.ts @@ -10,7 +10,7 @@ export class BaseAPI { this.http = axios.create({ // adapter + withCredentials ensures no popup on http basic auth fail adapter: 'fetch', - withCredentials: false, + //withCredentials: false, // baseURL gets set in PulpAPI paramsSerializer: { diff --git a/src/api/pulp.ts b/src/api/pulp.ts index 05321eb5..5e00fad3 100644 --- a/src/api/pulp.ts +++ b/src/api/pulp.ts @@ -11,11 +11,14 @@ export class PulpAPI extends BaseAPI { this.http.interceptors.request.use((request) => { if (!request.auth) { - request.auth = JSON.parse( + const credentials = JSON.parse( window.sessionStorage.credentials || window.localStorage.credentials || '{}', ); + if (credentials?.username !== 'HACK') { + request.auth = credentials; + } } request.baseURL = config.API_BASE_PATH; diff --git a/src/app-context.tsx b/src/app-context.tsx index 9dd4424f..352d23a9 100644 --- a/src/app-context.tsx +++ b/src/app-context.tsx @@ -14,15 +14,15 @@ export interface IAppContextType { queueAlert: (alert: AlertType) => void; setAlerts: (alerts: AlertType[]) => void; settings; // deprecated - user; // deprecated } export const AppContext = createContext(undefined); export const useAppContext = () => useContext(AppContext); +// FIXME: rename to AlertContext*; deal with deprecated featureFlags & settings export const AppContextProvider = ({ children }: { children: ReactNode }) => { const [alerts, setAlerts] = useState([]); - const { credentials } = useUserContext(); + const { hasPermission } = useUserContext(); // hub compat for now const featureFlags = { @@ -43,7 +43,6 @@ export const AppContextProvider = ({ children }: { children: ReactNode }) => { }; const queueAlert = (alert) => setAlerts((alerts) => [...alerts, alert]); - const hasPermission = (_name) => true; // FIXME: permission handling return ( { queueAlert, setAlerts, settings, - // FIXME: hack - user: credentials - ? { - username: credentials.username, - groups: [], - model_permissions: {}, - } - : null, }} > {children} diff --git a/src/components/delete-user-modal.tsx b/src/components/delete-user-modal.tsx index 7374ef71..9ea8bfeb 100644 --- a/src/components/delete-user-modal.tsx +++ b/src/components/delete-user-modal.tsx @@ -19,7 +19,7 @@ export const DeleteUserModal = ({ user, }: IProps) => { const [waiting, setWaiting] = useState(false); - const { credentials } = useUserContext(); + const { getUsername } = useUserContext(); if (!user || !isOpen) { return null; @@ -29,11 +29,11 @@ export const DeleteUserModal = ({ closeModal(false)} deleteAction={() => deleteUser()} - isDisabled={waiting || user.username === credentials.username} + isDisabled={waiting || user.username === getUsername()} spinner={waiting} title={t`Delete user?`} > - {user.username === credentials.username ? ( + {user.username === getUsername() ? ( t`Deleting yourself is not allowed.` ) : ( diff --git a/src/containers/ansible-remote/tab-access.tsx b/src/containers/ansible-remote/tab-access.tsx index 78fa8a6c..a798f3a7 100644 --- a/src/containers/ansible-remote/tab-access.tsx +++ b/src/containers/ansible-remote/tab-access.tsx @@ -28,7 +28,6 @@ interface TabProps { featureFlags; hasPermission; state: { params }; - user; }; } diff --git a/src/containers/ansible-repository/tab-access.tsx b/src/containers/ansible-repository/tab-access.tsx index 4f1d2ef0..2fb4c587 100644 --- a/src/containers/ansible-repository/tab-access.tsx +++ b/src/containers/ansible-repository/tab-access.tsx @@ -28,7 +28,6 @@ interface TabProps { featureFlags; hasPermission; state: { params }; - user; }; } diff --git a/src/containers/login/login.tsx b/src/containers/login/login.tsx index b71ead81..c0870f16 100644 --- a/src/containers/login/login.tsx +++ b/src/containers/login/login.tsx @@ -14,7 +14,7 @@ function PulpLoginPage(_props) { const { setCredentials, clearCredentials } = useUserContext(); const { next } = useQueryParams(); - const [username, setUsername] = useState(''); + const [username, setUsername] = useState('HACK'); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [redirect, setRedirect] = useState(''); @@ -25,6 +25,15 @@ function PulpLoginPage(_props) { }, []); const onLoginClick = (e) => { + if (username === 'HACK') { + setCredentials(username, password, remember); + setRedirect( + next && next !== '/login/' ? next : formatPath(Paths.core.status), + ); + e?.preventDefault(); + return; + } + PulpLoginAPI.try(username, password) .then(() => { // verified, save diff --git a/src/layout.tsx b/src/layout.tsx index 7d6af8b9..81dad0c3 100644 --- a/src/layout.tsx +++ b/src/layout.tsx @@ -33,16 +33,14 @@ import { useUserContext } from './user-context'; export const StandaloneLayout = ({ children }: { children: ReactNode }) => { const [aboutModalVisible, setAboutModalVisible] = useState(false); - const { credentials, clearCredentials } = useUserContext(); + const { getUsername, clearCredentials } = useUserContext(); + const userName = getUsername(); let aboutModal = null; let docsDropdownItems = []; let userDropdownItems = []; - let userName: string; - - if (credentials) { - userName = credentials.username; + if (userName) { userDropdownItems = [ Username: {userName} diff --git a/src/menu.tsx b/src/menu.tsx index 37c54caa..50e98c27 100644 --- a/src/menu.tsx +++ b/src/menu.tsx @@ -28,7 +28,7 @@ const menuSection = (name, options = {}, items = []) => ({ const altPath = (p) => formatPath(p, {}, null, { ignoreMissing: true }); // condition: loggedIn OR condition: and(loggedIn, hasPlugin('rpm')) -const loggedIn = ({ user }) => !!user; +const loggedIn = ({ isLoggedIn }) => isLoggedIn(); const hasPlugin = (name) => ({ plugins }) => @@ -284,7 +284,7 @@ export const StandaloneMenu = () => { const location = useLocation(); const [menu, setMenu] = useState([]); - const { credentials } = useUserContext(); + const { isLoggedIn } = useUserContext(); const plugins = usePlugins(); @@ -312,7 +312,7 @@ export const StandaloneMenu = () => { diff --git a/src/user-context.tsx b/src/user-context.tsx index f87a4c06..333747d0 100644 --- a/src/user-context.tsx +++ b/src/user-context.tsx @@ -7,15 +7,18 @@ import React, { } from 'react'; interface IUserContextType { + clearCredentials: () => void; credentials: { username: string; password: string; remember: boolean }; + getUsername: () => string; + hasPermission: (name: string) => boolean; + isLoggedIn: () => boolean; setCredentials: ( username: string, password: string, remember?: boolean, ) => void; - clearCredentials: () => void; - updateUsername: (username: string) => void; updatePassword: (password: string) => void; + updateUsername: (username: string) => void; } const UserContext = createContext(undefined); @@ -47,19 +50,30 @@ export const UserContextProvider = ({ children }: { children: ReactNode }) => { window.localStorage.removeItem('credentials'); window.sessionStorage.removeItem('credentials'); } + + // if (!credentials) { + // setCredentials({ username: 'HACK' }); + // } }, [credentials]); + const getUsername = () => credentials?.username; + const isLoggedIn = () => !!credentials?.username; + const hasPermission = (_name) => true; // FIXME: permission handling + return ( setCredentials(null), credentials, + getUsername, + hasPermission, + isLoggedIn, setCredentials: (username, password, remember = false) => setCredentials({ username, password, remember }), - clearCredentials: () => setCredentials(null), - updateUsername: (username) => - setCredentials((credentials) => ({ ...credentials, username })), updatePassword: (password) => setCredentials((credentials) => ({ ...credentials, password })), + updateUsername: (username) => + setCredentials((credentials) => ({ ...credentials, username })), }} > {children}