Skip to content

Commit

Permalink
fix(oidc) rely on api response for auth checks, as the oidc cookie is…
Browse files Browse the repository at this point in the history
… now httponly and not visible to the ui, hide status bar and avoid operation fetch in case a user is not authenticated, fixes canonical#569

Signed-off-by: David Edler <david.edler@canonical.com>
  • Loading branch information
edlerd committed Feb 21, 2024
1 parent 09f5662 commit 621f2e1
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 19 deletions.
7 changes: 6 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useAuth } from "context/auth";
import { setTitle } from "util/title";
import CustomLayout from "components/CustomLayout";
import NoMatch from "components/NoMatch";
import { logout } from "util/helpers";

const CertificateAdd = lazy(() => import("pages/login/CertificateAdd"));
const CertificateGenerate = lazy(
Expand Down Expand Up @@ -55,13 +56,17 @@ const WarningList = lazy(() => import("pages/warnings/WarningList"));
const HOME_REDIRECT_PATHS = ["/", "/ui", "/ui/project"];

const App: FC = () => {
const { defaultProject, isAuthLoading } = useAuth();
const { defaultProject, isAuthLoading, isAuthenticated } = useAuth();
setTitle();

if (isAuthLoading) {
return <Loader />;
}

if (!isAuthenticated) {
logout();
}

return (
<Suspense
fallback={
Expand Down
6 changes: 2 additions & 4 deletions src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@ import ProjectSelector from "pages/projects/ProjectSelector";
import { isWidthBelow, logout } from "util/helpers";
import { useProject } from "context/project";
import { useMenuCollapsed } from "context/menuCollapsed";
import { getCookie } from "util/cookies";
import { useDocs } from "context/useDocs";

const isSmallScreen = () => isWidthBelow(620);

const Navigation: FC = () => {
const { isRestricted } = useAuth();
const { isRestricted, isOidc } = useAuth();
const docBaseLink = useDocs();
const { menuCollapsed, setMenuCollapsed } = useMenuCollapsed();
const { project, isLoading } = useProject();
const [projectName, setProjectName] = useState(
project && !isLoading ? project.name : "default",
);
const hasOidcCookie = Boolean(getCookie("oidc_access"));

useEffect(() => {
project && project.name !== projectName && setProjectName(project.name);
Expand Down Expand Up @@ -225,7 +223,7 @@ const Navigation: FC = () => {
Settings
</NavLink>
</li>
{hasOidcCookie && (
{isOidc && (
<li className="p-side-navigation__item">
<a
className="p-side-navigation__link"
Expand Down
6 changes: 6 additions & 0 deletions src/components/StatusBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { useToastNotification } from "context/toastNotificationProvider";
import { ICONS, Icon } from "@canonical/react-components";
import { iconLookup, severityOrder } from "util/notifications";
import useEventListener from "@use-it/event-listener";
import { useAuth } from "context/auth";

interface Props {
className?: string;
}

const StatusBar: FC<Props> = ({ className }) => {
const { isAuthLoading, isAuthenticated } = useAuth();
const { toggleListView, notifications, countBySeverity, isListView } =
useToastNotification();

Expand All @@ -22,6 +24,10 @@ const StatusBar: FC<Props> = ({ className }) => {
}
});

if (isAuthLoading || !isAuthenticated) {
return null;
}

const notificationIcons = severityOrder.map((severity) => {
if (countBySeverity[severity]) {
return (
Expand Down
3 changes: 3 additions & 0 deletions src/context/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { fetchProjects } from "api/projects";
interface ContextProps {
isAuthenticated: boolean;
isAuthLoading: boolean;
isOidc: boolean;
isRestricted: boolean;
defaultProject: string;
}

const initialState: ContextProps = {
isAuthenticated: false,
isAuthLoading: true,
isOidc: false,
isRestricted: false,
defaultProject: "default",
};
Expand Down Expand Up @@ -57,6 +59,7 @@ export const AuthProvider: FC<ProviderProps> = ({ children }) => {
<AuthContext.Provider
value={{
isAuthenticated: (settings && settings.auth !== "untrusted") ?? false,
isOidc: settings?.auth_user_method === "oidc",
isAuthLoading: isLoading,
isRestricted,
defaultProject,
Expand Down
5 changes: 5 additions & 0 deletions src/context/operationsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "react";
import { LxdOperation } from "types/operation";
import { queryKeys } from "util/queryKeys";
import { useAuth } from "context/auth";

type OperationsContextType = {
operations: LxdOperation[];
Expand All @@ -32,6 +33,8 @@ const OperationsContext = createContext<OperationsContextType>({
});

const OperationsProvider: FC<Props> = ({ children }) => {
const { isAuthenticated } = useAuth();

const {
data: operationList,
error,
Expand All @@ -40,7 +43,9 @@ const OperationsProvider: FC<Props> = ({ children }) => {
} = useQuery({
queryKey: [queryKeys.operations],
queryFn: () => fetchAllOperations(),
enabled: isAuthenticated,
});

const refetchTimerRef = useRef<NodeJS.Timeout | null>(null);

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions src/types/server.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LxdConfigPair } from "./config";

type LXDAuthMethods = "tls" | "oidc" | "unix";

type SupportedStorageDriver = {
Name: string;
Version: string;
Expand Down
4 changes: 0 additions & 4 deletions src/util/cookies.tsx

This file was deleted.

16 changes: 6 additions & 10 deletions src/util/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { LxdInstance } from "types/instance";
import { LxdProject } from "types/project";
import { LxdProfile } from "types/profile";
import { LxdNetwork } from "types/network";
import { getCookie } from "./cookies";
import { LxdStorageVolume } from "types/storage";
import { Dispatch, SetStateAction } from "react";

Expand Down Expand Up @@ -60,14 +59,7 @@ export const handleResponse = async (response: Response) => {
if (!response.ok) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const result: ErrorResponse = await response.json();
const errorCode = result.error_code;
const isAuthError = errorCode === 401 || errorCode === 403;
const hasOidcCookie = Boolean(getCookie("oidc_access"));
if (isAuthError && hasOidcCookie) {
logout();
} else {
throw Error(result.error);
}
throw Error(result.error);
}
return response.json();
};
Expand Down Expand Up @@ -248,7 +240,11 @@ export const continueOrFinish = (
};

export const logout = (): void =>
void fetch("/oidc/logout").then(() => window.location.reload());
void fetch("/oidc/logout").then(() => {
if (!window.location.href.includes("/ui/login")) {
window.location.href = "/ui/login";
}
});

export const capitalizeFirstLetter = (val: string): string =>
val.charAt(0).toUpperCase() + val.slice(1);
Expand Down

0 comments on commit 621f2e1

Please sign in to comment.