From dc90db6591d0eff101127cf9c7f5144c20cfdbdc Mon Sep 17 00:00:00 2001 From: Alex <33497058+bexsoft@users.noreply.github.com> Date: Mon, 22 May 2023 11:20:45 -0600 Subject: [PATCH] Changed SSO Login screen to hide login form by default (#2807) Signed-off-by: Benjamin Perez --- models/login_details.go | 3 - portal-ui/src/ProtectedRoutes.tsx | 2 +- portal-ui/src/api/consoleApi.ts | 1 - portal-ui/src/screens/LoginPage/LoginPage.tsx | 250 ++--------- .../src/screens/LoginPage/StrategyForm.tsx | 391 +++++++++--------- portal-ui/src/screens/LoginPage/loginSlice.ts | 14 +- portal-ui/src/screens/LoginPage/types.ts | 1 - .../test-fix-ui-crash-for-policy.ts | 2 +- portal-ui/tests/permissions-2/inspect.ts | 2 +- .../tests/permissions-7/resourceTesting.ts | 10 + portal-ui/tests/utils/roles.ts | 2 +- restapi/embedded_spec.go | 6 - restapi/user_login.go | 10 + swagger.yml | 2 - 14 files changed, 261 insertions(+), 435 deletions(-) diff --git a/models/login_details.go b/models/login_details.go index 51d99c652..ad162ca06 100644 --- a/models/login_details.go +++ b/models/login_details.go @@ -41,9 +41,6 @@ type LoginDetails struct { // animated login AnimatedLogin bool `json:"animatedLogin,omitempty"` - // is direct p v - IsDirectPV bool `json:"isDirectPV,omitempty"` - // is k8 s IsK8S bool `json:"isK8S,omitempty"` diff --git a/portal-ui/src/ProtectedRoutes.tsx b/portal-ui/src/ProtectedRoutes.tsx index ac2eb7cf4..3b500c514 100644 --- a/portal-ui/src/ProtectedRoutes.tsx +++ b/portal-ui/src/ProtectedRoutes.tsx @@ -64,7 +64,7 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => { dispatch(saveSessionResponse(res)); dispatch(userLogged(true)); setSessionLoading(false); - dispatch(globalSetDistributedSetup(res.distributedMode || false)); + dispatch(globalSetDistributedSetup(res?.distributedMode || false)); if (res.customStyles && res.customStyles !== "") { const overrideColorVariants = getOverrideColorVariants( diff --git a/portal-ui/src/api/consoleApi.ts b/portal-ui/src/api/consoleApi.ts index 04d586941..390bd9db7 100644 --- a/portal-ui/src/api/consoleApi.ts +++ b/portal-ui/src/api/consoleApi.ts @@ -466,7 +466,6 @@ export interface LoginDetails { | "service-account" | "redirect-service-account"; redirectRules?: RedirectRule[]; - isDirectPV?: boolean; isK8S?: boolean; animatedLogin?: boolean; } diff --git a/portal-ui/src/screens/LoginPage/LoginPage.tsx b/portal-ui/src/screens/LoginPage/LoginPage.tsx index fbca5dca1..215413de5 100644 --- a/portal-ui/src/screens/LoginPage/LoginPage.tsx +++ b/portal-ui/src/screens/LoginPage/LoginPage.tsx @@ -16,13 +16,9 @@ import React, { Fragment, useEffect } from "react"; import { useNavigate } from "react-router-dom"; -import { Button, Loader, LoginWrapper, RefreshIcon } from "mds"; -import { Theme } from "@mui/material/styles"; -import createStyles from "@mui/styles/createStyles"; -import makeStyles from "@mui/styles/makeStyles"; +import { Box, Button, Loader, LoginWrapper, RefreshIcon } from "mds"; import { loginStrategyType, redirectRule } from "./types"; import MainError from "../Console/Common/MainError/MainError"; -import { spacingUtils } from "../Console/Common/FormComponents/common/styleLibrary"; import { AppState, useAppDispatch } from "../../store"; import { useSelector } from "react-redux"; import { getFetchConfigurationAsync, getVersionAsync } from "./loginThunks"; @@ -31,205 +27,6 @@ import StrategyForm from "./StrategyForm"; import { redirectRules } from "../../utils/sortFunctions"; import { getLogoVar } from "../../config"; -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - position: "absolute", - top: 0, - left: 0, - width: "100%", - height: "100%", - overflow: "auto", - }, - form: { - width: "100%", // Fix IE 11 issue. - }, - submit: { - margin: "30px 0px 8px", - height: 40, - width: "100%", - boxShadow: "none", - padding: "16px 30px", - }, - loginSsoText: { - fontWeight: "700", - marginBottom: "15px", - }, - ssoSelect: { - width: "100%", - fontSize: "13px", - fontWeight: "700", - color: "grey", - }, - ssoMenuItem: { - fontSize: "15px", - fontWeight: "700", - color: theme.palette.primary.light, - "&.MuiMenuItem-divider:last-of-type": { - borderBottom: "none", - }, - "&.Mui-focusVisible": { - backgroundColor: theme.palette.grey["100"], - }, - }, - ssoLoginIcon: { - height: "13px", - marginRight: "25px", - }, - ssoSubmit: { - marginTop: "15px", - "&:first-of-type": { - marginTop: 0, - }, - }, - separator: { - marginLeft: 4, - marginRight: 4, - }, - linkHolder: { - marginTop: 20, - font: "normal normal normal 14px/16px Inter", - }, - miniLinks: { - margin: "auto", - textAlign: "center", - color: "#B2DEF5", - "& a": { - color: "#B2DEF5", - textDecoration: "none", - }, - "& .min-icon": { - width: 10, - color: "#B2DEF5", - }, - }, - miniLogo: { - marginTop: 8, - "& .min-icon": { - height: 12, - paddingTop: 2, - marginRight: 2, - }, - }, - loginPage: { - height: "100%", - margin: "auto", - }, - buttonRetry: { - display: "flex", - justifyContent: "center", - }, - loginContainer: { - flexDirection: "column", - maxWidth: 400, - margin: "auto", - "& .right-items": { - backgroundColor: "white", - padding: 40, - }, - "& .consoleTextBanner": { - fontWeight: 300, - fontSize: "calc(3vw + 3vh + 1.5vmin)", - lineHeight: 1.15, - color: theme.palette.primary.main, - flex: 1, - height: "100%", - display: "flex", - justifyContent: "flex-start", - margin: "auto", - - "& .logoLine": { - display: "flex", - alignItems: "center", - fontSize: 18, - }, - "& .left-items": { - marginTop: 100, - background: - "transparent linear-gradient(180deg, #FBFAFA 0%, #E4E4E4 100%) 0% 0% no-repeat padding-box", - padding: 40, - }, - "& .left-logo": { - "& .min-icon": { - color: theme.palette.primary.main, - width: 108, - }, - marginBottom: 10, - }, - "& .text-line1": { - font: " 100 44px 'Inter'", - }, - "& .text-line2": { - fontSize: 80, - fontWeight: 100, - textTransform: "uppercase", - }, - "& .text-line3": { - fontSize: 14, - fontWeight: "bold", - }, - "& .logo-console": { - display: "flex", - alignItems: "center", - - "@media (max-width: 900px)": { - marginTop: 20, - flexFlow: "column", - - "& svg": { - width: "50%", - }, - }, - }, - }, - }, - "@media (max-width: 900px)": { - loginContainer: { - display: "flex", - flexFlow: "column", - - "& .consoleTextBanner": { - margin: 0, - flex: 2, - - "& .left-items": { - alignItems: "center", - textAlign: "center", - }, - - "& .logoLine": { - justifyContent: "center", - }, - }, - }, - }, - loginStrategyMessage: { - textAlign: "center", - }, - loadingLoginStrategy: { - textAlign: "center", - width: 40, - height: 40, - }, - submitContainer: { - textAlign: "right", - marginTop: 30, - }, - linearPredef: { - height: 10, - }, - retryButton: { - alignSelf: "flex-end", - }, - iconLogo: { - "& .min-icon": { - width: "100%", - }, - }, - ...spacingUtils, - }) -); - export interface LoginStrategyPayload { accessKey: string; secretKey: string; @@ -251,7 +48,6 @@ export const getTargetPath = () => { const Login = () => { const dispatch = useAppDispatch(); const navigate = useNavigate(); - const classes = useStyles(); const loginStrategy = useSelector( (state: AppState) => state.login.loginStrategy @@ -308,19 +104,32 @@ const Login = () => { } default: loginComponent = ( -
+ {loadingFetchConfiguration ? ( - + ) : ( -
-

+ +

An error has occurred
The backend cannot be reached.

-
-
+ +
)} -
+
); } @@ -351,11 +160,18 @@ const Login = () => { logoProps={{ applicationName: "console", subVariant: getLogoVar() }} form={loginComponent} formFooter={ - + Documentation - | + | { > GitHub - | + | { > Support - | + | { > Download - + } promoHeader={ High-Performance Object Store diff --git a/portal-ui/src/screens/LoginPage/StrategyForm.tsx b/portal-ui/src/screens/LoginPage/StrategyForm.tsx index e57122300..f37fbbe98 100644 --- a/portal-ui/src/screens/LoginPage/StrategyForm.tsx +++ b/portal-ui/src/screens/LoginPage/StrategyForm.tsx @@ -14,72 +14,47 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import Grid from "@mui/material/Grid"; -import React from "react"; +import React, { Fragment, useState } from "react"; import { + Box, Button, + DropdownSelector, + Grid, + InputBox, LockFilledIcon, LogoutIcon, PasswordKeyIcon, + Select, UserFilledIcon, } from "mds"; -import { setAccessKey, setSecretKey, setSTS, setUseSTS } from "./loginSlice"; import { - InputAdornment, - LinearProgress, - MenuItem, - Select, - SelectChangeEvent, -} from "@mui/material"; + setAccessKey, + setDisplayEmbeddedIDPForms, + setSecretKey, + setSTS, + setUseSTS, +} from "./loginSlice"; +import { LinearProgress } from "@mui/material"; import { AppState, useAppDispatch } from "../../store"; import { useSelector } from "react-redux"; -import { LoginField } from "./LoginField"; -import makeStyles from "@mui/styles/makeStyles"; -import { Theme } from "@mui/material/styles"; -import createStyles from "@mui/styles/createStyles"; -import { spacingUtils } from "../Console/Common/FormComponents/common/styleLibrary"; import { doLoginAsync } from "./loginThunks"; import { IStrategyForm } from "./types"; -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - position: "absolute", - top: 0, - left: 0, - width: "100%", - height: "100%", - overflow: "auto", - }, - form: { - width: "100%", // Fix IE 11 issue. - }, - submit: { - margin: "30px 0px 8px", - height: 40, - width: "100%", - boxShadow: "none", - padding: "16px 30px", - }, - submitContainer: { - textAlign: "right", - marginTop: 30, - }, - linearPredef: { - height: 10, - }, - ...spacingUtils, - }) -); - const StrategyForm = ({ redirectRules }: IStrategyForm) => { const dispatch = useAppDispatch(); - const classes = useStyles(); + + const [ssoOptionsOpen, ssoOptionsSetOpen] = useState(false); + const [anchorEl, setAnchorEl] = React.useState< + (EventTarget & HTMLButtonElement) | null + >(null); const accessKey = useSelector((state: AppState) => state.login.accessKey); const secretKey = useSelector((state: AppState) => state.login.secretKey); const sts = useSelector((state: AppState) => state.login.sts); const useSTS = useSelector((state: AppState) => state.login.useSTS); + const displaySSOForm = useSelector( + (state: AppState) => state.login.ssoEmbeddedIDPDisplay + ); const loginSending = useSelector( (state: AppState) => state.login.loginSending @@ -90,177 +65,207 @@ const StrategyForm = ({ redirectRules }: IStrategyForm) => { dispatch(doLoginAsync()); }; - let ssoOptions: React.ReactNode = null; + let selectOptions = [ + { + label: useSTS ? "Use Credentials" : "Use STS", + value: useSTS ? "use-sts-cred" : "use-sts", + }, + ]; + let ssoOptions: any[] = []; if (redirectRules.length > 0) { - ssoOptions = redirectRules.map((r, idx) => ( - - - {r.displayName} - {r.serviceType ? ` - ${r.serviceType}` : ""} - - )); + ssoOptions = redirectRules.map((r) => ({ + label: `${r.displayName}${r.serviceType ? ` - ${r.serviceType}` : ""}`, + value: r.redirect, + icon: , + })); + + selectOptions = [ + { label: "Use Credentials", value: "use-sts-cred" }, + { label: "Use STS", value: "use-sts" }, + ]; } - const extraActionSelector = (e: SelectChangeEvent) => { - const value = e.target.value; - + const extraActionSelector = (value: string) => { if (value) { - console.log(value); - if (value.includes("use-sts")) { - console.log("si"); - dispatch(setUseSTS(!useSTS)); + if (redirectRules.length > 0) { + let stsState = true; + + if (value === "use-sts-cred") { + stsState = false; + } + + dispatch(setUseSTS(stsState)); + dispatch(setDisplayEmbeddedIDPForms(true)); return; } - window.location.href = e.target.value as string; + if (value.includes("use-sts")) { + dispatch(setUseSTS(!useSTS)); + return; + } } }; + const submitSSOInitRequest = (value: string) => { + window.location.href = value; + }; + return ( -
- - - ) => - dispatch(setAccessKey(e.target.value)) + {redirectRules.length > 0 && ( + + +